Manage ServicePrincipalName Properties Using PowerShell 1


A few years ago [1] I wrote about how you could enable Domain Accounts to self-manage their ServicePrincipalNames.  This is particularly advantageous when using Kerberos to secure services.

We recently needed to set up some service accounts in Active Directory to participate in establishing a Kerberos capability for middleware integration.  I began unpacking the ADSIEdit approach, but stopped.  Whilst you can reach your end goal using the “established” approaches, it’s an absolute pain to deploy these changes to other environments.  Surely there must be a better way?

Enter PowerShell.  We can automate (by scripting) the ability to grant Active Directory accounts the ability to read and write ServicePrincipalName.  Eureka!  Full credit goes to this excellent answer on StackOverflow [2].

   1: Function Set-SpnPermission {

   2:     param(

   3:         [adsi]$TargetObject,

   4:         [Security.Principal.IdentityReference]$Identity,

   5:         [switch]$Write,

   6:         [switch]$Read

   7:     )

   8:     if(!$write -and !$read){

   9:         throw "Missing either -read or -write"

  10:     }

  11:     $rootDSE = [adsi]"LDAP://RootDSE"

  12:     $schemaDN = $rootDSE.psbase.properties["schemaNamingContext"][0]

  13:     $spnDN = "LDAP://CN=Service-Principal-Name,$schemaDN"

  14:     $spnEntry = [adsi]$spnDN

  15:     $guidArg=@("")

  16:     $guidArg[0]=$spnEntry.psbase.Properties["schemaIDGUID"][0]

  17:     $spnSecGuid = new-object GUID $guidArg

  18:  

  19:     if($read ){$adRight=[DirectoryServices.ActiveDirectoryRights]"ReadProperty" }

  20:     if($write){$adRight=[DirectoryServices.ActiveDirectoryRights]"WriteProperty"}

  21:     if($write -and $read){$adRight=[DirectoryServices.ActiveDirectoryRights]"readproperty,writeproperty"}

  22:     $accessRuleArgs = $identity,$adRight,"Allow",$spnSecGuid,"None"

  23:     $spnAce = new-object DirectoryServices.ActiveDirectoryAccessRule $accessRuleArgs

  24:     $TargetObject.psbase.ObjectSecurity.AddAccessRule($spnAce)

  25:     $TargetObject.psbase.CommitChanges()    

  26:     return $spnAce

  27: }

Now, you’d invoke this function this way:

   1: $TargetObject = "LDAP://CN=svc_account,OU=Service Accounts,DC=Development,DC=sanderstechnology,DC=com"

   2: $Identity = [security.principal.ntaccount]"DEVELOPMENT\svc_account" 

   3: Set-SpnPermission -TargetObject $TargetObject -Identity $Identity -write -read

Voila!

[1] http://sanderstechnology.com/2010/some-handy-articles-on-configuring-kerberos-with-service-principal-names-spns/9987/
[2] http://stackoverflow.com/questions/4156743/powershell-how-do-you-set-the-read-write-service-principal-name-ad-permissions


About Rob Sanders

IT Professional and TOGAF 9 certified Enterprise Architect with nearly two decades of industry experience, 18 years in commercial software development and 11 years in IT consulting. Check out the "About Rob" page for more information.


Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

One thought on “Manage ServicePrincipalName Properties Using PowerShell

  • Mark

    thanks for the post. I also came across this one liner using dsacls


    dsacls "CN=SQL Service Account,OU=Service Accounts,OU=Site,OU=Region,DC=domain,DC=com" /G SELF:RPWP;"servicePrincipalName"