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”Overview
Section titled “Overview”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.
Script Capabilities
Section titled “Script Capabilities”| Function | Description | Business Value |
|---|---|---|
| User Discovery | Retrieves all users in the organization | Complete user inventory for accurate mapping |
| Device Inventory | Fetches all managed Windows devices | Comprehensive device management coverage |
| Activity Analysis | Identifies most recent user logon per device | Data-driven primary user assignment |
| API Integration | Updates primary user via Microsoft Graph API | Automated user-device relationship management |
| Change Tracking | Reports all primary user updates | Audit trail and compliance documentation |
Script Operations
Section titled “Script Operations”1. Authentication Setup
Section titled “1. Authentication Setup”- 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
2. Data Collection Process
Section titled “2. Data Collection Process”- Retrieves all organizational users using Get-MgBetaUser
- Collects all managed Windows devices via Get-MgBetaDeviceManagementManagedDevice
- Creates efficient user lookup hashtable for performance optimization
3. Primary User Analysis
Section titled “3. Primary User Analysis”- Examines UsersLoggedOn property for each device
- Identifies most recent user based on LastLogOnDateTime
- Compares current primary user with most active user
4. Update Execution
Section titled “4. Update Execution”- 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
Implementation
Section titled “Implementation”# 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 ScopesConnect-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 deviceForEach ($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." }}Key Benefits
Section titled “Key Benefits”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
Technical Requirements
Section titled “Technical Requirements”- 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
Important Considerations
Section titled “Important Considerations”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.