{"id":4386,"date":"2013-01-02T00:01:00","date_gmt":"2013-01-02T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/01\/02\/powershell-workflows-restrictions\/"},"modified":"2013-01-02T00:01:00","modified_gmt":"2013-01-02T00:01:00","slug":"powershell-workflows-restrictions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-workflows-restrictions\/","title":{"rendered":"PowerShell Workflows: Restrictions"},"content":{"rendered":"<p><strong>Summary:<\/strong>&nbsp;Windows PowerShell MVP Richard Siddaway talks about restrictions on Windows PowerShell workflows.\nMicrosoft Scripting Guy, Ed Wilson, is here. Today, we have the second in a series of guest blog posts written by Windows PowerShell MVP Richard Siddaway dealing with Windows PowerShell workflow.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong> &nbsp;&nbsp;The first article,&nbsp;<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. You should read that article 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>&nbsp;and has also written two books on Windows PowerShell. His most recent 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;\nIn the last post, I introduced the basics of Windows PowerShell workflows. I mentioned a number of restrictions around workflows. It&rsquo;s time to look at those restrictions and discover how they can be overcome.\nWorkflow restrictions tend to fall into the following groups:<\/p>\n<ul>\n<li>Unsupported Windows PowerShell activities<\/li>\n<li>Scope of variables<\/li>\n<li>Objects are de-serialized<\/li>\n<li>Cmdlets that haven&rsquo;t had workflow activities created<\/li>\n<\/ul>\n<h2>Unsupported Windows PowerShell activities<\/h2>\n<p>A number of Windows PowerShell keywords and techniques aren&rsquo;t supported in workflows. The following table provides a summary.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td colspan=\"3\" valign=\"top\" width=\"591\">  <strong>Unsupported PowerShell techniques<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Begin,Process,End<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>Break,Continue<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>Subexpressions<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Multiple assignment<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>Modify loop variable<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>Dynamic parameters<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Set properties<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>Dot sourcing<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>Advanced parameter validation<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Positional parameters<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>Switch statement<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>Trap statement<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Inline help<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>Setting drive qualified variables<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>Method invocation on objects<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"165\">\n<p>Single #requires<\/p>\n<\/td>\n<td valign=\"top\" width=\"208\">\n<p>&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"217\">\n<p>&nbsp;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;\nOne other issue I&rsquo;ve see regards using custom Windows PowerShell drives&mdash;workflows may fail if they are present.\nSome of these restrictions&mdash;such using the trap statement&mdash;aren&rsquo;t too much of an issue. In this case, you should be using a try-catch block. Other restrictions will be more awkward such as not being able to use a switch statement. If you try what looks like a perfectly valid switch statement (try replacing &ldquo;workflow&rdquo; with &ldquo;function&ldquo; and see what happens).<\/p>\n<p style=\"padding-left: 30px\">workflow testswitch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$os<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;switch ($os) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;XP&#8221;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&#8220;Time to upgrade&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;Windows7&#8221;&nbsp; {&#8220;OK &#8211; but not the lastest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;Windows 8&#8221; {&#8220;Latest and greatest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}\n&nbsp;\nYou will get a sea of red error messages:<\/p>\n<p style=\"padding-left: 30px\">At line:5 char:2<\/p>\n<p style=\"padding-left: 30px\">+&nbsp; switch ($os) {<\/p>\n<p style=\"padding-left: 30px\">+&nbsp; ~~~~~~~~~~~~~~\n&nbsp;\nCase-insensitive switch statements are not supported in a Windows PowerShell workflow. Supply the -CaseSensitive flag, and ensure that case clauses are written appropriately. To write a case-insensitive case statement, first convert the input to either uppercase or lowercase, and update the case clauses to match.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ParserError: (:) [], ParentContainsErrorRecordEx<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; ception<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : SwitchCaseSensitive\n&nbsp;\nSo you might think you can do this:<\/p>\n<p style=\"padding-left: 30px\">workflow testswitchi {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$os<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;switch -CaseSensitive ($os.ToUpper())&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;XP&#8221;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&#8220;Time to upgrade&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;WINDOWS7&#8221;&nbsp; {&#8220;OK &#8211; but not the lastest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;WINDOWS 8&#8221; {&#8220;Latest and greatest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;\nNope. More red.<\/p>\n<p style=\"padding-left: 30px\">At line:5 char:25<\/p>\n<p style=\"padding-left: 30px\">+&nbsp; switch -CaseSensitive ($os.ToUpper())&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">+&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;\nMethod invocation is not supported in a Windows PowerShell Workflow. To use .NET Framework scripting, place your commands in an inline script:<\/p>\n<p style=\"padding-left: 30px\">InlineScript {<\/p>\n<p style=\"padding-left: 30px\">&lt;commands&gt; }.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ParserError: (:) [], ParentContainsErrorRecordEx<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; ception<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : MethodInvocationNotSupported<\/p>\n<p style=\"padding-left: 30px\">&nbsp;\nSo time to trot out the workflow &ldquo;get out of jail card&rdquo; &ndash; InlineScript<\/p>\n<p style=\"padding-left: 30px\">workflow testswitch {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;param (<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$os<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;InlineScript {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;switch ($using:os) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;XP&#8221;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&#8220;Time to upgrade&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;Windows7&#8221;&nbsp; {&#8220;OK &#8211; but not the lastest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8220;Windows 8&#8221; {&#8220;Latest and greatest&#8221;}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">}\n&nbsp;\nThis works as you would expect.\nOther restrictions such as the BEGIN, PROCESS, and END blocks that you can use in functions impact features that don&rsquo;t really fit with the workflow concept. The other restriction that can have a big impact is that you can&rsquo;t use inline comment-based Help. You have to use XML-based Help files. There are a number of ways to generate these files&mdash;one of the easiest is <a href=\"http:\/\/blogs.technet.com\/b\/jamesone\/archive\/2009\/07\/24\/powershell-on-line-help-a-change-you-should-make-for-v2-3-and-how-to-author-maml-help-files-for-powershell.aspx\" target=\"_blank\">through InfoPath as described by James O&rsquo;Neill<\/a>.\nNot having parameter validation available could be a big problem if your workflows are heavily parameterized. This restriction doesn&rsquo;t appear to have a workaround unless you create the validation code inside the workflow.\nYou will have noticed the $using:computer I used last time and $using:os in the code demonstrating the switch statement. This syntax is part of the solution to overcoming the second restriction that is the scope of variables.<\/p>\n<h2>Scope of variables<\/h2>\n<p>In workflows, the following restrictions on the use of variables occur:<\/p>\n<ul>\n<li>Variables defined in a higher scope are visible to lower workflow scopes but not Inlinescript scopes<\/li>\n<li>CANNOT have a variable in a lower scope with same name as a variable in higher scope<\/li>\n<li>if define or redefine variable can use it in that scope without problems<\/li>\n<li>there is no $global scope<\/li>\n<li>use &ldquo;$using&rdquo; in InlineScript blocks to access variables defined in a higher scope<\/li>\n<li>modification of a variable from a higher scope in an InlineScript&nbsp;requires the use of a temporary variable<\/li>\n<li>use &ldquo;$workflow&rdquo; to modify variable defined in a higher scope<\/li>\n<li>CANNOT use subexpressions<\/li>\n<\/ul>\n<p>That probably looks very confusing but this demonstration should help clear things up<em>. I recommend that you run this and work through the output.<\/em><\/p>\n<p style=\"padding-left: 30px\">workflow demo-scope {<\/p>\n<p style=\"padding-left: 30px\"># This is a workflow top-level variable<\/p>\n<p style=\"padding-left: 30px\">$a = 22<\/p>\n<p style=\"padding-left: 30px\">&#8220;Initial value of A is: $a&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Access $a from Inlinescript (bringing a workflow variable to the Windows PowerShell session) using $using<\/p>\n<p style=\"padding-left: 30px\">inlinescript {&#8220;PowerShell variable A is: $a&#8221;}<\/p>\n<p style=\"padding-left: 30px\">inlinescript {&#8220;Workflow variable A is: $using:a&#8221;}<\/p>\n<p style=\"padding-left: 30px\">## changing a variable value<\/p>\n<p style=\"padding-left: 30px\">$a = InlineScript {$b = $Using:a+5; $b}<\/p>\n<p style=\"padding-left: 30px\">&#8220;Workflow variable A after InlineScript change is: $a&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">parallel {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;sequence {<\/p>\n<p style=\"padding-left: 30px\"># Reading a top-level variable (no $workflow: needed)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&#8220;Value of A inside parallel is: $a&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Updating a top-level variable with $workflow:&lt;variable name&gt;<\/p>\n<p style=\"padding-left: 30px\">&nbsp; $workflow:a = 3<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&#8220;Updated value of A is: $a&#8221;<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">demo-scope\nYou should see something like this as your output:<\/p>\n<p style=\"padding-left: 30px\">Initial value of A is: 22<\/p>\n<p style=\"padding-left: 30px\">PowerShell variable A is:<\/p>\n<p style=\"padding-left: 30px\">Workflow variable A is: 22<\/p>\n<p style=\"padding-left: 30px\">Workflow variable A after InlineScript change is: 27<\/p>\n<p style=\"padding-left: 30px\">Value of A inside parallel is: 27<\/p>\n<p style=\"padding-left: 30px\">Updated value of A is: 3\nThe workflow starts by defining a variable, $a = 22, and then displaying its value. In an InlineScript, if you try to access a variable defined in a higher scope, you get nothing as shown in the second line of the output. You have to use $using:a to access the variable. If you want to change that variable you have to use a second variable and return it to the original variable:<\/p>\n<p style=\"padding-left: 30px\">$a = InlineScript {$b = $Using:a+5; $b}\nThe output shows the variable now has a value of 27.\nMoving into the parallel block you can read the variable without any scope issues. If you need to change the variable&rsquo;s value you access via the $workflow scope.\nBottom line with variables: keep it simple and be careful.<\/p>\n<h2>Objects are de-serialized<\/h2>\n<p>The third restriction is that objects in workflows are de-serialized. This is similar to the position in Windows PowerShell remoting (which is not surprising as workflows use the same transport mechanism). As an aside object de-serialization is becoming much more prevalent in Windows PowerShell. It appears in:<\/p>\n<ul>\n<li>Windows PowerShell remoting<\/li>\n<li>Remote access via CIM sessions<\/li>\n<li>WSMAN cmdlets<\/li>\n<li>Workflows<\/li>\n<\/ul>\n<p>Perhaps it&rsquo;s time for the normal approach to become one of working in this manner.\nA de-serialized object gives you the properties of the object BUT not the methods. In other words, it is inert. Lots of Windows PowerShell code does something like these examples:<\/p>\n<p style=\"padding-left: 30px\">$string = &#8220;abcde&#8221;<\/p>\n<p style=\"padding-left: 30px\">$string.ToUpper()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$os = Get-WmiObject -Class Win32_OperatingSystem<\/p>\n<p style=\"padding-left: 30px\">$os.ConvertToDateTime($os.LastBootUpTime)\n&nbsp;\nThis approach isn&rsquo;t going to work.<\/p>\n<p style=\"padding-left: 30px\">workflow test2 {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$string = &#8220;abcde&#8221;<\/p>\n<p style=\"padding-left: 30px\">$string.ToUpper()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$os = Get-WmiObject -Class Win32_OperatingSystem<\/p>\n<p style=\"padding-left: 30px\">$os.ConvertToDateTime($os.LastBootUpTime)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;\nWill throw an error about method invocation not being supported. You can however do this:<\/p>\n<p style=\"padding-left: 30px\">workflow test2 {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">inlinescript {<\/p>\n<p style=\"padding-left: 30px\">$string = &#8220;abcde&#8221;<\/p>\n<p style=\"padding-left: 30px\">$string.ToUpper()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$os = Get-WmiObject -Class Win32_OperatingSystem<\/p>\n<p style=\"padding-left: 30px\">$os.ConvertToDateTime($os.LastBootUpTime)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">}\nDon&rsquo;t try and access variables from a higher scope that represent objects and then invoke methods&mdash;it won&rsquo;t work.\nBottom line on de-serialized objects&mdash;if you need the methods of an object, access it through an inlinescript. Remember that you can nest InlineScript&nbsp;blocks in parallel blocks!<\/p>\n<h2>Cmdlets that haven&rsquo;t had workflow activities created<\/h2>\n<p>The final restriction is around the cmdlets that haven&rsquo;t been turned into workflows. Remember last time there was a problem with using the <strong>Format*<\/strong> cmdlets in workflows. The way around it is to use the InlineScript keyword like this:<\/p>\n<p style=\"padding-left: 30px\">workflow foreachpitest {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; param([string[]]$computers)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; foreach &ndash;parallel ($computer in $computers){<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; InlineScript {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get-WmiObject &ndash;Class Win32_OperatingSystem &ndash;ComputerName $using:computer |<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Format-List<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}&nbsp;\nOther cmdlets that haven&rsquo;t been turned into workflow activities are shown in the following table. You can use them in InlineScript blocks.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"370\">  <strong>Unsupported cmdlet (group)<\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p><strong>Reason<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>*Alias, *FormatData, *History, *Location, *PSDrive, *Transcript, *TypeDate, *Variable, Connect\/Disconnect-Wsman<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>Only change Windows PowerShell session so not needed in workflow<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>Show-Command, Show-ControlPanelItem, Get-Credential, Show-EventLog, Out-Gridview, Read-Host, Debug-Process<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>Workflows don&rsquo;t support interactive cmdlets<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>*BreakPoint, Get-PSCallStack, Set-PSDebug<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>Workflows don&rsquo;t support script debugging<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>*Transaction<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>Workflows don&rsquo;t support transactions<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>Format*<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>No formatting support<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>*PSsession, *PSsessionoption<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>Remoting controlled by workflow<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"370\">\n<p>Export-Console,Get-ControlPanelItem, Out-Default, Out-Null, Write-Host, Export-ModuleMember, Add-PSSnapin, Get-PSSnapin, Remove-PSSnapin, Trace-Command<\/p>\n<\/td>\n<td valign=\"top\" width=\"231\">\n<p>&nbsp;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;\nThere are a number of cmdlets that are local execution only in workflows.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"150\">  <strong>Add-Member&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p><strong>Compare-Object&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p><strong>ConvertFrom-Csv&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p><strong>ConvertFrom-Json&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>ConvertFrom-StringData&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Convert-Path&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>ConvertTo-Csv&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>ConvertTo-Html&nbsp;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>ConvertTo-Json&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>ConvertTo-Xml&nbsp;&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>ForEach-Object&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>Get-Host<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>Get-Member&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Get-Random&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>Get-Unique&nbsp;&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>Group-Object&nbsp;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>Measure-Command&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Measure-Object<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>New-PSSessionOption&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>New-PSTransportOption&nbsp;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>New-TimeSpan&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Out-Default&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>Out-Host&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>Out-Null<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>Out-String<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Select-Object&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>Sort-Object&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>Update-List&nbsp;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>Where-Object&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Write-Debug&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>Write-Error&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>Write-Host&nbsp;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"150\">\n<p>Write-Output&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"129\">\n<p>Write-Progress&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"159\">\n<p>Write-Verbose&nbsp;<\/p>\n<\/td>\n<td valign=\"top\" width=\"186\">\n<p>&nbsp;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;\nIf you want to use them remotely&mdash;you&rsquo;ve guessed it&mdash;use an InlineScript.\nYou can find out more about workflow restrictions in the Help files:<\/p>\n<p style=\"padding-left: 30px\">about_ActivityCommonParameters<\/p>\n<p style=\"padding-left: 30px\">about_Checkpoint-Workflow<\/p>\n<p style=\"padding-left: 30px\">about_Foreach-Parallel<\/p>\n<p style=\"padding-left: 30px\">about_InlineScript<\/p>\n<p style=\"padding-left: 30px\">about_Parallel<\/p>\n<p style=\"padding-left: 30px\">about_Sequence<\/p>\n<p style=\"padding-left: 30px\">about_Suspend-Workflow<\/p>\n<p style=\"padding-left: 30px\">about_WorkflowCommonParameters<\/p>\n<p style=\"padding-left: 30px\">about_Workflows\nYou may not see them when you first load Windows PowerShell. Import the <strong>PSWorkflow<\/strong> module and they will become visible.\nI&rsquo;ve tried to cover the restrictions you will face when using workflows. As I said in the first article in the series, <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2012\/12\/26\/powershell-workflows-the-basics.aspx\" target=\"_blank\">PowerShell Workflows: The Basics<\/a>, if you don&rsquo;t understand the restrictions they will trip you up.\nNext time, we&rsquo;ll look at nesting workflows and using Windows PowerShell functions with workflows.\n~Richard\nThank you, Richard, for another great article. Join 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.\n<strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary:&nbsp;Windows PowerShell MVP Richard Siddaway talks about restrictions on Windows PowerShell workflows. Microsoft Scripting Guy, Ed Wilson, is here. Today, we have the second in a series of guest blog posts written by Windows PowerShell MVP Richard Siddaway dealing with Windows PowerShell workflow. Note &nbsp;&nbsp;The first article,&nbsp;PowerShell Workflows: The Basics, introduced the basic concepts of [&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,4,45,382],"class_list":["post-4386","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-richard-siddaway","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-workflow"],"acf":[],"blog_post_summary":"<p>Summary:&nbsp;Windows PowerShell MVP Richard Siddaway talks about restrictions on Windows PowerShell workflows. Microsoft Scripting Guy, Ed Wilson, is here. Today, we have the second in a series of guest blog posts written by Windows PowerShell MVP Richard Siddaway dealing with Windows PowerShell workflow. Note &nbsp;&nbsp;The first article,&nbsp;PowerShell Workflows: The Basics, introduced the basic concepts of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4386","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=4386"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4386\/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=4386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}