Skip to content

Instantly share code, notes, and snippets.

@joerodgers
Last active April 3, 2024 16:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joerodgers/7f29f9010a0cfa263da28d4a59004cda to your computer and use it in GitHub Desktop.
Save joerodgers/7f29f9010a0cfa263da28d4a59004cda to your computer and use it in GitHub Desktop.
Gets all External Users Assigned to a SPO/OD4B site in O365
#requires -modules "PnP.PowerShell"
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
# connect to the tenant
Connect-PnPOnline `
-Url [https://$env:O365_TENANT-admin.sharepoint.com]https://$env:O365_TENANT-admin.sharepoint.com `
-ClientId $env:O365_CLIENTID `
-Thumbprint $env:O365_THUMBPRINT `
-Tenant $env:O365_TENANTID `
-ErrorAction Stop
# get all ODSP Urls in the tenant
$sites = Get-PnPTenantSite -IncludeOneDriveSites -Filter "LockState -ne 'NoAccess'"
# query each site for external users
$pageSize = 50
$guests = foreach( $site in $sites )
{
Write-Host "[$(Get-Date)] - Scanning site: $($site.Url)"
do
{
$externalUsers = Get-PnPExternalUser -SiteUrl $site.Url -Position $position -PageSize $pageSize
$externalUsers | Select-Object @{Name="SiteUrl"; E={$site.Url}}, AcceptedAs, DisplayName, UserPrincipalName, InvitedAs, InvitedBy, UniqueId, UserId, WhenCreated, IsCrossTenant
$position += $pageSize
}
while( $externalUsers.Count -eq $pageSize )
$position = 0
}
$timestamp = Get-Date -Format FileDateTime
$guests | Export-Csv -Path "C:\_temp\SPO ExternalUsers_$timestamp.csv" -NoTypeInformation
<#
# collect some basic metrics on the results
$tenantSitesWithGuests = $externalUsers | Group-Object -Property "SiteUrl"
$spoSitesWithGuests = $tenantSitesWithGuests | Where-Object -Property "Name" -notmatch "-my.sharepoint.com"
$od4bSitesWithGuests = $tenantSitesWithGuests | Where-Object -Property "Name" -match "-my.sharepoint.com"
$od4bsites = $sites | Where-Object -Property "Template" -match "SPSPERS"
$sposites = $sites | Where-Object -Property "Template" -notmatch "SPSPERS"
$guestDomainGroups = $externalUsers | Select-Object @{ Name="Domain"; Expression={ $_.AcceptedAs -split "@" | Select-Object -Index 1 }} | Group-Object Domain
$od4bSiteCount = $od4bsites.Count
$spoSiteCount = $sposites.Count
# break out spo site guest accounts by domain type
$spodomaintypes = foreach( $group in $spoSitesWithGuests )
{
$x = [PSCustomObject] @{
SiteUrl = $group.Name
CorporateDomainCount = 0
PersonalDomainCount = 0
}
foreach( $user in $group.Group )
{
if( $user.AcceptedAs -match "gmail.com|yahoo.com|outlook.com|live.com|hotmail.com|aol.com" )
{
$x.PersonalDomainCount++
}
else
{
$x.CorporateDomainCount++
}
}
$x
}
# break out od4b site guest accounts by domain type
$od4bdomaintypes = foreach( $group in $od4bSitesWithGuests )
{
$x = [PSCustomObject] @{
SiteUrl = $group.Name
CorporateDomainCount = 0
PersonalDomainCount = 0
}
foreach( $user in $group.Group )
{
if( $user.AcceptedAs -match "gmail.com|yahoo.com|outlook.com|live.com|hotmail.com|aol.com" )
{
$x.PersonalDomainCount++
}
else
{
$x.CorporateDomainCount++
}
}
$x
}
$table1 = $externalUsers |
Group-Object -Property SiteUrl |
Select-Object Name, Count, @{ Name="Percent"; Expression={ ([Math]::Round( $_.Count / $sites.Count, 4)) * 100 }} |
Sort-Object Name |
Format-Table -AutoSize |
Out-String
$table2 = [PSCustomObject] @{
TotalSitesWithGuests = $tenantSitesWithGuests.Count
TotalSites = $urls.Count
Percent = [Math]::Round( ($tenantSitesWithGuests.Count/$urls.Count), 4) * 100
} | Format-Table -AutoSize | Out-String
$table3 = $guestDomainGroups |
Select-Object Name, Count, @{ Name="Percent"; Expression={ ([Math]::Round( $_.Count / ($guestDomainGroups | Measure-Object -Property Count -Sum).Sum, 2)) * 100 }} |
Sort-Object Percent -Descending |
Format-Table -AutoSize |
Out-String
$table4 = [PSCustomObject] @{
SiteType = "SharePoint"
SitesWithGuestsCount = $spoSitesWithGuests.Count
SitesWithCorpGuestsCount = @($spodomaintypes | Where-Object -Property "CorporateDomainCount" -gt 0).Count
SitesWithNonCorpGuestsCount = @($spodomaintypes | Where-Object -Property "PersonalDomainCount" -gt 0).Count
TotalSites = $spoSiteCount
PercentWithGuests = [Math]::Round( ($spoSitesWithGuests.Count / $sposites.Count), 4) * 100
PercentWithCorpGuests = [Math]::Round( ((($spodomaintypes | Where-Object -Property "CorporateDomainCount" -gt 0).Count) / $sposites.Count), 4) * 100
PercentWithNonCorpGuests = [Math]::Round( ((($spodomaintypes | Where-Object -Property "PersonalDomainCount" -gt 0).Count) / $sposites.Count), 4) * 100
},
[PSCustomObject] @{
SiteType = "OneDrive"
SitesWithGuestsCount = $od4bSitesWithGuests.Count
SitesWithCorpGuestsCount = @($od4bdomaintypes | Where-Object -Property "CorporateDomainCount" -gt 0).Count
SitesWithNonCorpGuestsCount = @($od4bdomaintypes | Where-Object -Property "PersonalDomainCount" -gt 0).Count
TotalSites = $od4bSiteCount
PercentWithGuests = [Math]::Round( ($od4bSitesWithGuests.Count / $sposites.Count), 4) * 100
PercentWithCorpGuests = [Math]::Round( ((($od4bdomaintypes | Where-Object -Property "CorporateDomainCount" -gt 0).Count) / $sposites.Count), 4) * 100
PercentWithNonCorpGuests = [Math]::Round( ((($od4bdomaintypes | Where-Object -Property "PersonalDomainCount" -gt 0).Count) / $sposites.Count), 4) * 100
} | Sort-Object SiteType -Descending | Format-Table -AutoSize | Out-String
$table5 = [PSCustomObject] @{
DomainType = "Corporate"
TotalDomains = $sposites.Count
Percent = [Math]::Round( ($spoSitesWithGuests.Count / $sposites.Count), 4) * 100
},
[PSCustomObject] @{
DomainType = "Personal"
TotalDomains = ($domaintypes | Measure-Object -Property "PersonalDomainCount" -Sum).Sum
Percent = [Math]::Round( ($spoSitesWithGuests.Count / $sposites.Count), 4) * 100
} | Sort-Object SiteType -Descending | Format-Table -AutoSize | Out-String
$table1
$table2
$table3
$table4
$table5
<# example output
Name Count Percent
---- ----- -------
https://contoso.sharepoint.com/sites/ExternalSharing 3 0.35
https://contoso.sharepoint.com/sites/ModernSiteExtSharingTest 1 0.12
https://contoso.sharepoint.com/sites/target 1 0.12
https://contoso.sharepoint.com/sites/teamsite 7 0.81
https://contoso-my.sharepoint.com/ 1 0.12
TotalSitesWithGuests TotalSites Percent
-------------------- ---------- -------
5 867 0.58
Name Count Percent
---- ----- -------
gmail.com 3 23
outlook.com 2 15
M365x797212.onmicrosoft.com 2 15
M365x050801.OnMicrosoft.com 2 15
M365B460882.onmicrosoft.com 1 8
blah.org 1 8
contoso.com 1 8
tailspin.com 1 8
SiteType SitesWithGuestsCount SitesWithCorpGuestsCount SitesWithNonCorpGuestsCount TotalSites PercentWithGuests PercentWithCorpGuests PercentWithNonCorpGuests
-------- -------------------- ------------------------ --------------------------- ---------- ----------------- --------------------- ------------------------
SharePoint 4 4 2 847 0.47 0.47 0.24
OneDrive 1 0 1 20 0.12 0 0
DomainType TotalDomains Percent
---------- ------------ -------
Corporate 847 0.47
Personal 5 0.47
#>
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment