Skip to content

Script to Update Primary User of Windows Devices in Microsoft Graph

Primary User Update Script for Windows Devices

Section titled “Primary User Update Script for Windows Devices”

This comprehensive PowerShell script connects to Microsoft Graph and automates the process of updating the primary user assignment for Windows devices based on the most recent user logon activity. The script ensures accurate user-device relationships for better management and reporting.


FunctionDescriptionBusiness Value
User DiscoveryRetrieves all users in the organizationComplete user inventory for accurate mapping
Device InventoryFetches all managed Windows devicesComprehensive device management coverage
Activity AnalysisIdentifies most recent user logon per deviceData-driven primary user assignment
API IntegrationUpdates primary user via Microsoft Graph APIAutomated user-device relationship management
Change TrackingReports all primary user updatesAudit trail and compliance documentation

  • Prompts for Tenant ID or primary domain
  • Connects to Microsoft Graph Beta endpoint with comprehensive scopes
  • Requires Directory.Read.All, DeviceManagementManagedDevices.ReadWrite.All, AuditLog.Read.All, and Policy.Read.All permissions
  • Retrieves all organizational users using Get-MgBetaUser
  • Collects all managed Windows devices via Get-MgBetaDeviceManagementManagedDevice
  • Creates efficient user lookup hashtable for performance optimization
  • Examines UsersLoggedOn property for each device
  • Identifies most recent user based on LastLogOnDateTime
  • Compares current primary user with most active user
  • Constructs Microsoft Graph API calls for user assignment changes
  • Updates primary user when activity indicates different user should be primary
  • Provides detailed output for all changes and non-changes

Terminal window
# Prompt the user to enter Tenant Id or Primary domain
$TenantId = Read-Host "Please enter Tenant Id or Primary domain"
# Define the scopes needed for the Microsoft Graph API permissions
$Scopes = "Directory.Read.All, DeviceManagementManagedDevices.ReadWrite.All, AuditLog.Read.All, Policy.Read.All"
# Connect to Microsoft Graph with the provided Tenant Id and Scopes
Connect-MgGraph -TenantId $TenantId -Scopes $Scopes -NoWelcome
# Retrieve all users in the organization
$users = Get-MgBetaUser -All
# Retrieve all managed devices in the organization
$devices = Get-MgBetaDeviceManagementManagedDevice -All -Filter "operatingsystem eq 'Windows'"
# Convert the users list to a hashtable for quick lookups
$userHashTable = @{}
ForEach ($user in $users) {
$userHashTable[$user.Id] = $user
}
# Iterate over each managed device
ForEach ($device in $devices) {
# Extract the device ID and device name
$ManagedDeviceId = $device.Id
$ManagedDeviceDeviceName = $device.DeviceName
# Sort the users logged on to the device by last logon date and get the most recent user
$PrimaryUserObjectId = $device.UsersLoggedOn | Sort-Object -Property LastLogOnDateTime -Descending | Select-Object -First 1 | Select-Object -ExpandProperty UserId
# Retrieve the new primary user and the existing user details from the hashtable
$NewUser = $userHashTable[$PrimaryUserObjectId]
$NewUserId = $NewUser.Id
$NewUserPrincipalName = $NewUser.UserPrincipalName
$ExistingUser = $userHashTable[$device.UserId]
$ExistingUserId = $ExistingUser.Id
$ExistingUserPrincipalName = $ExistingUser.UserPrincipalName
# Check if the new primary user is different from the existing primary user
if ($NewUserId -ne $ExistingUserId) {
# Construct the URL for the POST request to set the primary user for the device
$URL = "https://graph.microsoft.com/beta/deviceManagement/managedDevices('$ManagedDeviceId')/users/" + '$ref'
# Create the body of the POST request with the primary user's object ID
$Body = @{
"@odata.id" = "https://graph.microsoft.com/beta/users/$PrimaryUserObjectId"
} | ConvertTo-Json
# Invoke the POST request to the Graph API to update the primary user of the device
Invoke-MgGraphRequest -Uri $URL -Method POST -Body $Body
# Output the change for confirmation
Write-Output "Primary user of $ManagedDeviceDeviceName changed from $ExistingUserPrincipalName to $NewUserPrincipalName"
} else {
# Output the no change needed message
Write-Output "Primary user of $ManagedDeviceDeviceName is already $ExistingUserPrincipalName, no change needed."
}
}

Ideal for: Organizations with shared Windows devices or frequent user changes

Use Cases:

  • Shared device environments (schools, hospitals, retail)
  • Device reassignment scenarios
  • Compliance reporting accuracy
  • User-based license optimization
  • Security incident response

  • Microsoft Graph PowerShell SDK with Beta module
  • Global Administrator or Intune Administrator privileges
  • Microsoft Graph API permissions for device and user management
  • Windows devices with user activity tracking enabled

Critical: This script makes permanent changes to device-user relationships. Always test in a non-production environment first.

Note: The script requires devices to have user logon activity data available. Devices without recent user activity may not be processed.

Performance: For large organizations, consider processing devices in batches to avoid API throttling.