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