By configuring computer delegation with PowerShell, you can determine whether you can access an Active Directory (AD) computer from another computer. This article will demonstrate the difference between unconstrained delegation, constrained delegation to any service, and constrained delegation to specified services.

The concept of computer delegation in a nutshell

To make it easy to understand the whole article, let's work on an example:

  1. You are logged in on ComputerA.
  2. You connect from ComputerA to ComputerB via a PSSession.
  3. From the PSSession on ComputerB, you want to copy files from the central repository on ComputerC to ComputerB.

This scenario is called a "double hop," and without delegation, you will get an "Access denied" error message.

Two different approaches

The "one to many" approach consists of setting the ComputerB account with a list of ComputerC-like computers that ComputerB can access.

This concerns:

  • Unconstrained delegation (from ComputerB you can access all services on all other computers).
  • Constrained delegation to any service (from ComputerB you can access all services on a specified list of computers).
  • Constrained delegation to specified services (from ComputerB you can access a specified list of services on a specified list of computers). This offers two options: using Kerberos only or using any authentication protocol.

The "one from many" approach consists of setting the ComputerC account with the list of all ComputerB-like computers allowed to access all services on ComputerC through a double hop.

This last approach concerns resource-based constrained delegation.

A full comparison of all of these different possibilities is beyond the scope of this article.
However, you should know that:

  • "No delegation" is the most secure option. Therefore, set delegation only when you have to.
  • Unconstrained delegation is the least secure solution.
  • Every type of delegation has its own advantages and limitations.
  • Constraint delegation is easy to manage, and when deleting your computer account, the delegation goes with it.
  • With resource-based constrained delegation, one computer account can contain a very long list of other computers. You should regularly check that all computer accounts from this list still exist and that there are no duplicates.
  • Domain controllers are set with unconstrained delegation by design. Don't change this behavior, and ensure that when you configure delegation massively with a script, exclude domain controllers from its computer list.

Important note:

Based on my findings, when you set delegation, it needs a few seconds or even minutes before you can check the value with a Get verb and also before all involved computers become aware of the delegation.

This can lead you to wrong conclusions when you play around and you want to check the results too fast.

Unconstrained delegation to any service

Unconstrained delegation with the user interface

Unconstrained delegation with the user interface

This is attainable with the Set-ADAccountControl cmdlet.

Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedForDelegation $true

Constrained delegation to specified services with Kerberos only

Constrained delegation using Kerberos only with the user interface

Constrained delegation using Kerberos only with the user interface

In this case, you must specify a list of ComputerC's service principal names (SPNs) in ComputerB's account. To obtain the list of SPNs, you can use the Get-ADComputer cmdlet and display the servicePrincipalName property of ComputerC.

Get-ADComputer ComputerC -Properties servicePrincipalName | Select-Object ‑ExpandProperty servicePrincipalName
Get the list of SPNs from ComputerC

Get the list of SPNs from ComputerC

Then you add ComputerC's list of SPNs you need to ComputerB's account with the Set-ADComputer cmdlet along with the Add parameter. This parameter accepts a hash table containing an array of strings as input.

Set-ADComputer -Identity ComputerB -Add @{'msDS-AllowedToDelegateTo'=@('HOST/ComputerC','WSMAN/ComputerC.MyDomain.com')}

Constrained delegation to specified services only with any authentication protocol

Constrained delegation with any protocol with the user interface

Constrained delegation with any protocol with the user interface

As with the former method, you must find the list of ComputerC's SPNs and add those you need to the ComputerB account.

However, you must also use the Set-ADAccountControl cmdlet with the TrustedToAuthForDelegation parameter.

Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $true
Set-ADComputer -Identity ComputerB -Add @{'msDS-AllowedToDelegateTo'=@('HOST/ComputerC','WSMAN/ComputerC.MyDomain.com')}

Note: Do not confuse the TrustedToAuthForDelegation parameter for constrained delegation with the TrustedForDelegation parameter from above, which applies to unconstrained delegation only.

Resource-based constrained delegation

There's no screenshot here because there is no native user interface to set this value. You must do it with PowerShell.

