Lerch Web Wiki

Random, erratic, no responsibility is taken for the correctness of this information

User Tools

Site Tools


powershell:ad:locate_my_dc

Locate my DC

Howdy girls and boys,

today we are going to talk about a way to locate a DC in your AD environment.

We all know the problem: you have a script that wants to make some modifications to a number of Active Directory objects so you need to target the script to a writeable domain controller inside your AD and preferably one that isn’t to far away from the computer the script is running on. So how do we locate this DC?

Windows has a built in way to locate a DC called DC locator mechanism. Why don’t we use this DC locator to find the appropriate DC for us? Let’s do this! Wait a second…how can we trigger this DC locator? And how do we get the result of that “DC locator call” ?

You already guessed it, we will use PowerShell.

So with the help of my friend Michael and his blog post, I have this little script for you

function Use-DCLocator {
$contextType = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Domain
$domain = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($contextType)
[System.DirectoryServices.ActiveDirectory.LocatorOptions]$Options = `
    [System.DirectoryServices.ActiveDirectory.LocatorOptions]::ForceRediscovery -bor `
    [System.DirectoryServices.ActiveDirectory.LocatorOptions]::WriteableRequired
try
{
    $Site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().ToString()
    $foundDC = ([System.DirectoryServices.ActiveDirectory.DomainController]::FindOne($domain, $Site, $Options)).Name
}
catch
{      
    $foundDC = ([System.DirectoryServices.ActiveDirectory.DomainController]::FindOne($domain, $Options)).Name
}
$foundDC
}

Looks way too complicated? Granted, this isn’t pure PowerShell. This is .Net!

What do we do here? We rely on the foundation of PowerShell: the mighty .Net Framework and the class [System.DirectoryServices.ActiveDirectory.DomainController] of which we use the method FindOne().

So first of all we need to define a context for the DC Locator so it knows we are looking for a DC in a domain. The context can be one of:

  • ApplicationPartition
  • ConfigurationSet
  • Directory Server
  • Domain
  • Forest

Second we assign this ContextType to an actual DirectoryContext object which we later will hand over to the DC Locator.

What DC do we actually want to find? We can tell the DC Locator to look for specific DCs by using Locator Options. Be aware that we have to cast the type of the variable as [System.DirectoryServices.ActiveDirectory.LocatorOptios] as we do in Line 3. Otherwise the result of the –bor would be an integer which the DC Locator is unwilling to understand. The options we can use here are:

  • AvoidSelf
  • ForceRediscovery
  • KdcRequired
  • TimeServerRequired
  • WriteableRequired

We are going to use ForceRediscovery and WriteableRequired, so we can be sure we won’t get a RODC and the DC Locator is going through the discovery process again and we will get a “living” DC. The options we need are combined by the –bor (bitwise OR) so we get the flags set appropriately.

Let’s try (hint) to find the site we are in, so we can give that to the DC Locator as well and find a nearby DC. How? Just use another .Net Class [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite] and it’s method GetComputerSite() and transform this into a string. Could we determine the site we are in? If so, give all we have to DC Locator and let him get the DC we are desperately looking for (Line 6).

If we were not able to determine which site our PC is in, we just give the other information we have to the DC Locator and get back a DC may not be in our site but otherwise has all the capabilities we are looking for.

So here it is (Line 11) present that DC to the user (or whatever function you want to perform tasks against it).

Hopefully this wasn’t to boring stuff for a Sunday afternoon Winking smile

Till next time…

powershell/ad/locate_my_dc.txt · Last modified: 2017/02/27 09:13 by marcus