Lab 03: Conditional Access - CLI Solutions
Note: Conditional Access policies are primarily managed through the portal. CLI/PowerShell is useful for automation and bulk operations.
Prerequisites
powershell
# Install Microsoft Graph module
Install-Module Microsoft.Graph -Scope CurrentUser
# Connect with appropriate scopes
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess", "Policy.Read.All", "Directory.Read.All"Task 1-2: Named Locations
Create IP-based Named Location
powershell
# Create a trusted IP location
$params = @{
"@odata.type" = "#microsoft.graph.ipNamedLocation"
displayName = "Corporate Office IPs"
isTrusted = $true
ipRanges = @(
@{
"@odata.type" = "#microsoft.graph.iPv4CidrRange"
cidrAddress = "203.0.113.0/24"
}
@{
"@odata.type" = "#microsoft.graph.iPv4CidrRange"
cidrAddress = "198.51.100.0/24"
}
)
}
New-MgIdentityConditionalAccessNamedLocation -BodyParameter $paramsCreate Country-based Named Location
powershell
# Create blocked countries location
$params = @{
"@odata.type" = "#microsoft.graph.countryNamedLocation"
displayName = "Blocked Countries"
countriesAndRegions = @("RU", "CN", "KP", "IR")
includeUnknownCountriesAndRegions = $false
}
New-MgIdentityConditionalAccessNamedLocation -BodyParameter $paramsList Named Locations
powershell
# List all named locations
Get-MgIdentityConditionalAccessNamedLocation |
Select-Object DisplayName, Id, "@odata.type"Task 3-6: Conditional Access Policies
Create Basic CA Policy (MFA for All)
powershell
# Policy: Require MFA for all users, all apps
$params = @{
displayName = "CA-Require-MFA-All-Users"
state = "enabledForReportingButNotEnforced" # Report-only mode
conditions = @{
users = @{
includeUsers = @("All")
excludeUsers = @("admin-account-object-id") # Emergency access
}
applications = @{
includeApplications = @("All")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsCreate Location-based Policy
powershell
# Get the blocked countries location ID
$blockedLocation = Get-MgIdentityConditionalAccessNamedLocation |
Where-Object { $_.DisplayName -eq "Blocked Countries" }
# Policy: Block sign-ins from blocked countries
$params = @{
displayName = "CA-Block-High-Risk-Countries"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
}
applications = @{
includeApplications = @("All")
}
locations = @{
includeLocations = @($blockedLocation.Id)
}
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsCreate Policy Targeting Specific Group
powershell
# Get group ID
$group = Get-MgGroup -Filter "displayName eq 'CA-Test-Group'"
# Policy for specific group
$params = @{
displayName = "CA-MFA-For-Test-Group"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeGroups = @($group.Id)
}
applications = @{
includeApplications = @("All")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsCreate Guest User Policy
powershell
# Policy: MFA for all guest users
$params = @{
displayName = "CA-Guest-MFA-Required"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeGuestsOrExternalUsers = @{
guestOrExternalUserTypes = "b2bCollaborationGuest,b2bCollaborationMember"
externalTenants = @{
membershipKind = "all"
}
}
}
applications = @{
includeApplications = @("All")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsTask 7: Enable Policy (Change from Report-Only)
powershell
# Get policy
$policy = Get-MgIdentityConditionalAccessPolicy |
Where-Object { $_.DisplayName -eq "CA-Require-MFA-All-Users" }
# Update to enabled
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policy.Id `
-State "enabled"
# Or back to report-only
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policy.Id `
-State "enabledForReportingButNotEnforced"Task 8-9: Review and Audit
List All Policies
powershell
# List all CA policies with their state
Get-MgIdentityConditionalAccessPolicy |
Select-Object DisplayName, State, Id |
Format-Table -AutoSizeGet Policy Details
powershell
# Get specific policy details
$policy = Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId "policy-id"
$policy | ConvertTo-Json -Depth 10Export All Policies (Backup)
powershell
# Export all policies to JSON
$policies = Get-MgIdentityConditionalAccessPolicy
$policies | ConvertTo-Json -Depth 10 | Out-File "ca-policies-backup.json"Check Sign-in Logs for CA Impact
powershell
# Get sign-in logs with CA results
Connect-MgGraph -Scopes "AuditLog.Read.All"
Get-MgAuditLogSignIn -Top 50 |
Select-Object CreatedDateTime, UserDisplayName, AppDisplayName,
ConditionalAccessStatus |
Format-Table -AutoSize
# Filter for failures due to CA
Get-MgAuditLogSignIn -Filter "conditionalAccessStatus eq 'failure'" -Top 50 |
Select-Object CreatedDateTime, UserDisplayName, AppDisplayNameAzure CLI Alternative
bash
# Note: Azure CLI has limited CA support, use Graph API or PowerShell
# List CA policies using REST
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
# Create policy using REST
az rest --method POST \
--url "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" \
--body '{
"displayName": "CA-Test-Policy",
"state": "enabledForReportingButNotEnforced",
"conditions": {
"users": {
"includeUsers": ["All"]
},
"applications": {
"includeApplications": ["All"]
}
},
"grantControls": {
"operator": "OR",
"builtInControls": ["mfa"]
}
}'Policy Templates (Common Scenarios)
Block Legacy Authentication
powershell
$params = @{
displayName = "CA-Block-Legacy-Auth"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
}
applications = @{
includeApplications = @("All")
}
clientAppTypes = @("exchangeActiveSync", "other")
}
grantControls = @{
operator = "OR"
builtInControls = @("block")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsRequire Compliant Device
powershell
$params = @{
displayName = "CA-Require-Compliant-Device"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
}
applications = @{
includeApplications = @("All")
}
platforms = @{
includePlatforms = @("all")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("compliantDevice")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsSession Control - Sign-in Frequency
powershell
$params = @{
displayName = "CA-Session-Timeout"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
}
applications = @{
includeApplications = @("All")
}
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
sessionControls = @{
signInFrequency = @{
value = 4
type = "hours"
isEnabled = $true
}
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $paramsCleanup
powershell
# Delete specific policy
$policy = Get-MgIdentityConditionalAccessPolicy |
Where-Object { $_.DisplayName -like "CA-Lab-*" }
foreach ($p in $policy) {
Remove-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $p.Id
}
# Delete named locations
$locations = Get-MgIdentityConditionalAccessNamedLocation |
Where-Object { $_.DisplayName -like "*Lab*" }
foreach ($loc in $locations) {
Remove-MgIdentityConditionalAccessNamedLocation -NamedLocationId $loc.Id
}
# Disconnect
Disconnect-MgGraphUseful Commands Reference
| Task | Command |
|---|---|
| List policies | Get-MgIdentityConditionalAccessPolicy |
| Create policy | New-MgIdentityConditionalAccessPolicy |
| Update policy | Update-MgIdentityConditionalAccessPolicy |
| Delete policy | Remove-MgIdentityConditionalAccessPolicy |
| List locations | Get-MgIdentityConditionalAccessNamedLocation |
| Create location | New-MgIdentityConditionalAccessNamedLocation |
| Get sign-in logs | Get-MgAuditLogSignIn |