TL;DR
You are not misunderstanding WinRM. This is the Windows double-hop problem, and the error you are seeing is its exact signature. NTLM cannot delegate credentials to a second machine, so the Invoke-Command running on your Automation Server has nothing to authenticate to the target with. Two fixes below. Start with Option 1, since it needs no changes on the Windows side.
What is actually happening
The orchestrator authenticates to your Automation Server over NTLM. You can see this in your own log output:
Running a NTLM connection
NTLM does not support credential delegation. The session created on the Automation Server holds a network logon token with no usable credentials attached to it. When your script then calls Invoke-Command -ComputerName <target>, that second hop has no credentials to present, and Windows returns:
Connecting to remote server failed with the following error message :
A specified logon session does not exist. It may already have been terminated.
That maps to error code 0x8009030e (SEC_E_NO_CREDENTIALS), which literally means no credentials are available in the current session. Microsoft covers the behaviour and its supported workarounds in Multi-Hop Support in WinRM.
Option 1: pass credentials explicitly on the second hop (recommended)
This is the fastest path and requires no configuration changes on Windows.
The PowerShell plugin connection has two fields, Script Username and Password and Script Secret Key. Values placed there are injected into your script as PowerShell variables ($username, $password, $secret_key) before it runs.
- Populate Script Username and Password with an account that has admin rights on the target endpoints.
- Build a credential object in your script and pass it to
Invoke-Command:
$cred = New-Object System.Management.Automation.PSCredential($username, $password)
Invoke-Command -ComputerName TARGET -Credential $cred -ScriptBlock {
msg * "This device has been quarantined by the Security Operations Centre. Please contact the Service Desk."
}
Because the credentials are supplied explicitly, the Automation Server performs a fresh authentication to the target and no delegation is involved.
Two caveats:
$password is already provided to you as a SecureString. Do not run ConvertTo-SecureString on it again.
- Avoid apostrophes and quotes in that password. The plugin builds the variable assignment using single-quoted interpolation, so those characters break parsing and you will get a
ParserError.
Option 2: switch the connection to CredSSP
CredSSP exists for exactly this scenario. It delegates your real credentials to the Automation Server, so onward hops authenticate normally and your original script works unmodified.
In the plugin connection:
- Set Auth Type to
CredSSP
- Set Port to
5986
The port matters. The plugin's CredSSP code path only builds an https:// endpoint, unlike the NTLM and Kerberos paths, which fall back to http on 5985. Setting port 5985 with CredSSP will fail regardless of how Windows is configured. A self-signed certificate is fine, since the plugin passes server_cert_validation="ignore".
Then, on the Automation Server only:
Enable-WSManCredSSP -Role Server
You do not need the -Role Client or -DelegateComputer half of that command. The CredSSP client in this setup is the Linux orchestrator rather than a Windows machine, so the AllowFreshCredentials policy does not apply.
Security note: CredSSP sends credentials to the Automation Server in a delegatable form. That is worth weighing against how well that server is hardened before choosing this route.
A note on Kerberos
Switching Auth Type to Kerberos will not solve the double hop with the current plugin. The underlying pywinrm library exposes a kerberos_delegation flag, off by default, that controls whether the TGT is forwarded to the target. The plugin does not set it. Constrained or unconstrained delegation configured in AD will not help until that flag is exposed.
Test the notification separately
Worth isolating: msg * runs non-interactively when invoked over WinRM, and it relies on Terminal Services session enumeration to find logged-in users. Confirm the notification actually displays by running the msg command locally on a target machine as SYSTEM. If nothing appears on screen, you will know whether you are chasing the remoting problem or the notification itself.
Consider skipping the jump box
If network segmentation is not what is driving the Automation Server design, the simplest architecture is to remove the second hop entirely. The Address field is set per action, so you can point the plugin directly at the endpoint you want to notify.