Detect AAD/Hybrid/On-Prem AD Join Status via Registry When Running as SYSTEM
Scripts executing as NT AUTHORITY\SYSTEM cannot use dsregcmd /status to determine Azure AD join status because the utility requires a domain user account context, causing it to fail silently or with a recognition error in RMM environments. The reliable alternative is to query the HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo registry key directly, which is accessible to SYSTEM and exposes TenantId and UserEmail values for AAD-joined machines. Combining this with a Netlogon or DirectoryServices check allows complete classification of any endpoint as AAD joined, Hybrid joined, on-prem only, or unjoined.
Indicators
- dsregcmd /status returns 'not recognized as the name of a cmdlet, function, script file, or operable program' when executed as SYSTEM
- Full path invocation '& "C:\Windows\System32\dsregcmd.exe" /status' also fails under NT AUTHORITY\SYSTEM context
- RMM scripts running as SYSTEM are unable to retrieve AAD join status via standard dsregcmd methods
- Automation or reporting tasks cannot categorise workstations into AAD joined, Hybrid joined, on-prem, or unjoined groups
Likely causes
- dsregcmd /status is documented by Microsoft to require a domain user account context and will not function under NT AUTHORITY\SYSTEM
- RMM platforms commonly execute scripts as SYSTEM by default, removing access to all user-context-dependent diagnostic utilities
- No built-in PowerShell cmdlet exposes AAD join state in a SYSTEM-compatible way without registry inspection
Diagnostic steps
-
Confirm failure by running 'dsregcmd /status' as SYSTEM. Expected error: 'dsregcmd is not recognized as the name of a cmdlet, function, script file, or operable program.' This validates the context restriction rather than a PATH issue.
-
Confirm the restriction is context-based by also trying the full path: '& "C:\Windows\System32\dsregcmd.exe" /status'. If this also fails, the execution context (SYSTEM) is confirmed as the cause.
-
Query the AAD join registry key: '$subKey = Get-Item "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" -ErrorAction SilentlyContinue'. If the key exists, the machine is AAD joined or Hybrid AD joined.
-
Enumerate GUID sub-keys under JoinInfo and extract join details: '$guids = $subKey.GetSubKeyNames(); foreach ($guid in $guids) { $guidSubKey = $subKey.OpenSubKey($guid); $tenantId = $guidSubKey.GetValue("TenantId"); $userEmail = $guidSubKey.GetValue("UserEmail"); Write-Output "TenantId: $tenantId | UserEmail: $userEmail" }'
-
Check for on-prem AD membership by querying the Netlogon registry key: '(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -ErrorAction SilentlyContinue).DomainName'. A non-null value indicates on-prem domain membership. Alternatively use: '[System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()' wrapped in a try/catch.
-
Combine results to classify the endpoint: (a) CloudDomainJoin key exists AND Netlogon DomainName is populated = Hybrid AD joined; (b) CloudDomainJoin key exists, no DomainName = AAD joined only; (c) No CloudDomainJoin key, DomainName populated = on-prem AD only; (d) Neither present = unjoined/workgroup.
-
Output or store the classification result in the RMM platform custom field or device attribute for grouping, reporting, or policy targeting.
Resolution path
- Abandon dsregcmd /status as a detection method in any script that runs as NT AUTHORITY\SYSTEM
- Query 'HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo' for the existence of GUID sub-keys to detect AAD or Hybrid join
- Read TenantId and UserEmail values from each GUID sub-key to confirm and record AAD join details
- Separately check for on-prem AD membership by reading 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DomainName' or via System.DirectoryServices.ActiveDirectory.Domain
- Combine both checks to classify each machine: Hybrid joined, AAD only, on-prem only, or unjoined/workgroup
- Store the classification result in the RMM platform device record for use in grouping, targeting, and reporting
Prevention
- Before deploying any RMM script, verify whether all required utilities support NT AUTHORITY\SYSTEM execution context
- Use registry-based detection as the SYSTEM-compatible fallback for any diagnostic tool that requires user context
- Document the required execution context (user vs. SYSTEM) for every diagnostic utility referenced in automation scripts
- Test all scripts explicitly under NT AUTHORITY\SYSTEM context — using tools such as PsExec -s — before production RMM deployment
- Maintain a library of SYSTEM-safe detection patterns (registry, WMI, .NET classes) for common endpoint state checks
Tools
- PowerShell (Get-Item, OpenSubKey, GetValue)
- Windows Registry — HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo
- Windows Registry — HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters
- System.DirectoryServices.ActiveDirectory.Domain .NET class
- dsregcmd.exe (user context only — not suitable for SYSTEM-context scripts)
- RMM platform PowerShell script execution engine