Query AD for Computers and Use Ping to Determine Status

Summary: Learn how to use Windows PowerShell to query Active Directory for computers, ping for status, and display in green/red.

 

Microsoft Scripting Guy Ed Wilson here. While the Scripting Wife and I were out in California speaking to the Microsoft Premier Field Engineers (PFE) about Windows PowerShell, a question arose. The PFE said he had a customer that needed to send a ping to a number of computers. The customer did not need a lot of information about the status, but more of a simple yes or no report on connectivity. Ping was the tool of choice due to simplicity. The problem is that Ping returns too much information. What the customer really wanted was an output that displayed the computer name in green (for up) and in red (for down). A simple status board to display the computer names. One problem, the PFE related, is that the collection of computers to monitor changes on nearly a daily basis. Therefore, the customer wants to query Active Directory for the computer names.

We left the reception Thursday night, and I went up to the room and put together this script. It could have been a “one-liner” but, it would have been difficult to read, so I spread it out over a couple of different lines. Here is the complete Query Active Directory and Ping Computers script in Windows PowerShell (for ease of use, I uploaded the script to the Scripting Guys Script Repository):

Query Active Directory and Ping Computers

Import-Module active*

$rtn = $null

Get-ADComputer -Filter * |

ForEach-Object {

  $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet

  IF($rtn -match ‘True’) {write-host -ForegroundColor green $_.dnshostname}

  ELSE { Write-host -ForegroundColor red $_.dnshostname }

}

The first thing the Query Active Directory and Ping Computers script does is import the ActiveDirectory module. I have written about this module quite a bit. In the Install Active Directory Management Service for Easy PowerShell Access post, I go into detail about the requirements to set up the Active Directory Management gateway. Next, I set the value of the $rtn variable to $null. This helps to avoid problems if there is already a $rtn variable with a different value.

I then use the Get-ADComputer cmdlet from the ActiveDirectory module (I have used the Get-ADComputer cmdlet numerous times on the Hey, Scripting Guy! Blog) to return all computers. The following line of code returns an ADComputer object from the Microsoft.ActiveDirectory.Management namespace:

Get-ADComputer -Filter *

By default, the ADComputer object contains only a few properties. The default properties are shown here:

DistinguishedName                                                                   

DNSHostName                                                                         

Enabled                                                                             

Name                                                                                

ObjectClass                                                                         

ObjectGUID                                                                          

SamAccountName                                                                      

SID                                                                                 

UserPrincipalName  

Other properties exist on a computer object. For example, the following figure illustrates properties that contain a value for the W7Client computer. The figure from ADSI Edit is shown here.

Image of properties containing a value for W7Client computer

To obtain access to additional property values, I need to add them to the property parameter (the reason for the small subset of properties returned by default is because of performance concerns). Here is an example of returning the DNSHostname and the lastlogon attribute values.

Get-ADComputer -Filter * -Properties lastlogon | select dnshostname, lastlogon

Unfortunately, the Test-Connection cmdlet does not accept piped input, and I need to use the Foreach-Object cmdlet to walk through the collection of ADComputer objects and ping the DNSHostname of each computer. To speed things along, I send one ping and reduce the BufferSize. I store the results in a variable named $rtn:

ForEach-Object {

  $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 –Quiet

The Test-Connection returns a True or a False depending upon whether the connection succeeds. But unfortunately, it is a string and not a true Boolean value. Therefore, in my decision portion of the script, I used the IF statement and did a match on the string True. If Test-Connection returns true, I display the DNSHostname of the computer in green. Otherwise, I display the DNSHostname of the computer in red. This portion of the script is shown here:

ForEach-Object {

  $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet

  IF($rtn -match ‘True’) {write-host -ForegroundColor green $_.dnshostname}

  ELSE { Write-host -ForegroundColor red $_.dnshostname }

}

The script and associated output are shown in the following figure.

Image of script and associated output

 

Well, that is about all there is to querying Active Directory Domain Services for computer accounts, and pinging them to see if they are up and running or not. Join me tomorrow for more cool Windows PowerShell stuff.

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