{"id":4269,"date":"2013-01-23T00:01:00","date_gmt":"2013-01-23T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/01\/23\/powershell-workflows-restarting-the-computer\/"},"modified":"2013-01-23T00:01:00","modified_gmt":"2013-01-23T00:01:00","slug":"powershell-workflows-restarting-the-computer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-workflows-restarting-the-computer\/","title":{"rendered":"PowerShell Workflows: Restarting the Computer"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary:<\/strong><span style=\"font-size: 12px\"> Windows PowerShell MVP Richard Siddaway continues with part five of his awesome Windows PowerShell workflow basics articles.<\/span>\nMicrosoft Scripting Guy, Ed Wilson, is here. Today, we have the fifth in a series of guest blog posts written by Windows PowerShell MVP and <a href=\"http:\/\/blogs.technet.comhttps:\/\/devblogs.microsoft.com\/scripting\/announcing-the-2012-honorary-scripting-guys\/\" target=\"_blank\">Honorary Scripting Guy<\/a> Richard Siddaway dealing with Windows PowerShell workflow.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;The first article, <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2012\/12\/26\/powershell-workflows-the-basics.aspx\" target=\"_blank\">PowerShell Workflows: The Basics<\/a><em>, <\/em>introduced the basic concepts of Windows PowerShell workflow. The second article, <a href=\"http:\/\/blogs.technet.comhttps:\/\/devblogs.microsoft.com\/scripting\/powershell-workflows-restrictions\/\" target=\"_blank\">PowerShell Workflows: Restrictions<\/a><em>, <\/em>discussed the restrictions encountered with working with Windows PowerShell workflows. The third article was <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/01\/09\/powershell-workflows-nesting.aspx\" target=\"_blank\">PowerShell Workflows: Nesting<\/a>. The fourth article talked about <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/01\/16\/powershell-workflows-job-engine.aspx\" target=\"_blank\">PowerShell Workflows: Job Engine<\/a>. You should read those articles prior to reading today&rsquo;s article.\nRichard has written a <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/richard+siddaway\/\" target=\"_blank\">number of guest Hey, Scripting Guy! Blog posts<\/a>, and he has also written two books on Windows PowerShell. His most written book, <a href=\"http:\/\/www.manning.com\/jones2\/\" target=\"_blank\">PowerShell in Depth<\/a>, is co-written with fellow MVPs Don Jones and Jeffrey Hicks.\nNow, take it away, Richard &hellip;\nYou saw in the last article that Windows PowerShell workflows can survive being stopped and restarted. In certain circumstances, workflows can also survive the Windows PowerShell session being terminated. In this post, you will discover how workflows can survive a reboot.\nA computer needs to reboot for a number of activities, for instance:<\/p>\n<ul>\n<li>Renaming the computer<\/li>\n<li>Joining or leaving a domain<\/li>\n<li>Some software installs or updates<\/li>\n<li>Triggering of a Chkdsk on a system drive<\/li>\n<\/ul>\n<p>It is possible to perform these activities as a series of steps separated by a reboot. Workflows enable you to set the process off and forget about it until it has finished the processing-reboot-processing cycle.\nConsider the following three scenarios:<\/p>\n<ol>\n<li>Restarting a remote computer against which you are running a workflow.<\/li>\n<li>Restarting the computer running the workflow and <em>manually<\/em> restarting the workflow.<\/li>\n<li>Restarting the computer running the workflow and <em>automatically<\/em> restarting the workflow.<\/li>\n<\/ol>\n<p>The first case is the easiest, so that&rsquo;s where we&rsquo;ll start.<\/p>\n<h2>Restarting a remote computer in a workflow<\/h2>\n<p>To keep the examples simple&mdash;so you can concentrate on how the workflows deal with the restarts&mdash;the following basic workflow forms the basis of the example:<\/p>\n<p style=\"padding-left: 30px\">workflow test-restart {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param ([string[]]$computernames)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;foreach -parallel ($computer in $computernames) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-WmiObject -Class Win32_ComputerSystem -PSComputerName $computer<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-WmiObject -Class Win32_OperatingSystem -PSComputerName $computer<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}\nAll it does is get the computer system and operating system information via WMI calls. The WMI cmdlets are used rather than the newer CIM cmdlets so that WSMAN versions don&rsquo;t become a factor. Two remote computers will be used in the test:<\/p>\n<ul>\n<li><strong>W12standard<\/strong> &ndash; Windows Server&nbsp;2012 (Windows PowerShell 3.0)<\/li>\n<li><strong>WebR201<\/strong> &ndash; Windows Server&nbsp;2008&nbsp;R2 (Windows PowerShell 2.0)<\/li>\n<\/ul>\n<p>The workflow is used like this:<\/p>\n<p style=\"padding-left: 30px\">PS&gt; test-restart -computernames w12standard, webr201\nIn this case, I&rsquo;m explicitly telling the activities to access a remote computer. This isn&rsquo;t the only way to achieve this. You&rsquo;ll learn more about using workflow parameters in the next article.\nThe remote computers are accessed in parallel with a sequence of two WMI calls applied to each computer. The commands within the <strong>foreach<\/strong> block are processed in sequence, but the computers are processed in parallel.\nNow you can add the logic to restart the computers.<\/p>\n<p style=\"padding-left: 30px\">workflow test-restart {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param ([string[]]$computernames)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;foreach -parallel ($computer in $computernames) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-WmiObject -Class Win32_ComputerSystem -PSComputerName $computer<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Restart-Computer -Wait -PSComputerName $computer<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-WmiObject -Class Win32_OperatingSystem -PSComputerName $computer<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}\nThe work of restarting the remote computers is done by this line:<\/p>\n<p style=\"padding-left: 30px\">Restart-Computer -Wait -PSComputerName $computer\nThe important parameter is <strong>&ndash;Wait<\/strong>. It tells the workflow to wait until the remote computer has restarted before progressing to the next command.\nIf you run this in Windows PowerShell Integrated Scripting Environment (ISE) or the Windows PowerShell console, you will see a progress bar with messages informing you of the stages of the restart. These include:<\/p>\n<ul>\n<li>Waiting for restart to begin<\/li>\n<li>Verifying computer has restarted<\/li>\n<li>Waiting for WMI connectivity<\/li>\n<li>Waiting for Windows PowerShell connectivity<\/li>\n<li>Waiting for WinRM connectivity<\/li>\n<\/ul>\n<p>In my example, Windows Server&nbsp;2012 restarts a lot faster than Windows Server&nbsp;2008&nbsp;R2.\nIn the workflow topic <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/jj574130.aspx\" target=\"_blank\">Restarting the Computer in a Workflow<\/a>, the following code can be found:<\/p>\n<p style=\"padding-left: 30px\">Restart-Computer -Wait -PSConnectionRetryCount 4 -PSConnectionRetryInterval 5<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;The <strong>PSConnectionRetryCount<\/strong> and <strong>PSConnectionRetryInterval<\/strong> parameters do not appear to be recognized as workflow activity parameters.\nYou can always run the workflow as a Windows PowerShell job:<\/p>\n<p style=\"padding-left: 30px\">PS&gt; test-restart -computernames w12standard, webr201 -AsJob<\/p>\n<p style=\"padding-left: 30px\">Id&nbsp;&nbsp;&nbsp;&nbsp; Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PSJobTypeName&nbsp;&nbsp; State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HasMoreData&nbsp;&nbsp;&nbsp;&nbsp; Location&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;-&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">25&nbsp;&nbsp;&nbsp;&nbsp; Job25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PSWorkflowJob&nbsp;&nbsp; Running&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; True&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localhost&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\nAfter the job has finished, you can examine the data. All you get is the returned WMI data. The progress messages during the reboots will be supressed.<\/p>\n<h2>Restarting the computer running the workflow<\/h2>\n<p>Two options exist here:<\/p>\n<ul>\n<li>Restart the workflow manually<\/li>\n<li>Restart the workflow automatically<\/li>\n<\/ul>\n<p>Let&rsquo;s start with a manual restart.<\/p>\n<h3>Manual restart of workflow<\/h3>\n<p>Running a workflow that reboots the computer it&rsquo;s running on and then manually restarting the workflow is not an optimal solution&mdash;ideally, you want the computer to do all the work. But it involves less coding and is a simpler solution. There are times when quick and simple gets the job done. This approach also forms the basis for starting the workflow automatically.\nIn this example, I&rsquo;m going to show how to use the new <strong>Rename-Computer<\/strong> cmdlet (workflow activity). Renaming a computer running Windows is one of the examples that requires a reboot.<\/p>\n<p style=\"padding-left: 30px\">workflow rename-localsystem {<\/p>\n<p style=\"padding-left: 30px\">param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[string]$newname<\/p>\n<p style=\"padding-left: 30px\">)<\/p>\n<p style=\"padding-left: 30px\">Rename-Computer -Newname $newname -Force -Passthru\n&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Restart-Computer -Wait<\/p>\n<p style=\"padding-left: 30px\">Get-CimInstance -ClassName Win32_ComputerSystem |<\/p>\n<p style=\"padding-left: 30px\">Select-Object -ExpandProperty Name |<\/p>\n<p style=\"padding-left: 30px\">Set-Content -Path &#8220;C:Scripts$newname.txt&#8221;<\/p>\n<p style=\"padding-left: 30px\">}\nThe workflow takes the new computer name as a parameter. It uses that name to perform the rename, and then uses <strong>Restart-Computer<\/strong> with the <strong>&ndash;Wait<\/strong> parameter. After the reboot, the name of the computer is retrieved and put into a text file of that name.\nYou can start by manually displaying the current computer name. In this case, it is TEST1NOJOBPARAM. It&rsquo;s a name the system ended up with from some previous tests.<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; $env:COMPUTERNAME<\/p>\n<p style=\"padding-left: 30px\">TEST1NOJOBPARAM<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; rename-localsystem -newname W12SUS\nYou can then run the workflow supplying the new name. Notice that the <strong>&ndash;AsJob<\/strong> parameter hasn&rsquo;t been used. The rename occurs and the system reboots.\nAfter the reboot, you can connect to the computer and test for the file.<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; ls<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Directory: C:scripts<\/p>\n<p style=\"padding-left: 30px\">Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastWriteTime&nbsp;&nbsp;&nbsp;&nbsp; Length Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">d&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14\/12\/2012&nbsp;&nbsp;&nbsp;&nbsp; 18:45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Setup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">-a&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02\/01\/2013&nbsp;&nbsp;&nbsp;&nbsp; 11:58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 rename-localsystem.ps1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n&nbsp;\nThe file hasn&rsquo;t been produced. A suspended job exists, as shown below.<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; Import-Module PSWorkflow<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; Get-Job | Format-Table -AutoSize<\/p>\n<p style=\"padding-left: 30px\">Id Name PSJobTypeName State&nbsp;&nbsp;&nbsp;&nbsp; HasMoreData Location&nbsp; Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212; &#8212;- &#8212;&#8212;&#8212;&#8212;- &#8212;&#8211;&nbsp;&nbsp;&nbsp; &nbsp;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">3&nbsp; Job2 PSWorkflowJob Suspended True&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localhost rename-localsystem\nResume the job. The job finishes and the file is produced. As a final test, you can check the environmental variable for the computer name.<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; ls<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Directory: C:scripts<\/p>\n<p style=\"padding-left: 30px\">Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastWriteTime&nbsp;&nbsp;&nbsp;&nbsp; Length Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">d&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14\/12\/2012&nbsp;&nbsp;&nbsp;&nbsp; 18:45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Setup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">-a&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02\/01\/2013&nbsp;&nbsp;&nbsp;&nbsp; 11:58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 280 rename-localsystem.ps1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">-a&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02\/01\/2013&nbsp;&nbsp;&nbsp;&nbsp; 12:24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8 W12SUS.txt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:scripts&gt; $env:COMPUTERNAME<\/p>\n<p style=\"padding-left: 30px\">W12SUS\nThere will be times when you need to restart the computer, but the workflow terminates at that point. This is a perfectly legitimate scenario, as shown in this example:<\/p>\n<p style=\"padding-left: 30px\">workflow add-localsystemtodomain{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; $domcred,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$ipv4address<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)<\/p>\n<p style=\"padding-left: 30px\">$index = Get-NetIPInterface -AddressFamily IPv4 -Dhcp Enabled |<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Select-Object -ExpandProperty&nbsp; ifIndex<\/p>\n<p style=\"padding-left: 30px\">New-NetIPAddress -InterfaceIndex $index -AddressFamily IPv4 `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;-IPAddress $ipv4address -PrefixLength 24<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Set-DnsClientServerAddress -InterfaceIndex $index -ServerAddresses &#8220;10.10.54.201&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Set-DnsClient -InterfaceIndex $index -ConnectionSpecificSuffix &#8220;manticore.org&#8221;<\/p>\n<p style=\"padding-left: 30px\">Add-Computer -Credential $domcred -DomainName Manticore `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;-OUPath &#8220;OU=Security Servers,OU=Servers,DC=Manticore,DC=org&#8221; -Force<\/p>\n<p style=\"padding-left: 30px\">Restart-Computer&nbsp;<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">## remove relicit jobs<\/p>\n<p style=\"padding-left: 30px\">Get-Job |<\/p>\n<p style=\"padding-left: 30px\">where PSJobTypeName -eq &#8220;PSWorkflowJob&#8221; |<\/p>\n<p style=\"padding-left: 30px\">Remove-Job<\/p>\n<p style=\"padding-left: 30px\">$cred = Get-Credential<\/p>\n<p style=\"padding-left: 30px\">add-localsystemtodomain -domcred $cred -ipv4address &#8220;10.10.54.170&#8221; -JobName AddToDomain\nThe new networking cmdlets are used to set the static IP address of the virtual machine&rsquo;s network adapter. The DNS servers and connection suffix are also set. The workflow adds the computer to the domain and then reboots.\nThe script cleans up any workflow-related jobs, asks for the credentials used to join the domain, and then fires the workflow. The <strong>&ndash;Wait<\/strong> parameter isn&rsquo;t used on <strong>Restart-Computer<\/strong>, so a Windows PowerShell job isn&rsquo;t produced and no further processing occurs.\nWhat about a situation where you want to control the restarting of the workflow, but then let the system take care of it?<\/p>\n<h3>Automatic restart of workflow<\/h3>\n<p>The online documentation I have seen states that a Windows PowerShell scheduled job can be used to perform this task. I had zero success with that approach, so I switched to using a scheduled task. Windows PowerShell 3.0 introduced a set of cmdlets for working with scheduled tasks. These are WMI-based and are only available on Windows&nbsp;8 and Windows Server&nbsp;2012. It would be possible to duplicate this functionality by using the COM interface to the task scheduler, but that is a task for another day.\nI went for a very simple approach while testing this because of the problems I was having, but there is enough here to show you the concept. Let&rsquo;s start with a workflow:<\/p>\n<p style=\"padding-left: 30px\">workflow test-restart {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Get-WmiObject -Class Win32_ComputerSystem | Out-File -FilePath C:Reportscomp.txt<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Get-ChildItem -Path C:Reports | Out-File -FilePath C:dir.txt<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Restart-Computer -Wait<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Get-WmiObject -Class Win32_OperatingSystem | Out-File -FilePath C:Reportsos.txt<\/p>\n<p style=\"padding-left: 30px\">}\nThe workflow uses <strong>Get-WmiObject<\/strong> to get the <strong>Win32_ComputerSystem<\/strong> class and creates a file containing the data. <strong>Get-ChildItem<\/strong> produces a listing of the folder containing the report. This tests that the first step in the workflow was performed.\n<strong>Restart-Computer<\/strong> is used with the <strong>&ndash;Wait<\/strong> parameter to produce a suspended workflow job and the computer reboots.\nAfter the system restarts, the workflow is resumed by a scheduled task, and the last step of producing a file containing data from the <strong>Win32_OperatingSystem<\/strong> class is performed.\nNext step is to create the scheduled task:<\/p>\n<p style=\"padding-left: 30px\">$actionscript = &#8216;-NonInteractive -WindowStyle Normal -NoLogo -NoProfile -NoExit -Command &#8220;&amp;&#8221;c:reportstest-resume.ps1&#8221;&#8221;&#8216;<\/p>\n<p style=\"padding-left: 30px\">$pstart =&nbsp; &#8220;C:WindowsSystem32WindowsPowerShellv1.0powershell.exe&#8221;<\/p>\n<p style=\"padding-left: 30px\">Get-ScheduledTask -TaskName Test | Unregister-ScheduledTask -Confirm:$false<\/p>\n<p style=\"padding-left: 30px\">$act = New-ScheduledTaskAction -Execute $pstart -Argument $actionscript<\/p>\n<p style=\"padding-left: 30px\">$trig = New-ScheduledTaskTrigger -AtLogOn<\/p>\n<p style=\"padding-left: 30px\">Register-ScheduledTask -TaskName Test -Action $act -Trigger $trig -RunLevel Highest\nI want my scheduled task to run Windows PowerShell, so I define the starting parameters for Windows PowerShell in the <strong>$actionscript<\/strong> variable. <strong>$pstart<\/strong> contains the command to start Windows PowerShell.\nThe next line removes any instances of the scheduled task.\nThe task action is defined by using <strong>New-ScheduledTaskAction<\/strong>. A trigger is defined to control when the task fires. I&rsquo;ve set this to be when I log on, because I wanted to see the task run. Change <strong>&ndash;AtLogon<\/strong> to <strong>&ndash;AtStartUp<\/strong>, if required.\nRegister the task data to create the task. Ensure that <strong>&ndash;RunLevel Highest<\/strong> is included, so your task runs with elevated privileges.\nThe last bit of the puzzle is the script that the scheduled task calls:<\/p>\n<p style=\"padding-left: 30px\">Get-ChildItem -Path C:Reports | Out-File -FilePath C:Reportsdir.txt<\/p>\n<p style=\"padding-left: 30px\">Import-Module PSWorkflow<\/p>\n<p style=\"padding-left: 30px\">Get-Job | Resume-Job\nThis creates another directory listing, imports the workflow module, and then resumes the suspended job. You can filter on the job name if you might have more than one suspended job on the system you are restarting.\nAfter the computer has restated, and you&rsquo;ve logged on, you&rsquo;ll see a Windows PowerShell window open and the workflow job will continue.\nOne oddity is that the timestamp on the os.txt file matches that of the comp.txt file! The os.txt file is definitely produced after the reboot though.\nClean up the job in the usual way and remove the scheduled task<\/p>\n<p style=\"padding-left: 30px\">Get-ScheduledTask -TaskName Test | Unregister-ScheduledTask -Confirm:$false\nThis doesn&rsquo;t seem to be an elegant solution, but it works. I&rsquo;ll keep looking at the scheduled job option and blog about it if I get it working.<\/p>\n<h2>Gotchas<\/h2>\n<p>One very big gotcha that I&rsquo;ve discovered testing this functionality is that you shouldn&rsquo;t run workflows through ISE.\nAccording to the documentation, you can run a workflow like this:<\/p>\n<p style=\"padding-left: 30px\">workflow test-restart {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Get-WmiObject -Class Win32_ComputerSystem<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Restart-Computer -Wait<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Get-WmiObject -Class Win32_OperatingSystem<\/p>\n<p style=\"padding-left: 30px\">}\nIf you run it through ISE, you won&rsquo;t get a suspended job&mdash;it&rsquo;ll carry on to completion. Run it through the console and everything works as expected. Many thanks to Steven Murawski for helping me track that one down.\nThe other thing to remember is to save any output to disk or you will lose it on reboot.<\/p>\n<h2>Conclusion<\/h2>\n<p>After working through these scenarios, I&rsquo;ve come to the conclusion that running the workflows against a remote computer when you need a restart is by far the easiest way to do it.&nbsp; Rebooting the local computer during a workflow is possible, but it can involve a lot of head-scratching to get it working the way you want.\n~Richard\nThank you, Richard&mdash;another great job.\nJoin me tomorrow for more cool Windows PowerShell stuff.\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><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Windows PowerShell MVP Richard Siddaway continues with part five of his awesome Windows PowerShell workflow basics articles. Microsoft Scripting Guy, Ed Wilson, is here. Today, we have the fifth in a series of guest blog posts written by Windows PowerShell MVP and Honorary Scripting Guy Richard Siddaway dealing with Windows PowerShell workflow. Note &nbsp;&nbsp;The [&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,189,3,45,382],"class_list":["post-4269","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-richard-siddaway","tag-scripting-guy","tag-windows-powershell","tag-workflow"],"acf":[],"blog_post_summary":"<p>Summary: Windows PowerShell MVP Richard Siddaway continues with part five of his awesome Windows PowerShell workflow basics articles. Microsoft Scripting Guy, Ed Wilson, is here. Today, we have the fifth in a series of guest blog posts written by Windows PowerShell MVP and Honorary Scripting Guy Richard Siddaway dealing with Windows PowerShell workflow. Note &nbsp;&nbsp;The [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4269","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=4269"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4269\/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=4269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}