diff --git a/Office 365 manager report/GetM365ManagerAndDirectReports.ps1 b/Office 365 manager report/GetM365ManagerAndDirectReports.ps1 new file mode 100644 index 0000000..d1709af --- /dev/null +++ b/Office 365 manager report/GetM365ManagerAndDirectReports.ps1 @@ -0,0 +1,238 @@ + +param ( + [string] $UserName = $null, + [string] $Password = $null, + [Switch] $UsersWithoutManager, + [Switch] $DisabledUsers, + [Switch] $UnlicensedUsers, + [Switch] $DirectReports, + [string[]] $Department +) + + +#Check AzureAD module availability and connects the module +Function ConnectToAzureAD { + $AzureAd = (Get-Module AzureAD -ListAvailable).Name + if ($Empty -eq $AzureAd) { + Write-host "Important: AzureAD PowerShell 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 module? [Y] Yes [N] No + if ($confirm -match "[yY]") { + Write-host "Installing AzureAD" + Install-Module AzureAd -Allowclobber -Repository PSGallery -Force + Write-host "AzureAD module is installed in the system successfully." + } + else { + Write-host "Exiting. `nNote: AzureAD PowerShell module must be available in your system to run the script." + Exit + } + } + #Importing Module by default will avoid the cmdlet unrecognized error + Import-Module AzureAd -ErrorAction SilentlyContinue -Force + #Storing credential in script for scheduling purpose/Passing credential as parameter + if (($UserName -ne "") -and ($Password -ne "")) { + $SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force + $Credential = New-Object System.Management.Automation.PSCredential $UserName, $SecuredPassword + Connect-AzureAD -Credential $Credential | Out-Null + } + else { + Connect-AzureAD | Out-Null + } + Write-Host "AzureAD PowerShell module is connected successfully" + #End of Connecting AzureAD +} + +#Handle Empty attributes here +Function GetPrintableValue($RawData) { + if (($null -eq $RawData) -or ($RawData.Equals(""))) { + return "-"; + } else { + $StringVal = $RawData | Out-String + return $StringVal; + } +} + +#Processes the param and prepares respective filters. +Function FindUseCase { + #Appends all the usecases choice of the user + if (($Department.Length) -gt 0) { + $DepartmentList = '"' + ($Department -join '","') + '"' + $UseCaseFilter = '$_.Department -in ' + $DepartmentList + } + if ($DisabledUsers.IsPresent) { + if ($UseCaseFilter -ne $null) { + $UseCaseFilter = $UseCaseFilter.ToString() + '-and $_.AccountEnabled -eq $false' + } + else { + $UseCaseFilter = '$_.AccountEnabled -eq $false' + } + } + if ($UnlicensedUsers.IsPresent) { + if ($UseCaseFilter -ne $null) { + $UseCaseFilter = $UseCaseFilter.ToString() + ' -and ($_.AssignedLicenses).count -eq 0' + } else { + $UseCaseFilter = '($_.AssignedLicenses).count -eq 0' + } + } + + if ($UseCaseFilter -ne $null) { + #Filters the users to generate report + $UseCaseFilter = [ScriptBlock]::Create($UseCaseFilter) + Get-AzureADUser | Where-Object $UseCaseFilter | foreach-object { + $CurrUserData = $_ + ProcessUserData + } + } else { + #No Filter- Gets all the users without any filter + Get-AzureADUser | foreach-object { + $CurrUserData = $_ + ProcessUserData + } + } +} + +#Processes User info and calls respective functions based on the requested report +Function ProcessUserData { + if ($DirectReports.IsPresent) { + $CurrUserDirectReport = Get-AzureADUserDirectReport -ObjectID (($CurrUserData.ObjectId).Tostring()) + if ($CurrUserDirectReport -ne $Empty) { + #Manager has Direct Reports, Exporting Manager and their Direct Reports Info + RetrieveUserDirectReport + ExportManagerAndDirectReports + } + } else { + $CurrManagerData = Get-AzureADUserManager -objectID (($CurrUserData.ObjectId).Tostring()) + + #Processing Manager Report Types + if ($CurrManagerData -ne $Empty -and !$UsersWithoutManager.IsPresent) { + #User has Manager assigned, Exporting User & Manager Data. + RetrieveUserManagerData + ExportUserAndManagerData + } + if ($CurrManagerData -eq $Empty -and $UsersWithoutManager.IsPresent) { + #User has no Manager, Exporting User Data only + RetrieveUserManagerData + ExportUserDataOnly + } + } +} + +#Saves User and Manager info into variables +Function RetrieveUserManagerData { + #Processing user data + $global:ExportedUser = $global:ExportedUser + 1 + $global:UserName = $CurrUserData.DisplayName + $global:UserUPN = $CurrUserData.UserPrincipalName + $global:UserAccountType = $CurrUserData.UserType + $global:UserDepartment = GetPrintableValue $CurrUserData.Department + + if (($CurrUserData.AssignedLicenses) -ne $null) { + $global:UserLicense = "Licensed" + } + else { + $global:UserLicense = "Unlicensed" + + } + if ( ($CurrUserData.AccountEnabled) -eq $True) { + $global:UserAccount = "Active" + } + else { + $global:UserAccount = "Disabled" + } + + #Processing manager data + if ($CurrManagerData -ne $Empty) { + $global:ManagerName = $CurrManagerData.DisplayName + $global:ManagerUPN = $CurrManagerData.UserPrincipalName + $global:ManagerDepartment = GetPrintableValue $CurrManagerData.Department + if ( ($CurrManagerData.AccountEnabled) -eq $True) { + $global:ManagerAccount = "Active" + } + else { + $global:ManagerAccount = "Disabled" + } + } +} + +#Saves Manager and Direct Reports info into variables +Function RetrieveUserDirectReport { + #Pocessing manager data + $global:ExportedUser = $global:ExportedUser + 1 + $global:ManagerName = $CurrUserData.DisplayName + $global:ManagerUPN = $CurrUserData.UserPrincipalName + $global:ManagerDepartment = GetPrintableValue $CurrUserData.Department + + #Processing Direct report data + $global:NoOfDirectReports = ($CurrUserDirectReport.DisplayName).count + if ($global:NoOfDirectReports -gt 1) { + $NameList = @() + $UPNList = @() + + $CurrUserDirectReport | Select-Object DisplayName | ForEach-Object { + $NameList += $($_.DisplayName) + $global:DirectReportsNames = ($NameList -join ", ") + } + $CurrUserDirectReport | Select-Object UserPrincipalName | ForEach-Object { + $UPNList += $($_.UserPrincipalName) + $global:DirectReportsUPNs = ($UPNList -join ", ") + } + + } elseif ($global:NoOfDirectReports.count -eq 1) { + $global:DirectReportsNames = $CurrUserDirectReport.DisplayName + $global:DirectReportsUPNs = $CurrUserDirectReport.UserPrincipalName + } +} + +#Used for 'UsersWithoutManager' param. Exports user info alone. +Function ExportUserDataOnly { + $global:ExportCSVFileName = "UsersWithoutManagerReport-" + $global:ReportTime + Write-Progress "Retrieving the Data of the User: $global:UserName" "Processed Users Count: $global:ExportedUser" + + $ExportResult = @{'User Name' = $global:UserName; 'UPN' = $global:UserUPN; 'Account Status' = $global:UserAccount; 'User Type' = $global:UserAccountType; 'License Status' = $global:UserLicense; 'Department' = $global:UserDepartment } + $ExportResults = New-Object PSObject -Property $ExportResult + $ExportResults | Select-object 'User Name', 'UPN', 'Department', 'User Type', 'Account Status', 'License Status' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force +} + +#Used for 'RetrieveUserManagerData' param. Exports User and Manager info. +Function ExportUserAndManagerData { + $global:ExportCSVFileName = "UsersWithManagerReport-" + $global:ReportTime + Write-Progress "Retrieving the Manager Data of the User: $global:UserName" "Processed Users Count: $global:ExportedUser" + + $ExportResult = @{'User Name' = $global:UserName; 'User UPN' = $global:UserUPN; 'User Account Status' = $global:UserAccount; 'User Account Type' = $global:UserAccountType; 'Manager Name' = $global:ManagerName; 'Manager UPN' = $global:ManagerUPN ; 'Manager Department' = $global:ManagerDepartment; 'Manager Account Status' = $global:ManagerAccount ; 'User Department' = $global:UserDepartment; 'User License Status' = $global:UserLicense } + $ExportResults = New-Object PSObject -Property $ExportResult + $ExportResults | Select-object 'User Name', 'User UPN', 'Manager Name', 'Manager UPN', 'Manager Department', 'Manager Account Status', 'User Department', 'User Account Status', 'User Account Type', 'User License Status' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force +} + +#Used for 'RetrieveUserManagerData' param. Exports User and Direct reports. +Function ExportManagerAndDirectReports { + $global:ExportCSVFileName = "UsersWithDirectReports-" + $global:ReportTime + Write-Progress "Retrieving the Manager Data of: $global:ManagerName" "Processed Managers Count: $global:ExportedUser" + + $ExportResult = @{'Manager Name' = $global:ManagerName; 'Manager UPN' = $global:ManagerUPN; 'Manager Department' = $global:ManagerDepartment; 'No. of Direct Reports' = $global:NoOfDirectReports; 'Direct Reports Names' = $global:DirectReportsNames; 'Direct Reports UPN' = $global:DirectReportsUPNs} + $ExportResults = New-Object PSObject -Property $ExportResult + $ExportResults | Select-object 'Manager Name' , 'Manager UPN' , 'Manager Department' , 'No. of Direct Reports' , 'Direct Reports Names' , 'Direct Reports UPN' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force +} + +# Execution starts here. +ConnectToAzureAD + +$global:ExportedUser = 0 +$global:ReportTime = ((Get-Date -format "MMM-dd hh-mm-ss tt").ToString()) + ".csv" + +FindUseCase + +if ((Test-Path -Path $global:ExportCSVFileName) -eq "True") { + #Open file after code execution finishes + Write-Host "The output file available in $global:ExportCSVFileName" -ForegroundColor Green + write-host "Exported $global:ExportedUser records to CSV." + $prompt = New-Object -ComObject wscript.shell + $userInput = $prompt.popup("Do you want to open output file?", 0, "Open Output File", 4) + If ($userInput -eq 6) { + Invoke-Item "$global:ExportCSVFileName" + } +} else { + #Notification when usecase doesn't have the data in the tenant + Write-Host "No data found with the specified criteria" +} +Write-Host `nFor more Microsoft 365 reports"," please check o365reports.com -ForegroundColor Cyan +Disconnect-AzureAD +Write-host "`nDisconnected AzureAD Session Successfully"