The aim of this post is to explain how to detect KMS hosts installed by mistakes.

Since the new activation mechanism introduces by MS since Vista, most of sysadmins have many difficulties to understand the difference between Product Activation and Licenses management. Also, very often, sysadmins uses KMS host keys instead of KMS client keys or MAK keys.

When a computer running Vista up to W2k8 r2 is installed, often by mistakes, they are installed with a bad key and typically in this post, they are installed with a KMS host key. The problem is, by default, when a computer try to activate a KMS host against the MS online clearinghouse, the limit of max KMS hosts is 6. Also a KMS host try to create a SRV record in his current DNS namespace (_vlmcs._tcp.mycompany.com).

If there are KMS hosts installed and activated by mistakes, there are no WAY to ask to MS the list of KMS hosts. We can request to extend the limit by sending an email to Kmsadd@microsoft.com. Or we can use the VAMT v2 utility to perform audits and correct the problems.

So, after several years explaining how to activate MS computers to many sysadmins, I wrote a powershell script to get _vlmcs SRV records on a list of DNS namespace (input file dns-namespace-list.csv). This script requires dnsshell to work properly: http://dnsshell.sourceforge.net

# Get KMS SRV records on a list of domains
# Created   : 10/01/2012
# Updated   : 02/02/2012
# Author    : jdalbera
# Comments  : This script scans a list of domains for SRV records that may
# indicate they may be running KMS host.
# It writes the results to a text file
#
cls
Write-Host ""
Write-Host "------------------------------------------"
Write-Host " Get KMS SRV records on a list of domains "
Write-Host "------------------------------------------"
Write-Host ""
## VARIABLES
$domainscsvlist = '.\dns-namespace-list.csv'
$date = Get-Date -Format ddMMyyyy
$log = ".\logs\KMS-getVLMCSRecords-$date.txt"
# LOAD MODULE
Import-Module dnsshell
# LOAD INPUT FILE
$domains = Import-Csv $domainscsvlist
foreach ($row in $domains)
      {
      $domaintotest = $row.namespace
      $vlmcscheck = Get-Dns _vlmcs._tcp.$domaintotest srv | select -ExpandProperty answer
      $vlmcslist = Get-Dns _vlmcs._tcp.$domaintotest srv | select -ExpandProperty answertostring | ft
      if ($vlmcscheck -ne $null)
                  {
                  Write-host VLMCS SRV Records found for $domaintotest
                  $domaintotest | Out-File -append $log
                  "_vlmcs._tcp.$domaintotest" | Out-File -append $log
                  $vlmcslist | Out-File -append $log
                  }
      else
                  {
                  Write-Host No records found for $domaintotest
                  "No records found for $domaintotest" | Out-File -append $log
                  }
      Write-Host "---------------------------------------------------------------"
      $vlmcscheck = $null
      }
Write-Host "*****************"
Write-Host " Checks complete "
Write-Host "*****************"
Write-Host ""