{"id":862,"date":"2010-04-20T00:00:00","date_gmt":"2010-04-20T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/new-remoting-features-in-powershell-2-0\/"},"modified":"2016-07-28T10:42:49","modified_gmt":"2016-07-28T10:42:49","slug":"new-remoting-features-in-powershell-2-0","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/new-remoting-features-in-powershell-2-0\/","title":{"rendered":"New Remoting Features in PowerShell 2.0"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"start\">PowerShell 1.0 was a fantastic leap forward for  Windows-based administrators, enabling them to manage Microsoft products from  the command line in a consistent and powerful way. However, one area which could  possibly be considered weak, and which had many calls for improvement, was in  the ability to remotely manage computers. Although the <b>Get-WMIObject<\/b>  cmdlet had remote functionality and there were other ways to get round running  commands and scripts on remote computers, PowerShell 2.0 goes a long way to  improve the experience. There are many more cmdlets that have built-in remoting  functionality, and PowerShell 2.0 also adds full remoting capabilities with  other servers.<\/p>\n<p>In the course of this article, I&#8217;m going to introduce you  to some of this fantastic new functionality, point out why it&#8217;s such a huge leap  forward from PowerShell 1.0, and take you on a whirlwind tour of some newfound  powers at your fingertips. By the time we&#8217;re finished, I hope you&#8217;ll agree with  me that PowerShell 2.0 remoting is a great piece of technology, and definitely  something you should investigate more.<\/p>\n<h2> New cmdlets with remoting functionality<\/h2>\n<p>In PowerShell 1.0, only the <b>Get-WMIObject<\/b> cmdlet had  the<b> ComputerName<\/b> parameter available, enabling administrators to execute  that cmdlet against remote machines. In PowerShell 2.0, this list has been  extended to thirty five cmdlets with the <b>ComputerName<\/b> parameter,  including two of the most popular, Get-Process and Get-Service.<\/p>\n<p><b>Tip:<\/b> to quickly find which cmdlets have a <b> ComputerName<\/b> parameter available, you can run the below command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Get-Command | Where-Object {$_.definition -match  'computername'}\n\n<\/pre>\n<p>It is important to note that the  remoting functionality used with the ComputerName parameter is not consistent  across all cmdlets, and is determined by the creator of the cmdlet. Most likely  it will not be using the technology which &#8216;full&#8217; PowerShell remoting takes  advantage of, and will typically be using something like RPC instead.<\/p>\n<p>Great examples of this enhanced functionality are the <b> Get-Service <\/b>&#160;and <b>Set-Service<\/b> cmdlets, which now make it possible to  query services on a remote computer and then manipulate them. To demonstrate:  the following command queries the <b>Print<\/b> <b>Spooler<\/b> service on the  remote machine <b>Test01<\/b>:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Get-Service Spooler  -ComputerName Test01\n<\/pre>\n<p>We observe that this service currently has a status of <b> Stopped<\/b>. By running the same command again, and this time piping it through  to the <b>Set-Service<\/b> cmdlet and using the <b>Status<\/b> parameter to apply  a status of <b>Running<\/b>, we observe that this service has now started:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Get-Service Spooler  -ComputerName Test01 |  Set-Service -Status Running\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM1.JPG\" alt=\"1007-JM1.JPG\" \/><\/p>\n<p class=\"caption\">Fig 1. &#8211; A successful start of the Print Spool service  using PowerShell 2.0<\/p>\n<p>Previously, in PowerShell 1.0, we could have done this  through WMI using the <b>Get-WMIObject<\/b> cmdlet and its ComputerName  parameter:<\/p>\n<ul>\n<li> First of all store the results of a WMI query into the $Service  variable.<\/li>\n<\/ul>\n<pre class=\"lang:ps theme:powershell-ise\">$Service  =Get-WmiObject -ComputerName Test01  win32_service-filter  \"name='Spooler'\"\n<\/pre>\n<p><\/p>\n<ul>\n<li>Then execute the <b>StartService<\/b> method to start the <b>Print  Spooler<\/b> service on Test01.<\/li>\n<\/ul>\n<pre class=\"lang:ps theme:powershell-ise\">$Service.StartService()\n<\/pre>\n<p>The <b>ReturnValue<\/b> of 0 indicates that this was  successful. <\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM2.JPG\" alt=\"1007-JM2.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 2&#160; &#8211; A successful start of the Print Spool service  through WMI, using PowerShell 1.0<\/p>\n<p>Clearly it still only took two lines of code in PowerShell  1.0 to achieve this task, but in PowerShell 2.0 we were able to take advantage  of the pipeline with the <b>Get-Service <\/b>&#160;and <b>Set-Service<\/b> cmdlets,  &#160;and we didn&#8217;t need to investigate which WMI classes and methods we might have  needed to achieve the same outcome.<\/p>\n<h2> WinRM 2.0 and the Windows Management Framework<\/h2>\n<p>Aside from these cmdlets with enhanced capabilities,  PowerShell 2.0 also ships with full remoting functionality. By that I mean that  it is possible to connect your local PowerShell session to a remote computer and  execute commands just as if you were sitting in front of the server console. The  technology to make this happen relies on WinRM 2.0, which is Microsoft&#8217;s latest  implementation of the WS-Management Protocol, a SOAP-based protocol used to  manage a variety of hardware devices. The theory behind this is that it will  provide a shared way for differing systems to communicate with each other.<\/p>\n<p>WinRM 2.0 communicates via HTTP, and so is likely to be  firewall-friendly; it also listens on ports 5985 (default) and 5986 (encrypted),  avoiding issues with locally installed IIS. Even though it uses HTTP for  communication, security has still been considered; either NTLM or Kerberos are  used for authentication, and if you wish to configure WinRM 2.0 to use SSL, that  is possible too. A lot of the configuration can be carried out via new  PowerShell cmdlets shipped with version 2.0, but more on that later.<\/p>\n<p>Since PowerShell 2.0 and WinRM 2.0 go hand in hand,  Microsoft has bundled them up together along with a new version of BITS  (Background Intelligent Transfer Service) 4.0, making a single package known as  the Windows Management Framework. Although this collection makes some sense if  you know the background, there <i>can<\/i> be some confusion if an administrator  is searching for the download of PowerShell 2.0, ends up at the homepage for the  Windows Management Framework (<a href=\"http:\/\/support.microsoft.com\/kb\/968929\">http:\/\/support.microsoft.com\/kb\/968929<\/a>)  and wonders what the heck that is. Well, now you know!<\/p>\n<p>The components of the Windows Management Framework are  already installed with both Windows Server 2008 R2 and Windows 7, althoughWinRM  2.0 is not enabled by default on Windows 7. The components have also been made  available for older OS &#160;versions, and you can download all of those from the  homepage of the Windows Management Framework. Essentially, it is available for  the various flavours of Windows Server 2008 and 2003, as well as the Windows  Vista and XP client operating systems &#8211; although BITS 4.0 is <i>not<\/i>  available for Windows Server 2003 or XP. This might sound like a muddle, but in  short, it is possible to run remote PowerShell 2.0 sessions both to and from all  these different operating systems.<\/p>\n<p>At this point, Unix \/ Linux administrators might be sitting  back and chuckling to themselves, saying that they&#8217;ve had this since the  beginning of time with Telnet \/ SSH, and wondering what all the fuss is about;  and to a certain extent, that is a very fair point. However, the great news for <i>Windows<\/i> administrators is that you now have a scalable, consistent  command line interface which you can use against remote machines &#8211; you no longer  have anything standing in the way of efficiently managing and automating your  systems! Even if this was just an equivalent of SSH, that would be a decent  start, but I&#8217;m hopefully about to show you that PowerShell remoting is <i> significantly<\/i> more than that.<\/p>\n<h2> Getting Started<\/h2>\n<p>First of all, you obviously need to make sure you&#8217;ve got a  server which meets the requirements for PowerShell 2.0 remoting; either Windows  Server 2008 R2 with everything already built-in, or Windows Server 2008 or 2003  with the Windows Management Framework downloaded and installed. Once you&#8217;ve got  that, configuration for PowerShell 2.0 remoting, if the computer is a member of  a domain, is as simple as running this cmdlet&#8230;<\/p>\n<h2>Enable-PSRemoting<\/h2>\n<p>&#8230;which will make all the necessary changes for you.  However, if you are operating within a workgroup then you need to make some  additional changes. Specifically, if the Operating System is Windows XP then you  will need to adjust the Local Security Policy setting<b> <\/b>(<b>Network Access:  Sharing and Security Model for local accounts<\/b>)<b> <\/b>to <b>Classic<\/b>.<\/p>\n<p>Then, for <i>any<\/i> Windows Operating System, including  Windows XP, you will need to add the names of the remote computer(s) into the <b> TrustedHosts<\/b> setting of WinRM. You can do this using the PowerShell command  below:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Set-Item WSMan:localhost\\Client\\TrustedHosts -value ServerName\n<\/pre>\n<div class=\"note\">\n<p class=\"note\">Note: You will need to run  the <b>Enable-PSRemoting<\/b> cmdlet from a PowerShell session with elevated  privileges, i.e. <b>Run as administrator<\/b>.<\/p>\n<\/div>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM3.JPG\" alt=\"1007-JM3.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 3 &#8211; running the PowerShell cmdlet with elevated  privileges<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM4.JPG\" alt=\"1007-JM4.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 4 &#8211; Enable-<b>PSRemoting<\/b> initially runs <b> Set-WSManQuickConfig<\/b><\/p>\n<p>You can see from the screenshot above that the <b> Enable-PSRemoting<\/b> cmdlet actually initially runs the <b>Set-WSManQuickConfig<\/b>  cmdlet, which in turn is one of the new cmdlets I mentioned previously that have  been included as part of PowerShell 2.0 for working with WS-Management. <b> Set-WSManQuickConfig<\/b> will carry out four steps:<\/p>\n<ol>\n<li> Start or restart (as necessary) the WinRM service<\/li>\n<li>Set the WinRM service startup type to be Automatic<\/li>\n<li>Create a listener to accept requests on any IP address<\/li>\n<li>Enable a firewall exception for WS-Management traffic (known as <i> Windows Remote Management<\/i>)<\/li>\n<\/ol>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM5.JPG\" alt=\"1007-JM5.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 5 &#8211; The Firewall exception for WS-Management traffic<\/p>\n<p>You will receive confirmation of what has been carried out  in each step.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM6.JPG\" alt=\"1007-JM6.JPG\" \/><\/p>\n<p>If you are running on a 64bit machine, then you will be  prompted to additionally create a 32bit session configuration &#8211; accept this, and  then your configuration will be complete. In addition to the WS-Management  configuration, to ensure that all registered Windows PowerShell session  configurations will have been enabled to receive instructions from a remote  computer, the following steps will have also been taken:<\/p>\n<ol>\n<li> Registered the <b>Microsoft.PowerShell<\/b> session configuration, if it  is not already registered.<\/li>\n<li>Registered the <b>Microsoft.PowerShell32<\/b> session configuration on  64-bit computers, if it is not already registered.<\/li>\n<li>Removed the &#8220;Deny Everyone&#8221; setting from the security descriptor for all  the registered session configurations.<\/li>\n<li>Restarted the WinRM service to make the preceding changes effective.<\/li>\n<\/ol>\n<p>So quite a lot has been configured, but it&#8217;s all been made  nice and easy for the administrator in one short command.<\/p>\n<div class=\"note\">\n<p class=\"note\"><b>Note:<\/b> In an Enterprise  environment you will obviously not want to run <b>Enable-PSRemoting<\/b> on every  machine you wish to configure for remoting. Fortunately, it is possible to make  these changes via the Group Policy setting <strong> Computer  Configuration\\Policies\\Administrative Templates\\Windows Components\\Windows  Remote Management\\WinRM Service\\Allow automatic configuration of listeners.<\/strong>  Group Policy could also be used to configure the necessary firewall change and  ensure that the WinRM service was set to start automatically.<\/p>\n<\/div>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM7.JPG\" alt=\"1007-JM7.JPG\" \/><\/p>\n<h2>Interactive Sessions<\/h2>\n<p>Now that you are ready to begin using PowerShell remote  sessions, we will &#160;start off with a look at running an interactive session. Say,  for instance, that you wish to quickly connect to a remote computer to run a few  interactive commands and you don&#8217;t need to save the session for later use &#8211; a  fairly typical situation for a Unix \/ Linux administrator wishing to quickly SSH  into a remote server.<\/p>\n<p>To do this, you will need to use the <b>Enter-PSSession<\/b>  and <b>Exit-PSSession <\/b>cmdlets,<b> <\/b>and connect to a remote computer where <b>Enable-PSRemoting<\/b> has previously been run. To begin the session, use<b>  Enter-PSSession<\/b> and specify which computer you wish to connect to:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Enter-PSSession-ComputerName  Test01\n<\/pre>\n<p>You will see that your prompt is now preceded by the name  of the server you have connected to:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM8.JPG\" alt=\"1007-JM8.JPG\" \/><\/p>\n<p>From  classhere, you can now run any commands just as if you were  sat in front of the console at Test01; for example, you could look at the  contents of the C:\\ drive&#8230;<\/p>\n<p class=\"MsoNormal\"><b> dir<\/b><\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM9.JPG\" alt=\"1007-JM9.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 6 &#8211; Querying the C:\\ drive contents on a remote  machine<\/p>\n<p>Or examine the currently running processes which are from  Microsoft products&#8230;<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Get-Process | Where-Object {$_.Company -like  'Microsoft Corporation'} | Format-Table Name,Company -AutoSize\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM10.JPG\" alt=\"1007-JM10.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 7 &#8211; Finding all the currently-running process which  originate from Microsoft products<\/p>\n<p>Once you are finished with the session, you can quickly  tear it down without any parameters using <b>Exit-PSSession<\/b>:<\/p>\n<pre>Exit-PSSession\n<\/pre>\n<p>Once you&#8217;ve done this, you will notice that your prompt  changes back to normal now that you are back on the local computer.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM11.JPG\" alt=\"1007-JM11.JPG\" \/><\/p>\n<h2>Persistent Sessions<\/h2>\n<p>If the story ended there, then you might say to yourself &#8220;<i>Terrific,  Windows now has a solution similar to SSH. I can manage Windows Servers remotely  from the command line<\/i>.&#8221; However, the PowerShell story is all about <i> automation<\/i>, and not just for one remote server, but for as many as you can  handle. To that end, there are a number of other cmdlets in PowerShell 2.0 for  working with remoting and, starting with <b>New-PSSession<\/b>, I will show you  how to advantage of these and very simply use some of the very powerful tools  now at your disposal.<\/p>\n<p>The <b>New-PSSession<\/b> cmdlet creates persistent remote  PowerShell sessions to one or multiple computers. The difference between this  and&#160; <b>Enter-PSSession<\/b> is that <i>these<\/i> sessions are maintained for  later use, either for ad hoc connections or, more typically, to run commands or  scripts against. You can also store these sessions as objects in a variable for  ease of reference. For instance, the command below will create a persistent  remote PowerShell session to the computer Test01, and store it in the <b> $sessions<\/b> variable: <\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$sessions  =New-PSSession -ComputerName Test01\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM12.JPG\" alt=\"1007-JM12.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 8 &#8211; Creating and storing a persistent session<\/p>\n<p>The stored session is an object of type <b> System.Management.Automation.Runspaces.PSSession<\/b>, and has methods and  properties just like any other object.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM13.JPG\" alt=\"1007-JM13.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 9 &#8211; The methods and properties of  System.Management.Automation.Runspace.PSSession object<\/p>\n<p>If you wanted to, you could now use that session with the <b>Enter-PSSession<\/b> cmdlet and remotely connect to the server Test01 with  minimum hassle:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Enter-PSSession  -Session $sessions\n<\/pre>\n<h3>Remote Commands, Local Results<\/h3>\n<p>What would actually be far more interesting (not to mention  useful) would be to submit some commands to that remote server via this  persistent session, and return the results to your local session. To do that, we  can use another new PowerShell 2.0 cmdlet: <b>Invoke-Command<\/b>.<\/p>\n<p>Let&#8217;s say we wanted to run another new PowerShell 2.0  cmdlet <b>Get-Culture<\/b> , which <i>doesn&#8217;t<\/i> have a built-in ComputerName  parameter, on the remote Test01 server in order to retrieve information about  the current culture settings. The command below will make use of the already  established remote PowerShell session with Test01, run the command contained  within the scriptblock <i>on<\/i> Test01, and then return the results to the  local session:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Invoke-Command -Session $sessions -ScriptBlock {Get-Culture}<\/pre>\n<p>You will notice that the results are returned to your local  session and contain a column named PSComputerName, which indicates which remote  computer the results were returned from.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM100.JPG\" alt=\"1007-JM100.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 10 &#8211; The Culture settings from Test01, returned to the  local session<\/p>\n<p>Another useful parameter included with <b>Invoke-Command<\/b> is the <b>FilePath<\/b> parameter. So instead of having all their commands inside  a chunky scriptblock, an administrator can instead specify the path to a local PowerShell script, have that script run locally on the desired server, and  return the results back to the local session. <\/p>\n<p>For example, the command below would execute the local PowerShell script <b>QueryServer.ps1<\/b> on the remote server Test01 and return  the results:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Invoke-Command -Session $sessions -FilePath C:\\Scripts\\QueryServer.ps1\n<\/pre>\n<p>The possibilities for using these techniques with remote  sessions are potentially limitless, and a really powerful and efficient leap can  be made with just one minor amendment when creating the remote session with <b>New-PSSession <\/b>(which I&#8217;ll tell you about in just a moment). It doesn&#8217;t take  great imagination to extend the ideas we&#8217;ve been looking at, potentially saving  the administrator hours of work.<\/p>\n<p>Envisage a scenario where, instead of needing to determine  the culture settings on just one server (Test01), this time we need to find the  same settings on 100, or even 1000 servers. If you have the names of the servers  stored somewhere easily accessible, say in a CSV file or a SQL database, an  administrator could very easily first query that datasource for the names, and  then create persistent remote PowerShell 2.0 sessions to all of those servers  from <i>one<\/i> command. <\/p>\n<div class=\"note\">\n<p class=\"note\"><b>Note:<\/b> by default, PowerShell will only process 32 sessions created by <b>New-PSSession<\/b> at one  time, and any others will be queued. Depending on system resources and network  bandwidth, it is possible to increase this value via the <b>ThrottleLimit<\/b> parameter.<\/p>\n<\/div>\n<p>Let&#8217;s say the administrator has these server names stored  in the file <b>C:\\Scripts\\Servers.csv<\/b>. Creating these 100 or 1000 sessions  is now as simple as running <b>New-PSSession<\/b> and using another PowerShell cmdlet, <b>Get-Content<\/b>, to read in those names for <b>New-PSSession<\/b> to  use:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$sessions = New-PSSession -ComputerName (Get-Content C:\\Scripts\\Servers.csv)\n<\/pre>\n<p>All those sessions would then be created and, once again,  stored in the <b>$sessions<\/b> variable. Next, the administrator would just need  to re-run exactly the same code for <b>Invoke-Command<\/b> , and they would  receive the culture settings for all 100 or 1000 servers in their local session.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Invoke-Command -Session $sessions -ScriptBlock {Get-Culture}<\/pre>\n<p>Sessions stored within the <b>$sessions<\/b> variable will  remain there until either the client PowerShell session itself is closed, they  have been removed with the <b>Remove-PSSession<\/b> cmdlet, or they have timed  out. Each remote server maintains a heartbeat connection with the client by  default for four minutes, and if there is no network communication between them  during this period then the session will break. To manually close the sessions,  use the command below:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Remove-PSSession -Session $sessions\n<\/pre>\n<h2>Advanced Session Options<\/h2>\n<p>There are a number of other cmdlets which ship with PowerShell 2.0 for the advanced configuration of remote PowerShell sessions. The  first and most obvious of these is the <b>New-PSSessionOption<\/b> cmdlet, which  enables an administrator to configure advanced options for use with the <b>New-PSSession<\/b> cmdlet. For instance, they might want to fine tune the  connection by changing the default timeout period from four minutes, turn off  compression or set some restrictions on the maximum size of an object that the  local machine can receive from the remote computer (in bytes). These options can  be stored in a variable:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$SessionOptions = New-PSSessionOption -IdleTimeout 1200000 -NoCompression -MaximumReceivedObjectSize 104857676\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM15.JPG\" alt=\"1007-JM15.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 11 &#8211; Setting the advanced options for persistent  sessions<\/p>\n<p>&#8230;and then picked up for use by the <b>New-PSSession<\/b> cmdlet with the SessionOption parameter:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">New-PSSession -ComputerName Test01 -SessionOption $SessionOptions\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM16.JPG\" alt=\"1007-JM16.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 12 &#8211; A persistent session employing the  Administrator&#8217;s customized advanced settings<\/p>\n<p>Alternatively, an administrator can set session options  directly on the machine which will be connected to, either so that particular  functionality can be offered to the administrator connecting remotely or so that  session settings can be enforced. To achieve this, we can use the <b>Register-PSSessionConfiguration<\/b> cmdlet. <\/p>\n<p>A good example for this cmdlet is to use the <b>StartupScript<\/b> parameter; when a remote administrator connects in and  specifies this specific session configuration, they will receive the  functionality specified in the startup script. So, say an administrator creates  a startup script containing the function Write-Logfile seen below:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM17.JPG\" alt=\"1007-JM17.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 13 &#8211; A startup script containing a Write-Logfile script, ready to be activated remotely<\/p>\n<p>Now they can register a new PSSessionConfiguration called <b>WriteLogfile<\/b> with the above file specified as a startup script, which  will in turn create a dynamic module using the scriptblock containing the  Write-Logfile function:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Register-PSSessionConfiguration -name WriteLogfile -StartupScript C:\\Scripts\\StartupScript.ps1\n<\/pre>\n<p>They will first be prompted for confirmation of the action:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM18.JPG\" alt=\"1007-JM18.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 14 &#8211; Setting up the Write-Logfile functionality &#8211; part  1<\/p>\n<p>&#8230;and then confirmation for restarting the WinRM service to  pick up the new PSSessionConfiguration.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM19.JPG\" alt=\"1007-JM19.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 15 &#8211; Confirming the WinRM service restart<\/p>\n<p>For the remote administrator to make use of this new PSSessionConfiguration, they should use the <b>ConfigurationName<\/b> property of  the <b>New-PSSession<\/b> cmdlet:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">New-PSSession -ConfigurationName WriteLogfile -ComputerName Test01\n<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM20.JPG\" alt=\"1007-JM20.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 16 &#8211; Setting the ConfigurationName property in  New-PSSession<\/p>\n<p>They can then connect to that session with:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Enter-PSSession -Id 3\n<\/pre>\n<p>&#8230;and test that the Write-Logfile function is available:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">Get-Command Write-Logfile<\/pre>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1007-JM21.JPG\" alt=\"1007-JM21.JPG\" \/><\/p>\n<p class=\"caption\">Fig. 17 &#8211; testing the new Write-Logfile functionality<\/p>\n<h2>Summary<\/h2>\n<p>Missing from the original 1.0 release of Windows PowerShell was the ability to work remotely against Windows Servers. Although some  functionality was available with the <b>Get-WMIObject<\/b> cmdlet, this has been  greatly enhanced in version 2.0 with the addition of many more cmdlets which  have the ability to function against remote computers, and <i>full<\/i> remoting capabilities that work either interactively or with persistent sessions.  Administrators can and should take advantage of these new possibilities to work  more efficiently with the servers they manage, and increase the levels of  automation within their environment.<\/p>\n<p>I&#8217;ve taken you on a very brief tour of some of the  highlights of this new and enhanced functionality, and I invite you to find out  more and start experimenting.<\/p>\n<p class=\"note\">This article was commissioned by Red Gate Software, engineers of ingeniously simple tools for optimizing your Exchange email environment. <br \/>Learn more about <a href=\"http:\/\/www.red-gate.com\/products\/Exchange\/index.htm?utm_source=simpletalk&amp;utm_medium=weblink&amp;utm_content=exchangenote&amp;utm_campaign=esa\">Exchange Server Archiver<\/a> and <a href=\"http:\/\/www.red-gate.com\/products\/PST_Importer\/index.htm?utm_source=simpletalk&amp;utm_medium=weblink&amp;utm_content=pstnote&amp;utm_campaign=PSTImporter\">PST Importer.<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Eager to quell misinformation, Jonathan Medd points why PowerShell 2.0 is so much more than just super-charged SSH. He describes some new commands with full remoting functionality, and then explains persistent sessions, and how they give you that much sought-after power: administration automation.&hellip;<\/p>\n","protected":false},"author":101115,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[35],"tags":[4951,4635,5169,4871],"coauthors":[],"class_list":["post-862","post","type-post","status-publish","format-standard","hentry","category-powershell","tag-jonathan-medd","tag-powershell","tag-powershell-2-0","tag-sysadmin"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/101115"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":40308,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/862\/revisions\/40308"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=862"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}