In the following example we will allow ComputerB1 and ComputerB2 to access ComputerC with the Set-ADComputer cmdlet. The input for the PrincipalsAllowedToDelegateToAccount parameter is an array of distinguished names. But for convenience we will use a computer object as input, and the cmdlet will find out the distinguished name itself.

Set-ADComputer ComputerC -PrincipalsAllowedToDelegateToAccount (Get-ADComputer ComputerB1),(Get-ADComputer ComputerB2)

Please note that the PrincipalsAllowedToDelegateToAccount parameter is only available on Windows 8 or Windows Server 2012 computers and later.

Check the current delegation for a computer

The computer account object stores all values, which the Get-ADComputer cmdlet can retrieve.

Get-ADComputer ComputerName -Properties * | Format-List -Property *delegat*,msDS-AllowedToActOnBehalfOfOtherIdentity
Check delegation for a computer

Check delegation for a computer

When using resource-based constrained delegation, it will display System.DirectoryServices.ActiveDirectorySecurity for the msDS-AllowedToActOnBehalfOfOtherIdentity property.

You must then expand this value to see the content, especially the list of computers allowed to access ComputerC in the Access property.

Get-ADComputer ComputerC -Properties * | Select-Object -ExpandProperty msDS-AllowedToActOnBehalfOfOtherIdentity |Format-List
Check details of resource based delegation for a computer

Check details of resource based delegation for a computer

Remove delegation

To remove unconstrained delegation from ComputerB, use the following command:

Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedForDelegation $false

To remove constrained delegation from ComputerB, use the following two commands:

Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $falseSet-ADComputer -Identity ComputerB -Clear 'msDS-AllowedToDelegateTo'

To remove resource-based constraint delegation from ComputerC, use the following command:

Subscribe to 4sysops newsletter!

Set-ADComputer ComputerC -PrincipalsAllowedToDelegateToAccount $Null
avatar
9 Comments
  1. Sedrick White 4 years ago

    You are missing a closing ‘)’ in both delegation commands.

    incorrect:
    Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’}
    correct:
    Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’)}

    incorrect:
    Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’}

    correct:
    Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’)}

    avatar
  2. Sedrick White 4 years ago

    When removing delegation, I would recommend using the -Remove option instead of -Clear. if you have multiple delegations this would clear them all.

    • Author

      @Sedrick

      Yes, that’s the point with my example using -Clear, like the example that follows and which uses $Null to removes all principals from the PrincipalsAllowedToDelegateToAccount property.

      But if you want to remove only some entries of the msDS-AllowedToDelegateTo property, you are right, the -Remove option is the way to go.

  3. assad 4 years ago

    Hi Luc,

    what happens when a constrained delegation is removed from computer c. The reason i ask is that in our infrastructure there is an issue that computer a cannot access coputer c after a reboot(cifs share access). I would like to remove all delegations from c so that we can access it. 

    thanks

    azd

    • Author

      @assad

      If you remove delegation you cannot access resources through computerB anymore. You have to access them directly from ComputerA to ComputerC.

  4. John A Rolstead 3 years ago

    another way to get just the values set

    (Get-ADServiceAccount <GMSANAME> -Properties * | Select-Object -ExpandProperty msDS-AllowedToActOnBehalfOfOtherIdentity).Access.IdentityReference.Value

  5. Meex 3 years ago

    Hi,

    thx for your very interesting blog! I have a question, we need to run a lot of servers in a docker environment (tomcat), the tomcat servers a running all with the same user called tomcat. From the tomcat server it should be possible to call a second servers webservice. So as I understand right I have to allow delegation for the tomcats. But I'm not sure, should I allow delegation to the user tomcat, or to the tomcat servers? I connect the server with the tomcat user by 

    setspn -A HTTP/tomcatsrv1.example.com tomcat

    then I generate the keytab file

    ktpass /out c:\temp\tomcat.keytab 
            /mapuser tomcat@EXAMPLE.COM
            /princ HTTP/tomcatsrv1.com@EXAMPLE.COM
            /pass ******** /ptype KRB5_NT_PRINCIPAL

    User tomcat has set constrainted delegation for all auth protocolls to the webservice server?

     

    But somehow it doesn't work :-/

     

    regards

    Meex

     

  6. Dane Winkler 5 months ago

    What PowerShell command do I use to mass set a list of computers for ‘Do not trust this computer for delegation’?

Leave a reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account