All scripts
Microsoft 365 621
Viva Engage Community Membership Report
Pulls every Viva Engage (Yammer) community, its membership count, and current admins using Microsoft Graph, so you can spot communities with no active admin or an unusually large membership before they become a governance headache.
Get-VivaEngageCommunityMembershipReport.ps1
<#
.SYNOPSIS
Reports on Viva Engage (Yammer) community membership and admin coverage.
.DESCRIPTION
Connects to Microsoft Graph and pulls every Viva Engage community, its
member count, and the current list of community admins. Communities
with zero admins or an unusually high member count are flagged, so you
can catch ownerless communities and oversized ones before they turn
into a support problem. Requires the Microsoft.Graph module and an
account with Community.Read.All (or Community.ReadWrite.All)
permissions. This uses the beta Graph endpoint since Viva Engage
communities are not yet in v1.0.
.AUTHOR
Shehryar Hassan
.EXAMPLE
.\Get-VivaEngageCommunityMembershipReport.ps1 -LargeCommunityThreshold 500 -OutputPath .\communities.csv
Runs the report, flags communities with more than 500 members, and
writes the results to communities.csv.
#>
[CmdletBinding()]
param(
[int]$LargeCommunityThreshold = 500,
[string]$OutputPath = ".\VivaEngageCommunityReport.csv"
)
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication)) {
Write-Error "Microsoft.Graph module is not installed. Run: Install-Module Microsoft.Graph -Scope CurrentUser"
return
}
Import-Module Microsoft.Graph.Authentication -ErrorAction Stop
Connect-MgGraph -Scopes "Community.Read.All" -NoWelcome
$results = @()
$uri = "https://graph.microsoft.com/beta/employeeExperience/communities?`$top=50"
while ($uri) {
$response = Invoke-MgGraphRequest -Method GET -Uri $uri
foreach ($community in $response.value) {
$communityId = $community.id
$memberCount = 0
$adminNames = @()
try {
$adminUri = "https://graph.microsoft.com/beta/employeeExperience/communities/$communityId/owners?`$select=displayName,mail"
$admins = Invoke-MgGraphRequest -Method GET -Uri $adminUri
$adminNames = $admins.value | ForEach-Object { $_.displayName }
}
catch {
Write-Warning "Could not read admins for community '$($community.displayName)': $($_.Exception.Message)"
}
try {
$memberUri = "https://graph.microsoft.com/beta/employeeExperience/communities/$communityId/members/`$count"
$countResponse = Invoke-MgGraphRequest -Method GET -Uri $memberUri -Headers @{ "ConsistencyLevel" = "eventual" }
$memberCount = [int]$countResponse
}
catch {
Write-Warning "Could not read member count for community '$($community.displayName)': $($_.Exception.Message)"
}
$results += [PSCustomObject]@{
CommunityName = $community.displayName
CommunityId = $communityId
Privacy = $community.privacy
MemberCount = $memberCount
AdminCount = $adminNames.Count
Admins = ($adminNames -join "; ")
NoAdminFlag = ($adminNames.Count -eq 0)
LargeGroupFlag = ($memberCount -gt $LargeCommunityThreshold)
}
}
$uri = $response.'@odata.nextLink'
}
$results | Sort-Object MemberCount -Descending | Export-Csv -Path $OutputPath -NoTypeInformation
$noAdminCount = ($results | Where-Object { $_.NoAdminFlag }).Count
$largeCount = ($results | Where-Object { $_.LargeGroupFlag }).Count
Write-Host "Report saved to $OutputPath"
Write-Host "$($results.Count) communities checked, $noAdminCount with no admin, $largeCount over $LargeCommunityThreshold members"
Disconnect-MgGraph | Out-Null
Read it before you run it, and test in a safe tenant first.