Roberto
Roberto

Reputation: 71

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.

Upvotes: 7

Views: 10024

Answers (1)

mklement0
mklement0

Reputation: 437052

[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

Upvotes: 6

Related Questions