Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate AzureAD B2B Pending and Accepted User Reports. Associated Blog Post can be found here https://blog.darrenjrobinson.com/azure-active-directory-b2b-pending-and-accepted-user-reports/
# Adding the AD library for AuthN
Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureADPreview\2.0.0.52\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
# This is the tenant id of you Azure AD. You can use tenant name instead if you want.
$tenantID = "customer.onmicrosoft.com"
$authString = "https://login.microsoftonline.com/$tenantID"
# The resource URI for your token.
$resource = "https://graph.microsoft.com/"
# This is the common client id.
$client_id = "1950a258-227b-4e31-a9cf-717495945fc2"
# Username and Password
$username = "user@domain.com.au"
$password = "p@$$w0rd1234"
# Output Path
$outPath = "C:\Reports"
# ********************** Authentication to Azure ***************************
# The username must be MFA disabled user Admin at least, and must not be a live id.
$creds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" `
-ArgumentList $Username,$Password
# Create a authentication context with the above authentication string.
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" `
-ArgumentList $authString
# Acquire access token from server.
$authenticationResult = $authContext.AcquireToken($resource,$client_id,$creds)
# Use the access token to setup headers for your http request.
$authHeader = $authenticationResult.AccessTokenType + " " + $authenticationResult.AccessToken
$headers = @{"Authorization"=$authHeader; "Content-Type"="application/json"}
# Get first Page of Results for Accepted B2B Users
$B2BAccepted = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/users?filter=externalUserState eq 'Accepted'" -Headers $headers -Method Get
# Get first Page of Results for Pending B2B Users
$B2BPending = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/users?filter=externalUserState eq 'PendingAcceptance'" -Headers $headers -Method Get
$AcceptedObjects = @()
$PendingObjects = @()
# Add in our first objects
$AcceptedObjects += $B2BAccepted.value
$PendingObjects += $B2BPending.value
$moreAcceptedObjects = $B2BAccepted
$morePendingObjects = $B2BPending
# B2B Accepted
# Get all the remaining objects in batches if we didn't return them all already
if ($B2BAccepted.'@odata.nextLink'){
$moreAcceptedObjects.'@odata.nextLink' = $B2BAccepted.'@odata.nextLink'
do
{
$moreObjects = Invoke-RestMethod -Method Get -Headers @{
Authorization = $authenticationResult.CreateAuthorizationHeader()
'Content-Type' = "application/json"
} -Uri ($moreAcceptedObjects.'@odata.nextLink' -f $authenticationResult.TenantId)
$moreObjects.value.count
$AcceptedObjects += $moreObjects.value
$AcceptedObjects.Count
} while ($moreObjects.'@odata.nextLink')
}
# B2B Pending
# Get all the remaining objects in batches if we didn't return them all already
$moreObjects = $null
if ($B2BPending.'@odata.nextLink'){
$morePendingObjects.'@odata.nextLink' = $B2BPending.'@odata.nextLink'
do
{
$moreObjects = Invoke-RestMethod -Method Get -Headers @{
Authorization = $authenticationResult.CreateAuthorizationHeader()
'Content-Type' = "application/json"
} -Uri ($morePendingObjects.'@odata.nextLink' -f $authenticationResult.TenantId)
$moreObjects.value.count
$PendingObjects += $moreObjects.value
$PendingObjects.Count
} while ($moreObjects.'@odata.nextLink')
}
$ReportTemplate = [pscustomobject][ordered]@{
displayName = $null
mail = $null
accountEnabled = $null
createdDateTime = $null
externalUserStateChangeDateTime = $null
}
$cssStyle = '<style>body{background:#252525;font:87.5%/1.5em Lato,sans-serif;padding:20px}table{border-spacing:1px;border-collapse:collapse;background:#F7F6F6;border-radius:6px;overflow:hidden;max-width:800px;width:100%;margin:0 auto;position:relative}td,th{padding-left:8px}thead tr{height:60px;background:#367AB1;color:#F5F6FA;font-size:1.2em;font-weight:700;text-transform:uppercase}tbody tr{height:48px;border-bottom:1px solid #367AB1;text-transform:capitalize;font-size:1em;&:last-child {;border:0}tr:nth-child(even){background-color:#dae5f4;}tr:nth-child(odd){background:#b8d1f3;}</style>'
$pendingReport = @()
foreach ($pendingUser in $PendingObjects) {
$pendingDate = $null
$createdDate = $null
$pUser = $ReportTemplate.PsObject.Copy()
$pendingDate = get-date($pendingUser.externalUserStateChangeDateTime)
$createdDate = get-date($pendingUser.createdDateTime)
write-host -foregroundcolor yellow "$($pendingUser.displayName) pending since $($pendingDate)"
$pUser.accountEnabled = $pendingUser.accountEnabled
$pUser.createdDateTime = $createdDate
$pUser.displayName = $pendingUser.displayName
$pUser.mail = $pendingUser.mail
$pUser.externalUserStateChangeDateTime = $pendingDate
$pendingReport += $puser
}
$pendingReport | ConvertTo-Html -Body $cssStyle | Out-File "$($outPath)\PendingB2BUsers.html"
$acceptedReport = @()
foreach ($acceptedUser in $AcceptedObjects){
$acceptedDate = get-date($acceptedUser.externalUserStateChangeDateTime)
write-host -foregroundcolor Green "$($acceptedUser.displayName) accepted on $($acceptedDate)"
$pendingDate = $null
$createdDate = $null
$aUser = $ReportTemplate.PsObject.Copy()
$pendingDate = get-date($acceptedUser.externalUserStateChangeDateTime)
$createdDate = get-date($acceptedUser.createdDateTime)
$aUser.accountEnabled = $acceptedUser.accountEnabled
$aUser.createdDateTime = $createdDate
$aUser.displayName = $acceptedUser.displayName
$aUser.mail = $acceptedUser.mail
$aUser.externalUserStateChangeDateTime = $pendingDate
$acceptedReport += $aUser
}
$acceptedReport | ConvertTo-Html -Body $cssStyle | Out-File "$($outPath)\AcceptedB2BUsers.html"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.