{"id":2740,"date":"2013-10-12T00:01:00","date_gmt":"2013-10-12T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/10\/12\/disconnected-sessions-phenotype-and-genotype-part-2\/"},"modified":"2013-10-12T00:01:00","modified_gmt":"2013-10-12T00:01:00","slug":"disconnected-sessions-phenotype-and-genotype-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/disconnected-sessions-phenotype-and-genotype-part-2\/","title":{"rendered":"Disconnected Sessions: Phenotype and Genotype (Part 2)"},"content":{"rendered":"<p><strong>Summary<\/strong>: Learn about a revolutionary feature in Windows PowerShell&nbsp;3.0 that lets you disconnect from and reconnect to PSSessions.\nToday we continue our 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. Here&#8217;s June&hellip;\n<span style=\"font-size: 12px\">I hope that everyone got a chance to try the scenario that I discussed in <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/10\/05\/disconnected-sessions-phenotype-and-genotype-part-1.aspx\" target=\"_blank\">Disconnected Sessions: Phenotype and Genotype (Part 1)<\/a>. In this post, I&#8217;ll show you how to use the <strong>InDisconnectedSessions<\/strong> parameter of <strong>Invoke-Command<\/strong> and share a few &#8220;gotchas&#8221; to keep you out of trouble.<\/span><\/p>\n<h2>Disconnect Immediately<\/h2>\n<p>Our savvy IT pro is ready to head to a long meeting. So, she starts a command in a disconnected session. The really efficient command that follows creates the remote session, disconnects from the session, and then runs the command in the disconnected session, thereby keeping all of the command results in the disconnected session:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PS C:&gt; Invoke-Command -ComputerName Server02 {&lt;commands&gt;} -InDisconnectedSession -SessionName TestWeekly<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;Id Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ComputerName&nbsp;&nbsp;&nbsp; State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConfigurationName&nbsp;&nbsp;&nbsp;&nbsp; Availability<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&#8212; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; 5 TestWeekly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Server02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Disconnected&nbsp; Microsoft.PowerShell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; None\nWhen she returns from her meeting, the commands are still running. (Must have been a short meeting&hellip;)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s = Get-PSSession -ComputerName Server02 -Name TestWeekly | Connect-PSSession<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;Id Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ComputerName&nbsp;&nbsp;&nbsp; State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConfigurationName&nbsp;&nbsp;&nbsp;&nbsp; Availability<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&#8212; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; 5 TestWeekly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Server02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Opened&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft.PowerShell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Busy<\/p>\n<h2>Gotchas: IdleTimeout<\/h2>\n<p>I know you&#8217;ll want to try this right now. Who wouldn&#8217;t? But before you run off, I want to give you some hints to avoid problems.\nThe value of the <strong>IdleTimeout<\/strong> property of the PSSession determines how long the PSSession is maintained while it&#8217;s idle (including the heartbeat). When the timeout expires, Windows PowerShell removes the PSSession. This is especially important for disconnected PSSessions that might be left idle for long periods by design.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; (Get-PSSession -ComputerName Server01 -Name Diag).IdleTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">7200000\nThe default value of the <strong>IdleTimeout<\/strong> property of a PSSession is determined by the value of the <strong>IdleTimeoutMs<\/strong> property of the session configuration that is used to create the session.\nIn this scenario, the IT pro did not specify a session configuration (New-PSSession -ConfigurationName &lt;name&gt;), so the PSSession used the default session configuration, Microsoft.PowerShell, where the value of the <strong>IdleTimeoutMs<\/strong> property is 7200000 milliseconds, or two hours.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; (Get-PSSessionConfiguration Microsoft.PowerShell).IdleTimeoutMs<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">7200000\nThere are several ways to extend the idle timeout of a PSSession:<\/p>\n<ul>\n<li>You can specify a longer idle timeout in the session options. The value that you specify must be less than or equal to the value of the <strong>MaxIdleTimeoutMs<\/strong> property of the session configuration. The <strong>MaxIdleTimeoutMs<\/strong> value of the Microsoft.PowerShell session configuration is Int32.MaxValues, which is more than 24 days, so it&#8217;s not typically an issue.<\/li>\n<\/ul>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C: &gt; (Get-PSSessionConfiguration Microsoft.Powershell).MaxIdleTimeoutMs<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">2147483647<\/p>\n<p style=\"padding-left: 30px\">The following command creates a session option object with an idle timeout of 24 hours:<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C: &gt; $o = New-PSSessionOption -IdleTimeout (60 * 60 * 24 * 1000)<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C: &gt; $s = New-PSSession -Name Diag -ComputerName Server01 -SessionOption $o<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C: &gt; $s.IdleTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">86400000<\/p>\n<ul>\n<li>You can change the idle timeout when you disconnect from the session. The <strong>Disconnect-PSSession <\/strong>command has an <strong>IdleTimeoutSec<\/strong> parameter. (Be careful&mdash;this value is in seconds, not milliseconds, like the others.)<\/li>\n<\/ul>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $s = Get-PSSession -ComputerName Server01 -name Diag<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $s.IdleTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">7200000<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; Disconnect-PSSession $s -IdleTimeoutSec (60 * 60 * 24)<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">Id Name&nbsp;&nbsp; ComputerName&nbsp;&nbsp;&nbsp; State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ConfigurationName&nbsp; &nbsp;&nbsp;&nbsp;Availability<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&#8212; &#8212;-&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;7 Diag&nbsp;&nbsp; Server01 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Disconnected&nbsp; Microsoft.PowerShell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; None<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $s.IdleTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">86400000<\/p>\n<ul>\n<li>You can create a session configuration with a longer idle timeout. When you create sessions that use this session configuration, they&#8217;ll have the longer idle timeout by default.<\/li>\n<\/ul>\n<p style=\"padding-left: 30px\">The <strong>IdleTimeoutMs<\/strong> property of a session configuration (the one that determines the default idle timeout of sessions) cannot exceed the maximum permitted idle timeout for a session configuration, which is the lesser of the <strong>MaxIdleTimeoutMs<\/strong> property of the session configuration and the <strong>IdleTimeout<\/strong> value for WSMan shells.<\/p>\n<p style=\"padding-left: 30px\">So, when you create a session configuration with a long idle timeout value, you might have to extend the shell <strong>IdleTimeout<\/strong> and the session configuration <strong>MaxIdleTimeoutMs<\/strong>. This command sequence creates a <strong>LongTimeout<\/strong> session configuration with a maximum idle timeout of 24 hours and a default idle timeout of 23 hours:<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; Set-Item WSMan:Server01shellIdleTimeout -Value (60 * 24 * 24 * 1000)<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $to = New-PSTransportOption -MaxIdleTimeoutSec (60 * 60 * 24)<br \/> -IdleTimeoutSec (60 * 60 * 23) <br \/> PS C:&gt; Register-PSSessionConfiguration -Name LongTimeout -TransportOption $to<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; (Get-PSSessionConfiguration LongTimeout) | Format-List -Property *idle*<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">ProcessIdleTimeoutSec : 0<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">IdleTimeoutms&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 82800000<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">MaxIdleTimeoutms&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 86400000<\/p>\n<p style=\"padding-left: 30px\">Now, when you create a PSSession with the new session configuration, it has the long timeout by default.<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $s = New-PSSession -Name Diag -ComputerName Server01 -ConfigurationName LongTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">PS C:&gt; $s.IdleTimeout<\/p>\n<p class=\"Code\" style=\"padding-left: 60px\">86400000<\/p>\n<h2>Gotchas: OutputBufferingMode<\/h2>\n<p>Another potential &#8220;gotcha&#8221; is the <strong>OutputBufferingMode<\/strong>. The output buffer for the session stores the output of commands before they are written to the console or to a file. Typically, output is delivered immediately, so the buffer never fills. But when a session is disconnected, the output can&#8217;t be written, so it piles up in the output buffer. <strong>OutputBufferingMode<\/strong> tells Windows PowerShell what to do when the output buffer is full.<\/p>\n<p> The default value, <strong>Block<\/strong>, prevents commands from running when the buffer is full. You never lose output, but your commands are suspended until the buffer has empty space. The alternate value, <strong>Drop<\/strong>, lets the commands continue to run. The oldest output objects in the output buffer are replaced by the output of later commands. The commands are not interrupted, but you can lose results.\nNeither option is perfect, and the one you choose depends on the commands or scripts that you&#8217;re running and on whether and how they store data.\nThe <strong>OutputBufferingMode<\/strong> value of a session is determined by the <strong>OutputBufferingMode<\/strong> value of the session configuration. You can change the value in a session configuration, create a session configuration with a different value, create a session option with a different <strong>OutputBufferingMode<\/strong>, or change the <strong>OutputBufferingMode<\/strong> when you disconnect from the session.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $o = New-PSSessionOption -OutputBufferingMode Drop<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s = New-PSSession -ComputerName localhost -name Diag -SessionOption $o<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s.OutputBufferingMode<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Drop<\/p>\n<p class=\"Code\">-or-<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s | Disconnect-PSSession -OutputBufferingMode Drop<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s.OutputBufferingMode<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Drop<\/p>\n<h2>Sessions are User-Specific<\/h2>\n<p>The sessions that <strong>Get-PSSession -ComputerName<\/strong> gets are determined by who is asking. The cmdlet returns only the sessions that the current user created. So, if your colleague is looking for sessions that you created, they won&#8217;t see them. However, you can use group credentials to create a session that others can see.<\/p>\n<h2>Remember Remove-PSSession<\/h2>\n<p>Because the sessions are persistent, be sure to remove the sessions that you&#8217;re no longer using. Windows PowerShell will remove them when the <strong>IdleTimeout<\/strong> expires, but they will consume resources until that occurs.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s = Get-PSSession -ComputerName Server01 -name Diag<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:&gt; $s | Remove-PSSession<\/p>\n<h2>And, if that&#8217;s not enough&#8230;<\/h2>\n<p>If you&#8217;re not already pretty jazzed about this, there&#8217;s more to come. In Windows PowerShell&nbsp;4.0, you can enter a busy PSSession while a command is running. You can watch the command run, see output in the console, and even use Ctrl+C&nbsp; to stop a running command or script. (In Windows PowerShell&nbsp;3.0, you&#8217;ll get a busy session error until the command completes.)\n~June\nThanks, June! I can&rsquo;t wait to read Part 3.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn about a revolutionary feature in Windows PowerShell&nbsp;3.0 that lets you disconnect from and reconnect to PSSessions. Today we continue our 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. Here&#8217;s June&hellip; I hope [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,370,57,3,4,45],"class_list":["post-2740","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-june-blender","tag-remoting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn about a revolutionary feature in Windows PowerShell&nbsp;3.0 that lets you disconnect from and reconnect to PSSessions. Today we continue our 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. Here&#8217;s June&hellip; I hope [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2740"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2740\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}