Friday, February 03, 2012

Powershell and calling commands

Some tips I gathered while working on invoking commands from Powershell. (an example would be calling iisreset from Powershell).

1. The Call (or invocation) Operator “&”

The call operator is used to run a command or even a script block. Here is an example:

$cmd = "systeminfo" #where systeminfo is a dos-command
& $cmd

2. Passing parameters to the command:

If you try:

$cmd = "ping www.google.com"
& $cmd

You will find that an error will be thrown. To pass parameters to the call-operator, you need to send them as separate strings:"

$cmd = "ping"
& $cmd "www.google.com"

In addition, if you need to pass separate arguments, each one should be sent as a separate string.

$cmd = "ping"
& $cmd "www.google.com" "-n" "2"

One nice little work-around to passing each argument as a separate quoted string is to use the split command:

$cmd = "ping"
& $cmd "www.google.com -n 2".split()

3. Use the automatic variable $LastExitCode to determine the exit code of the command you just ran using the call-operator:

It’s a contrived example, but its just so that I can illustrate how to use $LastExitCode:

$LASTEXITCODE = 0;
$cmd = "cmd.exe"
$result = & $cmd '/c copy z:\txt.txt m:\txt.txt';
Write-Host $LASTEXITCODE;
if ($LASTEXITCODE -ne 0)
{
    Write-Host "Error" -ForegroundColor DarkRed
    $result
}

In the above example, the copy command will fail and because of that the “Error” message will be printed to the screen.

4. Capturing error messages:

One problem with the above example is that, you don’t get to capture the error message reported by the copy (although it gets printed to the screen, its not in the $result object). If you want to be able to log all the error messages, you should redirect StdErr to StdOutput and this is done by appending “2>&1” to command above:

$LASTEXITCODE = 0; #reset the value of the lastexitcode. done so that you can be sure that lastexitcode was set by your call
$cmd = "cmd.exe"
$result = & $cmd '/c copy z:\txt.txt m:\txt.txt 2>&1';
Write-Host $LASTEXITCODE;
if ($LASTEXITCODE -ne 0)
{
    Write-Host "Error" -ForegroundColor DarkRed
    $result
}

Tip:

The PowerShell Community Extensions projects has a command-line tool called “EchoArgs”. It is a useful tool for the purpose of determining how powershell will pass along arguments to a command.

More Info:

Call operator: http://technet.microsoft.com/en-us/library/dd347588.aspx
LastExitCode: http://technet.microsoft.com/en-us/library/dd347675.aspx
EchoArgs: http://stackoverflow.com/questions/8905232/powershells-call-operator-syntax-and-double-quotes

No comments: