Summary: Microsoft premier field engineer, Ian Farr, talks about using Windows PowerShell to work with RODC accounts.
Microsoft Scripting Guy, Ed Wilson, is here. Today I would like to introduce a new guest blogger, Ian Farr. Ian tells us about himself:
I started out writing UNIX shell scripts to automate simple tasks. Then as a Windows IT pro, I discovered VBScript, and it ignited a passion for automation. Over the years, I've used batch files, KiXtart, JScript, HTAs, Perl, JavaScript, and Python. I love solving problems with scripts, and I've written code for several large enterprise environments. I now work as a premier field engineer at Microsoft, teaching Windows PowerShell and helping my customers with their own scripts.
Today, I’d like to share with you my function Get-ADRodcAuthenticatedNotRevealed.ps1.
One of my customers has a large number of Read-only domain controllers (RODCs). Each one is configured (by using password replication policies) to only store the account credentials of specific low-privileged user and computer accounts. If an “allowed” account authenticates against its designated RODC, its credentials are cached on that RODC. The account is then added to the “revealed” list. If the RODC loses connectivity to the central site, it can still authenticate accounts in its revealed list.
Of course, an RODC can authenticate accounts that are not in an applicable password replication policy. To do this, it must communicate with a Read-Write domain controller. All accounts that an RODC has authenticated, including those in the revealed list, can be found in the appropriately named authenticated list. By now, you’re probably thinking, “What does all of have to do with Windows PowerShell and scripting?”
Hang on…I’m almost there.
RODCs are most suited to branch office locations, so it’s reasonable to assume that each RODC has authenticated accounts from applicable allowed password replication policies. It’s also reasonable to assume that user and computer accounts that are not defined in a password replication policy may have been authenticated—for example, perhaps a roaming user has visited and plugged in their laptop to the LAN.
You may also see authenticated accounts that are part of a “denied” password replication policy. Built-in privileged groups and accounts, by default, do not have their credentials stored on an RODC.
Now to analyse specific RODC usage. How do you determine which accounts are stored in the “authenticated” list, but don’t appear in the “revealed” list?
At last…some Windows PowerShell!
I’ve published the Get-ADRodcAuthenticatedNotRevealed function on the TechNet Script Center Repository. It will return account objects that are authenticated but not revealed.
You could add the script to $profile, so it is loaded to the PSDrive function (see Use PowerShell to Work Easily with Dives and Paths) when Windows PowerShell opens. Or you can access it as needed by dot sourcing the script file:
. .\Get-ADRodcAuthenticatedNotRevealed.ps1
Here’s a suggested way to use the function:
Get-ADDomainController -Filter {IsReadOnly -eq $True} | Get-ADRodcAuthenticatedNotRevealed
Here, we get all of the RODCs from the domain that the user is currently logged in to and pipe them one-by-one into the function. This line could happily be part of a script that defines or references the function.
We can just as easily pipe a hand-typed list of RODCs:
“NINJARODC01”, “ninjarodc02” | Get-ADRodcAuthenticatedNotRevealed
Or the contents of a text file:
Get-Content –Path rodc.txt | Get-ADRodcAuthenticatedNotRevealed
By the way, this is the geeky way to get the contents of that file:
${c:rodc.txt} | Get-ADRodcAuthenticatedNotRevealed
The Get-ADRodcAuthenticatedNotRevealed function processes each RODC that is passed down the pipeline with a Process script block. Script blocks are the building blocks of Windows PowerShell. They are recognized by those interesting curly braces you see everywhere: { }.
Next, we compare the output of two cmdlets. The first cmdlet gets all authenticated accounts from the RODC currently in the pipeline:
$AuthenticatedAccounts = Get-ADDomainControllerPasswordReplicationPolicyUsage -Identity $Rodc -AuthenticatedAccounts
The second gets all the revealed accounts:
$RevealedAccounts = Get-ADDomainControllerPasswordReplicationPolicyUsage -Identity $Rodc -RevealedAccounts
Here’s the comparison:
Comparison = Compare-Object -ReferenceObject $AuthenticatedAccounts -DifferenceObject $RevealedAccounts
After the comparison is performed, we filter on those accounts that only appear in the reference object by using the side indicator output, “< =”, as shown here:
$Results = $Comparison | Where-Object {$_.SideIndicator -eq "<="}
Here’s what the $Comparison side indicators represent:
- “<=” implies that these accounts only appear in the AuthenticatedAccounts list
- “=>” implies that the accounts appear only in the RevealedAccounts list
- “==” implies that the accounts are present in both lists (the IncludeEqual switch has to be supplied to the Compare-Object cmdlet)
$Results now contains authenticated accounts that have not been revealed. Let’s return them to the calling scope:
$Results.InputObject
We could export the account objects to XML, or as in the following example, to a file:
$Results.InputObject | Export-CSV -Path "$($Rodc)_AuthenticatedNotRevealed.csv" -Force
We’ll end up with a .csv file of authenticated but not revealed accounts for each RODC processed. It will look something like this:
NINJARODC01_AuthenticatedNotRevealed.csv
Now to write a function to analyse the Get-ADRodcAuthenticatedNotRevealed output…
Here is the function: Get-ADRodcAuthenticatedNotRevealed.ps1.
~Ian
Thank you, Ian, for sharing your knowledge and time.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy