本文介绍了PowerShell远程处理:控制目标版本(PowerShell Core或Windows PowerShell);跨平台远程处理的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个针对Windows 的自我回答的问题解决了以下方面:

现在有 两个 PowerShell版本-旧版,仅Windows Windows PowerShell 跨平台PowerShell Core ,两者都可以安装在给定的Windows计算机上:

  • 如何确定执行哪个PowerShell版本 远程命令 ,例如通过Invoke-Command -ComputerName?

  • 我如何通过配置定位到临时永久的特定版本?

注意:

要通过在给定计算机上远程处理来确定目标版本,该版本必须为设置为进行远程处理:

  • 仅自动设置了Windows PowerShell 用于远程处理,但仅在运行Windows Server 2012或更高版本的服务器上进行了设置.

  • p>
  • 从v7开始,PowerShell Core 尚未随Windows一起提供.如果您使用的是官方安装程序,则可以选择在安装过程中启用远程处理.

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

  • 必须从相应版本运行 .

  • 必须在具有管理员权限的情况下运行


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

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

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

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

    • 限制(自v7起):基于SSH的远程处理当前不支持远程端点配置和Just Justough Administration(JEA)."

  • 对于 Unix-to-Windows 远程处理( Unix 指的是类似Unix的平台,例如macOS和Linux)-是,从类似Unix的计算机迁移到Windows计算机-您也可以通过其他配置使用基于WinRM的远程处理:

    • 在Windows计算机上:

      • 必须通过为HTTPS配置WinRM来启用SSL连接.
      • 要在类似Unix的计算机上使用的用户帐户必须在 local 管理员组中定义为 local 用户帐户-域帐户将不起作用./li>
    • 类Unix的计算机必须使用带有-Authentication Basic -UseSsl参数的远程cmdlet.

    • 请参阅 about_Remote_Requirements

  • 正在 psl中研究基于Unix WSMan的实现. -omi-provider存储库 ,该存储库已使 Linux 机器能够用作远程目标(即 server 组件已经可用-我不清楚它是否也可以安装在 macOS 上);但是,在撰写本文时,客户端组件尚未投入生产.
    一旦客户端客户端组件可用,在类似Unix的机器(Linux,macOS)之间以及类似Unix的机器和Windows机器之间,就可以进行统一的基于WSMan的跨平台远程处理.

解决方案

注意:默认情况下,更改PowerShell [Core]定位的远程端点的目标-从7.0开始仍在使用 Window PowerShell -正在考虑:请参见此GitHub问题.


由本地指定的远程会话配置决定在远程计算机上将使用哪种PowerShell版本以及可能的版本:

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

  • 注意事项:Get-PSSessionConfiguration必须在提升会话中(作为管理员)运行,并且由于 bug 在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',这意味着 Windows PowerShell 默认情况下是针对远程计算机的从PowerShell Core运行 :

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

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

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

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

    • 使用目标计算机上安装的最新v7.x版本定位主要 PowerShell Core版本(例如PowerShell.7).

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

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

  • 要定位PowerShell Core 临时 ,请使用-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 }

  • 默认情况下,要从给定的 client 计算机中永久性地将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

This self-answered question, which focuses on Windows, addresses the following aspects:

Now that there are two PowerShell editions - the legacy, Windows-only Windows PowerShell and the cross-platform PowerShell Core, both may be installed on a given Windows machine:

  • How can I tell which PowerShell edition will execute remote commands, such as via Invoke-Command -ComputerName?

  • How can I target a specific edition, both ad hoc and persistently, through configuration?

Note:

For an edition to be targetable via remoting on a given machine, it must be set up for remoting:

  • Only Windows PowerShell is automatically set up for remoting, but only on servers running Windows Server 2012 or higher.

  • As of v7, PowerShell Core doesn't come with Windows yet; if you're using the official installer, you're given the option of enabling remoting during the installation.

In any event, you can use Enable-PSRemoting to (re-)enable PowerShell remoting on demand, which:

  • must be run from the respective edition.

  • must be run with administrative privileges


[1] That is, the question focuses on WinRM-based remoting (WinRM is a Windows-specific implementation of the DTMF WSMan (WS-Management) standard).

