This script I use to update employee job titles and managers. It runs monthly for us to sync employee changes in their job titles and managers. This detects if you try and add a manger that is 'below' the user's current status. Meaning you can add yourself as a manger to yourself. Nor could you add an employee that was your subordinate as a manger to yourself.
Create a file called UserUpdates.csv and put in the comma delimited data.
UserPrincipalName,ManagerUPN,JobTitle,Department,OfficeLocation user1@company.com,manager1@company.com,Systems Administrator,IT,NYCuser2@company.com,manager2@company.com,Network Supervisor,ITOP,FLA
Create a new file called UpdateUser.ps1 and paste in the code that is down below in this post.
Change the path in the script to reflect the path your csv file is located
$csvPath = "C:\updates\UserUpdates.csv"
run the script in powershell (as admin) .\UpdateUser.ps1
the script will prompt you for a user with rights to make the changes, usually some administrator of the tenant. Then it will run the script a line at a time.
At time of writing, the prompt that worked for me would look like this style below: And I would select my admin user that had creds. I found that sometimes it would give me a different looking one, and i would have to run the script again, because it would ask for creds every single time it ran a new line in the csv.
# ###########################
# Cobbled together with CoPilot and ChatGTP
# Update the following items via a CSV
# - Manager Job Title Department Office Location
#
# Added circular hierarchy validation
# Uses Microsoft Graph PowerShell SDK
# #############################
# Install module if needed:
# Install-Module Microsoft.Graph -Scope CurrentUser
Import-Module Microsoft.Graph.Users
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
# UserPrincipalName,ManagerUPN,JobTitle,Department,OfficeLocation
# user1@company.com,manager@company.com,Systems Administrator,IT,NYC
$csvPath = "C:\updates\UserUpdates.csv"
# Import CSV
$users = Import-Csv -Path $csvPath
# ###########################
# Function: Detect/Prevent Circular Management Structure
# ###########################
function Test-ManagerCircularReference {
param (
[string]$UserId,
[string]$ManagerId
)
# Prevent self-manager assignment
if ($UserId -eq $ManagerId) {
return $true
}
$currentManagerId = $ManagerId
while ($currentManagerId) {
# Detect circular hierarchy
if ($currentManagerId -eq $UserId) {
return $true
}
try {
$manager = Get-MgUserManager `
-UserId $currentManagerId `
-ErrorAction Stop
if ($manager.Id) {
$currentManagerId = $manager.Id
}
else {
$currentManagerId = $null
}
}
catch {
$currentManagerId = $null
}
}
return $false
}
# ###########################
# Process the CSV file
# ###########################
foreach ($entry in $users) {
$userUPN = $entry.UserPrincipalName.Trim()
$managerUPN = $entry.ManagerUPN.Trim()
$jobTitle = $entry.JobTitle.Trim()
$department = $entry.Department.Trim()
$officeLocation = $entry.OfficeLocation.Trim()
Write-Host ""
Write-Host "Processing: $userUPN" -ForegroundColor Cyan
try {
# ###########################
# Get User
# ###########################
$user = Get-MgUser `
-UserId $userUPN `
-ErrorAction Stop
# ###########################
# Update User Properties
# ###########################
Update-MgUser `
-UserId $user.Id `
-JobTitle $jobTitle `
-Department $department `
-OfficeLocation $officeLocation
Write-Host "SUCCESS: Updated user profile properties." `
-ForegroundColor Green
# ###########################
# Update Manager (if provided)
# ###########################
if (![string]::IsNullOrWhiteSpace($managerUPN)) {
$manager = Get-MgUser `
-UserId $managerUPN `
-ErrorAction Stop
# Validate hierarchy
$hasCircularReference = Test-ManagerCircularReference `
-UserId $user.Id `
-ManagerId $manager.Id
if ($hasCircularReference) {
Write-Host "SKIPPED: Circular hierarchy detected." `
-ForegroundColor Yellow
}
else {
Set-MgUserManagerByRef `
-UserId $user.Id `
-BodyParameter @{
"@odata.id" = "https://graph.microsoft.com/v1.0/users/$($manager.Id)"
}
Write-Host "SUCCESS: Updated manager." `
-ForegroundColor Green
}
}
else {
Write-Host "INFO: No manager specified." `
-ForegroundColor DarkYellow
}
}
catch {
Write-Host "FAILED: $($_.Exception.Message)" `
-ForegroundColor Red
}
}
# Disconnect Graph Session
Disconnect-MgGraph
Write-Host ""
Write-Host "Processing complete." -ForegroundColor Cyan
No comments:
Post a Comment
Feel free to leave a comment! If you have any information that you think should be included, please do so here and I'll get it added in.