Guidelines

This site is for tech Q&A. Please keep your posts focused on the subject at hand.

Ask one question at a time. Don't conflate multiple problems into a single question.

Make sure to include all relevant information in your posts. Try to avoid linking to external sites.

Links to documentation are fine, but in addition you should also quote the relevant parts in your posts.

0 votes
243 views
243 views

I have a Hyper-V test environment on my work PC where I use a small PowerShell function for quickly creating new VMs from exported ones that I use as templates. But when I added a switch statement to the function in order to enhance template selection I discovered that PowerShell ignores the switch statement completely.

By stripping down the function I found out that the problem arises from a parameter named $Switch (for attaching the new VM to a virtual switch).

Demonstration:

function foo {
  Param(
    [String] $Switch
  )

  'start'
  switch ($true) {
    default { 'should display' }
  }
  'end'
}

Invoking the above function (with or without argument) produces the following output:

start
end

when it should produce:

start
should display
end

Renaming the parameter resolves the issue, so I'm going to do that, but even so I'd like to understand what is going wrong here.

in Scripting
edited by
by (115)
2 18 33
edit history

Please log in or register to answer this question.

1 Answer

0 votes
 

You experience this issue because $Switch is actually one of PowerShell's automatic variables. Getting weird behavior from using the names of automatic variables for parameters is a common PowerShell gotcha.

From about_Switch:

The switch statement can use the $_ and $switch automatic variables. For more information, see about_Automatic_Variables.

and from about_Automatic_Variables:

$switch
Contains the enumerator not the resulting values of a Switch statement. The $switch variable exists only while the Switch statement is running; it's deleted when the switch statement completes execution. For more information, see about_Switch.

The solution to this problem is to avoid using automatic variable names for parameters. Rename the parameter (e.g. to $VSwitch) and the problem will disappear. Optionally you can define an alias for the parameter

function foo {
  Param(
    [Alias('Switch')]
    [String] $VSwitch
  )
  #...
}

so that you retain the ability to invoke the function like this

foo -Switch 'something'

That would save you the trouble of having to refactor all code that uses the function.


edited by
by (115)
2 18 33
edit history
...