{"id":12641,"date":"2011-09-20T00:01:00","date_gmt":"2011-09-20T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/09\/20\/solve-problems-with-external-command-lines-in-powershell\/"},"modified":"2011-09-20T00:01:00","modified_gmt":"2011-09-20T00:01:00","slug":"solve-problems-with-external-command-lines-in-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/solve-problems-with-external-command-lines-in-powershell\/","title":{"rendered":"Solve Problems with External Command Lines in PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy Ed Wilson discusses problems creating external command arguments using Windows PowerShell.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hey, Scripting Guy! I am using an external program that takes a <i>&ndash;o<\/i> command-line parameter followed by a path location. The program permits no space between the <i>&ndash;o<\/i> parameter and the supplied path. For example, Windows PowerShell sees an unclosed quote when I type the following command:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;.\\7za.exe x -o&#8221;C:\\TARGET\\P F&#8221; C:\\TEMP\\ProgramFiles.zip<\/p>\n<p>I need to escape the second (but not the first) double-quote for Windows PowerShell to parse the line correctly. Here is the revised command, with the escape character marked in yellow:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;.\\7za.exe x -o&#8221;C:\\TARGET\\P F`&#8221; C:\\TEMP\\ProgramFiles.zip<\/p>\n<p>This command looks strange, and I&rsquo;m confused as to why this is.&nbsp;<\/p>\n<p>&mdash;AM<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\" \/>Hello AM,<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. One of the things I do not enjoy about Windows PowerShell is the problem inherent in attempting to create a workable command line for complex external utilities. On occasion, I have spent several hours attempting to derive a workable command line for a single program. It is not just a Windows PowerShell problem; I have spent several hours attempting to figure out acceptable syntax for command-line utilities in the old command-prompt days as well. A quick survey of some of my friends reveals it is not just me.<\/p>\n<p>Windows PowerShell exacerbates the problem of command-line argument parsing because Windows PowerShell has its own syntax parser that must run before it passes control over to the external program.<\/p>\n<p>One thing to keep in mind is that external programs, such as 7-Zip can define their own rules for parsing arguments &ndash; and this includes their own quoting rules and escape characters. (In fact, 7-Zip defines its own rules for interpreting wildcard characters as well.) To make matters worse, at times we expect Windows PowerShell to execute commands, parse Windows PowerShell paths, update variables, and a host of other things before actually passing the resulting hodgepodge to the external utility for parsing.<\/p>\n<p>Not all is lost. A couple of things can help make sense on the Windows PowerShell side. One of my favorite tools comes with the PowerShell Community Extension Project (PSCX). I have written several times about the PSCX, and recently, I helped the Scripting Wife add the command to import the PSCX into her Windows PowerShell profile. One tool from that project that is useful to me when dealing with complex command lines is the EchoArgs.exe program. When the PSCX is installed, the installer copies the EchoArgs.exe utility to the installation directory. The tool is extremely easy to use. A quick example illustrates how to use EchoArgs.exe to see how Windows PowerShell will parse a command line.<\/p>\n<p>Suppose I want to use the nbtstat.exe program, but I am not sure how Windows PowerShell will parse the command line, and determine the arguments and the values supplied to the arguments to the command. The command line is shown here:<\/p>\n<p style=\"padding-left: 30px\">nbtstat -S 2<\/p>\n<p>To use the EchoArgs.exe program, I simply copy the arguments from the command line and paste them after the EchoArgs program. This is shown here, along with the associated output:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; EchoArgs.exe -S 2<\/p>\n<p style=\"padding-left: 30px\">Arg 0 is &lt;-S&gt;<\/p>\n<p style=\"padding-left: 30px\">Arg 1 is &lt;2&gt;<\/p>\n<p>In the preceding example, it is clear that Windows PowerShell sees the first argument as <b>&ndash;S<\/b> and the second argument as <b>2<\/b>.<\/p>\n<p>If I have the situation when a value needs to be calculated and I am not certain how Windows PowerShell will handle the argument, I can use EchoArgs to demystify the command line as well. This is shown here where I assign a value of <b>5<\/b> to the <b>$a<\/b> variable, and then perform a calculation to compute the value I wish to pass to the <b>&ndash;S<\/b> argument:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a = 5<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; EchoArgs.exe -S ($a-3)<\/p>\n<p style=\"padding-left: 30px\">Arg 0 is &lt;-S&gt;<\/p>\n<p style=\"padding-left: 30px\">Arg 1 is &lt;2&gt;<\/p>\n<p>Based upon the preceding, I feel confident that the following command would work (and it does):<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a = 5<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; nbtstat -S ($a-3)<\/p>\n<p>AM, the figure that follows illustrates using the EchoArgs utility to parse the arguments from the command line you supplied.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1754.hsg-9-20-11-01.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of using EchoArgs to parse arguments from command line\" alt=\"Image of using EchoArgs to parse arguments from command line\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1754.hsg-9-20-11-01.png\" \/><\/a><\/p>\n<p>As you can see, the EchoArgs utility is pretty slick and easy to use. Another way to see how Windows PowerShell will parse a command line is to ask it. That is right&mdash;by using the Windows PowerShell tokenizer (I wrote <a href=\"http:\/\/blogs.technet.com\/search\/searchresults.aspx?q=tokenizer&amp;sections=7618\">several articles about using the tokenizer<\/a>), it is possible to see exactly how Windows PowerShell will interpret a command line.<\/p>\n<p>To begin with, I will parse the same easy <b>nbtstat<\/b><i> <\/i>command I used with the EchoArgs utility. This will allow for a comparison between the two methods. The following command uses the <b>tokenize<\/b><i> <\/i>static method from the <b>psparser<\/b><i> <\/i>.NET Framework class. The first parameter is the command to parse. The <b>[ref]$null<\/b> is a requirement of the Tokenize command.<\/p>\n<p style=\"padding-left: 30px\">[management.automation.psparser]::Tokenize(&#8216;nbtstat -S 3&#8217;, [ref]$null)<\/p>\n<p>The command and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7457.hsg-9-20-11-02.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7457.hsg-9-20-11-02.png\" \/><\/a><\/p>\n<p>The output from the <b>tokenize<\/b> static method is rather extensive. The good thing is that it breaks everything into its role within the command&mdash;and not simply <b>arg 0<\/b> and <b>arg 1<\/b> as returned from the EchoArgs utility. The downside is that it is a bit more typing.<\/p>\n<p>But wait! This is Windows PowerShell, and a quick function can save lots of typing. I created the <b>Get-Args<\/b> function to make it easy to use the <b>tokenize<\/b> static method. The complete <b>Get-Args<\/b> function is shown here:<\/p>\n<p style=\"padding-left: 30px\">Function Get-Args<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$command<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[management.automation.psparser]::Tokenize($command,[ref]$null)<\/p>\n<p style=\"padding-left: 30px\">} #end function Get-Args<\/p>\n<p>To use the <b>Get-Args<\/b> function, I run the function to load it into memory, and then I supply the command line to the function. This technique is shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3652.hsg-9-20-11-03.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of running function and supplying command line to function\" alt=\"Image of running function and supplying command line to function\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3652.hsg-9-20-11-03.png\" \/><\/a><\/p>\n<p>When I call the function, I pass the entire command inside of literal quotation marks. The output is the same as the output received earlier when I used the <b>tokenize<\/b> method directly. The command and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2275.hsg-9-20-11-04.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of command and associated output\" alt=\"Image of command and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2275.hsg-9-20-11-04.png\" \/><\/a><\/p>\n<p>One cool thing is that I can parse your original command line, the one that was interpreted as incomplete, by using this method. As shown in the following figure, the <b>Get-Args<\/b> function easily parses the command. The other thing I like about this method is that I do not have to separate the arguments from the command. I simply copy the entire line.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2117.hsg-9-20-11-05.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of Get-Args function easily parsing command\" alt=\"Image of Get-Args function easily parsing command\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2117.hsg-9-20-11-05.png\" \/><\/a><\/p>\n<p>Well, AM, I hope this discussion helps you solve the mystery of the funky command line. I invite you to join me tomorrow for more cool Windows PowerShell stuff.<\/p>\n<p>&nbsp;<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto: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><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy Ed Wilson discusses problems creating external command arguments using Windows PowerShell. &nbsp; Hey, Scripting Guy! I am using an external program that takes a &ndash;o command-line parameter followed by a path location. The program permits no space between the &ndash;o parameter and the supplied path. For example, Windows PowerShell sees an [&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":[2,3,4,45],"class_list":["post-12641","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-running","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy Ed Wilson discusses problems creating external command arguments using Windows PowerShell. &nbsp; Hey, Scripting Guy! I am using an external program that takes a &ndash;o command-line parameter followed by a path location. The program permits no space between the &ndash;o parameter and the supplied path. For example, Windows PowerShell sees an [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12641","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=12641"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12641\/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=12641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}