From fc5aca1a8b306f989e8483dd761b105b3b8b01e8 Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:20:30 +0100 Subject: [PATCH 1/5] Enhance Get-TenantNameByTenantId function Added functionality to retrieve tenant name from Graph and DKIM records. --- KillChain_utils.ps1 | 94 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/KillChain_utils.ps1 b/KillChain_utils.ps1 index 25bbab5..041a6ae 100644 --- a/KillChain_utils.ps1 +++ b/KillChain_utils.ps1 @@ -1,7 +1,8 @@ -# Checks whether the domain has MX records pointing to MS cloud +# Checks whether the domain has MX records pointing to MS cloud # Jun 16th 2020 # Aug 30th 2022: Fixed by maxgrim # Fe. 19th 2025: Add new mx.microsoft check by Michael Morten Sonne +# January 8th 2026: Added functionality to retrieve Tenant Name from Graph (authentication to dummy tenant required) and DKIM records (unauthenticated) function HasCloudMX { @@ -440,3 +441,94 @@ function GetMDIInstance return $null } } + +# Gets the tenant's initial domain (*.onmicrosoft.com) by tenant ID +# Uses DKIM records (most reliable) or MS Graph API as fallback +# Jan 8th 2026 +function Get-TenantNameByTenantId +{ + [cmdletbinding()] + Param( + [Parameter(Mandatory=$True)] + [String]$TenantId, + [Parameter(Mandatory=$False)] + [String]$SubScope, + [Parameter(Mandatory=$False)] + [String]$Domain + ) + Process + { + # Determine the correct onmicrosoft suffix based on subscope + switch($SubScope) + { + "DOD" { $onmicrosoftSuffix = "\.onmicrosoft\.us$" } + "DODCON" { $onmicrosoftSuffix = "\.onmicrosoft\.us$" } + default { $onmicrosoftSuffix = "\.onmicrosoft\.com$" } + } + + # Method 1: Try DKIM records - most reliable unauthenticated method + # DKIM CNAME records point to selector1-._domainkey..onmicrosoft.com + if(-not [string]::IsNullOrEmpty($Domain)) + { + Write-Verbose "Trying to get tenant name from DKIM records for $Domain..." + $selectors = @("selector1", "selector2") + foreach($selector in $selectors) + { + try + { + $dkimRecord = Resolve-DnsName -Name "$selector._domainkey.$Domain" -Type CNAME -DnsOnly -NoHostsFile -NoIdn -ErrorAction SilentlyContinue | + Select-Object -ExpandProperty NameHost + + if($dkimRecord -match $onmicrosoftSuffix) + { + # Extract tenant name from: selector1-domain-com._domainkey.TENANTNAME.onmicrosoft.com + $tenantName = ($dkimRecord -split '\._domainkey\.')[1] + + # Verify this tenant name belongs to the correct tenant ID + $verifyTenantId = Get-TenantID -Domain $tenantName + if($verifyTenantId -eq $TenantId) + { + Write-Verbose "Found tenant name from DKIM: $tenantName (verified)" + return $tenantName + } + else + { + Write-Verbose "DKIM tenant name $tenantName belongs to different tenant: $verifyTenantId" + } + } + } + catch { } + } + } + + # Method 2: Try MS Graph API with cached access token + Write-Verbose "Trying to get tenant info via MS Graph API..." + try + { + $AccessToken = Get-AccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "1b730954-1685-4b74-9bfd-dac224a7b894" + + if(-not [string]::IsNullOrEmpty($AccessToken)) + { + Write-Verbose "Found cached MS Graph access token, querying tenant info..." + $results = Call-MSGraphAPI -AccessToken $AccessToken -API "tenantRelationships/findTenantInformationByTenantId(tenantId='$TenantId')" + + if(-not [string]::IsNullOrEmpty($results.defaultDomainName)) + { + Write-Verbose "Got default domain from MS Graph: $($results.defaultDomainName)" + return $results.defaultDomainName + } + } + else + { + Write-Verbose "No cached MS Graph access token found." + } + } + catch + { + Write-Verbose "MS Graph API call failed: $_" + } + + Write-Verbose "Unable to determine tenant name." + return $null + } +} From c3aa4513d251fac9e75916839f49f95c99c08a7a Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:21:02 +0100 Subject: [PATCH 2/5] Implement fallback for tenant name retrieval Added fallback method to retrieve tenant name if autodiscover fails, including user warning for authentication requirement. --- KillChain.ps1 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/KillChain.ps1 b/KillChain.ps1 index 018ece8..57da092 100644 --- a/KillChain.ps1 +++ b/KillChain.ps1 @@ -1,4 +1,4 @@ -# +# # This file contains functions for Azure AD / Office 365 kill chain # @@ -243,6 +243,19 @@ function Invoke-ReconAsOutsider } } + # Fallback: If tenant name was not found from autodiscover, try alternative method + if([string]::IsNullOrEmpty($tenantName)) + { + Write-Verbose "Tenant name not found from autodiscover, trying alternative method..." + $tenantName = Get-TenantNameByTenantId -TenantId $tenantId -SubScope $tenantSubscope -Domain $DomainName + + # If still not found, give user a hint + if([string]::IsNullOrEmpty($tenantName)) + { + Write-Warning "Tenant name lookup requires authentication. Run 'Get-AADIntAccessTokenForMSGraph -SaveToCache' first (can use any tenant)." + } + } + Write-Host "Tenant brand: $tenantBrand" Write-Host "Tenant name: $tenantName" Write-Host "Tenant id: $tenantId" From aba1aebd6902a752381515ce3bb272f6c3a953fc Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:32:29 +0100 Subject: [PATCH 3/5] Update user existence check for cloud sync --- KillChain.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KillChain.ps1 b/KillChain.ps1 index 57da092..f2ab2dd 100644 --- a/KillChain.ps1 +++ b/KillChain.ps1 @@ -282,7 +282,7 @@ function Invoke-ReconAsOutsider } # Cloud sync not definitive, may use different domain name - if(DoesUserExists -User "ADToAADSyncServiceAccount@$($tenantName)") + if(![string]::IsNullOrEmpty($tenantName) -and (DoesUserExists -User "ADToAADSyncServiceAccount@$($tenantName)")) { Write-Host "Uses cloud sync: $true" } From df01b70334df59eabaaee57d87cce0aeed8bda53 Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Sat, 10 Jan 2026 12:43:04 +0100 Subject: [PATCH 4/5] Update to fix associated domains lookup --- AADInternals.psd1 | 1 + AccessToken_utils.ps1 | 223 ++++++++++++++++++++++++++++++++++++------ KillChain.ps1 | 17 +++- KillChain_utils.ps1 | 108 +++++++++++++++++++- 4 files changed, 312 insertions(+), 37 deletions(-) diff --git a/AADInternals.psd1 b/AADInternals.psd1 index e4dafcc..1c311c3 100644 --- a/AADInternals.psd1 +++ b/AADInternals.psd1 @@ -181,6 +181,7 @@ DISCLAIMER: Functionality provided through this module are not supported by Micr "Get-OpenIDConfiguration" "Get-TenantId" "Get-TenantDomains" + "Get-TenantDomainsFromACS" "Get-Cache" "Clear-Cache" "Add-AccessTokenToCache" diff --git a/AccessToken_utils.ps1 b/AccessToken_utils.ps1 index 02e3d27..fca7f65 100644 --- a/AccessToken_utils.ps1 +++ b/AccessToken_utils.ps1 @@ -1290,6 +1290,84 @@ function Add-RefreshTokenToCache # Gets other domains of the given tenant # Jun 15th 2020 +# Gets domains from Access Control Service metadata +# Jan 10th 2026 +function Get-TenantDomainsFromACS +{ +<# + .SYNOPSIS + Gets domains from the tenant using Access Control Service metadata endpoint + + .DESCRIPTION + Uses the Azure Access Control Service (ACS) metadata endpoint to retrieve + registered email domains (allowedAudiences) for a tenant. This endpoint returns + domains that are registered with the tenant for email routing and federation purposes. + + Requires the tenant's initial domain name (*.onmicrosoft.com). + + .Example + Get-AADIntTenantDomainsFromACS -TenantName company.onmicrosoft.com + + company.com + company.mail.onmicrosoft.com + company.onmicrosoft.com + +#> + [cmdletbinding()] + Param( + [Parameter(Mandatory=$True)] + [String]$TenantName + ) + Process + { + try + { + # Build the ACS metadata endpoint URL + $uri = "https://accounts.accesscontrol.windows.net/$TenantName/metadata/json/1" + + Write-Verbose "Querying ACS metadata endpoint: $uri" + + # Query the endpoint + $response = Invoke-RestMethod -Uri $uri -UseBasicParsing -ErrorAction Stop + + # Extract domains from allowedAudiences + # Format: 00000001-0000-0000-c000-000000000000/accounts.accesscontrol.windows.net@ + $domains = @() + if($response.allowedAudiences) + { + foreach($audience in $response.allowedAudiences) + { + if($audience -match '@(.+)$') + { + $domain = $matches[1] + # Filter out GUID entries (these represent tenant IDs, not domain names) + if($domain -notmatch '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$') + { + $domains += $domain + } + } + } + } + + if($domains.Count -gt 0) + { + Write-Verbose "Found $($domains.Count) domains from ACS metadata" + return ($domains | Sort-Object -Unique) + } + else + { + Write-Verbose "No domains found in ACS metadata" + return @() + } + } + catch + { + Write-Verbose "Error querying ACS metadata: $($_.Exception.Message)" + return @() + } + } +} + function Get-TenantDomains { <# @@ -1297,8 +1375,10 @@ function Get-TenantDomains Gets other domains from the tenant of the given domain .DESCRIPTION - Uses Exchange Online autodiscover service to retrive other - domains from the tenant of the given domain. + Uses Exchange Online autodiscover service AND Access Control Service (ACS) + metadata endpoint to retrieve all domains from the tenant. Since Microsoft + has limited the autodiscover endpoint, this function now queries both sources + and merges the results for comprehensive domain enumeration. The given domain SHOULD be Managed, federated domains are not always found for some reason. If nothing is found, try to use .onmicrosoft.com @@ -1322,31 +1402,39 @@ function Get-TenantDomains ) Process { + # Collection for all discovered domains + $allDomains = @() + # Get Tenant Region subscope from Open ID configuration if not provided if([string]::IsNullOrEmpty($SubScope)) { $SubScope = Get-TenantSubscope -Domain $Domain } - # Use the correct url - switch($SubScope) + # Method 1: Try autodiscover (may return limited results due to Microsoft mitigation) + try { - "DOD" # DoD - { - $uri = "https://autodiscover-s-dod.office365.us/autodiscover/autodiscover.svc" - } - "DODCON" # GCC-High - { - $uri = "https://autodiscover-s.office365.us/autodiscover/autodiscover.svc" - } - default # Commercial/GCC + Write-Verbose "Querying autodiscover endpoint..." + + # Use the correct url + switch($SubScope) { - $uri = "https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc" + "DOD" # DoD + { + $uri = "https://autodiscover-s-dod.office365.us/autodiscover/autodiscover.svc" + } + "DODCON" # GCC-High + { + $uri = "https://autodiscover-s.office365.us/autodiscover/autodiscover.svc" + } + default # Commercial/GCC + { + $uri = "https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc" + } } - } - # Create the body - $body=@" + # Create the body + $body=@" @@ -1365,22 +1453,97 @@ function Get-TenantDomains "@ - # Create the headers - $headers=@{ - "Content-Type" = "text/xml; charset=utf-8" - "SOAPAction" = '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"' - "User-Agent" = "AutodiscoverClient" + # Create the headers + $headers=@{ + "Content-Type" = "text/xml; charset=utf-8" + "SOAPAction" = '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"' + "User-Agent" = "AutodiscoverClient" + } + + $response = Invoke-RestMethod -UseBasicParsing -Method Post -uri $uri -Body $body -Headers $headers -ErrorAction Stop + $autodiscoverDomains = @($response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain) + + if($autodiscoverDomains.Count -gt 0) + { + Write-Verbose "Autodiscover returned $($autodiscoverDomains.Count) domain(s)" + $allDomains += $autodiscoverDomains + } } - # Invoke - $response = Invoke-RestMethod -UseBasicParsing -Method Post -uri $uri -Body $body -Headers $headers - - # Return - $domains = @($response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain) - if($Domain -notin $domains) + catch + { + Write-Verbose "Autodiscover query failed: $($_.Exception.Message)" + } + + # Method 2: Try ACS metadata endpoint (provides comprehensive domain list) + try + { + Write-Verbose "Querying ACS metadata endpoint..." + + # Try to get tenant name (*.onmicrosoft.com) + $tenantName = $null + + # If the provided domain is already a tenant name, use it + if($Domain -match '^[^.]*\.onmicrosoft\.((com)|(us))$') + { + $tenantName = $Domain + } + else + { + # Try to get tenant ID and derive tenant name + try + { + $tenantId = Get-TenantID -Domain $Domain + if(![string]::IsNullOrEmpty($tenantId)) + { + Write-Verbose "Got tenant ID: $tenantId, retrieving tenant name..." + $tenantName = Get-TenantNameByTenantId -TenantId $tenantId -SubScope $SubScope -Domain $Domain + } + } + catch + { + Write-Verbose "Could not determine tenant name: $($_.Exception.Message)" + } + } + + # If we have a tenant name, query the ACS metadata endpoint + if(![string]::IsNullOrEmpty($tenantName)) + { + Write-Verbose "Using tenant name: $tenantName for ACS query" + $acsDomains = Get-TenantDomainsFromACS -TenantName $tenantName + + if($acsDomains.Count -gt 0) + { + Write-Verbose "ACS metadata returned $($acsDomains.Count) domain(s)" + $allDomains += $acsDomains + } + } + else + { + Write-Verbose "Could not determine tenant name, skipping ACS query" + } + } + catch + { + Write-Verbose "ACS metadata query failed: $($_.Exception.Message)" + } + + # Merge, deduplicate and ensure the queried domain is included + if($allDomains.Count -gt 0) + { + $uniqueDomains = $allDomains | Select-Object -Unique | Sort-Object + if($Domain -notin $uniqueDomains) + { + $uniqueDomains = @($uniqueDomains) + @($Domain) | Sort-Object + } + Write-Verbose "Total unique domains found: $($uniqueDomains.Count)" + return $uniqueDomains + } + else { - $domains += $Domain + # If both methods failed, return at least the queried domain + Write-Warning "Could not retrieve tenant domains. Returning only the queried domain." + return @($Domain) } - $domains | Sort-Object } } diff --git a/KillChain.ps1 b/KillChain.ps1 index 018ece8..25cc189 100644 --- a/KillChain.ps1 +++ b/KillChain.ps1 @@ -243,6 +243,19 @@ function Invoke-ReconAsOutsider } } + # Fallback: If tenant name was not found from autodiscover, try alternative method + if([string]::IsNullOrEmpty($tenantName)) + { + Write-Verbose "Tenant name not found from autodiscover, trying alternative method..." + $tenantName = Get-TenantNameByTenantId -TenantId $tenantId -SubScope $tenantSubscope -Domain $DomainName + + # If still not found, give user a hint + if([string]::IsNullOrEmpty($tenantName)) + { + Write-Warning "Tenant name lookup requires authentication. Run 'Get-AADIntAccessTokenForMSGraph -SaveToCache' first (can use any tenant)." + } + } + Write-Host "Tenant brand: $tenantBrand" Write-Host "Tenant name: $tenantName" Write-Host "Tenant id: $tenantId" @@ -269,7 +282,7 @@ function Invoke-ReconAsOutsider } # Cloud sync not definitive, may use different domain name - if(DoesUserExists -User "ADToAADSyncServiceAccount@$($tenantName)") + if(![string]::IsNullOrEmpty($tenantName) -and (DoesUserExists -User "ADToAADSyncServiceAccount@$($tenantName)")) { Write-Host "Uses cloud sync: $true" } @@ -280,7 +293,7 @@ function Invoke-ReconAsOutsider Write-Host "CBA enabled: $tenantCBA" } - return $domainInformation + return $domainInformation | Format-Table -AutoSize } } diff --git a/KillChain_utils.ps1 b/KillChain_utils.ps1 index 25bbab5..83c7d2e 100644 --- a/KillChain_utils.ps1 +++ b/KillChain_utils.ps1 @@ -1,4 +1,4 @@ -# Checks whether the domain has MX records pointing to MS cloud +# Checks whether the domain has MX records pointing to MS cloud # Jun 16th 2020 # Aug 30th 2022: Fixed by maxgrim # Fe. 19th 2025: Add new mx.microsoft check by Michael Morten Sonne @@ -31,8 +31,13 @@ function HasCloudMX } } - $results = Resolve-DnsName -Name $Domain -Type MX -DnsOnly -NoHostsFile -NoIdn -ErrorAction SilentlyContinue | - Select-Object -ExpandProperty nameexchange + $dnsResults = Resolve-DnsName -Name $Domain -Type MX -DnsOnly -NoHostsFile -NoIdn -ErrorAction SilentlyContinue + + # Extract nameexchange property only if results exist and have the property + $results = @() + if($dnsResults) { + $results = $dnsResults | Where-Object { $_.NameExchange } | Select-Object -ExpandProperty NameExchange + } # Normalize $filter into an array if (-not ($filter -is [System.Collections.IEnumerable])) { @@ -41,8 +46,10 @@ function HasCloudMX # Check results $filteredResults = @() - foreach ($pat in $filter) { - $filteredResults += $results | Where-Object { $_ -like $pat } + if($results.Count -gt 0) { + foreach ($pat in $filter) { + $filteredResults += $results | Where-Object { $_ -like $pat } + } } return $filteredResults.Count -gt 0 @@ -440,3 +447,94 @@ function GetMDIInstance return $null } } + +# Gets the tenant's initial domain (*.onmicrosoft.com) by tenant ID +# Uses DKIM records (most reliable) or MS Graph API as fallback +# Jan 8th 2026 +function Get-TenantNameByTenantId +{ + [cmdletbinding()] + Param( + [Parameter(Mandatory=$True)] + [String]$TenantId, + [Parameter(Mandatory=$False)] + [String]$SubScope, + [Parameter(Mandatory=$False)] + [String]$Domain + ) + Process + { + # Determine the correct onmicrosoft suffix based on subscope + switch($SubScope) + { + "DOD" { $onmicrosoftSuffix = "\.onmicrosoft\.us$" } + "DODCON" { $onmicrosoftSuffix = "\.onmicrosoft\.us$" } + default { $onmicrosoftSuffix = "\.onmicrosoft\.com$" } + } + + # Method 1: Try DKIM records - most reliable unauthenticated method + # DKIM CNAME records point to selector1-._domainkey..onmicrosoft.com + if(-not [string]::IsNullOrEmpty($Domain)) + { + Write-Verbose "Trying to get tenant name from DKIM records for $Domain..." + $selectors = @("selector1", "selector2") + foreach($selector in $selectors) + { + try + { + $dkimRecord = Resolve-DnsName -Name "$selector._domainkey.$Domain" -Type CNAME -DnsOnly -NoHostsFile -NoIdn -ErrorAction SilentlyContinue | + Select-Object -ExpandProperty NameHost + + if($dkimRecord -match $onmicrosoftSuffix) + { + # Extract tenant name from: selector1-domain-com._domainkey.TENANTNAME.onmicrosoft.com + $tenantName = ($dkimRecord -split '\._domainkey\.')[1] + + # Verify this tenant name belongs to the correct tenant ID + $verifyTenantId = Get-TenantID -Domain $tenantName + if($verifyTenantId -eq $TenantId) + { + Write-Verbose "Found tenant name from DKIM: $tenantName (verified)" + return $tenantName + } + else + { + Write-Verbose "DKIM tenant name $tenantName belongs to different tenant: $verifyTenantId" + } + } + } + catch { } + } + } + + # Method 2: Try MS Graph API with cached access token + Write-Verbose "Trying to get tenant info via MS Graph API..." + try + { + $AccessToken = Get-AccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "1b730954-1685-4b74-9bfd-dac224a7b894" + + if(-not [string]::IsNullOrEmpty($AccessToken)) + { + Write-Verbose "Found cached MS Graph access token, querying tenant info..." + $results = Call-MSGraphAPI -AccessToken $AccessToken -API "tenantRelationships/findTenantInformationByTenantId(tenantId='$TenantId')" + + if(-not [string]::IsNullOrEmpty($results.defaultDomainName)) + { + Write-Verbose "Got default domain from MS Graph: $($results.defaultDomainName)" + return $results.defaultDomainName + } + } + else + { + Write-Verbose "No cached MS Graph access token found." + } + } + catch + { + Write-Verbose "MS Graph API call failed: $_" + } + + Write-Verbose "Unable to determine tenant name." + return $null + } +} From 26ae4d53d1f374ebde0b1c3f411af1d0456c1ee3 Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:17:46 +0100 Subject: [PATCH 5/5] Update AccessToken_utils.ps1 Update for DOD and GCC Tenants --- AccessToken_utils.ps1 | 44 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/AccessToken_utils.ps1 b/AccessToken_utils.ps1 index fca7f65..fd4770b 100644 --- a/AccessToken_utils.ps1 +++ b/AccessToken_utils.ps1 @@ -1303,7 +1303,13 @@ function Get-TenantDomainsFromACS registered email domains (allowedAudiences) for a tenant. This endpoint returns domains that are registered with the tenant for email routing and federation purposes. - Requires the tenant's initial domain name (*.onmicrosoft.com). + Requires the tenant's initial domain name (*.onmicrosoft.com or *.onmicrosoft.us for gov clouds). + + .Parameter TenantName + The tenant's initial domain name (e.g., company.onmicrosoft.com, company.onmicrosoft.us) + + .Parameter SubScope + Optional tenant subscope/region identifier (DOD, DODCON, etc.) .Example Get-AADIntTenantDomainsFromACS -TenantName company.onmicrosoft.com @@ -1312,18 +1318,43 @@ function Get-TenantDomainsFromACS company.mail.onmicrosoft.com company.onmicrosoft.com + .Example + Get-AADIntTenantDomainsFromACS -TenantName company.onmicrosoft.us -SubScope DOD + + company.com + company.mail.onmicrosoft.us + company.onmicrosoft.us + #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] - [String]$TenantName + [String]$TenantName, + [Parameter(Mandatory=$False)] + [String]$SubScope ) Process { try { - # Build the ACS metadata endpoint URL - $uri = "https://accounts.accesscontrol.windows.net/$TenantName/metadata/json/1" + # Build the ACS metadata endpoint URL based on cloud environment + # Reference: https://learn.microsoft.com/en-us/exchange/configure-oauth-authentication-between-exchange-and-exchange-online-organizations-exchange-2013-help + # Note: Government clouds use login.microsoftonline.us instead of accounts.accesscontrol + switch($SubScope) + { + "DOD" # DoD + { + $uri = "https://login.microsoftonline.us/$TenantName/metadata/json/1" + } + "DODCON" # GCC-High + { + $uri = "https://login.microsoftonline.us/$TenantName/metadata/json/1" + } + default # Commercial/GCC + { + $uri = "https://accounts.accesscontrol.windows.net/$TenantName/metadata/json/1" + } + } Write-Verbose "Querying ACS metadata endpoint: $uri" @@ -1331,7 +1362,8 @@ function Get-TenantDomainsFromACS $response = Invoke-RestMethod -Uri $uri -UseBasicParsing -ErrorAction Stop # Extract domains from allowedAudiences - # Format: 00000001-0000-0000-c000-000000000000/accounts.accesscontrol.windows.net@ + # Format (Commercial): 00000001-0000-0000-c000-000000000000/accounts.accesscontrol.windows.net@ + # Format (Gov clouds): 00000001-0000-0000-c000-000000000000/login.microsoftonline.us@ $domains = @() if($response.allowedAudiences) { @@ -1509,7 +1541,7 @@ function Get-TenantDomains if(![string]::IsNullOrEmpty($tenantName)) { Write-Verbose "Using tenant name: $tenantName for ACS query" - $acsDomains = Get-TenantDomainsFromACS -TenantName $tenantName + $acsDomains = Get-TenantDomainsFromACS -TenantName $tenantName -SubScope $SubScope if($acsDomains.Count -gt 0) {