From 362c5d5ca09acf566e5e974de6e427640444d81c Mon Sep 17 00:00:00 2001 From: AdminDroid <49208841+admindroid-community@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:12:05 +0530 Subject: [PATCH] Export Office 365 Admin Report with MS Graph Export Office 365 Admin Report with MS Graph --- Office 365 Admin Report/AdminReport.ps1 | 275 +++++++++++++----------- 1 file changed, 148 insertions(+), 127 deletions(-) diff --git a/Office 365 Admin Report/AdminReport.ps1 b/Office 365 Admin Report/AdminReport.ps1 index 5ab6db1..5570618 100644 --- a/Office 365 Admin Report/AdminReport.ps1 +++ b/Office 365 Admin Report/AdminReport.ps1 @@ -1,163 +1,184 @@ <# ============================================================================================= -Name: Microsoft 365 Admin Report +Name: Export Microsoft 365 Admin Report using MS Graph PowerShell Description: This script exports Microsoft 365 admin role group membership to CSV -Version: 1.0 +Version: 3.0 website: o365reports.com Script by: O365Reports Team For detailed Script execution: https://o365reports.com/2021/03/02/Export-Office-365-admin-role-report-powershell ============================================================================================ #> - param ( -[string] $UserName = $null, -[string] $Password = $null, [switch] $RoleBasedAdminReport, +[switch] $ExcludeGroups, [String] $AdminName = $null, -[String] $RoleName = $null) - +[String] $RoleName = $null, +[string] $TenantId, +[string] $ClientId, +[string] $CertificateThumbprint +) + #Check for module availability -$msOnline = (get-module MsOnline -ListAvailable).Name -if($msOnline -eq $null){ -Write-host "Important: Module MsOnline 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 MsOnline module..." -Install-Module MsOnline -Repository PsGallery -Force -AllowClobber -Write-host "Required Module is installed in the machine Successfully" -ForegroundColor Magenta - } elseif($confirm -cnotmatch "[yY]" ){ -Write-host "Exiting. `nNote: MsOnline module must be available in your system to run the script" -Exit - } +$MsGraphModule = Get-Module Microsoft.Graph -ListAvailable +if($MsGraphModule -eq $null) +{ + Write-host "Important: Microsoft graph 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 module? [Y] Yes [N] No + if($confirm -match "[yY]") + { + Write-host "Installing Microsoft graph module..." + Install-Module Microsoft.Graph -Scope CurrentUser + Write-host "Microsoft graph module is installed in the machine successfully" -ForegroundColor Magenta + } + else + { + Write-host "Exiting. `nNote: Microsoft graph module must be available in your system to run the script" -ForegroundColor Red + Exit + } } - -#Importing Module by default will avoid the cmdlet unrecognized error -Import-Module MsOnline -Force -Write-Host "Connecting to Office 365..." - -#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-MsolService -Credential $credential | Out-Null -} -else - { -Connect-MsolService - } - +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 +{ + Connect-MgGraph -Scopes "Directory.Read.All" -ErrorAction SilentlyContinue -Errorvariable ConnectionError |Out-Null + if($ConnectionError -ne $null) + { + Write-Host "$ConnectionError" -Foregroundcolor Red + Exit + } +} +Write-Host "Microsoft Graph Powershell module is connected successfully" -ForegroundColor Green +Select-MgProfile beta Write-Host "Preparing admin report..." -$admins=@() -$list = @() -$outputCsv=".\AdminReport_$((Get-Date -format MMM-dd` hh-mm` tt).ToString()).csv" - -function process_Admin{ -$roleList= (Get-MsolUserRole -UserPrincipalName $admins.UserPrincipalName | Select-Object -ExpandProperty Name) -join ',' -if($admins.IsLicensed -eq $true) - { -$licenseStatus = "Licensed" - } -else - { -$licenseStatus= "Unlicensed" - } -if($admins.BlockCredential -eq $true) - { -$signInStatus = "Blocked" - } -else - { -$signInStatus = "Allowed" - } -$displayName= $admins.DisplayName -$UPN= $admins.UserPrincipalName -Write-Progress -Activity "Currently processing: $displayName" -Status "Updating CSV file" -if($roleList -ne "") - { -$exportResult=@{'AdminEmailAddress'=$UPN;'AdminName'=$displayName;'RoleName'=$roleList;'LicenseStatus'=$licenseStatus;'SignInStatus'=$signInStatus} -$exportResults= New-Object PSObject -Property $exportResult -$exportResults | Select-Object 'AdminName','AdminEmailAddress','RoleName','LicenseStatus','SignInStatus' | Export-csv -path $outputCsv -NoType -Append - } +$Admins=@() +$RoleList = @() +$OutputCsv=".\AdminReport_$((Get-Date -format MMM-dd` hh-mm` tt).ToString()).csv" +function Process_AdminReport +{ + $AdminMemberOf=Get-MgUserMemberOf -UserId $Admins.Id |Select-Object -ExpandProperty AdditionalProperties + $AssignedRoles=$AdminMemberOf|?{$_.'@odata.type' -eq '#microsoft.graph.directoryRole'} + $DisplayName=$Admins.DisplayName + if($Admins.AssignedLicenses -ne $null) + { + $LicenseStatus = "Licensed" + } + else + { + $LicenseStatus= "Unlicensed" + } + if($Admins.AccountEnabled -eq $true) + { + $SignInStatus = "Allowed" + } + else + { + $SignInStatus = "Blocked" + } + Write-Progress -Activity "Currently processing: $DisplayName" -Status "Updating CSV file" + if($AssignedRoles -ne $null) + { + $ExportResult=@{'Admin EmailAddress'=$Admins.mail;'Admin Name'=$DisplayName;'Assigned Roles'=(@($AssignedRoles.displayName)-join ',');'License Status'=$LicenseStatus;'SignIn Status'=$SignInStatus } + $ExportResults= New-Object PSObject -Property $ExportResult + $ExportResults | Select-Object 'Admin Name','Admin EmailAddress','Assigned Roles','License Status','SignIn Status' | Export-csv -path $OutputCsv -NoType -Append + } } - -function process_Role{ -$adminList = Get-MsolRoleMember -RoleObjectId $roles.ObjectId #Email,DisplayName,Usertype,islicensed -$displayName = ($adminList | Select-Object -ExpandProperty DisplayName) -join ',' -$UPN = ($adminList | Select-Object -ExpandProperty EmailAddress) -join ',' -$RoleName= $roles.Name -Write-Progress -Activity "Processing $RoleName role" -Status "Updating CSV file" -if($displayName -ne "") - { -$exportResult=@{'RoleName'=$RoleName;'AdminEmailAddress'=$UPN;'AdminName'=$displayName} -$exportResults= New-Object PSObject -Property $exportResult -$exportResults | Select-Object 'RoleName','AdminName','AdminEmailAddress' | Export-csv -path $outputCsv -NoType -Append - } -} - +function Process_RoleBasedAdminReport +{ + $AdminList = Get-MgDirectoryRoleMember -DirectoryRoleId $AdminRoles.Id |Select-Object -ExpandProperty AdditionalProperties + $RoleName=$AdminRoles.DisplayName + if($ExcludeGroups.IsPresent) + { + $AdminList=$AdminList| ?{$_.'@odata.type' -eq '#microsoft.graph.user'} + $DisplayName=$AdminList.displayName + } + else + { + $DisplayName=$AdminList.displayName + } + if($DisplayName -ne $null) + { + Write-Progress -Activity "Currently Processing $RoleName role" -Status "Updating CSV file" + $ExportResult=@{'Role Name'=$RoleName;'Admin EmailAddress'=(@($AdminList.mail)-join ',');'Admin Name'=(@($DisplayName)-join ',');'Admin Count'=$DisplayName.Count} + $ExportResults= New-Object PSObject -Property $ExportResult + $ExportResults | Select-Object 'Role Name','Admin Name','Admin EmailAddress','Admin Count' | Export-csv -path $OutputCsv -NoType -Append + } +} + #Check to generate role based admin report if($RoleBasedAdminReport.IsPresent) { -Get-MsolRole | ForEach-Object { -$roles= $_ #$ObjId = $_.ObjectId;$_.Name -process_Role - } + Get-MgDirectoryRole -All| ForEach-Object { + $AdminRoles= $_ + Process_RoleBasedAdminReport + } } #Check to get admin roles for specific user elseif($AdminName -ne "") { -$allUPNs = $AdminName.Split(",") -ForEach($admin in $allUPNs) - { -$admins = Get-MsolUser -UserPrincipalName $admin -ErrorAction SilentlyContinue -if( -not $?) - { -Write-host "$admin is not available. Please check the input" -ForegroundColor Red - } -else - { -process_Admin - } - } + $AllUPNs = $AdminName.Split(",") + ForEach($Admin in $AllUPNs) + { + $Admins=Get-MgUser -UserId $Admin -ErrorAction SilentlyContinue + if($Admins -eq $null) + { + Write-host "$Admin is not available. Please check the input" -ForegroundColor Red + } + else + { + Process_AdminReport + } + } } #Check to get all admins for a specific role elseif($RoleName -ne "") { -$RoleNames = $RoleName.Split(",") -ForEach($name in $RoleNames) - { -$roles= Get-MsolRole -RoleName $name -ErrorAction SilentlyContinue -if( -not $?) - { -Write-Host "$name role is not available. Please check the input" -ForegroundColor Red - } -else - { -process_Role - } - } + $RoleNames = $RoleName.Split(",") + ForEach($Name in $RoleNames) + { + $AdminRoles= Get-MgDirectoryRole -Filter "DisplayName eq '$Name'" -ErrorAction SilentlyContinue + if($AdminRoles -eq $null) + { + Write-Host "$Name role is not available. Please check the input" -ForegroundColor Red + } + else + { + Process_RoleBasedAdminReport + } + } } #Generating all admins report else - { -Get-MsolUser -All | ForEach-Object { -$admins= $_ -process_Admin - } +{ + Get-MgUser -All | ForEach-Object { + $Admins= $_ + Process_AdminReport + } } -write-Host "`nThe script executed successfully" #Open output file after execution -if((Test-Path -Path $outputCsv) -eq "True") { -Write-Host "The Output file availble in $outputCsv" -ForegroundColor Green -$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 "$OutputCSV" - } +if((Test-Path -Path $OutputCsv) -eq "True") +{ + Write-Host "The Output file availble in $outputCsv" -ForegroundColor Green + $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 "$OutputCsv" + Write-Host "Report generated successfuly" -ForegroundColor Green + } } -                                                 \ No newline at end of file +else +{ + Write-Host "No data found" -ForegroundColor Red +} +Disconnect-MgGraph|Out-Null