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 机器上:
如何判断哪个 PowerShell 版本将执行 remote commands,例如通过 Invoke-Command -ComputerName
?
如何定位特定版本,临时和持久,通过配置?
注:
要使某个版本可通过给定计算机上的远程处理定位,它必须是 set up for remoting:
只有 Windows PowerShell 自动 设置远程处理,但仅在 servers 运行ning Windows Server 2012 或更高版本。
从 v7 开始,PowerShell Core 还没有 Windows;如果您使用的是官方安装程序,您可以选择在安装过程中启用远程处理。
无论如何,您可以使用Enable-PSRemoting
按需(重新)启用 PowerShell 远程处理,其中:
必须是 运行 来自相应的版本。
必须运行具有管理权限
[1]即问题集中在WinRM-based remoting (WinRM is a Windows-specific implementation of the DTMF WSMan (WS-Management) standard).
至于跨平台 使用 PowerShell Core 进行远程处理:
您已经可以在所有平台上使用SSH-based remoting:
使用基于 SSH 的远程处理涉及与基于 WinRM 的远程处理大部分相同的 cmdlet,尽管涉及的参数不同;最值得注意的是,您通过 -HostName
参数指定目标计算机,而不是
-ComputerName
参数。
限制(从 v7 开始):"SSH-based remoting doesn't currently support remote endpoint configuration and Just Enough Administration (JEA)."
对于 Unix-to-Windows 远程处理 (Unix 指的是类 Unix 平台,例如 macOS 和 Linux) - 也就是说,从类 Unix 机器远程访问 Windows 机器 - 您也可以使用基于 WinRM 的远程处理和额外配置:
在 Windows 机器上:
- 必须通过为 HTTPS 配置 WinRM 来启用 SSL 连接。
- 要在类 Unix 机器上使用的用户帐户必须定义为 local 管理员组中的 local 用户帐户 -域帐户将无法使用。
类 Unix 机器必须使用带有 -Authentication Basic -UseSsl
参数的远程 cmdlet。
psl-omi-provider repository 正在开发基于 Unix WSMan 的实现,它已经启用了 Linux 台机器充当远程目标(也就是说,server 组件已经可用 - 我不清楚它是否也可以安装在 macOS);但是,截至撰写本文时,客户端组件尚未准备好投入生产。
一旦客户端客户端组件可用,统一的基于 WSMan 的跨平台远程处理将成为可能,无论是在类 Unix 机器(Linux、macOS)之间,还是在类 Unix 机器和 Windows 机器之间。
注意:更改远程端点 PowerShell [Core] 默认目标 - 从 7.0 开始仍然是 Window PowerShell - 正在考虑中:参见 this GitHub issue.
本地指定的 远程会话配置 决定了将在 远程机器:
Ad hoc,您可以使用远程 cmdlet 的 -ConfigurationName
参数 ,例如 Invoke-Command
、New-PSSession
和 Enter-PSSession
以明确指定会话配置。
持久,通过配置,您可以设置默认会话配置 通过 $PSSessionConfigurationName
preference variable(链接的帮助主题还讨论了其他与远程会话相关的首选项变量,即 $PSSessionApplicationName
和 $PSSessionOption
)
- 默认情况下,客户端连接到远程计算机上的会话配置
microsoft.powershell
(见下文)。因此,您也可以在远程目标机器上更改此配置的定义,但请注意,这意味着所有 使用默认值的客户端将使用重新定义的配置 - 请参阅底部了解如何实现此重新定义。
在远程操作的目标机器上、Get-PSSessionConfiguration
cmdlet列出客户端可用于连接的所有已注册会话配置,您可以使用 Register-PSSessionConfiguration
和 Unregister-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
这个自我回答的问题侧重于 Windows[1],涉及以下几个方面:
现在有 两个 PowerShell 版本 - 遗留版本,Windows - 只有 Windows PowerShell和跨平台PowerShell Core,两者都可能是安装在给定 Windows 机器上:
如何判断哪个 PowerShell 版本将执行 remote commands,例如通过
Invoke-Command -ComputerName
?如何定位特定版本,临时和持久,通过配置?
注:
要使某个版本可通过给定计算机上的远程处理定位,它必须是 set up for remoting:
只有 Windows PowerShell 自动 设置远程处理,但仅在 servers 运行ning Windows Server 2012 或更高版本。
从 v7 开始,PowerShell Core 还没有 Windows;如果您使用的是官方安装程序,您可以选择在安装过程中启用远程处理。
无论如何,您可以使用Enable-PSRemoting
按需(重新)启用 PowerShell 远程处理,其中:
必须是 运行 来自相应的版本。
必须运行具有管理权限
[1]即问题集中在WinRM-based remoting (WinRM is a Windows-specific implementation of the DTMF WSMan (WS-Management) standard).
至于跨平台 使用 PowerShell Core 进行远程处理:
您已经可以在所有平台上使用SSH-based remoting:
使用基于 SSH 的远程处理涉及与基于 WinRM 的远程处理大部分相同的 cmdlet,尽管涉及的参数不同;最值得注意的是,您通过
-HostName
参数指定目标计算机,而不是-ComputerName
参数。限制(从 v7 开始):"SSH-based remoting doesn't currently support remote endpoint configuration and Just Enough Administration (JEA)."
对于 Unix-to-Windows 远程处理 (Unix 指的是类 Unix 平台,例如 macOS 和 Linux) - 也就是说,从类 Unix 机器远程访问 Windows 机器 - 您也可以使用基于 WinRM 的远程处理和额外配置:
在 Windows 机器上:
- 必须通过为 HTTPS 配置 WinRM 来启用 SSL 连接。
- 要在类 Unix 机器上使用的用户帐户必须定义为 local 管理员组中的 local 用户帐户 -域帐户将无法使用。
类 Unix 机器必须使用带有
-Authentication Basic -UseSsl
参数的远程 cmdlet。
psl-omi-provider repository 正在开发基于 Unix WSMan 的实现,它已经启用了 Linux 台机器充当远程目标(也就是说,server 组件已经可用 - 我不清楚它是否也可以安装在 macOS);但是,截至撰写本文时,客户端组件尚未准备好投入生产。
一旦客户端客户端组件可用,统一的基于 WSMan 的跨平台远程处理将成为可能,无论是在类 Unix 机器(Linux、macOS)之间,还是在类 Unix 机器和 Windows 机器之间。
注意:更改远程端点 PowerShell [Core] 默认目标 - 从 7.0 开始仍然是 Window PowerShell - 正在考虑中:参见 this GitHub issue.
本地指定的 远程会话配置 决定了将在 远程机器:
Ad hoc,您可以使用远程 cmdlet 的
-ConfigurationName
参数 ,例如Invoke-Command
、New-PSSession
和Enter-PSSession
以明确指定会话配置。持久,通过配置,您可以设置默认会话配置 通过
$PSSessionConfigurationName
preference variable(链接的帮助主题还讨论了其他与远程会话相关的首选项变量,即$PSSessionApplicationName
和$PSSessionOption
)- 默认情况下,客户端连接到远程计算机上的会话配置
microsoft.powershell
(见下文)。因此,您也可以在远程目标机器上更改此配置的定义,但请注意,这意味着所有 使用默认值的客户端将使用重新定义的配置 - 请参阅底部了解如何实现此重新定义。
- 默认情况下,客户端连接到远程计算机上的会话配置
在远程操作的目标机器上、Get-PSSessionConfiguration
cmdlet列出客户端可用于连接的所有已注册会话配置,您可以使用 Register-PSSessionConfiguration
和 Unregister-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