Use PowerShell to Find Where the Current FSMO Roles are Assigned in Active Directory
A while back, I had a need to figure out with PowerShell what server in an Active Directory domain held the PDC Emulator FSMO Role. I found a script on a very popular blog site that figured it out by using a command similar to this:
1Get-ADDomainController -Filter * |
2Where-Object OperationMasterRoles -contains PDCEmulator |
3Select-Object -Property Name
While it accomplished what was necessary, I immediately thought "I can do better" and improved the one liner so it filtered left:
1Get-ADDomainController -Filter {
2 OperationMasterRoles -like 'PDCEmulator'
3} | Select-Object -Property name
At the April Philadelphia PowerShell User Group meeting, I won a copy of Managing Active Directory with Windows PowerShell written by Jeff Hicks and published by SAPIEN Technologies.
On page 90, I noticed one of the examples used the Get-ADDomain
cmdlet to retrieve which server
held the PDC Emulator role so it was time to investigate that cmdlet.
What I discovered is all of the domain level FSMO roles could be retrieved very easily using that cmdlet:
1Get-ADDomain |
2Select-Object -Property InfrastructureMaster, PDCEmulator, RIDMaster
A little more research and I found that the Get-ADForest
cmdlet could be used to obtain the server
names of the forest level FSMO role holders:
1Get-ADForest |
2Select-Object -Property DomainNamingMaster, SchemaMaster
I wrote a function named Get-FSMORole
that will retrieve the FSMO roles holders from the domain of
the current user that this function is being run by, or from domains that are provided via pipeline
or parameter input as shown in the following examples:
1function Get-FSMORole {
2 [CmdletBinding()]
3 param(
4 [Parameter(ValueFromPipeline=$True)]
5 [string[]]$DomainName = $env:USERDOMAIN
6 )
7 BEGIN {
8 Import-Module ActiveDirectory -Cmdlet Get-ADDomain, Get-ADForest -ErrorAction SilentlyContinue
9 }
10 PROCESS {
11 foreach ($domain in $DomainName) {
12 Write-Verbose "Querying $domain"
13 Try {
14 $problem = $false
15 $addomain = Get-ADDomain -Identity $domain -ErrorAction Stop
16 } Catch { $problem = $true
17 Write-Warning $_.Exception.Message
18 }
19 if (-not $problem) {
20 $adforest = Get-ADForest -Identity (($addomain).forest)
21
22 New-Object PSObject -Property @{
23 InfrastructureMaster = $addomain.InfrastructureMaster
24 PDCEmulator = $addomain.PDCEmulator
25 RIDMaster = $addomain.RIDMaster
26 DomainNamingMaster = $adforest.DomainNamingMaster
27 SchemaMaster = $adforest.SchemaMaster
28 }
29 }
30 }
31 }
32}
This function depends on either having the Remote Server Administration Tools installed or importing the Active Directory module locally via Implicit Remoting before running the function. In the previous example, the machine the function is being run on is running Windows 8 and the domain controllers are running Windows Server 2012, although I've tested it on a multiple Windows Server 2008 R2 forests where there's a trust between the forests and the function worked without issue.
µ