PowerShell: Use Active Directory SPNs to find domain services

Overview:

In this article, we will go over some basic high-level ways to find certain domain systems using the information contained in their service principal name (SPN) attribute.

I have tested these SPNs against a few dozen different environments and so far everything appears to be correct. Though something that I’ve noticed is that while ServicePrincipalNames are useful in locating certain systems on a domain quickly, the data’s accuracy is very much dependent on the service type and health of the domain.

What are ServicePrincipalNames (SPNs):

A service principal name (SPN) is a unique identifier of a service instance. SPNs are used by Kerberos authentication to associate a service instance with a service logon account. This allows a client application to request that the service authenticate an account even if the client does not have the account name.

In short the ServicePrincipalName attribute in Active Directory can be used to quickly find systems that offer certain services.

Finding SPNs:

To start I like to grab all the computers in a domain with a few filters to reduce any noise. In the command below I am gather any computers that are enabled and that have logged into the domain in the past 6 months. Then I store all returned data in a variable called “$ADComputers”.

A good reference for other SPNs can be found here

There a many other ways to filter computers in AD and this is just a quick and easy example.

$PastTime = (Get-Date).AddDays(-180)
$ADComputers = Get-ADComputer -Filter {enabled -eq $true -and LastLogonTimeStamp -gt $PastTime} -Properties servicePrincipalName,OperatingSystem | Sort-Object Name

Now using the “$ADComputers” variable from above we can filter those system even more to find the certain services by flagging off of their SPNs.

Any headings listed below with a “*” can sometimes not be accurate and if you are using these examples in a script you should also include another way to validate that the discovered SPN is accurate.

Show all SPNs

($ADComputers).servicePrincipalName | Sort-Object

Domain Name Servers (DNS)

$ADComputers | Where-Object {$_.servicePrincipalName -like "*DNS*"} | Select-Object Name,OperatingSystem

Hyper-V Hosts

$ADComputers | Where-Object { (! ($_.servicePrincipalName -like "*MSClusterVirtualServer*") -and $_.servicePrincipalName -like "*Hyper-V*") } | Select-Object Name,OperatingSystem

Hyper-V Virtual Cluster Objects

$ADComputers | Where-Object {$_.servicePrincipalName -like "*MSClusterVirtualServer*"} | Select-Object Name,OperatingSystem

DFSR & NtFRS

$ADComputers | Where-Object {$_.servicePrincipalName -like "*dfsr*"} | Select-Object Name,OperatingSystem

$ADComputers | Where-Object {$_.servicePrincipalName -like "*NtFrs*"} | Select-Object Name,OperatingSystem

Exchange & Mail Objects *

#Exchange
$ADComputers | Where-Object {$_.servicePrincipalName -like "*exchange*"} | Select-Object Name,OperatingSystem

#SMTP
$ADComputers | Where-Object {$_.servicePrincipalName -like "*SMTP*"} | Select-Object Name,OperatingSystem

#IMAP & POP
$ADComputers | Where-Object {$_.servicePrincipalName -like "*IMAP*"} | Select-Object Name,OperatingSystem
$ADComputers | Where-Object {$_.servicePrincipalName -like "*POP*"} | Select-Object Name,OperatingSystem

SQL *

$ADComputers | Where-Object {$_.servicePrincipalName -like "*MSSQLSvc*"} | Select-Object Name,OperatingSystem

HTTP *

$ADComputers | Where-Object {$_.servicePrincipalName -like "*HTTP*"} | Select-Object Name,OperatingSystem

iSCSI *

$ADComputers | Where-Object {$_.servicePrincipalName -like "*iSCSITarget*"} | Select-Object Name,OperatingSystem

Conclusion:

This by no means is a complete list of SPNs but after discovering the usefulness of these attributes I really wanted to share this with others.

The SPNs that I look for the most are DNS, Hyper-V, and Hyper-V Cluster Objects though something to note is that while these three have been very accurate for me so far, Windows be Windows and sometimes things don’t get populated as they should. So as a good recommendation you should use multiple verification methods when querying and validating systems in an AD environment.

The Get-WindowsFeature is a good secondary verification method to start with.

Invoke-Command -ComputerName MY-DC01 -ScriptBlock {Get-WindowsFeature}

Leave a Reply