Solved

How does Calm execute PowerShell on an endpoint?

  • 28 December 2021
  • 9 replies
  • 341 views

Userlevel 2
Badge +2

Hi all!

In an attempt to solve a problem with “round-tripping” JSON I’ve concluded that the only fix is to use PowerShell 7 since the ConvertTo-Json cmdlet in version 7 allows me to escape the troublesome characters.

This solution might just be me robbing Peter to pay Paul though as I now face the issue of getting Calm to use PowerShell 7 instead of the default 5.1 (a.k.a. Windows PowerShell).

I’ve gone so far to set the default PowerShell remote endpoint (windows.powershell) to point to PSH 7, which works if I do a traditional Enter-PSSession but not if I execute a PowerShell script in a Calm runbook.

Which leads up to the title of this topic, how does Calm execute PowerShell on an endpoint?

Since it’s using port 5985 it should be WinRM/WSMAN/remote PowerShell, but it completely ignores the fact that the default PSH remote endpoint is pointing to PSH 7.

Is it using another endpoint? Or is it not using WinRM after all?

icon

Best answer by JoseNutanix 28 December 2021, 12:11

View original

This topic has been closed for comments

9 replies

Userlevel 4
Badge +5

Hi Martin,

Please give a try the following snippet to set your session to PoSH 7:

# Run WITH ELEVATION (as administrator) and
# ONLY IF YOU UNDERSTAND THE IMPLICATIONS.

$ErrorActionPreference = 'Stop'

# The configuration whose definition you want to make the new default.
$newDefaultConfigSource = 'PowerShell.7'

# Standard registry locations and names.
$defaultConfigName = 'Microsoft.PowerShell'
$configXmlValueName = 'ConfigXml'
$configRootKey = 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin'

# Rename the current default configuration XML to "ConfigXml.OLD" to keep a backup.
Rename-ItemProperty $configRootKey\$defaultConfigName $configXmlValueName -NewName "$configXmlValueName.OLD"

# Get the configuration XML from the configuration that should become the new default.
# Modify it to replace the source configuration name with the default configuration name.
$xmlText = (Get-ItemPropertyValue $configRootKey\$newDefaultConfigSource $configXmlValueName) -replace
('\b{0}\b' -f [regex]::Escape($newDefaultConfigSource)), $defaultConfigName

# Save the modified XML as the default configuration's config XML.
Set-ItemProperty $configRootKey\$defaultConfigName $configXmlValueName $xmlText

# Restart the WinRM service for changes to take effect.
Restart-Service WinRM

 

Userlevel 2
Badge +2

Hi Jose.

I should’ve included a link to that snippet in my OP as that’s exactly what I did to configure the default endpoint, to no effect.

Here are my endpoints on the remote server:

 

And this is the output of $PSVersionTable executed from Calm on that server:

 

Userlevel 4
Badge +5

I haven’t tested myself, but others colleagues have done it with success. 

Userlevel 2
Badge +2

The configuration of the endpoint works as expected, as demonstrated by the Get-PSSessionConfiguration cmdlet, but Calm doesn't seem to use the default Microsoft.Powershell endpoint.

Userlevel 4
Badge +5

I’ll have to dig internally. But as mentioned, it works based on some internal threads. 
 

 

Userlevel 2
Badge +2

I can’t imagine that it makes any difference, but your screenshot shows an application and I’m using a runbook.

Unfortunately I have a couple of other tasks to take care of right now but I’d very much appreciate if you could do some internal digging. As soon as I get the time - hopefully tomorrow - I’ll return to this topic.

Userlevel 4
Badge +5

I have tested it and it’s working for me with a Runbook. 

 

 

Something that I notice with the script is that failed for me at the first execution. After checking the PoSH 7 installation and despite of having selected the checkbox for Enable-PSRemoting, I could see that in the registry the key PowerShell.7 under WSMAN\Plugin wasn’t created. This was making the snippet to fail. 

I had to open a PoSH 7 terminal and manually run Enable-PSRemoting. After this, the registry entries showed up, and the snippet worked. 

Then in Calm, I just did a test Runbook that has a simple task with a Write-Host Hello World and $PSVersionTable.

Userlevel 2
Badge +2

Hi Jose.

There’s a very simple solution to my issues with getting this to work; I’m an idiot. :)

I changed the settings on the wrong server (in my defense I’d like to point out that the names are very similar) and as soon as I changed the settings on the correct server - the actual endpoint - it works for me as well.

My only problem now is that the local user used for running PSH on the host no longer can log on via WinRM. It works with the actual Administrator account though so it should be possible to get it working again.

As always, a huge thanks for the help. I’ll close this thread when I have an answer to why my automation account stopped working.

Userlevel 2
Badge +2

The actual error I got when trying to use a local server account for remote management was “The WSMan service could not launch a host process to process the given request. Make sure the WSMan provider host server and proxy are properly registered.”

Since this account had previously worked my guess is that installing PowerShell 7.2 also increased security for remote management, preventing non-domain (aka local) accounts from accessing a computer through remote management. 

The solution is to disable the UAC for local accounts so that the remote session can start, or  possibly change to a domain account which I can’t do for a couple of reasons.

After creating the registry key HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System:LocalAccountTokenFilterPolicy (DWORD) and setting it to 1 my local account can now log on remotely from Calm and execute PowerShell scripts.