Here is the code that demonstrates the problem. The cmdlet Set-Location
has
the dynamic switch ReadOnly
if the provider is FileSystem
.
# provider that does not have the dynamic -ReadOnly
Set-Location env:
# case 1: works because we explicitly specify FileSystem
Get-ChildItem C:\ -ReadOnly
# case 2: fails even though we explicitly specify FileSystem
Get-ChildItem -ReadOnly C:\
Normally position of a switch parameter in a command does not matter. This not the case for a dynamic switch. The case 2 fails with the error:
Get-ChildItem : A parameter cannot be found that matches parameter name 'ReadOnly'.
What happens? I think that at the moment of dynamic parameters creation it is
not yet known that ReadOnly
is the switch. Thus, PowerShell treats it as a
regular parameter with its argument C:\
and C:\
therefore is not treated as
a positional parameter. As a result, Get-ChildItem
thinks that the location
is not specified and uses the current env:
. The provider Environment
does
not provide the dynamic switch ReadOnly
, so that finally the command fails
due to incorrect syntax, even though it is somewhat correct (the same command
works if the current provider is FileSystem
).
Questions:
- Is my understanding of the problem correct?
- Is this feature documented somewhere?
- Is there any workaround?
The last question is more about user commands being developed with dynamic parameters. The problem originally was noticed and described as Invoke-Build Issue #4. For the moment this issue is just documented. But I am still interested in workarounds.
Conclusions
- The described problem exists.
- It is not documented as such.
- Ways to work around, each solves the problem:
- Specify dynamic switches after positional parameter arguments
- Do not use positional parameters together with dynamic switches, i.e. specify parameter names.
- UPDATE: Not working anymore in latest PS v5.1+ (Specify dynamic switch arguments explicitly:
-ReadOnly:$true
)
Opened the bug: 960194