5

这个以 Windows [1]为重点的自答问题解决了以下几个方面:

现在有两个PowerShell 版本- 传统的、仅限Windows 的Windows PowerShell跨平台的 PowerShell Core,两者都可以安装在给定的 Windows 机器上:

  • 如何判断哪个 PowerShell 版本将执行远程命令,例如 via Invoke-Command -ComputerName

  • 我怎样才能通过配置来定位特定的版本,无论是临时的还是持久的?

笔记:

对于通过远程在给定机器上定位的版本,它必须设置为远程

  • 只有Windows PowerShell自动设置为远程处理,但仅限于运行 Windows Server 2012 或更高版本的服务器上。

  • 从 v7 开始,PowerShell Core还没有随 Windows 提供。如果您使用的是官方安装程序,您可以选择在安装期间启用远程处理。

在任何情况下,您都可以使用Enable-PSRemoting(重新)启用 PowerShell remoting on demand,其中:

  • 必须从相应的版本运行。

  • 必须以管理权限运行


[1] 也就是说,问题侧重于基于WinRM的远程处理(WinRM 是 DTMF WSMan (WS-Management) 标准的 Windows 特定实现)。

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

  • 您已经可以在所有平台上使用基于 SSH 的远程处理

    • 使用基于 SSH 的远程处理与基于 WinRM 的远程处理主要涉及相同的 cmdlet,但所涉及的参数不同;-HostName最值得注意的是,您通过参数而不是参数指定目标计算机-ComputerName

    • 限制(从 v7 开始):“基于 SSH 的远程处理当前不支持远程端点配置和 Just Enough Administration (JEA)。”

  • 对于Unix 到 Windows 的远程处理Unix指的是 macOS 和 Linux 等类 Unix 平台)——也就是说,从类 Unix 机器远程处理到 Windows 机器——您也可以使用基于 WinRM 的远程处理和附加配置:

    • 在 Windows 机器上:

      • 必须通过为 HTTPS 配置 WinRM 来启用 SSL 连接。
      • 从类 Unix 机器上使用的用户帐户必须定义​​为本地管理员组中的本地用户帐户- 域帐户将不起作用。
    • 类 Unix 机器必须使用带-Authentication Basic -UseSsl参数的远程 cmdlet。

    • 查看about_Remote_Requirements

  • psl-omi-provider 存储库中正在开发基于 Unix WSMan 的实现,它已经使Linux机器能够充当远程目标(也就是说,服务器组件已经可用 - 我不清楚它是否也可以安装在macOS上);然而,在撰写本文时,客户端组件还没有准备好生产。
    一旦客户端客户端组件可用,就可以在类 Unix 机器(Linux、macOS)之间以及类 Unix 机器和 Windows 机器之间进行统一的基于 WSMan 的跨平台远程处理。

4

1 回答 1

7

注意:正在考虑更改默认情况下远程端点 PowerShell [Core] 的目标(从 7.0 开始仍然是Window PowerShell):请参阅此 GitHub 问题


本地指定的远程会话配置决定了远程计算机上使用的 PowerShell 版本,可能还有版本

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

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

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

在远程操作的目标计算机上,Get-PSSessionConfigurationcmdlet 列出了客户端可用于连接的所有已注册会话配置,您可以使用Register-PSSessionConfiguration和管理这些配置Unregister-PSSessionConfiguration

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

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

  • 前缀'PowerShell.'是指 PowerShell Core

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

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

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

要在远程计算机上定位 PowerShell Core (PowerShell v6+)

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

    • 主要的PowerShell Core 版本为目标- 例如PowerShell.7- 使用目标计算机上安装的任何最新 v7.x 版本。

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

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

  • 要以 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
于 2019-10-04T14:36:36.257 回答