diff --git a/Set Azure AD User Manager using MS Graph/SetAzureADUserManager.ps1 b/Set Azure AD User Manager using MS Graph/SetAzureADUserManager.ps1 new file mode 100644 index 0000000..978b293 --- /dev/null +++ b/Set Azure AD User Manager using MS Graph/SetAzureADUserManager.ps1 @@ -0,0 +1,325 @@ +<# +============================================================================================= +Name: Assign manager to Office 365 users based on the users' properties +Description: This script assigns manager to Office 365 users based on the users' properties +Version: 1.0 +Website: m365scripts.com + +Script Highlights: +1. The script uses MS Graph PowerShell and installs MS Graph PowerShell SDK (if not installed already) upon your confirmation. +2. It can be executed with certificate-based authentication (CBA) too. +3. Assigns Manager in Office 365 by using more than 10+ user properties, such as filtering by department, job title, and city. +4. Furthermore, to assign a manager on a highly-filtered basis. You can use the following parameters. + -ExistingManager – Overrides your existing manager. + -ImportUsersFromCsvPath – Assign a manager to the bulk users through the CSV input file. + -ProcessOnlyUnmanagedUsers – Assign a manager to unmanaged users in the specific user property. + -GetAllUnmanagedUsers – Assign a manager to all unmanaged users. +5. Automatically, downloads a CSV file. The CSV file contains the usernames that match the given condition. +6. Credentials are passed as parameters, so worry not! +7. Generates a log file that contains the result status of your manager assignment. + +For detailed script execution: https://m365scripts.com/microsoft365/set-up-manager-for-office-365-users-based-on-the-users-property +============================================================================================ +#> +param ( + [string] $TenantId, + [string] $ClientId, + [string] $CertificateThumbprint, + [string] $Properties =$null, + [string] $ExistingManager=$null, + [switch] $ProcessOnlyUnmanagedUsers, + [string] $ImportUsersFromCsvPath=$null, + [switch] $GetAllUnmanagedUsers, + [string] $ManagerId="" +) +Function ConnectMgGraphModule +{ + $MsGraphBetaModule = Get-Module Microsoft.Graph.Beta -ListAvailable + if($MsGraphBetaModule -eq $null) + { + Write-host "Important: Microsoft Graph Beta module is unavailable. It is mandatory to have this module installed in the system to run the script successfully." + $confirm = Read-Host Are you sure you want to install Microsoft Graph Beta module? [Y] Yes [N] No + if($confirm -match "[yY]") + { + Write-host "Installing Microsoft Graph Beta module..." + Install-Module Microsoft.Graph.Beta -Scope CurrentUser -AllowClobber + Write-host "Microsoft Graph Beta module is installed in the machine successfully" -ForegroundColor Magenta + } + else + { + Write-host "Exiting. `nNote: Microsoft Graph Beta module must be available in your system to run the script" -ForegroundColor Red + Exit + } + } + try{ + if(($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbprint -ne "")) + { + Connect-MgGraph -TenantId $TenantId -AppId $ClientId -CertificateThumbprint $CertificateThumbprint -ErrorAction SilentlyContinue -ErrorVariable ConnectionError|Out-Null + if($ConnectionError -ne $null) + { + Write-Host $ConnectionError -Foregroundcolor Red + Exit + } + } + else + { + Disconnect-MgGraph -ErrorAction SilentlyContinue| Out-Null + Connect-MgGraph -Scopes "Directory.ReadWrite.All" -ErrorAction SilentlyContinue -Errorvariable ConnectionError |Out-Null + if($ConnectionError -ne $null) + { + Write-Host "$ConnectionError" -Foregroundcolor Red + Exit + } + } + } + catch + { + Write-Host $_.Exception.Message -ForegroundColor Red + Exit + } + Write-Host "Microsoft Graph Beta Powershell module is connected successfully`n" -ForegroundColor Green +} +Function RemoveManagedUsers { + $Users1 = $Users + $Global:Users = @() + Foreach ($User in $Users1) { + $CheckManager = $User.Manager.AdditionalProperties.displayName + $Percent = $Count / $Users1.length * 100 + $Count++ + Write-Progress -Activity "Checking for user as they already having manager or not" -PercentComplete $Percent + if($CheckManager.length -eq 0){ + $Global:Users += $User + } + } + Write-Progress -Activity "users" -Status "Ready" -Completed +} + +Function AssignManager { + if($ProcessOnlyUnmanagedUsers.IsPresent){ + RemoveManagedUsers + } + if(($global:Users).length -eq 0) { + $log = "No User found for this Filter Criteria" + Write-Warning($log) + CloseConnection + } + if($global:AlreadyFromCSV -eq $false){ + ExportUsers + } + While ($true) { + if($ManagerId -eq ""){ + $ManagerId = Read-Host "Enter manager's UserPrincipalName or Objectid" + } + $Manager = $UsersList |Where-Object{$_.UserPrincipalName -eq $ManagerId -or $_.Id -eq $ManagerId} + if($Manager.length -eq 0){ + Write-Warning "Enter the valid UserPrincipalName or object id" + $ManagerId = "" + continue + } + else { + break + } + } + $ErrorCount = 0 + Foreach ($User in $global:Users) { + $log = "Adding $($Manager.DisplayName) to $($User.DisplayName)" + $log>>$logfile + $Percentage = $Count/$global:Users.length * 100 + Write-Progress "Assigning manager($($Manager.DisplayName)) to the user: $($User.UserPrincipalName) Processed Users Count: $Count" -PercentComplete $Percentage + $Param = @{"@odata.id" = "https://graph.microsoft.com/v1.0/users/$($Manager.Id)"} + Set-MgBetaUserManagerByRef -UserId $User.Id -BodyParameter $Param -ErrorAction SilentlyContinue -ErrorVariable Err + if($Err -ne $null) + { + $log = "Manager assignment failed" + $log>>$logfile + $ErrorCount++ + continue + } + $log = "Manager assigned successfully" + $log>>$logfile + $Count++ + } + if($ErrorCount -ne $Users.Count) + { + Write-Host "The Manager($($Manager.DisplayName)) was assigned to your users Successfully" -ForegroundColor Green + } + Write-Host "log file location $logfile" + $prompt = New-Object -ComObject wscript.shell + $UserInput = $prompt.popup("Do you want to open Log file?", 0, "Open Output File", 4) + if ($UserInput -eq 6) { + Invoke-Item "$logfile" + } + CloseConnection +} + +Function ExportUsers { + $Holders = @() + $HeadName = 'UserName' + Foreach($User in $global:Users){ + $Obj = New-Object PSObject + $Obj | Add-Member -MemberType NoteProperty -Name $HeadName -Value $User.UserPrincipalName + $Holders += $Obj + } + $File = "ManagerAssignedUser"+$ReportTime+".csv" + $Holders | Export-csv $File -NoTypeinformation + Write-Host "Exported users are in the File Location- $Path\$File " -ForegroundColor Green +} +Function GetFilteredUsers{ + Foreach($Property in $FilteredProperties.Keys){ + $FilterProperty = $Property + $FilterValue = "$($FilteredProperties[$Property])" + $UsersList = $UsersList |?{$_.$FilterProperty -eq $FilterValue} + } + $global:Users = $UsersList +} + +Function ExistingManager { + $TargetManagerDetails = $UsersList |Where-Object{$_.UserPrincipalName -eq $ExistingManager -or $_.Id -eq $ExistingManager} + $UsersList| Foreach { + $Name = $_.Manager.AdditionalProperties.userPrincipalName + if ($Name.length -ne 0) { + Write-Progress -Activity "checking users having manager as $($TargetManagerDetails.DisplayName)" -Status "Processing : $Count - $($_.DisplayName)" + if(($Name).compareto($TargetManagerDetails.UserPrincipalName) -eq 0){ + $global:Users += $_ + } + $Count++ + } + } +} +Function ImportUsers { + $UserNames = @() + $global:AlreadyFromCSV = $true + try + { + (Import-CSV -path $ImportUsersFromCsvPath) | #file must having header Username and their values as userprincipalname or objectid + ForEach-Object { + $UserNames += $_.Username + } + } + catch + { + Write-Host $_.Exception.Message -ForegroundColor Red + CloseConnection + } + if($UserNames.length -eq 0) { + Write-Warning "No usernames found at the csv file,located at $Path" + CloseConnection + } + Foreach ($UserName in $UserNames) { + $Global:Users += $UsersList |Where-Object{$_.UserPrincipalName -eq $UserName -or $_.Id -eq $UserName} + Write-Progress "Retrieving user information from CSV file ,retrieved users count $Count" -Activity "users" -PercentComplete $Count + $Count++ + } + Write-Progress -Activity "users" -Status "Ready" -Completed + } +Function AllUnManagedUsers { + foreach($User in $UsersList){ + $GetManager = $User.Manager.AdditionalProperties + Write-Progress "Retrieving user with no manager - users count $Count" -Activity "users" -PercentComplete $count + $Count++ + if($getmanager.Count -eq 0) + { + $Global:Users += $User + } + } + Write-Progress -Activity "users" -Status "Ready" -Completed + } + +Function GetFilterProperties{ + $FilteredProperties = @{} + if($Properties -ne "") + { + $Properties= $Properties.Split(",") + Foreach($Property in $Properties) + { + $PropertyExists = $UsersList | Get-Member|?{$_.Name -contains "$Property"} + if($PropertyExists -eq $null) + { + Write-Host "$Property property is not available. Please provide valid property." -ForegroundColor Red + CloseConnection + } + While($true) + { + $PropertyValue = Read-Host "Enter the $Property value" + if($PropertyValue.Length -eq 0) + { + Write-Host "Value couldn't be null. Please enter again." -ForegroundColor Red + Continue + } + break + } + $FilteredProperties.Add($Property,$PropertyValue) + } + } + else + { + #if you want to add any property do it here at $userProperties (note: add only valid property with spellcheck) + $UserProperties = @("","Department","JobTitle","CompanyName","City","Country","State","UsageLocation","UserPrincipalName","DisplayName","AgeGroup","UserType") + if($Properties -eq ""){ + for ($index=1;$index -lt $UserProperties.length;$index++) { + Write-Host("$index)$($UserProperties[$index])") -ForegroundColor Yellow + } + Write-Host "`nEnter your choice from 1 to $(($UserProperties.length)-1). If you want to filter users by multiple attributes, give them as comma separated value." + Write-Host "(For example, if you want to filter users by Department and State, enter your choice as 5,8)" -ForegroundColor Yellow + [string]$Properties = Read-Host("Enter your choice") + } + while($Properties -eq "") + { + Write-Host "Choice couldn't be null. Please enter again." -ForegroundColor Red + [string]$Properties = Read-Host "`nEnter your choice" + } + try{ + [int []]$choice = $Properties.split(',') + for($i=0;$i -lt $choice.Length;$i++){ + [int]$index = $choice[$i] + $propertyValue = Read-Host "Enter $($UserProperties[$index]) value" + if(($propertyValue.length -eq 0)){ + Write-Host "Value couldn't be null. Please enter again." -ForegroundColor Red + $i--; + continue + } + $FilteredProperties.Add($UserProperties[$index],$propertyValue) + } + } + catch{ + Write-Host $_.Exception.Message -ForegroundColor Red + CloseConnection + } + } + GetFilteredUsers +} +Function CloseConnection +{ + Disconnect-MgGraph | Out-Null + Write-Host "Session disconnected successfully" + Exit +} +ConnectMgGraphModule +Write-Host "`nNote: If you encounter module related conflicts, run the script in a fresh Powershell window." -ForegroundColor Yellow +$UsersList = Get-MgBetaUser -All -ExpandProperty Manager +$Global:Users = @() +$Count = 1 +$ReportTime = ((Get-Date -format "MMM-dd hh-mm-ss tt").ToString()) +$LogFileName = "LOGfileForManagerAssignedUser"+$ReportTime+".txt" +$path = (Get-Location).path +$logfile = "$path\$LogFileName" +$global:AlreadyFromCSV = $false +#.................only param properties................... +if($ExistingManager.Length -ne 0){ + ExistingManager + AssignManager +} +if($ImportUsersFromCsvPath.Length -ne 0){ + ImportUsers + AssignManager +} +if($GetAllUnmanagedUsers.IsPresent){ + AllUnManagedUsers + AssignManager +} +#......................................................... +GetFilterProperties +AssignManager + +Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green +Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n \ No newline at end of file