Parameter Binding with Advanced Functions
-
Friday, January 18, 2013 3:15 PM
I have a function that I want to perform 3 different tasks. Each task is exclusive such that none of the three should be allowed to run in conjunction with the others. Here are the tasks:
- Create a key
- Read a specific key from a text file
- Read the first key from a text file (default behavior) - this should run when no arguments are present.
Here's a code snippet that I've written:
Param ( [CmdletBinding(DefaultParameterSetName="Fake")] [Parameter( ParameterSetName="ReadKey" )] [ValidateScript({$_ -ge -1})] [int] $ReadKey, [Parameter( ParameterSetName="CreateKey" )] [ValidateScript({$_ -gt 14})] [int] $CreateKey ) if ($CreateKey) { # Algorthm to create keys # Creates a key of length $CreateKey } elseif ($ReadKey) { # Gets a specific key $keyList = Get-Content keys.txt $keyList[$ReadKey] } else { # Gets the first key $keyList = Get-Content keys.txt $keyList[0] }NOTE: The Fake default parameter set name is an idea that came from: http://blogs.msdn.com/b/mediaandmicrocode/archive/2009/04/10/microcode-powershell-scripting-trick-fun-with-parameter-binding-the-fake-parameter-set-trick.aspx It did not fix the problem (obviously). Using the real parameter set names likewise did not fix the problem.
Problem: PowerShell keeps complaining that the parameter sets are ambiguous. I certainly understand why, but I don't know how to get the desired behavior. Ideas?
I feel like there's something obvious that I'm overlooking...
I'm the most humble person you've ever met.
- Edited by James Keeler Friday, January 18, 2013 3:18 PM Correct title
All Replies
-
Friday, January 18, 2013 3:40 PM
Here is the way I want it to work from the command line:
.\getKey.ps1 Returns the first key in keys.txt .\getKey.ps1 -ReadKey 5 Returns the sixth key in keys.txt .\getKey.ps1 -CreateKey 25 Creates a new key that is 25 characters long and adds it to keys.txt
As you can see, it makes no sense to allow someone to type .\getKey.ps1 -ReadKey 5 -CreateKey 25. It also makes complete sense that the default action would be to return the first key from the file.
I'm the most humble person you've ever met.
-
Friday, January 18, 2013 3:59 PM
I solved it. The following code performs as desired:
Param ( [ValidateScript({$_ -ge -1})] [int] $ReadKey, [ValidateScript({$_ -gt 14})] [int] $CreateKey ) if ($PSBoundParameters.ContainsKey('CreateKey') -and $PSBoundParameters.ContainsKey('ReadKey')) { throw "Invalid parameters." } elseif ($PSBoundParameters.ContainsKey('CreateKey')) { # Algorthm to create keys # Creates a key of length $CreateKey } elseif ($PSBoundParameters.ContainsKey('ReadKey')) { # Gets a specific key $keyList = Get-Content keys.txt $keyList[$ReadKey] } else { # Gets the first key $keyList = Get-Content keys.txt $keyList[0] }
I'm the most humble person you've ever met.
- Marked As Answer by James Keeler Friday, January 18, 2013 4:00 PM
-
Friday, January 18, 2013 5:55 PMModerator
I think that's a good solution and it's actually what I was going to suggest - dispense with creating parameter sets and just check which parameters are actually specified.
Bill

