This self-answered question, which focuses on Windows [1] , 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 than the -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:
The Unix-like machines must use the remoting cmdlets with the -Authentication Basic -UseSsl
parameters.
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
)
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 - eg, PowerShell.7
- using whatever the latest v7.x version is installed on the target machine.
Target a specific version - eg, PowerShell.7.1.2
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 }
$PROFILE
file:# When remoting, default to running PowerShell Core v7.x on the
# the target machines:
$PSSessionConfigurationName = 'PowerShell.7'
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.