PowerShell Function to Determine the Active Directory FSMO Role Holders via the .NET Framework

Last week I posted a PowerShell function to determine what Active Directory domain controllers held the FSMO roles for one or more domains and forests. That particular function used the Get-ADDomain and Get-ADForest cmdlets which are part of the Active Directory PowerShell module. As it so happens, a friend of mine, Shay Levy who is a PowerShell MVP posted an article on PowerShell Magazine that uses a couple of one liners that use the .NET Framework to return the FSMO role holders.

I'm not a .NET guy, but this started me thinking that there was probably a way with the .NET Framework to figure out where the FSMO roles were based on a given domain instead of the current one.

I decided to retro-fit my function to use the .NET Framework Class that Shay was using, but I figured out a different static method (I think that's what it's called, but correct me if I'm wrong). This other static method would indeed return the FSMO role holders based on a given domain name.

 1function Get-FSMORole {
 2<#
 3.SYNOPSIS
 4Retrieves the FSMO role holders from one or more Active Directory domains and forests.
 5.DESCRIPTION
 6Get-FSMORole uses the .NET Framework to determine which domain controller currently holds each
 7of the Active Directory FSMO roles. The Active Directory PowerShell module is not required.
 8.PARAMETER DomainName
 9One or more Active Directory domain names.
10.EXAMPLE
11Get-Content domainnames.txt | Get-FSMORole
12.EXAMPLE
13Get-FSMORole -DomainName domain1, domain2
14#>
15    [CmdletBinding()]
16    param(
17        [Parameter(ValueFromPipeline=$True)]
18        [string[]]$DomainName = $env:USERDOMAIN
19    )
20    PROCESS {
21        foreach ($domain in $DomainName) {
22            Write-Verbose "Querying $domain"
23            Try {
24            $problem = $false
25            $addomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain(
26                (New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $domain)))
27            } Catch { $problem = $true
28                Write-Warning $_.Exception.Message
29              }
30            if (-not $problem) {
31                $adforest = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest(
32                    (New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', (($addomain).forest))))
33
34                New-Object PSObject -Property @{
35                    InfrastructureMaster = $addomain.InfrastructureRoleOwner
36                    PDCEmulator = $addomain.PdcRoleOwner
37                    RIDMaster = $addomain.RidRoleOwner
38                    DomainNamingMaster = $adforest.NamingRoleOwner
39                    SchemaMaster = $adforest.SchemaRoleOwner
40                }
41            }
42        }
43    }
44}

fsmo-netframework.png

µ