PowerShell 远程处理:控制目标版本(PowerShell Core 或 Windows PowerShell);跨平台远程处理的状态

PowerShell remoting: Controlling what edition is being targeted (PowerShell Core or Windows PowerShell); the state of cross-platform remoting

这个自我回答的问题侧重于 Windows[1],涉及以下几个方面:

现在有 两个 PowerShell 版本 - 遗留版本,Windows - 只有 Windows PowerShell跨平台PowerShell Core,两者都可能是安装在给定 Windows 机器上:

注:

要使某个版本可通过给定计算机上的远程处理定位,它必须是 set up for remoting:

无论如何,您可以使用Enable-PSRemoting按需(重新)启用 PowerShell 远程处理,其中:


[1]即问题集中在WinRM-based remoting (WinRM is a Windows-specific implementation of the DTMF WSMan (WS-Management) standard).

至于跨平台 使用 PowerShell Core 进行远程处理:

注意:更改远程端点 PowerShell [Core] 默认目标 - 从 7.0 开始仍然是 Window PowerShell - 正在考虑中:参见 this GitHub issue.


本地指定的 远程会话配置 决定了将在 远程机器:

  • Ad hoc,您可以使用远程 cmdlet 的 -ConfigurationName 参数 ,例如 Invoke-CommandNew-PSSessionEnter-PSSession 以明确指定会话配置。

  • 持久,通过配置,您可以设置默认会话配置 通过 $PSSessionConfigurationName preference variable(链接的帮助主题还讨论了其他与远程会话相关的首选项变量,即 $PSSessionApplicationName$PSSessionOption

    • 默认情况下,客户端连接到远程计算机上的会话配置 microsoft.powershell(见下文)。因此,您也可以在远程目标机器上更改此配置的定义,但请注意,这意味着所有 使用默认值的客户端将使用重新定义的配置 - 请参阅底部了解如何实现此重新定义。

在远程操作的目标机器Get-PSSessionConfiguration cmdlet列出客户端可用于连接的所有已注册会话配置,您可以使用 Register-PSSessionConfigurationUnregister-PSSessionConfiguration:

进行管理
  • 警告Get-PSSessionConfiguration 必须 运行 在 提升的 会话中(如administrator),并且,由于 Windows PowerShell 5.1 中的 bug,您可能必须先 运行 以下虚拟命令:$null = Get-Command Test-WSMan,因此以确保定义 wsman: 驱动器)。

  • 名称前缀为'microsoft.powershell'的会话配置属于Windows PowerShell.

  • 前缀'PowerShell.'指PowerShellCore .

$PSSessionConfigurationName两个版本中默认为'http://schemas.microsoft.com/powershell/Microsoft.PowerShell',这意味着Windows PowerShell 默认情况下针对远程计算机 即使您 运行 来自 PowerShell Core:

  • Microsoft.PowerShell 部分指的是(64 位)Windows PowerShell 会话配置,如 Get-PSSessionConfiguration(小写)所列。

  • http://schemas.microsoft.com/powershell/前缀是可选的,可以省略;请注意,在前缀中使用 https: 确实 not 有效,并且 not 会自动切换到基于 SSL 的传输;对于后者,需要 explicit configuration。请注意,如果您的所有远程处理都发生在 Windows 域中,则不需要 HTTPS/SSL-based 远程处理。

在远程机器上以 PowerShell Core (PowerShell v6+) 为目标:

  • 通常,PowerShell Core 会话配置是版本特定的,您有两个选择:

    • 目标 主要 PowerShell 核心版本 - 例如,PowerShell.7 - 使用最新的 v7.x版本安装在目标机器上。

      • 这是更可取的,因为您的代码不需要每次在目标机器上安装补丁或次要版本更新时都更新。
    • 针对 特定的 版本 - 例如,PowerShell.7.1.2

      • 仅当您有多个共享相同主版本的并排安装,并且您明确需要以其中一个为目标时才执行此操作。
    • 同样,运行ning Get-PSSessionConfiguration 在目标机器上,从 elevated 会话中,告诉您所有已注册的名称会话配置。

  • 要针对 PowerShell Core ad hoc,请使用 -ConfigurationName PowerShell.7,例如:

# Connect to computer $comp and make it execute $PSVersionTable 
# in PowerShell Core v7.x, which tells you what PowerShell edition 
# and version is running.
Invoke-Command -ComputerName $comp -ConfigurationName PowerShell.7 { $PSVersionTable }
  • 从给定的客户端机器,默认情况下持续以PowerShell Core 为目标,在您的 $PROFILE 文件中添加如下内容:
# When remoting, default to running PowerShell Core v7.x on the
# the target machines:
$PSSessionConfigurationName = 'PowerShell.7'
  • 让给定远程服务器机器的所有客户端默认为PowerShell Core , 坚持,你必须重新定义服务器的microsoft.powershell会话配置,这需要管理权限;您可以修改以下代码段:
# 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