Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell script fails during remote execution but works locally

I am attempting to execute the code below. The errors are self-explanatory but only occur when run remotely. When run locally, all the code works and I can verify that they have the desired effect by pulling content from a web server that requires Tls12 and receiving an error when I have not changed the security protocol.

$tls12 = [Enum]::ToObject([Net.SecurityProtocolType], 3072)
[Net.ServicePointManager]::SecurityProtocol = $tls12

When run on the server, they execute flawlessly. When run remotely via Invoke-Command I receive this error.

Exception setting "SecurityProtocol": "The requested security protocol
is  not supported."
+ CategoryInfo          : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
+ PSComputerName        : servername

Alternatively, this line of code which is fundamentally the same.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

This also works when run on the server directly but results in this error when run remotely.

Exception setting "SecurityProtocol": "Cannot convert null to type
 "System.Net.SecurityProtocolType" due to invalid enumeration values. Specify one of the following enumeration values and 
try again. The possible enumeration values are "Ssl3, Tls"."
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
+ PSComputerName : servername

The remote server Windows Server 2008 R2 and is running powershell 2.0. The latest Framework version installed is 4.5 release 378389. The machine I am executing from is Windows 10 running powershell 5.0 and Framework 4.6.2 in case it matters.

This is the code I am using to execute it remotely.

$webSession = New-PsSession -ComputerName servername

$cmd = {
    #$tls12 = [Enum]::ToObject([Net.SecurityProtocolType], 3072)
    #[Net.ServicePointManager]::SecurityProtocol = $tls12
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
}

Invoke-Command -ScriptBlock $cmd -Session $webSession
remove-pssession  $webSession

If anyone has an idea or suggestion, I would greatly appreciate the help.

like image 432
Roberto Avatar asked Mar 06 '18 22:03

Roberto


People also ask

How do I run a remote PowerShell script on a remote computer?

To run a script on one or many remote computers, use the FilePath parameter of the Invoke-Command cmdlet. The script must be on or accessible to your local computer. The results are returned to your local computer.

What is %{ in PowerShell?

% alias for ForEach-Object. The % symbol represents the ForEach-Object cmdlet. It allows you to perform an action against multiple objects when that action normally only works on one object at a time.

Can not run script on PowerShell?

To fix this issue, we have to set the execution policy, so that the PowerShell script runs on the particular machine. Here is how: Open PowerShell Console by selecting “Run as Administrator” and get the execution Policy with the command: Get-ExecutionPolicy to get the current policy applied, such as “Restricted”.


1 Answers

[Note: The remainder of this answer SHOULD be true, but ISN'T: Even though the Tls12 value is not defined in an interactive PSv2 session, it can be assigned and takes effect using the OP's workaround, [Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([Net.SecurityProtocolType], 3072); by contrast, trying the same thing via PS remoting, using Invoke-Command -ComputerName fails for him. Upgrading PowerShell on the target machine may still be the answer, but this answer offers no explanation of the behavior.]


As Sambardo notes in a comment on the question, the symptom implies that the remote target machine doesn't support the Tls12 value:

PSv2 invariably uses a 2.0 version of the .NET framework, where TLS 1.2 is not supported - irrespective of the presence of newer .NET frameworks on a given machine.

If you run [enum]::GetNames([Net.SecurityProtocolType]) on a machine with PSv2 , you'll see that only the following values are supported:

# PSv2
> [enum]::GetNames([Net.SecurityProtocolType])
Ssl3
Tls

So the answer is to upgrade PowerShell on the remote machine.


As an aside: PowerShell's great flexibility around type conversions allows you to simply use string representations of [enum] values; e.g., the following 2 statements are equivalent:

[Net.ServicePointManager]::SecurityProtocol = 'Tls'

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls
like image 50
mklement0 Avatar answered Sep 22 '22 23:09

mklement0