Disconnected Sessions: Phenotype and Genotype (Part 1)

Disconnected Sessions: Phenotype and Genotype (Part 1)

  • Comments 3
  • Likes

Summary: Learn about a revolutionary feature in Windows PowerShell 3.0 that lets you disconnect from and reconnect to PSSessions.

Scripting Guy, Ed Wilson here. We have an exciting guest blog series that is written by Paul Higinbotham, a software design engineer for Windows PowerShell and June Blender, a senior programming writer for Windows Azure Active Directory. Today, June is going to start us off…

In Windows PowerShell 2.0, when you closed a session, such as your Windows PowerShell console window, or you lost your network connection, you lost all remote sessions (PSSessions) that you started in that session. And if a command just happened to be running in one of those remote sessions, the command stopped, and its results were forever lost.

All of that changed in Windows PowerShell 3.0. And, for those of us who multitask (frequently switching machines and coming and going between our home and office), it was a dream come true. I'm always surprised that I don't hear more people raving about this change. But maybe you just don't know the whole story.

To help me tell this story, I've recruited Paul Higinbotham, the Windows PowerShell developer who coded this feature. I'll explain how you use it (the "phenotype") and then, in a few follow-up posts, Paul will explain why it works (the "genotype"). I'm always pleased to get a chance to work with Paul, who's a great writer as well as a great coder. When you hear from him, you'll want to get to know him, too.

Need to go home? No problem!

So, here's the scenario:

  • An IT pro is hard at work diagnosing a failure on Server01, which is a remote machine with a tricky problem. She creates a PSSession to Server01 and then runs a few commands and a diagnostic script that takes a while to complete. In the meantime, she closes the session, closes the computer, and starts another task on a different machine. At the end of a long day, she heads home.
  • After dinner, she opens her home laptop, connects to her corporate network, starts Windows PowerShell, connects to the PSSession on Server01 and reviews the results. She runs a few more commands before calling it a day.
  • Next morning, she goes to work, reconnects to the session on Server01, and continues her investigation.

This scenario works in Windows PowerShell 3.0 because the PSSession is saved on the remote computer when the session is disconnected, either intentionally or unintentionally (such as when the network connection is interrupted). The PSSession becomes independent of the session in which it was created. Let's run through the commands that she uses.

First, she creates a PSSession named Diag on Server01, runs some commands and a script.

PS C:\> $s = New-PSSession -Name Diag -ComputerName Server01

PS C:\> $s

 

 Id Name            ComputerName    State         ConfigurationName     Availability

 -- ----            ------------    -----         -----------------     ------------

  2 Diag            localhost       Opened        Microsoft.PowerShell     Available

Notice that the State of the PSSession is Opened and the Availability is Available, which means that she can run commands in the PSSession.

Among the commands that she runs is a command to save the current date and time in a $Start variable in PSSession. She'll use this value to track the time spent on this machine.

PS C:\> Invoke-Command -Session $s {$start = get-date}

PS C:\> Invoke-Command -Session $s {$start}

 

Wednesday, September 18, 2013 2:51:20 PM

 

PS C:\> Invoke-Command -Session $s -FilePath Get-Diagnostics.ps1

PS C:\> Invoke-Command -Session $s { <more_commands>}

Before she moves to a different computer, she disconnects the PSSession. There are several ways to do this, including simply closing her laptop, but she uses the Disconnect-PSSession cmdlet.

PS C:\> Disconnect-PSSession $s
Id Name   ComputerName  State         ConfigurationName     Availability

-- ----   ------------  -----         -----------------     ------------

 2 Diag   Server01      Disconnected  Microsoft.PowerShell  None

Notice that the State is Disconnected and the Availability is None, which means that no one is using the session.

In Windows PowerShell 2.0, if a session is disconnected, all is lost. But in Windows PowerShell 3.0, the commands continue to run uninterrupted in the disconnected session. It's…well…revolutionary!

Meanwhile, at home…

