Passing arguments to nested functions or cmdlets

Last week I posted a function that could be used to  invoke a cmdlet using the fully qualified name (which consists of the name of the PSSnapin followed by a backslash and then the cmdlet name).  This function can be useful when you want to wrap a cmdlet with a function of the same name so that you can do some additional work when that cmdlet is used in a script.

In a script I have been working on, that function has come in very handy however I found a problem with the original function that I posted: it wasn’t properly passing parameters of type array to the cmdlet being invoked.  Fortunately a little work with the debugger that is included in the upcoming release of the PowerGUI Script Editor helped me find the error.  As a result of this debugging session I have come up with three rules that I will follow in the future when passing arguments from one function to another:

  1. When you want to pass the contents of $args on to another function or cmdlet, copy it to another variable and pass the values from there instead.
  2. Leave variables containing values as variables when passing them on to another function or cmdlet.
  3. Be sure to evaluate parameter names in the $args variable (or its copy) before passing them to another function or cmdlet so that the values are assigned to parameters by name, if appropriate.

Here’s a simple, festive example that shows how you would go about doing this while following these rules:

$v1 = “Joy”
$v2 = [string[]]@(‘to’,‘the’)
$v3 = “world”

function one {
   
$args | Out-Host
   
Invoke-Expression “two $($passThruArgs = $args; for ($i = 0; $i -lt $passThruArgs.Count; $i++) { if ($passThruArgs[$i] -match ‘^-‘) { $passThruArgs[$i] } else { `”`$passThruArgs[$i]`” } })”
}
function two {
   
$args | Out-Host
}one -firstWord $v1 -middlePart $v2 -lastWord $v3

All this code does is invoke function one passing a bunch of arguments.  Function one simply passes those arguments directly on to function two without any modification to them.  You can see this in the line that starts with the Invoke-Expression cmdlet.

The post I refered to earlier has been updated with a corrected Invoke-Cmdlet function that follows these rules as well.

Kirk out.

Technorati Tags: , , ,

Advertisements

2 thoughts on “Passing arguments to nested functions or cmdlets

  1. $query = @’
    #
    # select address, typeid, name from list
    # where active = 1
    # and master = 1
    # and unitid = $unitid order by name
    # ‘@

    will not properly evaluate $unitid. But if I make this a one line command like below, $unitid is properly evaluated. Is there a powershell limitation when using @’ and ‘@ ?

    $qresults = invoke-sql -Query “select address, typeid, name from porchlightlist where active = 1 and master = 1 and unitid = $unitid order by name “

    Like

    1. You need to use a double-quoted here string, not a single-quoted here-string. In PowerShell, double-quotes signifies that the string contains content that will be evaluated, while single-quotes signifies that it does not contain content that should be evaluated. If you change @’ and ‘@ to @” and “@ in your script, your $unitid value will be evaluated and the result will be placed in the string you are creating.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s