The joys of software – PowerShell remoting edition

I was happily scripting in PowerShell and the script appeared to work. It remoted to a server, got that state of a few services, if they were running, how much memory they used, etc.

It used – very simplified

$Session = New-PSSession -ComputerName $server
Invoke-Command -Session $Session -ScriptBlock {#Remote code}

So after testing on a single server, I let it lose on all the production servers.  It worked for about 40% of them – the rest did not give a hoot about the script content.

Why?  No idea at the time.  So – what was the differences between the servers? They all had PowerShell 7.x installed, but some where 2016+ while others where 2012R2.  

Changing the remote script to simply retrieve the most current PS version config that the WinRM would provide. 

function Get-PSConfigs { 
    param (
        [String] $server
    )
    Write-Host "--- $server --------------------------------------------------------------"
    $Session = New-PSSession -ComputerName $server
    if ($Session) {
        try {
            Invoke-Command -Session $Session -ArgumentList $server -ScriptBlock {
                Param ([string]$LocName)
                Get-PSSessionConfiguration | sort PSVersion -Descending | Select-Object -first 1
            }
        }
        finally {
            Remove-PSSession -Id $Session.Id
        }
    }
}

This revealed that all the servers that failed only offered PS version 4, and of those that worked, they only reported PS version 5.1.  Why!?  PS 7 was installed! Why didn’t the script run on PS 7?

So, after RTFM a lot, and experimenting a little, it turned out that to enable a configuration for remoting to PS 7, you have to start PWSH 7 with Administrator rights and run “Enable-PSRemoting”.

Only then will you have a PowerShell.7 configuration that you can use with New-PSSession.

function Get-PSSevenResults { 
    param (
        [string] $server
    )
    $Session = New-PSSession -ComputerName $server -ConfigurationName PowerShell.7 
    if ($Session) {
        try {
            Invoke-Command -Session $Session -ArgumentList $server -ScriptBlock {
                Param ([string]$ServerName)
                # remote executed code here
            }
        }
        finally {
            Remove-PSSession -Id $Session.Id
        }
    } 
}

Various error checking/handling removed for clarity

Fun fact – RDPing to 80+ servers, finding pwsh 7, starting it as admin, and running Enable-PSRemoting, is not really much fun at all.