- Settings:
Page
Normal
Plain layout without fancy styles
Font
Normal
Large fonts
Very large fonts
Colour
Normal
Restful colour scheme
Light text on a dark background

Note: user account creation on this site has been disabled.

Programming, speculative fiction, science, technology
Powered by Drupal, an open source content management system
Scope
Include Children
If you select a term with children (sub-terms), do you want those child terms automatically included in the search? This requires that "Items containing" be "any."
Categories

Everything in the Events vocabulary

"Events" is used for: Convention Post, Page, Story.

People mentioned in the articles

"People" is used for: Page, Convention Post, Story.

Themes mentioned in the article

"Themes" is used for: Page, Convention Post, Story.
Skip to top of page

Powershell scripts and command line arguments, with a sprinkling of Splunk

Passing arguments to a Powershell script caused me to pull my hair out... umm, scratch my head, lately. As with most technical problems, it appeared chaotic and intractable at first, and drew me into a black hole of spiraling confusion, where bugs mask other bugs; however, once I found a solution and tried to explain it to myself step-by-step, everything appeared orderly, even trivial. So now I don't even know why I'm writing this down. Actually, I do. It's so as not to go into the same black hole when I have to figure it again months or years from now.

It's easy to pass arguments to a Powershell script if you call it from the Powershell shell (pardon my inelegant expression). That's just

PS >./myScript "MyArgument"

What is more complicated is how to pass the arguments when invoking Powershell from DOS command shell, i.e. from cmd.exe window.

Suppose my script myScript.ps1 is in the folder C:\Users\elze\Documents\MyScripts\myScript.ps1"

I would invoke it as

powershell.exe -command "& C:\Users\elze\Documents\MyScripts\myScript.ps1"

where "&" is the command call operator.

Let's try to use Windows environmental variable %userprofile%, which, in my case, is C:\Users\elze.

powershell.exe -command "& %userprofile%\Documents\MyScripts\myScript.ps1"

It works.

Let's say myScript.ps1 is like this:


param(
[string]$myArg
)

Write-Host $myArg

"My Output" | out-file $myArg -encoding UTF8

$myArg is an output file name. When we pass it to the script, we need to pass the whole path to it, otherwise Powershell will assume it is in the working directory, and the working directory may or may not be where our output file is located. Let's say the output file, outputFile.txt is in the same directory as myScript.ps1. If cmd.exe was not invoked from this directory, the working directory will be something else.

How do you pass arguments to myScript.ps1 from DOS command line?

Apparently, the straightforward way

powershell.exe -command "& %userprofile%\Documents\MyScripts\myScript.ps1 -myArg %userprofile%\Documents\MyScripts\outputFile.txt"

works.

What if we have a space in the path? There is a good article on what to do about it (how to escape directory names and environmental variables) at http://www.tinyint.com/index.php/2011/04/20/escaping-quotes-in-powershel... .

Let's put our script in a folder called "Test Space". Clearly, the paths on the command line will have to be enclosed in quotes, otherwise they will be cut off after the space. Turns out, single quotes are enough, and Windows environmental variables still get expanded even when enclosed in single quotes:

powershell.exe -command "& '%userprofile%\Documents\MyScripts\Test Space\myScript.ps1' -myArg '%userprofile%\Documents\MyScripts\Test Space\outputFile.txt'"

still works.

Not so much when we use Powershell-style environmental variables, i.e. $env::

powershell.exe -command "& '$env:userprofile\Documents\MyScripts\Test Space\myScript.ps1' -myArg '$env:userprofile\Documents\MyScripts\Test Space\output.txt'"

We'll get an error "The term $env:userprofile\Documents\MyScripts\myScript.ps1 is not recognizeable as a script, cmdlet, etc."

In other words, $env:userprofile did not get expanded. To expand it, we would probably need to do what TinyInt suggested. (If, however, we didn't put single quotes around the script and argument paths, the $env: variables would get expanded just fine.)

An interesting, and relevant to me, use case was when this Powershell command was invoked by Splunk Forwarder. The scripts invoked by Splunk Forwarder are stored in directories in $SPLUNK_HOME path (e.g. C:\Program Files\SplunkUniversalForwarder). $SPLUNK_HOME is not a Windows environmental variable; apparently it's a Splunk environmental variable. The commands Splunk uses to invoke scripts are stored in files with extension .path. It looks for all the world like a DOS shell command, only it can also have Splunk environmental variables in it, such as $SPLUNK_HOME. My guess is that Splunk Forwarder expands its environmental variables before it executes the command. So, for example, this works:

powershell.exe -command "& '$SPLUNK_HOME\bin\scripts\myScript.ps1' -myArg '$SPLUNK_HOME\bin\scripts\inputFile.txt'"

The single quotes that enclose the paths don't keep $SPLUNK_HOME from getting expanded. And they also serve to enclose a directory name with the space in it (such as Program Files).