- September 15, 2015
- Posted by: Surender Kumar
- Category: PowerShell
Windows PowerShell Remoting
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 does 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:\MyScripts> Get-Command | Where-Object {$_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Sessi on" -and $_.ModuleName -notlike "*WSMan*"} CommandType Name ModuleName ----------- ---- ---------- Cmdlet Add-Computer Microsoft.PowerShell.Management Cmdlet Clear-EventLog Microsoft.PowerShell.Management Cmdlet Get-EventLog Microsoft.PowerShell.Management Cmdlet Get-HotFix Microsoft.PowerShell.Management Cmdlet Get-Process Microsoft.PowerShell.Management Cmdlet Get-PSSession Microsoft.PowerShell.Core [output cut]
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.
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. These upgrades are not required for remoting.
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.
To configure Windows PowerShell to receive remote commands:
1. Start Windows PowerShell. In Windows Vista and later versions of Windows, start Windows PowerShell with the “Run as administrator” option.
2. At the command prompt, use Enable-PSRemoting –Force command:
PS C:\Windows\system32> Enable-PSRemoting -Force WinRM has been updated to receive requests. WinRM service type changed successfully. WinRM service started.
If you run Enable-PSRemoting command without -Force, you will have to confirm the Y/N prompt two times as shown below:
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).
C:\Windows\system32>winrm quickconfig -quiet WinRM service is already running on this machine. WinRM is already set up for remote management on this computer.
PowerShell remoting is primarily intended for remotely managing domain-joined computers, and if you are preparing to deploy the first domain controller in a new forest there is no domain to join yet. 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:\> Get-WindowsFeature -ComputerName DC2 Get-WindowsFeature : WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer DC2. Verify that the computer exists on the network and that the name provided is spelled correctly. At line:1 char:1 + Get-WindowsFeature -ComputerName DC2 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : DeviceError: (Microsoft.Manag...rDetailsHandle):CimException) [Get-WindowsFeature], Exception + 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.
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 TrustedHosts 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:
PS C:\> Set-Item WSMan:\\localhost\client\TrustedHosts -Value DC2 -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 DC2
The DC2 is now listed under TrsustedHosts. You can now run PowerShell remoting commands on this remote computer from local computer.
If you are already in domain environment, you do not need to mess-up with TrustedHosts.
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 DC1 remote server, type:
PS D:\MyScripts> Enter-PSSession -ComputerName DC1
[DC1]: PS C:\Users\surender\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. Lets take a look at the syntax and other available optional parameters of Enter-PSSession command.
PS D:\MyScripts> Get-Help Enter-PSSession NAME Enter-PSSession SYNOPSIS Starts an interactive session with a remote computer. SYNTAX Enter-PSSession [-ComputerName] <String> [-ApplicationName <String>] [-Authentication <AuthenticationMechanism>] [-CertificateThumbprint <String>] [-ConfigurationName <String>] [-Credential <PSCredential>] [-EnableNetworkAccess] [-Port <Int32>] [-SessionOption <PSSessionOption>] [-UseSSL] [<CommonParameters>
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:
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.
[DC1]: PS C:\Users\surender\Documents> Exit-PSSession
PS D:\MyScripts>
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:
PS D:\MyScripts> Invoke-Command -ComputerName DC1, DC2, FileServer, LocalHost -ScriptBlock {Get-WmiObject -Class Win32_OperatingSystem | Format-List PSComputerName, Caption}
Caption PSComputerName RunspaceId
------- -------------- ----------
Microsoft Windows Server 2008 R2 Standard DC1 4a372458-5ca8-4d64-9e1c-66d2acd40800
Microsoft Windows 8.1 Enterprise LocalHost 3a819c2f-17af-47e4-adf3-f5736d1568c4
Microsoft Windows Server 2008 R2 Standard DC2 263a7f27-b1e2-40f2-acd2-6d6e9af8a972
Microsoft Windows Server 2012 R2 Standard FileServer ed664ed8-39f2-448b-99fc-fc8778ede30e
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 Get-DiskUsage.ps1 script on the DC1 and DC2 servers.
PS D:\MyScripts> Invoke-Command -ComputerName DC1, DC2 -FilePath D:\MyScripts\Get-DiskUsage.ps1
Name Used (GB) Free (GB) Provider Root CurrentLocation PSComputerName
---- --------- --------- -------- ---- --------------- --------------
C 42.06 37.45 C:\ ...surender\Documents DC1
D 191.68 193.95 D:\ DC1
E E:\ DC1
F 578.04 352.95 F:\ DC1
C 57.35 240.64 C:\ ...surender\Documents DC2
D 550.36 381.15 D:\ DC2
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.