mrbin
mrbin

Reputation: 355

How to use named parameters with unnamed parameters in PowerShell script?

I have this script init.ps1

param($s)
write-host $s
write-host $args

...

The idea is that, when I invoke init.ps1 service up, $s would be empty, and $args would be service up.

But when I do that, I got $s as service, $args as $up.

I intend $s to be used like init.ps1 service up -s auth to start the auth service only, for example.

Any idea how to fix this?

Upvotes: 3

Views: 4986

Answers (1)

Sage Pourpre
Sage Pourpre

Reputation: 10333

This is the intended behavior.

Some things to keep in mind:

  • $args will contains all the arguments passed down to your scripts.
  • If using named parameter (eg: $s in your case), then $args will contains any remaining parameters not bound to anything else.
  • Parameters delimiter is the space.

Based on that, what you have as result is what is expected. In init.ps1 service up, you have the script, then 2 parameters (space is the delimiter here, remember). Service get passed down as a positional parameter to the first one available $s. You did not define a second parameter in your script so the remaining argument up get passed down to the default handler $args, which contains the remaining parameter.

What you want is something more like this:

[CmdletBinding()]
param (
    $s,
    $state
)

# Do what you need
Write-Host $s -ForegroundColor Cyan 
Write-Host $state -ForegroundColor Green

From there, you'd invoke it like that:

& "C:\Path\to\YourScript.ps1" -s auth -state "Service Up" or, positionally & "C:\Path\to\YourScript.ps1" auth "Service Up"

Note: You don't have to specify the [CmdletBinding()] part but it will allow you to pass down common parameters such as -Verbose, -ErrorAction, etc...

About $Args

Contains an array of values for undeclared parameters that are passed to a function, script, or script block. When you create a function, you can declare the parameters by using the param keyword or by adding a comma-separated list of parameters in parentheses after the function name.

In an event action, the $args variable contains objects that represent the event arguments of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the SourceArgs property of the PSEventArgs object that Get-Event returns.

Note: $Args is an automatic variable. There's a couple of them in Powershell that you should be aware of. They can prove useful and knowing of them will prevent you from trying to use them for other purposes (this would have unintended effects)

Reference: about_Automatic_Variables

Upvotes: 6

Related Questions