AdminDroid 980cda0a72 Export Microsoft 365 Groups report
Export Microsoft 365 Groups report
2023-10-06 18:08:00 +05:30

279 lines
9.2 KiB
PowerShell

<#
=============================================================================================
Name: Microsoft 365 Group Report
Description: This script exports Microsoft 365 groups and their membership to CSV using Microsoft Graph PowerShell
Version: 3.0
Website: o365reports.com
Script Highlights:
~~~~~~~~~~~~~~~~~
1.The script uses Microsoft Graph PowerShell.
2.The script can be executed with certificate-based authentication (CBA) too.
3.Exports the report result to CSV.
4.You can get members count based on Member Type such as User, Group, Contact, etc.
5.The script is scheduler friendly.
6.Above all, the script exports output to nicely formatted 2 CSV files. One with group information and another with detailed group membership information.
For detailed Script execution: https://o365reports.com/2021/02/11/export-microsoft-365-group-report-to-csv-using-powershell
============================================================================================
#>
Param
(
[Parameter(Mandatory = $false)]
[string]$GroupIDsFile,
[switch]$DistributionList,
[switch]$Security,
[switch]$MailEnabledSecurity,
[Switch]$IsEmpty,
[Int]$MinGroupMembersCount,
[string]$TenantId,
[string]$ClientId,
[string]$CertificateThumbprint
)
Function Get_members
{
$DisplayName=$_.DisplayName
Write-Progress -Activity "`n Processed Group count: $Count "`n" Getting members of: $DisplayName"
$EmailAddress=$_.Mail
if($_.GroupTypes -eq "Unified")
{
$GroupType="Microsoft 365"
}
elseif($_.Mail -ne $null)
{
if($_.SecurityEnabled -eq $false)
{
$GroupType="DistributionList"
}
else
{
$GroupType="MailEnabledSecurity"
}
}
else
{
$GroupType="Security"
}
$GroupId=$_.Id
$Recipient=""
$RecipientHash=@{}
for($KeyIndex = 0; $KeyIndex -lt $RecipientTypeArray.Length; $KeyIndex += 2)
{
$key=$RecipientTypeArray[$KeyIndex]
$Value=$RecipientTypeArray[$KeyIndex+1]
$RecipientHash.Add($key,$Value)
}
$Members=Get-MgGroupMember -All -GroupId $GroupId
$MembersCount=$Members.Count
$Members=$Members.AdditionalProperties
#Filter for security group
if(($Security.IsPresent) -and ($GroupType -ne "Security"))
{
Return
}
#Filter for Distribution list
if(($DistributionList.IsPresent) -and ($GroupType -ne "DistributionList"))
{
Return
}
#Filter for mail enabled security group
if(($MailEnabledSecurity.IsPresent) -and ($GroupType -ne "MailEnabledSecurity"))
{
Return
}
#GroupSize Filter
if(([int]$MinGroupMembersCount -ne "") -and ($MembersCount -lt [int]$MinGroupMembersCount))
{
Return
}
#Check for Empty Group
elseif($MembersCount -eq 0)
{
$MemberName="No Members"
$MemberEmail="-"
$RecipientTypeDetail="-"
Print_Output
}
#Loop through each member in a group
else
{
foreach($Member in $Members){
if($IsEmpty.IsPresent)
{
return
}
$MemberName=$Member.displayName
if($Member.'@odata.type' -eq '#microsoft.graph.user')
{
$MemberType="User"
}
elseif($Member.'@odata.type' -eq '#microsoft.graph.group')
{
$MemberType="Group"
}
elseif($Member.'@odata.type' -eq '#microsoft.graph.orgContact')
{
$MemberType="Contact"
}
$MemberEmail=$Member.mail
if($MemberEmail -eq "")
{
$MemberEmail="-"
}
#Get Counts by RecipientTypeDetail
foreach($key in [object[]]$Recipienthash.Keys){
if(($MemberType -eq $key) -eq "true")
{
[int]$RecipientHash[$key]+=1
}
}
Print_Output
}
}
#Order RecipientTypeDetail based on count
$Hash=@{}
$Hash=$RecipientHash.GetEnumerator() | Sort-Object -Property value -Descending |foreach{
if([int]$($_.Value) -gt 0 )
{
if($Recipient -ne "")
{
$Recipient+=";"
}
$Recipient+=@("$($_.Key) - $($_.Value)")
}
if($Recipient -eq "")
{
$Recipient="-"
}
}
#Print Summary report
$Result=@{'DisplayName'=$DisplayName;'EmailAddress'=$EmailAddress;'GroupType'=$GroupType;'GroupMembersCount'=$MembersCount;'MembersCountByType'=$Recipient}
$Results= New-Object PSObject -Property $Result
$Results | Select-Object DisplayName,EmailAddress,GroupType,GroupMembersCount,MembersCountByType | Export-Csv -Path $ExportSummaryCSV -Notype -Append
}
#Print Detailed Output
Function Print_Output
{
$Result=@{'GroupName'=$DisplayName;'GroupEmailAddress'=$EmailAddress;'Member'=$MemberName;'MemberEmail'=$MemberEmail;'MemberType'=$MemberType}
$Results= New-Object PSObject -Property $Result
$Results | Select-Object GroupName,GroupEmailAddress,Member,MemberEmail,MemberType | Export-Csv -Path $ExportCSV -Notype -Append
}
Function CloseConnection
{
Disconnect-MgGraph | Out-Null
Exit
}
Function main()
{
#Check for MSOnline module
$MsGraphModule = Get-Module Microsoft.Graph -ListAvailable
if($MsGraphModule -eq $null)
{
Write-host "Important: MicrosoftGraph 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 `n"Installing MicrosoftGraph module..."
Install-Module Microsoft.Graph -Repository PsGallery -Force -AllowClobber -Scope CurrentUser
Write-host `n"Required Module is installed in the machine Successfully" -ForegroundColor Magenta
}
else
{
Write-host "Exiting. `nNote: MsGraph module must be available in your system to run the script. Please install required module." -ForegroundColor Red
Exit
}
}
Write-Host `n"Connecting to Microsoft Graph..."`n
$Scopes = @("Directory.Read.All"
)
#Storing credential in script for scheduling purpose/ Passing credential as parameter
$Error.Clear()
if(($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbprint -ne ""))
{
try
{
Connect-MgGraph -TenantId $TenantId -AppId $ClientId -CertificateThumbprint $CertificateThumbprint
}
catch
{
Write-Host `n"Please provide Correct Details!" -ForegroundColor Red
Exit
}
}
else
{
Connect-MgGraph -Scopes $Scopes
}
Write-Host `n"Microsoft Graph connected" -ForegroundColor Green
#Set output file
$ExportCSV=".\M365Group-DetailedMembersReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv" #Detailed report
$ExportSummaryCSV=".\M365Group-SummaryReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv" #Summary report
#Get a list of RecipientTypeDetail
$RecipientTypeArray=Get-Content -Path .\RecipientTypeDetails.txt -ErrorAction Stop
$Result=""
$Results=@()
$Count=0
Write-Progress -Activity "Collecting group info"
#Check for input file
if([string]$GroupIDsFile -ne "")
{
#We have an input file, read it into memory
$DG=@()
$DG=Import-Csv -Header "DisplayName" $GroupIDsFile
foreach($item in $DG){
Get-MgGroup -GroupId $item.displayname | Foreach{
$Count++
Get_Members
}
}
}
else
{
#Get all Office 365 group
Get-MgGroup -All -ErrorAction SilentlyContinue -ErrorVariable PermissionError| Foreach{
$Count++
Get_Members
}
if($PermissionError)
{
Write-Host "Please Add permissions!" -ForegroundColor Red
CloseConnection
}
}
#Open output file after execution
Write-Host `n"Script executed successfully"
if((Test-Path -Path $ExportCSV) -eq "True")
{
Write-Host `n" Detailed report available in:" -NoNewline -ForegroundColor Yellow
Write-Host $ExportCSV
Write-host `n" Summary report available in:" -NoNewline -ForegroundColor Yellow
Write-Host $ExportSummaryCSV
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
$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 "$ExportCSV"
Invoke-Item "$ExportSummaryCSV"
CloseConnection
}
}
Else
{
Write-Host `n"No group found" -ForegroundColor Red
CloseConnection
}
}
. main