2021-07-13 18:14:56 +05:30
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
2023-10-06 17:28:56 +05:30
Write-host " AzureAD module is installed in the system successfully. "
2021-07-13 18:14:56 +05:30
}
else {
Write-host " Exiting. `n Note: 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
}
2023-10-06 17:28:56 +05:30
Write-Host " AzureAD PowerShell module is connected successfully "
2021-07-13 18:14:56 +05:30
#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 )
2023-10-06 17:28:56 +05:30
Get-AzureADUser | Where-Object $UseCaseFilter | foreach-object {
2021-07-13 18:14:56 +05:30
$CurrUserData = $_
ProcessUserData
}
} else {
#No Filter- Gets all the users without any filter
2023-10-06 17:28:56 +05:30
Get-AzureADUser | foreach-object {
2021-07-13 18:14:56 +05:30
$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
2023-10-06 17:28:56 +05:30
Write-Host " The output file available in $global:ExportCSVFileName " -ForegroundColor Green
2021-07-13 18:14:56 +05:30
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
2023-10-06 17:28:56 +05:30
Write-Host " No data found with the specified criteria "
2021-07-13 18:14:56 +05:30
}
Write-Host ` nFor more Microsoft 365 reports " , " please check o365reports . com -ForegroundColor Cyan
Disconnect-AzureAD
Write-host " `n Disconnected AzureAD Session Successfully "