Lab 05: B2B Guest Users - CLI Solutions
Note: These are CLI/PowerShell alternatives. The portal approach in
solution.mdis recommended for AZ-104 exam preparation.
Prerequisites
powershell
# Install Microsoft Graph module (if not installed)
Install-Module Microsoft.Graph -Scope CurrentUser
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "User.Invite.All", "User.ReadWrite.All", "Group.ReadWrite.All", "Directory.ReadWrite.All"
# Azure CLI login
az loginTask 1-2: Review and Configure External Collaboration Settings
powershell
# Using Microsoft Graph PowerShell
# Get current authorization policy (includes guest settings)
$authPolicy = Get-MgPolicyAuthorizationPolicy
$authPolicy | Format-List *Guest*
# View guest invite restrictions
# B2BCollaborationInbound settings
Get-MgPolicyAuthorizationPolicy | Select-Object -ExpandProperty GuestUserRoleId
# Guest role IDs:
# a0b1b346-4d3e-4e8b-98f8-753987be4970 = Same as member users (most permissive)
# 10dae51f-b6af-4016-8d66-8c2a99b929b3 = Limited access (default)
# 2af84b1e-32c8-42b7-82bc-daa82404023b = Restricted access (most restrictive)Task 3: Invite a Guest User
Using Azure CLI
bash
# Invite guest user using Azure CLI
az ad user invite \
--invited-user-email-address "external@partner.com" \
--invited-user-display-name "External Partner User" \
--send-invitation-message true \
--invitation-message-body "Welcome! You're invited to collaborate on Project Alpha"
# Output will include:
# - id (user object ID)
# - inviteRedeemUrl (acceptance URL)
# - statusUsing Microsoft Graph PowerShell
powershell
# Create invitation
$invitation = New-MgInvitation `
-InvitedUserEmailAddress "external@partner.com" `
-InvitedUserDisplayName "External Partner User" `
-SendInvitationMessage:$true `
-InviteRedirectUrl "https://portal.azure.com"
# View invitation details
$invitation | Format-List *Task 4: Examine Guest User Properties
powershell
# Find guest users
Get-MgUser -Filter "userType eq 'Guest'" | Select-Object DisplayName, UserPrincipalName, Mail, UserType
# Get specific guest user by email
$guest = Get-MgUser -Filter "mail eq 'external@partner.com'"
# View all properties
$guest | Format-List *
# Check group memberships
Get-MgUserMemberOf -UserId $guest.Id | ForEach-Object {
Get-MgDirectoryObject -DirectoryObjectId $_.Id
}
# Check role assignments
Get-MgUserAppRoleAssignment -UserId $guest.IdTask 5: Check Invitation Status
powershell
# List all pending invitations (users who haven't accepted)
Get-MgUser -Filter "externalUserState eq 'PendingAcceptance'" |
Select-Object DisplayName, Mail, ExternalUserState
# Resend invitation if needed
$user = Get-MgUser -Filter "mail eq 'external@partner.com'"
# Create new invitation for same user (resend)
New-MgInvitation `
-InvitedUserEmailAddress "external@partner.com" `
-InvitedUser @{ Id = $user.Id } `
-SendInvitationMessage:$true `
-InviteRedirectUrl "https://portal.azure.com"Task 6: Grant Guest User Resource Access
bash
# Create resource group
az group create --name rg-guest-collaboration --location eastus
# Get guest user object ID
GUEST_ID=$(az ad user list --filter "mail eq 'external@partner.com'" --query "[0].id" -o tsv)
# Assign Reader role to guest on resource group
az role assignment create \
--assignee $GUEST_ID \
--role "Reader" \
--resource-group rg-guest-collaboration
# Verify assignment
az role assignment list \
--resource-group rg-guest-collaboration \
--assignee $GUEST_ID \
--output tableTask 7: Add Guest to Security Group and Assign Storage Access
bash
# Create security group
GROUP_ID=$(az ad group create \
--display-name "sg-external-partners" \
--mail-nickname "sg-external-partners" \
--description "External partner access group" \
--query id -o tsv)
# Add guest to group
az ad group member add \
--group sg-external-partners \
--member-id $GUEST_ID
# Verify membership
az ad group member list --group sg-external-partners --query "[].displayName"
# Create storage account
az storage account create \
--resource-group rg-guest-collaboration \
--name stguestcollab$RANDOM \
--sku Standard_LRS \
--location eastus
# Assign group role on storage account
STORAGE_ID=$(az storage account show \
--resource-group rg-guest-collaboration \
--name stguestcollab* \
--query id -o tsv)
az role assignment create \
--assignee $GROUP_ID \
--role "Storage Blob Data Contributor" \
--scope $STORAGE_IDTask 8: Conditional Access (Graph API)
powershell
# Note: Creating Conditional Access policies via CLI requires
# Microsoft Graph PowerShell or direct API calls
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
# Create CA policy targeting guests
$params = @{
DisplayName = "CA-Guest-MFA-Required"
State = "enabledForReportingButNotEnforced"
Conditions = @{
Users = @{
IncludeGuestsOrExternalUsers = @{
GuestOrExternalUserTypes = "b2bCollaborationGuest,b2bCollaborationMember,b2bDirectConnectUser,internalGuest"
ExternalTenants = @{
MembershipKind = "all"
}
}
}
Applications = @{
IncludeApplications = @("All")
}
}
GrantControls = @{
Operator = "OR"
BuiltInControls = @("mfa")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsTask 9: Review Guest Sign-in Logs
powershell
# Get sign-in logs for guest users
Connect-MgGraph -Scopes "AuditLog.Read.All"
# Get recent guest sign-ins
Get-MgAuditLogSignIn -Filter "userType eq 'Guest'" -Top 50 |
Select-Object CreatedDateTime, UserDisplayName, UserPrincipalName,
AppDisplayName, Status, ConditionalAccessStatus
# Get sign-ins for specific guest
Get-MgAuditLogSignIn -Filter "userPrincipalName eq 'external_partner.com#EXT#@tenant.onmicrosoft.com'" |
Select-Object CreatedDateTime, AppDisplayName, StatusTask 10: Remove Guest User
bash
# Remove from group
az ad group member remove \
--group sg-external-partners \
--member-id $GUEST_ID
# Remove direct role assignments
az role assignment delete \
--assignee $GUEST_ID \
--resource-group rg-guest-collaboration
# Delete user
az ad user delete --id $GUEST_ID
# Verify deletion
az ad user show --id $GUEST_ID # Should fail with "Resource not found"Cleanup
bash
# Delete resource group (includes storage account)
az group delete --name rg-guest-collaboration --yes --no-wait
# Delete security group
az ad group delete --group sg-external-partnerspowershell
# Delete Conditional Access policy
$policy = Get-MgIdentityConditionalAccessPolicy |
Where-Object { $_.DisplayName -eq "CA-Guest-MFA-Required" }
Remove-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policy.Id
# Disconnect
Disconnect-MgGraphUseful Commands Reference
| Task | Command |
|---|---|
| Invite guest | New-MgInvitation / az ad user invite |
| List guests | Get-MgUser -Filter "userType eq 'Guest'" |
| Add to group | az ad group member add |
| Remove from group | az ad group member remove |
| Delete user | az ad user delete --id <object-id> |
| View sign-ins | Get-MgAuditLogSignIn -Filter "userType eq 'Guest'" |
| Check invite status | Get-MgUser -Filter "externalUserState eq 'PendingAcceptance'" |
Microsoft Graph API Direct Calls
bash
# Invite user via REST API
curl -X POST "https://graph.microsoft.com/v1.0/invitations" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"invitedUserEmailAddress": "external@partner.com",
"invitedUserDisplayName": "External Partner",
"sendInvitationMessage": true,
"inviteRedirectUrl": "https://portal.azure.com"
}'