This PowerShell script is designed to connect to Microsoft Graph, retrieve all users and managed Windows devices in an organization, and update the primary user of each device based on the most recent user logon. The key operations in the script are:
- Prompt for Tenant ID: The user is prompted to enter their Tenant ID or primary domain to connect to Microsoft Graph.
- Connect to Microsoft Graph: The script authenticates to Microsoft Graph using the provided Tenant ID and requires several scopes including device management and directory read permissions.
- Retrieve Users and Devices: It fetches all users and Windows devices in the organization using the
Get-MgBetaUser
andGet-MgBetaDeviceManagementManagedDevice
cmdlets. - Identify the Primary User: For each device, the script compares the most recent user logon (determined by the
LastLogOnDateTime
property) to the current primary user. - Update the Primary User: If the most recent user is different from the current primary user, the script makes an API call to update the device's primary user using the Microsoft Graph API.
- Output: It provides feedback on whether the primary user was updated or if no change was necessary.
Here is the Script:
# 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
# Uncomment the following line to actually perform the update
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."
}
}