Hey, Scripting Guy! I need to obtain a listing of the domain controllers in my domain. I am thinking about using Windows PowerShell to query the Domain Controllers Organizational Unit, but I am not sure this is the right approach. Will this work? If it does work, will you write a Windows PowerShell script to query the computers in the Domain Controllers Organizational Unit?
<
p style=”MARGIN: 0in 0in 8pt” class=”MsoNormal”>– JM
Hello JM,
Microsoft Scripting Guy Ed Wilson here. Right now I am listening to elevator music (or lift music in the UK) because I am on hold waiting for the Script Center migration project meeting to begin. An incredible amount of work has been done by the migration team (which includes Microsoft Scripting Guy Craig, as well as honorary scripting guys Karen and Tharika) in moving all of the Hey, Scripting Guy! articles from the old platform to the new, moving all of the scripts from the old Web pages to the new TechNet Script Center Gallery, and moving the remainder of the content to the TechNet Library. This has involved more than 4,000 scripts and nearly 10,000 pages of Scripting Guy content.
There is still a little cleanup work to be done, which is why we continue to have these meetings. We recently enabled Bing as our search engine for the Hey, Scripting Guy! Blog, and that has made finding things on the site a lot better. Well, I have got to go, the meeting is starting. I hear Karen’s cheerful voice coming on the line. I will get back to you when the meeting is over.
JM, I am back. The easiest way to obtain a listing of domain controllers is to query the Domain Controllers Organizational Unit (OU). The Domain Controllers OU is the default location for all domain controllers. When you promote a regular member server to be a domain controller by using the DCPromo utility, it is automatically moved from its OU to the Domain Controllers OU. If you create a new server and during the installation you tell it to be a domain controller, it will likewise be automatically placed in the Domain Controllers OU. The Domain Controllers OU is seen here:
One advantage of a domain controller residing in the Domain Controllers OU is that it receives the Domain Controllers Group Policy object. This is seen here:
Unless you have a compelling reason for moving a domain controller from the Domain Controllers OU, you should not move a domain controller from the Domain Controllers OU. In the past, certain applications expected domain controllers to actually be in the Domain Controllers OU, and those applications would break if they could not find them there.
JM, to get back to your question, you should be okay to query the Domain Controllers OU to locate your domain controllers. A script that illustrates how to query the Domain Controllers OU, is seen here.
ListDomainControllersFromOU.ps1
$dc = [adsi]”LDAP://ou=domain controllers,dc=nwtraders,dc=com”
$dc.psbase.Children |
Format-Table -Property name, operatingsystem –AutoSize
You will need to modify the ListDomainControllersFromOU.ps1 script to point to your specific network—unless your domain happens to be named nwtraders.com.
The first thing the ListDomainControllersFromOU.ps1 script does is use the [adsi] type accelerator and the LDAP protocol to connect to the Domain Controllers OU in the nwtraders.com domain. This command returns a DirectoryEntry object that is stored in the $dc variable. This is seen here:
$dc = [adsi]”LDAP://ou=domain controllers,dc=nwtraders,dc=com”
The children property from the DirectoryEntry object is used to list all of the domain controllers from the OU. Because the children property is not directly exposed, the psbase property must be used to gain access to the children property. The command once again returns DirectoryEntry objects, which are piped. This line of code is seen here:
$dc.psbase.Children |
If you did not send the results down the pipeline, you would have an output similar to the one seen here:
distinguishedName : {CN=HYPERV,OU=Domain Controllers,DC=NWTraders,DC=Com}
Path : LDAP://CN=HYPERV,ou=domain controllers,dc=nwtraders,dc=com
distinguishedName : {CN=SERVER1,OU=Domain Controllers,DC=NWTraders,DC=Com}
Path : LDAP://CN=SERVER1,ou=domain controllers,dc=nwtraders,dc=com
If you are happy with that, you can remove the pipe from the $dc.psbase.Children line of code and crank up the Bob Seger and head out to your woodworking shop and make saw dust. If, on the other hand, you would like a cleaner display, you can use the Format-List cmdlet to create a better output. This line of code is seen here:
Format-Table -Property name, operatingsystem -AutoSize
The resulting display is seen here.
PS C:> C:Usersadministrator.NWTRADERSDocumentsListDomainControllersFromOU.ps1
name operatingsystem
—- —————
{HYPERV} {Windows Server 2008 R2 Standard}
{SERVER1} {Windows Server 2008 R2 Enterprise}
PS C:>
If you have moved your domain controllers from the Domain Controllers OU, you can still use Windows PowerShell to easily find them. In the FindAllDomainControllersForCurrentUserDomain.ps1 script, the static GetCurrentDomain method is used from the DirectoryServices.ActiveDirectory.Domain .NET Framework class. The GetCurrentDomain static method returns a DirectoryServices.ActiveDirectory.Domain object that represents the current user’s domain. After you have a domain object for the current user’s domain, you can use the FindAllDomainControllers method to list all of the domain controllers in the domain.
The FindAllDomainControllersForCurrentUserDomain.ps1 script is seen here.
FindAllDomainControllersForCurrentUserDomain.ps1
$domain = [directoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$domain.FindAllDomainControllers()
When you run the FindAllDomainControllersForCurrentUserDomain.ps1 script, the following is returned to the Windows PowerShell console:
PS C:> C:Usersadministrator.NWTRADERSDocumentsFindAllDomainControllersForCurrent
UserDomain.ps1
Forest : NWTraders.Com
CurrentTime : 10/5/2009 4:03:17 PM
HighestCommittedUsn : 70069
OSVersion : Windows Server 2008 R2 Standard
Roles : {SchemaRole, NamingRole, PdcRole, RidRole…}
Domain : NWTraders.Com
IPAddress : 192.168.1.100
SiteName : NewBerlinSite
SyncFromAllServersCallback :
InboundConnections : {68fbca46-8528-488f-a5b0-27c1fab452ac}
OutboundConnections : {42a3cd41-3c21-4912-9adf-4cc4aef1be9e}
Name : HyperV.NWTraders.Com
Partitions : {DC=NWTraders,DC=Com, CN=Configuration,DC=NWTraders,DC=
Com, CN=Schema,CN=Configuration,DC=NWTraders,DC=Com, DC
=DomainDnsZones,DC=NWTraders,DC=Com…}
Forest : NWTraders.Com
CurrentTime : 10/5/2009 4:03:17 PM
HighestCommittedUsn : 25205
OSVersion : Windows Server 2008 R2 Enterprise
Roles : {}
Domain : NWTraders.Com
IPAddress : 192.168.1.101
SiteName : NewBerlinSite
SyncFromAllServersCallback :
InboundConnections : {42a3cd41-3c21-4912-9adf-4cc4aef1be9e}
OutboundConnections : {68fbca46-8528-488f-a5b0-27c1fab452ac}
Name : Server1.NWTraders.Com
Partitions : {DC=NWTraders,DC=Com, CN=Configuration,DC=NWTraders,DC=
Com, CN=Schema,CN=Configuration,DC=NWTraders,DC=Com, DC
=DomainDnsZones,DC=NWTraders,DC=Com…}
PS C:>
As you can see from the above output, a decent amount of information is returned. You could, of course, use a Format cmdlet (such as Format-List or Format-Table) to customize your output if you wish, but the default display contains useful information.
If, however, the account that is running the script belongs to a different domain, than the one the computer account is in, you might want to retrieve the computer account domain object. This is illustrated in the FindAllDomainControllersForComputerDomain.ps1 script.
FindAllDomainControllersForComputerDomain.ps1
$domain = [directoryServices.ActiveDirectory.Domain]::GetComputerDomain()
$domain.FindAllDomainControllers()
The FindAllDomainControllersForComputerDomain.ps1 script is very similar to the FindAllDomainControllersForCurrentUserDomain.ps1 script. The only difference is the use of the GetComputerDomain static method to retrieve the directoryServices.ActiveDirectory.Domain object that represents the computers domain (instead of using the GetCurrentDomain static method). This modified line of code is seen here:
$domain = [directoryServices.ActiveDirectory.Domain]::GetComputerDomain()
When the FindAllDomainControllersForComputerDomain.ps1 script is run, the following output is displayed:
PS C:> C:Usersadministrator.NWTRADERSDocumentsFindAllDomainControllersForCompute
rDomain.ps1
Forest : NWTraders.Com
CurrentTime : 10/5/2009 4:18:29 PM
HighestCommittedUsn : 70087
OSVersion : Windows Server 2008 R2 Standard
Roles : {SchemaRole, NamingRole, PdcRole, RidRole…}
Domain : NWTraders.Com
IPAddress : 192.168.1.100
SiteName : NewBerlinSite
SyncFromAllServersCallback :
InboundConnections : {68fbca46-8528-488f-a5b0-27c1fab452ac}
OutboundConnections : {42a3cd41-3c21-4912-9adf-4cc4aef1be9e}
Name : HyperV.NWTraders.Com
Partitions : {DC=NWTraders,DC=Com, CN=Configuration,DC=NWTraders,DC=
Com, CN=Schema,CN=Configuration,DC=NWTraders,DC=Com, DC
=DomainDnsZones,DC=NWTraders,DC=Com…}
Forest : NWTraders.Com
CurrentTime : 10/5/2009 4:18:30 PM
HighestCommittedUsn : 25266
OSVersion : Windows Server 2008 R2 Enterprise
Roles : {}
Domain : NWTraders.Com
IPAddress : 192.168.1.101
SiteName : NewBerlinSite
SyncFromAllServersCallback :
InboundConnections : {42a3cd41-3c21-4912-9adf-4cc4aef1be9e}
OutboundConnections : {68fbca46-8528-488f-a5b0-27c1fab452ac}
Name : Server1.NWTraders.Com
Partitions : {DC=NWTraders,DC=Com, CN=Configuration,DC=NWTraders,DC=
Com, CN=Schema,CN=Configuration,DC=NWTraders,DC=Com, DC
=DomainDnsZones,DC=NWTraders,DC=Com…}
PS C:>
In this particular example, the output is from the FindAllDomainControllersForComputerDomain.ps1 script is the same as the output from the FindAllDomainControllersForCurrentUserDomain.ps1 script. This is because on my test system, the user account that was used to run the script is in the same domain as the computer account.
Well, JM, that is about all there is to retrieving a listing of domain controllers.
If you want to know exactly what we will be scripting tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
0 comments