Our IT pro finally finishes her tasks and goes home. After whipping up a gourmet dinner and enjoying an evening bicycle ride, she grabs her Surface Pro, connects to her corporate network, starts Windows PowerShell, and reconnects to the Diag PSSession on Server01. To find the disconnected PSSession, she uses the ComputerName parameter of the Get-PSSession cmdlet.

PS C:\> $s = Get-PSSession -ComputerName Server01 -Name Diag

PS C:\> $s

 

Id Name     ComputerName    State         ConfigurationName     Availability

 -- ----    ------------    -----         -----------------     ------------

  1 Diag    Server01        Disconnected  Microsoft.PowerShell          None

The ComputerName parameter of Get-PSSession works differently in Windows PowerShell 2.0 and Windows PowerShell 3.0. In Windows PowerShell 3.0, the ComputerName parameter is an implicit remoting command.

  • Windows PowerShell 2.0:
    Gets all PSSessions in the current session, and selects the ones that connect to Server01.
  • Windows PowerShell 3.0:
    Connects to the Server01 computer, and gets the PSSessions that this user started.

She's glad that she remembered to name the PSSession, because she has several PSSessions to the Server01 computer, and the ID property is not persistent; it can change with each connection.

Next, she uses the Connect-PSSession cmdlet to reconnect to the disconnected PSSession.

PS C:\> Connect-PSSession $s

PS C:\> $s

 

Id Name            ComputerName    State         ConfigurationName     Availability

-- ----            ------------    -----         -----------------     ------------

 9 Diag            Server01        Opened        Microsoft.PowerShell     Available

Now, the PSSession state is Opened, indicating that she's connected to it, and the Availability is Available, so she can run commands in the PSSession.

If, at this point, she peeks at the Diag PSSession from another computer (or another session on the same computer), it looks a bit different. From the perspective of another session, the Diag PSSession is Disconnected, that is, not connected to the current session. It is also Busy, meaning that it is connected to another session.

PS C:\> Get-PSSession -ComputerName Server01 -name Diag

 

 Id Name            ComputerName    State         ConfigurationName     Availability

 -- ----            ------------    -----         -----------------     ------------

  1 Diag            Server01        Disconnected  Microsoft.PowerShell          Busy

Now, back in the reconnected PSSession, our IT pro can review the output, and run more commands.

And that $Start variable from the afternoon? It's still there:

PS C:\> Invoke-Command -Session $s {$start}

 

Wednesday, September 18, 2013 2:51:20 PM

Back to work

When our roving IT pro gets to work bright and early in the morning, she opens her main computer and reconnects to the PSSession. This time, she uses Receive-PSSession, which gets the results of her commands and automatically reconnects to the PSSession.

PS C:\> $s = Get-PSSession -ComputerName Server01 -name Diag

PS C:\> $s

 

 Id Name            ComputerName    State         ConfigurationName     Availability

 -- ----            ------------    -----         -----------------     ------------

  1 Diag            Server01        Disconnected  Microsoft.PowerShell          None

 

PS C:\> $results = Receive-PSSession $s

PS C:\> $s

 

 Id Name            ComputerName    State         ConfigurationName     Availability

 -- ----            ------------    -----         -----------------     ------------

  7 Diag            localhost       Opened        Microsoft.PowerShell     Available

And that session-specific $Start variable is still in the PSSession:

PS C:\> Invoke-Command -Session $s {$start}

 

Wednesday, September 18, 2013 2:51:20 PM

Pretty remarkable? In the next post in this series (watch for it on Saturday, October 12), I'll show you how to use the InDisconnectedSessions parameter of Invoke-Command and share a few "gotchas" to keep you out of trouble. In the meantime, try it, and use the following Leave a comment section to send questions to me and Paul.

~June

Thanks, June. 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

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • This is all part of the implicate order of things.  PowerShell is just now expressing its pedigree.  As it evolves we should see an even better selection of traits expressed.  Yes, in software, pedigree is absolute.

  • Disconnect sessions are a great feature !

    They can be used for a lot more then just picking up your work session at home.

    We used it solve some issues we had  with specific snapins and modules.

    See www.lucd.info/.../siw-robust-sessions-and-powercli

  • Thanks, Luc! Great post.