Parameter Binding with Advanced Functions

Answered Parameter Binding with Advanced Functions

  • Friday, January 18, 2013 3:15 PM
     
      Has Code

    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:

    1. Create a key
    2. Read a specific key from a text file
    3. 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
     
      Has Code

    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
     
     Answered Has Code

    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 PM
    Moderator
     
     

    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