Testing for SRV records - need help pulling data out of hashtable

Howdy folks!

I am trying to design a test to verify SRV records exist in DNS but I am having some issues constructing the test. My idea is to check for three record types: DC, GC and KDC SRV records. My thought was if I have 29 Domain controllers (and their all global catalog servers), then I could simply count the # of domain controllers, then count the # of GC, KDC, and DC Srv records and compare the results.

I can do the query and get the record counts. I save them to a hashtable but then I get stuck. if I have 3 rows in the hash table, how would I find rows that do not equal the count in my $DCount variable?

Here’s my code for the record counts and the table creation:

$DCList = (get-adgroupmember "Domain Controllers").name
$DCCount = (get-adgroupmember "Domain Controllers").count
$PDCEmulator = (get-addomaincontroller -Discover -Service PrimaryDC).name
$MSDCSZoneName = '_msdcs.bigfirm.biz'
$ZoneName = 'bigfirm.biz'
$DC_SRV_Record = '_ldap._tcp.dc'
$GC_SRV_Record = '_ldap._tcp.gc'
$KDC_SRV_Record = '_kerberos._tcp.dc'
$PDC_SRV_Record = '_ldap._tcp.pdc' 
$Results = @{}

$Results.DCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $DC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)
$Results.GCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $GC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)
$Results.KDCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $KDC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)

Here’s my results:

Name                           Value                                                                                                                                                        
----                           -----                                                                                                                                                        
KDCRecordCount                 29                                                                                                                                                                                                                                                                                                              GCRecordCount                  29                                                                                                                                                           
DCRecordCount                  29  

let’s say GC RecordCount and DCRecordCount cam back as 28. I would like to pull those two records out and possibly save them to a new variable which I could then use to generate an email alert.

I need some help figuring out how to get the results from the hashtable. I am open to suggestions if someone can think of a better way to construct the logic.

Could you test the values in the table to find those that don’t match the expected value? Then add other logic to send your email or whatever.

$DCCount = 29

$Results = @{
DCRecordCount = 29
GCRecordCount = 28
KDCRecordCount = 29
}

$Results.GetEnumerator() | Where-Object {$_.value -ne $DCCount}
### (output below)
Name                           Value
----                           -----
GCRecordCount                  28

Not sure if you are trying to set an intention to test against.
Example:
“I have x number of DC’s, here is a test to ensure there are x records of each type existing in DNS.”

OR

You want to keep the number of DC’s abstract and test for equality of each SRV type, and only notify on differences.

The first option would require capturing the desired information of the infrastructure, then writing tests that check certain details about each one. So maintaining a list of DC node names, and then looping through a set of tests for each one.

The second option could be solved with Compare-Object, to compare the 3 types, and return what is different (If there is a value that can be compared between records.)
Example:

# Returned records are saved as an array, even if 1 record is returned.
# Parameters for the retrieval are fictitiously splatted to the cmdlet.)
$DCRecords  = @(Get-DNSServerResourceRecords @DCRecordParams)
$GCRecords  = @(Get-DNSServerResourceRecords @GCRecordParams)
$KDCRecords = @(Get-DNSServerResourceRecords @KDCRecordParams)

$differences  = @(Compare-Object -ReferenceObject $DCRecords.Hostname -DifferenceObject $GCRecords.Hostname)
$differences += @(Compare-Object -ReferenceObject $GCRecords.Hostname -DifferenceObject $KDCRecords.Hostname)
$differences += @(Compare-Object -ReferenceObject $KDCRecords.Hostname -DifferenceObject $DCRecords.Hostname)

$differences

or to stick with returning a count, here is an example:

#... UserConfiguration code ...

$Results.DCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $DC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)
$Results.GCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $GC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)
$Results.KDCRecordCount = ((Get-DnsServerResourceRecord -ZoneName $MSDCSZoneName -Name $KDC_SRV_Record  -RRType srv -ComputerName $PDCEmulator).count)

foreach ( $result in $Results.GetEnumerator() ) {
  "{0} - {1}" -f $result.Key, $result.Value
}

Hope that helps,
Brent