Finally the Azure AD Connect version is available through the Azure Portal:

But I am more interested in getting this using an API, as I am checking things towards customer tenants. Looking at the API calls behind the Azure Portal, we can find that it is using some endpoints from management.azure.com:

Step 1 – Getting the required access token
You can use the well known 1950a258-227b-4e31-a9cf-717495945fc2 app id with ROPC to get an access token as follows, only username and password required:
$secrets = @{
username = "abc@demo.com"
password = "MyPassword"
}
# Create uri and body - AAD graph (deprecated)
$uri = "https://login.microsoftonline.com/{0}/oauth2/token" -f $secrets.tenant
$body = "resource=https://management.azure.com/&client_id=1950a258-227b-4e31-a9cf-717495945fc2&grant_type=password&username={1}&password={0}" -f [System.Net.WebUtility]::UrlEncode($secrets.password), $secrets.username
# Get access token and build header
$token = $null
try {
$token = Invoke-RestMethod $uri -Body $body -ContentType "application/x-www-form-urlencoded" -ErrorAction SilentlyContinue
} catch {
Write-Error "Exception when getting AAD access token" -Exception $_
}
if($token.access_token) {
$Global:HeadersForAzure = @{Authorization = "Bearer $($token.access_token)"}
} else {
Write-Error "Unable to retrieve access token for https://management.azure.com"
}
Step 2 – Getting the latest actual version from Github
This step is not really crucial, but you can easily fetch the latest version from the Azure AD Connect version history, in order to compare to your tenant:
# Get latest version from Github
$VersionHistory = Invoke-RestMethod "https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/master/articles/active-directory/hybrid/reference-connect-version-history.md"
$_LatestVersion = $VersionHistory -split "`n" |
Where-Object {$_ -match "^## [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"} |
ForEach-Object {$_ -replace "## "} |
Sort-Object |
Select-Object -Last 1
if($_LatestVersion -notmatch "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") {
New-PolicyResult -Policy $Policy -Status "Failed" -StatusDetail "Unable to determine latest version of Azure AD Connect"
}
$LatestVersion = [Version] $_LatestVersion
Step 3 – Working with the API
Now we are ready to work with the API. Remember, this is an undocumented API, and it is prone to change without notification from Microsoft:
# Get AAD Connect Health service
$PremiumCheck = Invoke-RestMethod -Uri 'https://management.azure.com/providers/Microsoft.ADHybridHealthService/services/GetServices/PremiumCheck?serviceType=AadSyncService&skipCount=0&takeCount=50&api-version=2014-01-01' -Headers $Global:HeadersForAzure
if(!$PremiumCheck.Value) {
throw "Unable to get Azure AD Connect configuration from management.azure.com"
}
# Check Azure AD Connect status being healthy
if($PremiumCheck.value[0].health -ne "Healthy") {
throw "Azure AD Connect service not healthy"
}
# Get all servers providing the Azure AD Connect service
$ServiceMembers = Invoke-RestMethod -Uri "https://management.azure.com/providers/Microsoft.ADHybridHealthService/services/$($PremiumCheck.value[0].serviceName)/servicemembers?api-version=2014-01-01" -Headers $Global:HeadersForAzure
# Process servers, checking version, health and version
$ServiceMembers.value | ForEach-Object {
if(([Version] $_.osVersion) -lt ([Version] "10.0.14393.0")) {
throw "Server $($_.machineName) running too old operating system Windows build $($_.osVersion)"
}
if($_.Status -ne "Healthy") {
throw "Server $($_.machineName) is not healthy, according to Azure AD Connect Health"
}
$ServiceConfiguration = Invoke-RestMethod -Uri "https://management.azure.com/providers/Microsoft.ADHybridHealthService/services/$($PremiumCheck.value[0].serviceName)/servicemembers/$($_.serviceMemberId)/serviceconfiguration?api-version=2014-01-01" -Headers $Global:HeadersForAzure
if(([Version] $ServiceConfiguration.version) -lt $LatestVersion) {
throw "Server $($_.machineName) is running version $($ServiceConfiguration.version) of Azure AD Connect, which is not the latest ($LatestVersion)"
}
}
This API might be different in a few weeks, which means the example will stop working, but that’s life 🙂
How would I go about adding this to a foreach loop. Where I connect to msolservice via secure app model using my partner account, then pulling the customer list and pulling this info for each customer?
Good question. I believe you might can use some of the methods DrAzureAD has documented here, in order to get an access token: https://o365blog.com/post/partners/
I’m looking for a way to get the same information via an APP Registration (e.g. client ID & client app secret). Do you know if this is possible?
I did not succeed with this during my testing, so I believe they have som limitation going on here