Showing posts with label invoke-command. Show all posts
Showing posts with label invoke-command. Show all posts

Monday, February 5, 2018

PowerShell Remoting

Remoting is a feature that helps you manage Windows infrastructure in scale. It uses WS-MAN protocol implemented using WinRM. PS Remoting is enabled by default in Windows Server 2012 and later. It is recommended to turn on remoting because a lot of new graphical administrative tools are making use of PowerShell and PowerShell Remoting in the background.

Here I will be explaining remoting on systems part of same domain.

1:1 Remoting

This case is useful in managing a single system. Enter-PSSession cmdlet can be used for 1:1 remote connection.

Enter-PSSession -ComputerName AD-DNS


In the above screenshot you can see that I connected to AD-DNS from VM01 using Enter-PSSession. Once the session is established you can see the PS prompt changes to "[AD-DNS]:". This means currently you are in the command line prompt of AD-DNS. The next two cmdlets gets the IPV4 address and eventlogs of the remote machine.

1:Many Remoting

This case is useful if you want to run a specific command or task on a set of computers and get the results back to you.

invoke-command -ComputerName VM01, AD-DNS { gsv msiscsi }



What actually happens here is first a PS session is established to the remote machine. Load PowerShell and .NET and the give code is sent across the connection, execute the code on the remote machine, the resultant objects are then serialized into XML, send them across the connection, deserialize the XML to objects and place them in the pipeline of the PowerShell session.

Lets have a look at the below case where we execute gsv msiscsi on the local machine. You can see that the type name is System.ServiceProcess.ServiceController .


When you execute gsv msiscsi on remote machines by adding -ComputerName with the Invoke-Command, you can see the type name changed to Deserialized.System.ServiceProcess.ServiceController .


Another remoting use case given below where you want to check the remaining size of some specific drive on multiple machines.


PS Sessions

When you use the Enter-PSSession or Invoke-Command with -ComputerName parameter a remote session is established and it will run the task which was asked to and it will end the session when the task is complete. In case of Enter-PSSession cmdlet, the PS session will end once the user termiates the session using Exit-PSSession. So always there is an overhead of starting and ending a PS session. There is way to create persistent PS session using New-PSSession cmdlet.

$s1 = New-PSSession -ComputerName AD-DNS


Here $s1 will hold a persistent PS session to computer AD-DNS. Now you can invoke tasks remotely using the session that is already created and opened.


It is the responsibility of the user to remove the PS-Sessions after use. Otherwise it will remain opened and consume resources.

PowerShell Direct

PowerShell Direct is a new feature introduced in PowerShell version 5.1 which supports management of Windows 10 and Windows Server 2016 guest VMs running on Windows 10 or Windows Server 2016 host machines. This simply means you can establish a PowerShell session from the host machine to any of the VMs running on it by just using the VM name and it works even without network connectivity to the VM through a vSwitch. Because the connection is established not via network but over the Hyper-V VM bus. You can even use PS Direct sessions to copy files to a VM which does not have IP connectivity.

Lets have a look into the example below where I have few VMs hosted on Windows Server 2016. I will connect to one of the VM named "AD" using PS direct.


In the above screenshot you can see that a new PS session is established using the VM name. Now lets see how you can copy files to a VM over PS Direct sessions.


Hope this was useful. Happy PS remoting !

Reference ebooks:

Secrets of PowerShell Remoting
Layman's Guide to PowerShell 2.0 remoting

Reference videos:


Wednesday, March 15, 2017

Running a PowerShell script on multiple remote machines simultaneously

Below example shows how to trigger PowerShell scripts on a remote Windows machine and run as background jobs.

trigger.ps1

Invoke-Command -ComputerName testvm-03 -ScriptBlock {&C:\posh\io\iostress.ps1} -AsJob
Invoke-Command -ComputerName testvm-02 -ScriptBlock {&C:\posh\io\iostress.ps1} -AsJob
Invoke-Command -ComputerName testvm-01 -ScriptBlock {&C:\posh\io\iostress.ps1} -AsJob

Invoke-Command is used to execute scripts remotely. Above script (trigger.ps1) invokes a PS script (iostress.ps1) on 3 remote machines. Here the script being executed is saved on the corresponding remote machine itself. As each of the invoke-command is running as a background job on the local machine, the second invoke-command doesn't have to wait for the first invoke-command to complete and the third invoke-command doesn't have to wait for the first and second invoke-commands to complete. From the user perspective the command prompt returns immediately even if the jobs take longer time to complete. This case will be useful if you want to run a script on multiple remote machines at the same time.