Introduced in Windows Server 2008, read-only domain controllers (RODC) were a secure way to deploy DCs in remote locations. RODCs were read-only which meant that nothing could be directly written to them. This meant that a malicious attacker couldn't add his own user account and have it replicated back to all of the other DCs in an environment. It was much more secure than traditional domain controllers which allowed someone with the appropriate permissions to add objects at will to Active Directory.

Since RODCs were typically deployed in insecure locations, it's always a good practice to not authenticate any high-privilege accounts to an RODC. This could potentially allow someone to either crack the password (if the password was cached) or sniff the transaction in some manner. A good practice it to keep an eye on which accounts are being authenticated by these RODCs.

One way to do that is through PowerShell and the ActiveDirectory module. By using a script, we can determine which accounts are being authenticated by an RODC in our environment and take actions, if necessary.

To do this, we'll first need to find all of the RODCs currently in our environment.

$Rodcs = Get-ADDomainController -Filter { IsReadOnly -eq $True }

Next, since we don't care about "normal" accounts, we need a way to determine which admin accounts we care about. I'm defining an admin account by membership in either the Domain Admins, Enterprise Admins or Administrators domain groups.

Below I'm looping through each group and selecting only the samaccountName for each member of the group.

$AdminAccounts = @(
    'Domain Admins',
    'Enterprise Admins',
    'Administrators'
) | Get-AdGroupMember | Select-Object -ExpandProperty samAccountName

Next, I need to query each RODC for all of the accounts that have used them for authentication.

foreach ($Rodc in $Rodcs) {
    $Accounts = Get-ADDomainControllerPasswordReplicationPolicyUsage-Identity $Rodc -AuthenticatedAccounts | Select-Object -ExpandPropertysamAccountName
    if ($Accounts) {
        Compare-Object -ReferenceObject $AdminAccounts -DifferenceObject$Accounts -IncludeEqual
    } else {
        Write-Verbose 'No admin accounts found authenticated a RODC'
    }
}

If I found any accounts that were authenticated by that particular RODC in the loop, I then compare all of those accounts with all of the admin accounts I have defined using the Compare-Object cmdlet. If no admin accounts were found, I then just display a message to the user saying that no admin accounts were found.

foreach ($Rodc in $Rodcs) {
    $Accounts = Get-ADDomainControllerPasswordReplicationPolicyUsage-Identity $Rodc -AuthenticatedAccounts | Select-Object -ExpandPropertysamAccountName
    if ($Accounts) {
        Compare-Object -ReferenceObject $AdminAccounts -DifferenceObject$Accounts -IncludeEqual
    } else {
        Write-Verbose 'No admin accounts found authenticated a RODC'
    }
}

When this script is done, it then gives me a breakdown of all of the
accounts that have been authenticated by each of the RODCs in my
environment. At this point, I can take this list and decide if I need to
take action on it.

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!