As for cross-platform remoting with PowerShell Core:

  • You can already use SSH-based remoting, on all platforms:

    • Using SSH-based remoting involves mostly the same cmdlets as WinRM-based remoting, though the parameters involved differ; most notably, you specify the target computer(s) via the -HostName parameter rather thanthe -ComputerName parameter.

    • Limitations (as of v7): "SSH-based remoting doesn't currently support remote endpoint configuration and Just Enough Administration (JEA)."

  • For Unix-to-Windows remoting (Unix referring to Unix-like platforms such as macOS and Linux) - that is, remoting into a Windows machine from a Unix-like machine - you can alternatively use WinRM-based remoting with additional configuration:

    • On the Windows machine:

      • SSL connections must be enabled by configuring WinRM for HTTPS.
      • The user accounts to be used from the Unix-like machines must be defined as local user accounts in the local Administrators group - domain accounts won't work.
    • The Unix-like machines must use the remoting cmdlets with the -Authentication Basic -UseSsl parameters.

    • See about_Remote_Requirements

  • A Unix WSMan-based implementation is being worked on in the psl-omi-provider repository, which already enables Linux machines to act as remoting targets (that is, the server component is already usable - it's not clear to me whether it can also be installed on macOS); the client component, however, is not yet production-ready as of this writing.
    Once the client client component is available, uniform WSMan-based cross-platform remoting will be possible, both between Unix-like machines (Linux, macOS) and between Unix-like machines and Windows machines.

解决方案

Note: Changing what remote endpoint PowerShell [Core] targets by default - which as of 7.0 is still Window PowerShell - is being considered: see this GitHub issue.


It is the locally specified remoting session configuration that determines what PowerShell edition, and possibly version, will be used on the remote machine:

  • Ad hoc, you can use the -ConfigurationName parameter of remoting cmdlets such as Invoke-Command, New-PSSession, and Enter-PSSession to specify a session configuration explicitly.

  • Persistently, via configuration, you can set the default session configuration via the $PSSessionConfigurationName preference variable (the linked help topic also dicusses other remote-session-related preference variables, namely $PSSessionApplicationName and $PSSessionOption)

    • By default, clients connect to session configuration microsoft.powershell on the remote machine (see below). Therefore, you can alternatively change the definition of this configuration on the remote target machine, but note that this means that all clients that use the defaults will use the redefined configuration - see bottom for how to achieve this redefinition.

On the target machine of a remoting operation, Get-PSSessionConfiguration cmdlet lists all registered session configurations that clients can use to connect to, and which you can manage with Register-PSSessionConfiguration and Unregister-PSSessionConfiguration:

  • Caveat: Get-PSSessionConfiguration must be run in an elevated session (as administrator), and, due to a bug in Windows PowerShell 5.1, you may have to run the following dummy command first: $null = Get-Command Test-WSMan, so as to ensure that the wsman: drive is defined).

  • Session configurations whose names are prefixed with 'microsoft.powershell' belong to Windows PowerShell.

  • Prefix 'PowerShell.' refers to PowerShell Core.

$PSSessionConfigurationName defaults to 'http://schemas.microsoft.com/powershell/Microsoft.PowerShell' in both editions, which means that Windows PowerShell is by default targeted on remote machines even if you're running from PowerShell Core:

  • The Microsoft.PowerShell part refers to the (64-bit) Windows PowerShell session configuration, as listed by Get-PSSessionConfiguration (in lowercase).

  • The http://schemas.microsoft.com/powershell/ prefix is optional and can be omitted; note that using https: in the prefix does not work and will not automatically switch to an SSL-based transport; for the latter, explicit configuration is needed. Note that HTTPS/SSL-based remoting isn't necessary if all of your remoting happens within a Windows domain.

To target PowerShell Core (PowerShell v6+) on a remote machine:

  • Generally, PowerShell Core session configurations are version-specific, and you have two choices:

    • Target a major PowerShell Core version - e.g., PowerShell.7 - using whatever the latest v7.x version is installed on the target machine.

      • This is preferable, because your code then doesn't require updating every time you install a patch or minor version update on the target machine.
    • Target a specific version - e.g., PowerShell.7.1.2

      • Do this only if you have multiple, side-by-side installations that share the same major version, and you explicitly need to target one of them.
    • Again, running Get-PSSessionConfiguration on the target machine, from an elevated session, tells you the names of all registered session configurations.

  • To target PowerShell Core ad hoc, use -ConfigurationName PowerShell.7, for instance:

# 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 }

  • To target PowerShell Core by default, persistently, from a given client machine, add something like the following to your $PROFILE file:

# When remoting, default to running PowerShell Core v7.x on the
# the target machines:
$PSSessionConfigurationName = 'PowerShell.7'

  • To have all clients of a given remote server machine target PowerShell Core by default, persistently, you must redefine the server's microsoft.powershell session configuration, which requires administrative privileges; you can adapt the following snippet:

# 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

这篇关于PowerShell远程处理:控制目标版本(PowerShell Core或Windows PowerShell);跨平台远程处理的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 15:48