2023-07-17 16:00:09 +05:30
<#
2021-05-22 15:59:22 +05:30
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Name : Office365 User Membership Report Using PowerShell
Description : This script exports Office 365 user ' s group details to CSV
2023-04-25 20:07:33 +05:30
Version : 3.0
2021-05-22 15:59:22 +05:30
Website : o365reports . com
2023-07-17 16:00:09 +05:30
Script Highlights :
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
1 . Generates 12 different user membership reports .
2 . The script uses MS Graph PowerShell and installs MS Graph PowerShell SDK ( if not installed already ) upon your confirmation .
3 . It can be executed with certificate-based authentication ( CBA ) too .
4 . Supports both MFA and Non-MFA accounts .
5 . Allow to use filter to get guest users and their membership alone .
6 . Allow to use filter to get disabled users ’ membership .
7 . Helps to identify users who are not member of any groups .
8 . Exports report result to CSV .
9 . The script is scheduler-friendly .
2023-04-25 20:07:33 +05:30
For detailed script execution : https : / / o365reports . com / 2021 / 04 / 15 / export-office - 365 -groups -a -user -is -member -of -using -powershell
2021-05-22 15:59:22 +05:30
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#>
2023-04-25 20:07:33 +05:30
2021-04-15 20:52:25 +05:30
param
(
[ String ] $UsersIdentityFile ,
[ Switch ] $GuestUsersOnly ,
[ Switch ] $DisabledUsersOnly ,
2023-04-25 20:07:33 +05:30
[ Switch ] $UsersNotinAnyGroup ,
[ string ] $TenantId ,
[ string ] $ClientId ,
[ string ] $CertificateThumbprint
2021-04-15 20:52:25 +05:30
)
2023-07-17 16:00:09 +05:30
$MsGraphBetaModule = Get-Module Microsoft . Graph . Beta -ListAvailable
if ( $MsGraphBetaModule -eq $null )
2023-04-25 20:07:33 +05:30
{
2023-07-17 16:00:09 +05:30
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
2023-04-25 20:07:33 +05:30
if ( $confirm -match " [yY] " )
{
2023-07-17 16:00:09 +05:30
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
2023-04-25 20:07:33 +05:30
}
else
{
2023-07-17 16:00:09 +05:30
Write-host " Exiting. `n Note: Microsoft Graph Beta module must be available in your system to run the script " -ForegroundColor Red
2023-04-25 20:07:33 +05:30
Exit
}
}
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
}
}
2023-07-17 16:00:09 +05:30
Write-Host " Microsoft Graph Beta PowerShell module is connected successfully " -ForegroundColor Green
Write-Host " `n Note: If you encounter module related conflicts, run the script in a fresh PowerShell window. "
2021-04-15 20:52:25 +05:30
Function UserDetails {
2023-04-25 20:07:33 +05:30
if ( [ string ] $UsersIdentityFile -ne " " )
{
2021-04-15 20:52:25 +05:30
$IdentityList = Import-Csv -Header " UserIdentityValue " $UsersIdentityFile
2023-04-25 20:07:33 +05:30
foreach ( $IdentityValue in $IdentityList )
{
2021-04-15 20:52:25 +05:30
$CurIdentity = $IdentityValue . UserIdentityValue
2023-04-25 20:07:33 +05:30
try
{
2023-07-17 16:00:09 +05:30
$LiveUser = Get-MgBetaUser -UserId " $CurIdentity " -ExpandProperty MemberOf -ErrorAction SilentlyContinue
2023-04-25 20:07:33 +05:30
if ( $GuestUsersOnly . IsPresent -and $LiveUser . UserType -ne " Guest " )
{
2021-04-15 20:52:25 +05:30
continue
}
2023-04-25 20:07:33 +05:30
if ( $DisabledUsersOnly . IsPresent -and $LiveUser . AccountEnabled -eq $true )
{
2021-04-15 20:52:25 +05:30
continue
}
ProcessUser
}
2023-04-25 20:07:33 +05:30
catch
{
2021-04-15 20:52:25 +05:30
Write-Host Given UserIdentity : $CurIdentity is not valid / found .
}
}
}
2023-04-25 20:07:33 +05:30
else
{
if ( $GuestUsersOnly . Ispresent -and $DisabledUsersOnly . Ispresent )
{
2023-07-17 16:00:09 +05:30
Get-MgBetaUser -Filter " UserType eq 'Guest' " -ExpandProperty MemberOf -All | Where-Object { $_ . AccountEnabled -eq $false } | ForEach-Object {
2021-04-15 20:52:25 +05:30
$LiveUser = $_
ProcessUser
}
}
2023-04-25 20:07:33 +05:30
elseif ( $DisabledUsersOnly . Ispresent )
{
2023-07-17 16:00:09 +05:30
Get-MgBetaUser -ExpandProperty MemberOf -All | Where-Object { $_ . AccountEnabled -eq $false } | ForEach-Object {
2021-04-15 20:52:25 +05:30
$LiveUser = $_
ProcessUser
}
}
2023-04-25 20:07:33 +05:30
elseif ( $GuestUsersOnly . Ispresent )
{
2023-07-17 16:00:09 +05:30
Get-MgBetaUser -Filter " UserType eq 'Guest' " -ExpandProperty MemberOf -All | ForEach-Object {
2021-04-15 20:52:25 +05:30
$LiveUser = $_
ProcessUser
}
}
2023-04-25 20:07:33 +05:30
else
{
2023-07-17 16:00:09 +05:30
Get-MgBetaUser -ExpandProperty MemberOf -All | ForEach-Object {
2021-04-15 20:52:25 +05:30
$LiveUser = $_
ProcessUser
}
}
}
}
Function ProcessUser {
$GroupList = @ ( )
2023-04-25 20:07:33 +05:30
$RolesList = @ ( )
$Script:ProcessedUsers + = 1
2021-04-15 20:52:25 +05:30
$Name = $LiveUser . DisplayName
2023-04-25 20:07:33 +05:30
Write-Progress -Activity " Processing $Name " -Status " Processed Users Count: $Script:ProcessedUsers "
2023-07-17 16:00:09 +05:30
$UserMembership = Get-MgBetaUserTransitiveMemberOf -UserId $LiveUser . UserPrincipalName | Select-Object -ExpandProperty AdditionalProperties
2023-04-25 20:07:33 +05:30
$AllGroupData = $UserMembership | Where-object { $_ . '@odata.type' -eq " #microsoft.graph.group " }
if ( $AllGroupData -eq $null )
{
2021-04-15 20:52:25 +05:30
$GroupName = " - "
}
2023-04-25 20:07:33 +05:30
else
{
if ( $UsersNotinAnyGroup . IsPresent )
{
2021-04-15 20:52:25 +05:30
return
}
2023-04-25 20:07:33 +05:30
$GroupName = ( @ ( $AllGroupData . displayName ) -join ',' )
2021-04-15 20:52:25 +05:30
}
2023-04-25 20:07:33 +05:30
$AllRoles = $UserMembership | Where-object { $_ . '@odata.type' -eq " #microsoft.graph.directoryRole " }
if ( $AllRoles -eq $null ) {
2021-04-15 20:52:25 +05:30
$RolesList = " - "
}
2023-04-25 20:07:33 +05:30
else
{
$RolesList = @ ( $AllRoles . displayName ) -join ','
2021-04-15 20:52:25 +05:30
}
2023-04-25 20:07:33 +05:30
if ( $LiveUser . AccountEnabled -eq $True )
{
2021-04-15 20:52:25 +05:30
$AccountStatus = " Enabled "
}
2023-04-25 20:07:33 +05:30
else
{
2021-04-15 20:52:25 +05:30
$AccountStatus = " Disabled "
}
2023-04-25 20:07:33 +05:30
if ( $LiveUser . Department -eq $null )
{
2021-04-15 20:52:25 +05:30
$Department = " - "
}
2023-04-25 20:07:33 +05:30
else
{
2021-04-15 20:52:25 +05:30
$Department = $LiveUser . Department
}
2023-04-25 20:07:33 +05:30
if ( $LiveUser . AssignedLicenses -ne " " )
{
2021-04-15 20:52:25 +05:30
$LicenseStatus = " Licensed "
}
2023-04-25 20:07:33 +05:30
else
{
2021-04-15 20:52:25 +05:30
$LicenseStatus = " Unlicensed "
}
ExportResults
}
Function ExportResults {
2023-04-25 20:07:33 +05:30
$Script:ExportedUsers + = 1
$ExportResult = [ PSCustomObject ] @ { 'Display Name' = $Name ; 'Email Address' = $LiveUser . UserPrincipalName ; 'Group Name(s)' = $GroupName ; 'License Status' = $LicenseStatus ; 'Account Status' = $AccountStatus ; 'Department' = $Department ; 'Admin Roles' = $RolesList }
$ExportResult | Export-csv -path $ExportCSVFileName -NoType -Append
2021-04-15 20:52:25 +05:30
}
2023-04-25 20:07:33 +05:30
$ProcessedUsers = 0
$ExportedUsers = 0
2021-04-15 20:52:25 +05:30
$ExportCSVFileName = " .\UserMembershipReport_ $( ( Get-Date -format MMM-dd ` hh-mm -ss ` tt ) . ToString ( ) ) .csv "
UserDetails
#Open output file after execution
if ( ( Test-Path -Path $ExportCSVFileName ) -eq " True " ) {
Write-Progress -Activity " -- " -Completed
2023-04-25 20:07:33 +05:30
Write-Host " `n The Output result has " -NoNewline
Write-Host $Script:ExportedUsers Users -ForegroundColor Magenta -NoNewline
Write-Host " details "
2023-07-17 16:00:09 +05:30
Write-Host ` nThe Output file available in -NoNewline -Foregroundcolor Yellow ; Write-Host $ExportCSVFileName
2021-04-15 20:52:25 +05:30
$prompt = New-Object -ComObject wscript . shell
$userInput = $prompt . popup ( " Do you want to open output file? " , 0 , " Open Output File " , 4 )
2023-04-25 20:07:33 +05:30
if ( $userInput -eq 6 ) {
2021-04-15 20:52:25 +05:30
Invoke-Item " $ExportCSVFileName "
}
}
2023-04-25 20:07:33 +05:30
else
{
2023-07-17 16:00:09 +05:30
Write-Host ` nNo data / user found with the specified criteria
}
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