AdminDroid 5d5fb939d5 Set Manager to Microsoft 365 User in Bulk
Set Manager to Microsoft 365 User in Bulk
2023-07-17 16:03:18 +05:30

325 lines
13 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<#
=============================================================================================
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