How do I determine if a PowerShell Cmdlet parameter value was specified?
-
05-07-2019 - |
Question
In PowerShell 1.0, if I have a cmdlet parameter of an enum type, what is the recommended method for testing whether the user specified that parameter on the cmdlet command line? For example:
MyEnum : int { No = 0, Yes = 1, MaybeSo = 2 }
class DoSomethingCommand : PSCmdlet
...
private MyEnum isEnabled;
[Parameter(Mandatory = false)]
public MyEnum IsEnabled
{
get { return isEnabled; }
set { isEnabled = value; }
}
protected override void ProcessRecord()
{
// How do I know if the user passed -IsEnabled <value> to the cmdlet?
}
Is there any way to do this without having to seed isEnabled with a dummy value? By default it will equal 0, and I don't want to have to seed every parameter or add a dummy value to my enum. I've potentially got many cmdlets with 100's of parameters, there's got to be a better way. This is related to this question but I was looking for a cleaner way of doing this. Thanks.
Solution
In this case, I would use a nullable wrapper around the enum type e.g.
[Parameter(Mandatory = false)]
public MyEnum? IsEnabled { get; set; }
Note the ? modifier on MyEnum. Then you can test if it is set like so:
if (this.IsEnabled.HasValue) { ... }
OTHER TIPS
PowerShell aside, it's never good style to use 0 in that way. You should always use 0 for the most appropriate default. In this case, the most appropriate default should be something like "Unset."
Ultimately, this is nothing to do with PowerShell and everything to do with good coding practices for .NET.
- Oisin
As an option you can use $PSBoundParameters
collection to check whether passed to the method.
Let’s suppose we have a json file like following { "p1": "value1", "p2": "value2" }
and we want to create a function which accepts parameter p1
and p2
and update value of p1
and p2
in the file, if they are passed to the function. Let's say those values can be null
and and having those values as null is not equivalent to not passing them.
For example Update-Values -p1 $null
should update p1
to null
and should not change p2
.
To do so, we should be able to detect if the parameter has been passed to the method or not.
Example - How to detect if a parameter is passed, for an optional parameter which can accept null as value?
Function Update-Values ($p1, $p2) {
If($PSBoundParameters.ContainsKey("p1")) {
Write-Host "p1 passed"
}
else {
Write-Host "p1 not passed"
}
If($PSBoundParameters.ContainsKey("p2")) {
Write-Host "p2 passed"
}
else {
Write-Host "p2 not passed"
}
}
Then if you run the function using the following parameter:
Update-Values -p1 $null
# Update-Values -p1 "something"
As a result you will see:
p1 passed
p2 not passed
You can read the blog post here: How to determine if a parameter is passed to a Powershell Cmdlet.
Only thing I can see is to modify your enum so that value 0 is named Unknown or something like that.
Problem is that enums are just integers in background and integers are value types. Unfortunate consequence is that they need to have value and that value is 0 by default.
I know this thread is a little old now, but the best way to do this is to declare your parameter using the SwitchParameter type. Then your users don't have to pass -IsEnabled , they would just add something like -Enabled as a parameter.
You then test the .IsPresent property of your parameter to see if the caller added -Enabled to the call to the cmdlet.
bool wasSpecified = MyInvocation.BoundParameters.ContainsKey("IsEnabled");