Table of Contents
PowerShell Remoting uses the WS-Management protocol and lets you run any PowerShell command on one or more remote computers. It lets you establish persistent connections, start interactive sessions, and run scripts on multiple computers.
To use PowerShell remoting, remote computer must be configured for remote management. But there are many PowerShell cmdlets with a ComputerName parameter that enables you to collect data and change settings on one or more remote computers without any configuration on remote computer.
They use a variety of communication technologies and many work on all Windows operating systems that Windows PowerShell supports without any special configuration.
The cmdlets which do not require any configuration on remote machine are:
- Restart-Computer
- Test-Connection
- Clear-EventLog
- Get-EventLog
- Get-Hotfix
- Get-Process
- Get-Service
- Set-Service
- Get-WinEvent
- Get-WmiObject
All of cmdlets shown above does not use WS-Management protocol. These cmdlets use Microsoft .NET Framework methods to retrieve the objects from remote computers and does not use PowerShell remoting infrastructure. So, these cmdlets can be run on remote computers without the need to any configuration on remote computers.
Typically, the cmdlets which support remoting without special configuration have a ComputerName parameter and do not have a Session parameter. To find these cmdlets, you can use the following command:
PS D:\> Get-Command | Where-Object {$_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Session" -and $_.ModuleName -notlike "*WSMan*"}
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Add-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Clear-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-HotFix 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-Process 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-PSSession 3.0.0.0 Microsoft.PowerShell.Core
Cmdlet Get-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Get-WmiObject 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Invoke-WmiMethod 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Limit-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet New-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Remove-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Remove-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Remove-WmiObject 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Rename-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Restart-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Set-Service 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Set-WmiInstance 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Show-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Stop-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Test-Connection 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Write-EventLog 3.1.0.0 Microsoft.PowerShell.Management
Requirements for PowerShell Remoting
To use PowerShell remoting infrastructure, the local and remote computers must have:
- Windows PowerShell 2.0 or later
- The Microsoft .NET Framework 2.0 or later
- Windows Remote Management 2.0
To find the version number of an installed version of Windows PowerShell, you can use the $PSVersionTable automatic variable. The value of the $PSVersionTable.Version.Major property must be at least 2.
PS D:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.22621.1778
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.1778
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Windows Remote Management 2.0 is included in Windows 7 and in Windows Server 2008 R2. It is also included in the integrated installation package for earlier versions of Windows that includes PowerShell.
- PowerShell Integrated Scripting Environment (ISE) and the Out-Gridview cmdlet require the Microsoft .NET Framework 3.5 with Service Pack 1.
- The Get-WinEvent cmdlet requires the Microsoft .NET Framework 3.5 or greater.
Configure PowerShell Remoting
The remoting features of Windows PowerShell are supported by the WinRM service, which is the Microsoft implementation of the Web Services for Management (WS-Magement) protocol. To use the remoting features, you need to change the default configuration of WS-Management on the system.
Configure PowerShell Remoting for WORKGROUP computers
To configure Windows PowerShell to receive remote commands:
1️⃣ Start Windows PowerShell with the Run as administrator option.
2️⃣ At the command prompt, change the connection type to Private.
Set-NetConnectionProfile -NetworkCategory Private
PS C:\Windows\system32> Get-NetConnectionProfile
Name : Network
InterfaceAlias : Ethernet
InterfaceIndex : 6
NetworkCategory : Public
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic
PS C:\Windows\system32> Set-NetConnectionProfile -NetworkCategory Private
PS C:\Windows\system32> Get-NetConnectionProfile
Name : Network
InterfaceAlias : Ethernet
InterfaceIndex : 6
NetworkCategory : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic
If you don’t do that, you would get the following error when enabling PowerShell Remoting.
Set-WSManQuickConfig : … WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again. …
3️⃣ Now, use Enable-PSRemoting –Force command to enable PowerShell remoting:
Enable-PSRemoting -Force
PS C:\Windows\system32> Enable-PSRemoting -Force
WinRM is already set up to receive requests on this computer.
WinRM has been updated for remote management.
WinRM firewall exception enabled.
Configured LocalAccountTokenFilterPolicy to grant administrative rights remotely to local users.
This procedure allows users on other computers to establish remote connections and to run remote commands on the local computer. It also allows you to create a loopback connection on the local computer.
The same can be done using Windows cmd.exe (command prompt).
4️⃣ You need to enable the two stand-alone computers to talk to each other using the WS-Management protocol. If the computer from which you are running the remote commands is also running Windows Server 2012 or Windows Server 2012 R2, you just need to add the name of the remote server to the Trusted Hosts list in the local computer’s WinRM configuration. Doing this enables the local computer to connect to the remote server using NTLM as the authentication mechanism instead of Kerberos, which is used in domain-based environments.
By default, the TrustedHosts list is empty on every computer. So, it does not allow commands to any remote computer which is not in domain.
PS C:\> Get-Item WSMan:\\localhost\client\TrustedHosts
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String TrustedHosts
Now, you need to add remote ComputerName to TrsutedHosts list using Set-Item cmdlet as shown below:
Set-Item WSMan:\\localhost\client\TrustedHosts -Value DC01 -Concatenate -Force
That the –Concatenate parameter is mandatory if you want to add multiple conputers, otherwise every time you run the Set-Item command, it will keep overwriting the old values in TrustedHosts list. The -Force parameter is however optional, which is used to suppress the confirmation (Yes/No) prompt. Now, take a look on TrustedHosts list again.
PS C:\> Get-Item WSMan:\\localhost\client\TrustedHosts
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String TrustedHosts DC01
The DC01 is now listed under TrsustedHosts. You can now run PowerShell remoting commands on this remote computer from local computer.
Configure PowerShell Remoting for DOMAIN computers
PowerShell remoting is primarily intended for remotely managing domain-joined computers. In other words, the PC on which you are working is in workgroup and the remote server that you want to promote to a domain controller is also in a workgroup, not a domain. If you try to run any command on remote server, you will get the error as shown below:
PS C:\Windows\system32> Get-WindowsFeature -ComputerName DC01
Get-WindowsFeature : The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You can get more information about that by running the following command: winrm help config.
At line:1 char:1
+ Get-WindowsFeature -ComputerName DC01
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : DeviceError: (Microsoft.Manag…rDetailsHandle):CimException) [Get-WindowsFeature], Exce
ption
+ FullyQualifiedErrorId : UnSupportedTargetDevice,Microsoft.Windows.ServerManager.Commands.GetWindowsFeatureCommand
The error message clearly states that Error occurred while using Kerberos authentication. This is because by default WS-Man protocol uses Kerberos authentication. Since all computers are yet in workgroup environment; the Kerberos is not supported.
Starting Interactive Remote Session
To start an interactive session with a single remote computer, you can use the Enter-PSSession cmdlet. For example, to start an interactive session with the DC01 remote server, type:
PS C:\Windows\system32> Enter-PSSession -ComputerName DC01
[DC01]: PS C:\Users\admin\Documents>
The above command will start an interactive session with remote computer with currently logged-on user credentials. The command prompt changes to display the name of the computer to which you are connected. From then on, any commands that you type at the prompt run on the remote computer and the results are displayed on the local computer. Let’s take a look at the syntax and other available optional parameters of Enter-PSSession command.
Get-Help Enter-PSSession
Notice that Enter-PSSession cmdlet has a –Credential parameter which you can use to use to provide alternate credentials while connecting to remote computer. To use this parameter, run the command as shown below:
Enter-PSSession -ComputerName DC01 -Credential duybao\chris
You will see a dialog box prompting for credentials to be used to connect to remote computer. To end the interactive session, type Exit-PSSession or simply exit command.
PS C:\Windows\system32> Enter-PSSession -ComputerName DC01 -Credential duybao\chris
[DC01]: PS C:\Users\chris\Documents> exit
PS C:\Windows\system32>
Run a Remote Command
You do not always want to start interactive session to remote computer. What if you want to run just a single command on remote computer? PowerShell has Invoke-Command cmdlet to do this. To run any command on one or many remote computers, use the Invoke-Command cmdlet as shown below:
Invoke-Command -ComputerName DC01, HR-PC001, HR-PC007 -ScriptBlock {Get-WmiObject -Class Win32_OperatingSystem |
Format-Table PSComputerName, Caption, Version, BuildNumber}
#Output
PSComputerName Caption Version BuildNumber
-------------- ------- ------- -----------
DC01 Microsoft Windows Server 2022 Standard 10.0.20348 20348
PSComputerName Caption Version BuildNumber
-------------- ------- ------- -----------
HR-PC007 Microsoft Windows 10 Pro 10.0.19045 19045
PSComputerName Caption Version BuildNumber
-------------- ------- ------- -----------
HR-PC001 Microsoft Windows 11 Pro 10.0.22621 22621
To run a script on one or more remote computers, use the –FilePath parameter of the Invoke-Command cmdlet. The script must be on or accessible to your local computer. The results are returned to your local computer.
For example, the following command runs the diskusage.ps1 script on the HR-PC007 and HR-PC001 servers.
PS C:\> Invoke-Command -ComputerName HR-PC001, HR-PC007 -FilePath C:\diskusage.ps1
Name Used (GB) Free (GB) Provider Root CurrentLocation PSComputerName
---- --------- --------- -------- ---- --------------- --------------
C 23.76 35.92 C:\ ...or\Documents HR-PC007
C 32.50 26.78 C:\ ...or\Documents HR-PC001
PowerShell Sessions
Invoke-Command -ComputerName dc01, sql02, web01 {(Get-Service -Name W32time).Stop()} -Credential $Cred
Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred
For example, I ran two commands using the Invoke-Command cmdlet. That means two separate sessions had to be set up and torn down to run those two commands.
A PowerShell session to a remote computer can be used to run multiple commands against the remote computer without the overhead of a new session for each individual command. Create a PowerShell session to each of the three computers we’ve been working with in this chapter, DC01, SQL02, and WEB01.
PowerShell remote management just begins here. By using the cmdlets installed with PowerShell, you can establish and configure remote sessions both from the local and remote ends, create customized and restricted sessions, allow users to import commands from a remote session that actually run implicitly on the remote session, configure the security of a remote session, and much more.
$Session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred
Now use the variable named $Session to start the Windows Time service using a method and check the status of the service.
Invoke-Command -Session $Session {(Get-Service -Name W32time).Start()}
Invoke-Command -Session $Session {Get-Service -Name W32time}
Status Name DisplayName PSComputerName
------ ---- ----------- --------------
Running W32time Windows Time web01
Start... W32time Windows Time dc01
Running W32time Windows Time sql02
Once the session is created using alternate credentials, it’s no longer necessary to specify the credentials each time a command is run. When you’re finished using the sessions, be sure to remove them.
Get-PSSession | Remove-PSSession