PowerShell Remoting Results in Errorcode 0x80090322

A-X-O-L-O-T-L, my time has come to burn! I invoke the ancient power that I may return!

In a domain with around 700 servers, there seems to be a very small handful that will simply not allow me to use Enter-PSSession or Invoke-Command despite having domain admin credentials. They always respond with:

Connecting to remote server <servername> failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090322 occurred while using Kerberos authentication: An unknown security error occurred.

I’ve dug through event logs, firewall logs, antivirus logs, but wasn’t finding anything relevant.

Well guess what, I figured out the cause, and more importantly, the fix. Ok well, I found a post that pointed me in the right direction on technet so I’ll give credit where it’s due. Now to be fair, there’s a number of possible causes listed in the actual error message it returns, but mine was related to the Service Principal Name, or SPN.

So as it turns out, PowerShell remoting is trying to access servers using the SPN. Specifically it is using “HTTP/servername”. If you have service accounts in your environment configured with these same SPNs, then you’re going to have a bad time. The error code above occurs because PowerShell is finding the SPN for the service account, which obviously results in it failing to successfully access the server.

Now, the “hit it with a hammer” approach is to simply delete these SPNs from the service accounts. You should be very cautious when doing this though, as some applications (like in my environment) actually rely on these being in place.

So how do you get around it? You create a new SPN for the server giving you problems. Specifically an SPN that includes port 5985, like so

HTTP/servername:5985

(You can also use HTTP/servername:5986 for https traffic, but let’s just focus on 5985 for the sake of this post). An SPN can easily be added with the command line using the following command

setspn -s HTTP/servername:5985 servername

You can then validate that the SPN you just added is present by listing all the SPNs associated with the server. (it’s a lower case “L” for “list”)

setspn -l servername

After you create this new SPN you may need to wait a few minutes before it becomes accessible due to replication and what not. Assuming you’re more patient than I am, this should now run successfully.

$option = New-PSSessionOption -IncludePortInSPN
$session = New-PSSession -ComputerName <servername> -SessionOption $option
Invoke-Command -Session $session -scriptblock { whatever }

By doing the above, your script will now try to accessing the server using HTTP/servername:5985 instead of just HTTP/servername

You may run into a new problem at this point unfortunately. But fear not! The problem you may experience is you’ll have a mix of servers that have the new SPN configured and others that don’t (because they worked fine without it). If you try accessing a server with the commands above, but that server doesn’t have the new SPN configured with the port, now that one will begin giving you an error. You need to put some logic into the script to account for these two different types of servers.

  • Ones accessible via HTTP/servername
  • And ones accessible via HTTP/servername:5985

Generally when I’m doing something with “Invoke-Command” it’s because I have to do something to a group of servers all at once. Since I can’t always know off the top of my head which computers have the 5985 SPN configured and which ones don’t, I use an if statement and include the ServicePrincipalName property when I call Get-ADComputer. If it sees a service principal name containing 5985 it will connect using the code above, otherwise it’ll just stick to regular old invoke-command and proceed like normal.

$servers = Get-ADComputer -Filter <your filter> -Properties ServicePrincipalName
$option = New-PSSessionOption -IncludePortInSPN

ForEach($server in $servers){
    If($server.serviceprincipalname -like "*5985"){
        $session = New-PSSession -ComputerName $server.name -SessionOption $option
        Invoke-Command -Session $session -ScriptBlock { whatever }
        Get-PSSession | Remove-PSSession
    }Else{
        Invoke-Command -ComputerName $server.name -ScriptBlock { whatever }
    }
}

Well at this point you should be able to get those troublesome servers working, but how can you get in front of the problem? Write some quick PowerShell of course. All you’re looking for are user accounts that have an SPN set that includes “HTTP”. From there you can likely just look over the list it returns and spot any that are going to give you a problem.

Get-ADUser -Filter {ServicePrincipalName -like "HTTP*"} -properties ServicePrincipalName | Select-Object -ExpandProperty ServicePrincipalName

And with that you should be good to go. Godspeed.

3 thoughts on “PowerShell Remoting Results in Errorcode 0x80090322

Leave a Reply

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