Summary: Guest blogger, Jason Hofferle, talks about creating Windows PowerShell sessions and using implicit remoting.
Microsoft Scripting Guy, Ed Wilson, is here. Jason continues to hit home run after home run this week. Today is no exception. He talks about one of the coolest features in Windows PowerShell—that of implicit remoting. Here is Jason.
Jason Hofferle has been an IT professional since 1997. His experience includes enterprise desktop engineering for a Fortune 500 financial institution and Active Directory design for local governments and law enforcement. Jason currently works for the Defense Contract Management Agency, where he implements new technology such as virtual desktop infrastructure. He recently has been speaking about Windows PowerShell at SQL Saturday and IT Pro Camp events in Florida, and he frequently attends the Tampa PowerShell User Group.
Blog: Force Multiplication through IT Automation
Twitter: @jhofferle
In Part Three of this series, Interactive and Fan-Out Remoting, I talked about using Enter-PSSession and Invoke-Command to run commands on remote computers. In this post, I’m going to get into persistent sessions and using implicit remoting.
When using the ComputerName parameter with Invoke-Command, authentication is completed, the remoting session is established, the command is run, objects are sent back, and the remoting session is torn down. This works fine if there’s only a single command that needs to be run. But what if there’s a group of computers that need to be managed throughout the day? It’s not very efficient to go through all that overhead each time a command is run if you’re going to be managing a group of servers constantly. With PowerShell Remoting, we have the concept of sessions.
A session is a persistent connection with the remote computer. The New-PSSession cmdlet is used to open a session with one or more computers. Existing sessions can be viewed with the Get-PSSession cmdlet. By using a variable to reference the sessions I’ve created, it’s easy to use the Session parameter instead of the ComputerName parameter on Invoke-Command. Now Invoke-Command will use the existing sessions and avoid the overhead of initializing and tearing down a session each time I run a command.
$session = New-PSSession –ComputerName DC1,Win7-2
Invoke-Command –Session $session –ScriptBlock {Get-Process –Name lsass}
I can store several sessions in a single variable, and add sessions to this variable later. All the sessions can be created and stored in a variable, and I can run the same command against them easily. This is useful if I need different credentials to access different computers. I can start sessions with different connection options, store them in a single variable, and run commands against them all.
If I need to work interactively with a remote computer, I can use the Session parameter of Enter-PSSession to utilize an existing session. I can use array notation to access a specific PSSession in my $session variable, or I can pipe the session object of Get-PSSession to the Enter-PSSession cmdlet.
Sessions also enable a very useful capability called implicit remoting. If I’m sitting at my workstation, there may be modules and snap-ins that I’ve installed to extend the capabilities in Windows PowerShell. But if I don’t happen to be sitting at my own computer or I’ve had to rebuild my administration workstation, I might not have those cmdlets available. Wouldn’t it be nice if I didn’t have to install the Remote Server Administrator Tools (RSAT) when I needed to run the Microsoft Active Directory cmdlets?
To use implicit remoting, I start a Windows PowerShell session with a computer that already has the modules, snap-ins, or tools I need installed. In this case I want to use the Active Directory cmdlets, so I’m connecting to a domain controller. Then I use Invoke-Command to load the Active Directory module into my Windows PowerShell session on the domain controller. Finally, I use Import-PSSession with the Module parameter to automatically generate a local proxy function for the each cmdlet in the module I specified. Now I can use these remote cmdlets as if they were installed locally.
$dcSession = New-PSSession –ComputerName DC1
Invoke-Command –Session $dcSession –ScriptBlock {Import-Module ActiveDir*}
Import-PSSession –Session $dcSession –Module ActiveDir*
When I type a local cmdlet, Windows PowerShell calls the local cmdlet. When I type one of these imported cmdlets, Windows PowerShell calls the proxy function that takes care of the remote call for me. Windows PowerShell “implicitly” uses remoting to make everything appear like it’s happening locally. I can open sessions to my domain controller or to my servers running Exchange Server or SQL Server, and I can use Windows PowerShell to manage them all without having any of the management tools installed locally.
~Jason
WooHoo. Awesome job, Jason. Thank you for sharing your insights with us. We look forward to the exciting conclusion tomorrow.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy