Entra / Microsoft 365 · Users & guests
Update managers
A script to explore how to keep manager-employee assignments updated.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes User.ReadWrite.All, Directory.Read.All -NoWelcome
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -Scopes User.ReadWrite.All, Directory.Read.All -NoWelcomeWrite-Host "Setting up manager data..."# The manager data is in a CSV file with three columns: Department, Manager, and Level2Manager# Department Manager Level2Manager# Finance Ben.James@office365itpros.com Tony.Redmond@office365itpros.com# CEO Office Tony.Redmond@office365itpros.com# Sales Brian.Weakliam@office365itpros.com Kim.Akers@office365itpros.com$InputManagerData = "c:\temp\ManagerData.csv"$OutputCSVFile = "c:\temp\ManagerAssignments.csv"[int]$ErrorCount = 0$ManagerHash = @{}# Parse the manager data[array]$ManagerData = Import-Csv -Path $InputManagerDataForEach ($M in $ManagerData) {$ManagerName = $M.Manager$Manager = Get-MgUser -UserId $M.Manager -ErrorAction SilentlyContinueIf ($null -eq $Manager) {Write-Host ("Can't find a user account for {0} for the {1} department" -f $ManagerName, $M.Department)$ErrorCount++} Else {$ManagerHash.Add([string]$M.Department,[string]$M.Manager)}}If ($ErrorCount -gt 0) {Write-Host "Please fix the manager input file before proceeeding..." -foregroundcolor Redbreak}# Find user accounts with assigned licensesWrite-Host "Finding licensed user accounts..."[array]$Users = Get-MgUser -All -PageSize 999 -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable UsersFound `-Property Id, userPrincipalName, displayName, manager, department, jobtitle | Sort-Object DisplayNameIf (!($Users)) {Write-Host "Couldn't find any user accounts with assigned licenses!"break}Write-Host "Checking managers assigned to user accounts..."[array]$UsersNoDepartment = $Users | Where-Object {$null -eq $_.department}[array]$UsersWithDepartment = $Users | Where-Object {$null -ne $_.department}# Get default manager to assign people to when we can't find a department manager$DefaultManager = $ManagerData | Where-Object {$_.Department -eq "Default" } | Select-Object -ExpandProperty Manager$Report = [System.Collections.Generic.List[Object]]::new()ForEach ($User in $UsersWithDepartment) {$DefaultFlag = $Null; $DeptManager = $Null$DepartmentManager = $ManagerHash[$User.Department]# Check if we can identify a department manager for this user accountIf (($DepartmentManager) -and ($DepartmentManager -ne $User.UserPrincipalName)) {Write-Host ("User account {0} has manager {1}" -f $User.displayName, $DepartmentManager)} ElseIf (($DepartmentManager) -and ($DepartmentManager -eq $User.UserPrincipalName)) {# The user is a department manager, so we update with the level 2 manager$DeptManager = $True$DepartmentManager = $ManagerData | Where-Object {$_.Department -eq $User.Department} | Select-Object -ExpandProperty Level2ManagerIf ($DepartmentManager) {Write-Host ("User account {0} is a manager, so we use level 2 manager {1}" -f $User.displayName, $DepartmentManager)}}# Use the default manager if we can't find a department manager for some reason, but don't update the CEOIf (!($DepartmentManager) -and ($User.JobTitle -ne "Chief Executive Officer")) {$DefaultFlag = "Yes"$DepartmentManager = $DefaultManager }$UserManager = (Get-MgUserManager -UserId $User.Id -ErrorAction SilentlyContinue).additionalProperties.userPrincipalNameIf ($DepartmentManager -eq $UserManager) {# Same manager, so don't update$DepartmentManager = $Null }# Update the accountIf ($DepartmentManager) {Write-Host ("Updating user account {0} with manager {1}" -f $User.displayName, $DepartmentManager)$ManagerId = ("https://graph.microsoft.com/v1.0/users/{0}" -f $DepartmentManager)$NewManager = @{"@odata.id"=$ManagerId}Set-MgUserManagerByRef -UserId $User.Id -BodyParameter $NewManager$ReportLine = [PSCustomObject]@{Account = $User.UserPrincipalNameUser = $User.DisplayNameDepartment = $User.DepartmentManager = $DepartmentManager"Department Manager" = $DeptManager"Assigned Default Manager" = $DefaultFlag}$Report.Add($ReportLine)}} # End ForEach User# Output the details of accounts that we didn't process because they don't have a department propertyIf ($UsersNoDepartment) {Write-Host ""Write-Host "These users were not processed because their accounts do not have a populated department"$UsersNoDepartmentWrite-Host ""}# Generate output file$Report | Out-GridView -Title "Users with updated departmental managers"$Report | Export-CSV -NoTypeInformation $OutputCSVFileWrite-Host ("Processing complete. Output file available in {0}." -f $OutputCSVFile)
Attribution
Author
Office365itpros