The 2 AM Call That Started This Post
A managed customer paged us last quarter. Their nightly PowerShell job hit a remote file server, then tried to copy from a third box. It failed every single night with an access denied. Local interactive? Worked fine. Remote? Dead.
Classic double-hop. And the root cause was a PowerShell remoting authentication mismatch nobody had thought about since the original WinRM rollout. If you run any kind of fleet automation, you need to understand which protocol PSRemoting picks, why, and when to override it.
Kerberos Is the Default, and That’s Usually Fine
PSRemoting was built for Active Directory. When both boxes are domain-joined (or in trusting domains), and the client can resolve the target hostname, Kerberos is what you get. The server needs a valid SPN registered in AD that matches the target you typed into Enter-PSSession.
Three conditions, all required:
- Both machines in the same domain or trusted domains
- Hostname or FQDN resolvable from the client
- SPN registered and matches the connection target
Miss any of those and Negotiate quietly falls back to NTLM. That’s the part that bites people.
The Hostname vs IP Gotcha
This is the one I see weekly. You run Enter-PSSession -ComputerName 10.20.30.40 and it works. You assume Kerberos. It’s not. Kerberos needs a name to build the SPN lookup, so an IP forces a fallback to NTLM almost every time. If you connect by IP across a workgroup or partial trust, you’ll also need the target on the client’s TrustedHosts list or HTTPS configured.
Want to verify? Check the session after connecting:
$s = New-PSSession -ComputerName fileserver01.corp.local
Invoke-Command -Session $s { klist }
No ticket for the target? You’re on NTLM. Simple as that.
NTLM: The Fallback Nobody Asked For
NTLM kicks in when Kerberos can’t. Local accounts always force NTLM. So do IP-based connections and workgroup boxes. The auth still works, the channel is still encrypted under WS-Management, but you lose mutual auth and you cannot delegate credentials further. That second part is what breaks scripts.
One opinion I’ll stand behind: if your automation runs over NTLM in 2026, you’ve got an architecture problem, not a PowerShell problem. Fix DNS, register the SPN, or move the box into AD. We’ve migrated managed VPS fleets specifically to clean up this kind of mess for clients who inherited messy environments.
The Double-Hop Problem and Why CredSSP Exists
Here’s the scenario from that 2 AM page. Your script connects from Box A to Box B with Kerberos. On Box B, the script tries to read a UNC path on Box C. Box B has your Kerberos ticket but cannot forward it to Box C. Access denied. Every time.
This is the double-hop problem and it’s been around since PSRemoting shipped. Kerberos delegation can fix it via the “Trusted for Delegation” flag in AD, but messing with domain-level delegation policy for a one-off script is a heavy hammer.
Enable CredSSP, Carefully
CredSSP is the same mechanism RDP uses. It delegates your actual credentials to the remote box, which can then reuse them for the second hop. It doesn’t need AD, which is why it’s the answer for workgroup automation too.
Enable on the target first:
Enable-WSManCredSSP -Role Server
Then on the client:
Enable-WSManCredSSP -Role Client -DelegateComputer "fileserver01.corp.local"
Then connect with the right flag:
Enter-PSSession -ComputerName fileserver01.corp.local -Authentication CredSSP -Credential (Get-Credential)
Caveat — and this matters — CredSSP hands the actual credential to the remote box. If that box is compromised, the attacker has the cleartext credential, not just a derived hash. We deployed CredSSP across one client’s backup automation tier specifically because their backup storage jobs needed to traverse three machines, but we scoped it to a dedicated service account with zero interactive logon rights and locked the delegation list down via Group Policy. That’s the only way I’d ever recommend it.
The Full Authentication Parameter Cheat Sheet
The -Authentication parameter on Invoke-Command, Enter-PSSession, and New-PSSession accepts a fixed enum. Worth knowing what each one actually does:
- Default — Negotiate. Tries Kerberos, falls back to NTLM.
- Kerberos — Forces Kerberos. Fails hard if the SPN isn’t there.
- Negotiate — Same as Default. Domain account picks Kerberos, local account picks NTLM.
- NegotiateWithImplicitCredential — Uses your current logged-on context.
- CredSSP — Delegates the full credential. Double-hop friendly.
- Basic — Cleartext over HTTP. Pair with HTTPS or don’t use it.
- Digest — HTTP digest auth. Almost never the right answer.
Forcing -Authentication Kerberos is my preferred posture for any production automation. It fails loudly instead of silently degrading to NTLM, which means you catch the SPN problem during testing, not at 2 AM.
The SPN Trap Almost Nobody Talks About
PowerShell remoting registers under HTTP/ by default. If something else in your environment already grabbed HTTP/hostname — a service account for IIS, a SharePoint farm, anything — WinRM Kerberos will fail with 0x80090322. The error is useless. The fix is to either use a port-qualified SPN or switch the listener to use the WSMAN/ SPN where it exists. We hit this on a financial services client’s environment last year. Took half a day to trace because nothing in the WinRM logs pointed at the SPN collision.
What You Should Actually Do Monday Morning
Audit your PSRemoting setup. Run this on every box that initiates remote sessions:
Get-WSManCredSSP
Get-Item WSMan:\localhost\Client\TrustedHosts
If you see a wildcard in TrustedHosts, fix it. If CredSSP is enabled on every server, scope it down. If your automation runs over NTLM, register the SPN and use FQDNs in your scripts. The NIST Cybersecurity Framework won’t tell you any of this specifically, but the principle is the same: least privilege, fail closed, no silent fallbacks.
If you want a second set of eyes on your PSRemoting posture before something breaks at 2 AM, reach out — we audit Windows automation tiers across managed environments and the same five mistakes show up every single time. For more PowerShell deep dives, check our writeups on REST API calls with Invoke-RestMethod and PowerShell providers for the registry.
The Takeaway
Kerberos is the default, the secure choice, and the one that actually works in a properly built domain. NTLM is the fallback that means something’s wrong with your setup. CredSSP solves the double-hop but should be tightly scoped to specific delegation targets and service accounts. Force the auth type explicitly in your scripts so failures are loud, and the 2 AM pages stop being about authentication mysteries.


