Powershell脚本在远程执行期间失败,但可以在本地运行

Rob*_*rto 5 powershell powershell-2.0 powershell-remoting

我正在尝试执行以下代码。这些错误是不言自明的,但仅在远程运行时发生。在本地运行时,所有代码都可以正常工作,我可以通过从需要Tls12的Web服务器中提取内容并在未更改安全协议的情况下收到错误来验证它们是否具有预期的效果。

$tls12 = [Enum]::ToObject([Net.SecurityProtocolType], 3072)
[Net.ServicePointManager]::SecurityProtocol = $tls12
Run Code Online (Sandbox Code Playgroud)

在服务器上运行时,它们可以完美执行。通过Invoke-Command远程运行时,出现此错误。

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

或者,这行代码从根本上是相同的。

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Run Code Online (Sandbox Code Playgroud)

直接在服务器上运行时,此方法也有效,但在远程运行时,会导致此错误。

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
Run Code Online (Sandbox Code Playgroud)

远程服务器Windows Server 2008 R2,并且正在运行powershell 2.0。安装的最新Framework版本是4.5版本378389。我要执行的计算机是运行powershell 5.0和Framework 4.6.2的Windows 10(以防万一)。

这是我用来远程执行的代码。

$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
Run Code Online (Sandbox Code Playgroud)

如果有人有想法或建议,我将不胜感激。

mkl*_*nt0 5

[注意:这个答案的其余部分应该是正确的,但不是:即使该Tls12值没有在交互式 PSv2 会话中定义,它也可以使用 OP 的解决方法进行分配生效, ; 相比之下,通过PS 远程处理尝试同样的事情,使用对他来说失败了在目标计算机上升级 PowerShell 可能仍然是答案,但此答案没有提供对该行为的解释。][Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([Net.SecurityProtocolType], 3072)Invoke-Command -ComputerName


正如Sambardo在对该问题的评论中指出的那样,该症状意味着远程目标计算机不支持该Tls12值:

PSv2总是使用2.0不支持 TLS 1.2 的 .NET 框架版本- 无论给定计算机上是否存在较新的.NET 框架。

如果您在装有 PSv2 的[enum]::GetNames([Net.SecurityProtocolType])计算机上运行,​​您将看到仅支持以下值:

# PSv2
> [enum]::GetNames([Net.SecurityProtocolType])
Ssl3
Tls
Run Code Online (Sandbox Code Playgroud)

所以答案是升级远程计算机上的 PowerShell


顺便说一句:PowerShell 在类型转换方面具有极大的灵活性,允许您简单地使用值的字符串[enum]表示形式;例如,以下 2 个语句是等效的:

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

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls
Run Code Online (Sandbox Code Playgroud)