Solved

Why is this messing up my parameter set?

Posted on 2015-01-04
5
130 Views
Last Modified: 2015-01-05
I hate to ask yet another question involving Powershell parametersets but I can't figure out why something is breaking my code. Take a look at this code:

[CmdletBinding(SupportsShouldProcess=$TRUE)]
Param(
    [parameter(ValueFromPipeline=$TRUE)]
    $ComputerName=[System.Net.Dns]::GetHostName(),
    $group="Administrators",
  [parameter(Mandatory=$true,ParameterSetName="add")]
    [System.Security.SecureString] $Password,
    [parameter(Mandatory=$true,ParameterSetName="add")]
     $add,
  [parameter(Mandatory=$true,ParameterSetName="delete")]
  [Parameter(ParameterSetName="add")]
   $delete
)

Write-Output "Delete: $Delete"
Write-Output "Add: $Add"

This is a shorter piece of code to help figure out the problem with a much longer powershell script. Anyway the code works IF I don't pass anything in the pipeline just to the "delete" parameter. So the following all work:

.\TestExchange.ps1 -add testUser
.\TestExchange.ps1 -delete testUser
Get-Content .\ComputerList.txt | .\TestExchange.ps1 -add testUser
Get-Content .\ComputerList.txt | .\TestExchange.ps1 -add testUser -delete testUser2

However the following causes a problem:

Get-Content .\ComputerList.txt | .\TestExchange.ps1 -delete testUser

When I do this I am inexplicably prompted for both the "password" parameter and the "add" parameter.  When I simply pass the "delete" parameter I should NOT be prompted for the "password" and "add" parameters (the "password" parameter should only prompt if I pass the "Add" parameter).  "ComputerList.txt" simply contains a string of a single computer BTW.

Can anyone explain why this is happening? I don't understand why passing the "delete" parameter works by itself, but if I use the pipeline in front of it it suddenly thinks I want to use the "add" parameterset instead of the "delete" parameterset.

Any help is much appreciated.
0
Comment
Question by:rsts_support
5 Comments
 
LVL 16

Accepted Solution

by:
DansDadUK earned 250 total points
ID: 40531142
I know very little about Powershell, but it seems that your definition does not satisfy the rule that "Each parameter set must have at least one unique parameter. If possible, make this parameter a mandatory parameter".

i.e. parameter set 'add' has parameters:
computername (mandatory?)
password (mandatory)
$add (mandatory)
$delete (optional)

and parameter set 'delete' has parameters:
computername (mandatory?)
$delete (mandatory)
0
 
LVL 40

Expert Comment

by:Subsun
ID: 40531493
Here you have defined the Delete parameter under the ParameterSetName 'add'

[parameter(Mandatory=$true,ParameterSetName="delete")]
 [Parameter(ParameterSetName="add")]
  $delete


Try to remove [Parameter(ParameterSetName="add")]

[parameter(Mandatory=$true,ParameterSetName="delete")]
$delete
0
 
LVL 16

Expert Comment

by:DansDadUK
ID: 40531603
Try to remove ...

Which will mean that the two parameter sets then each have at least one unique parameter.
0
 
LVL 39

Assisted Solution

by:footech
footech earned 250 total points
ID: 40531882
I know from your previous question that one of your goals is to require that at least one at least one of the parameters (-add or -delete) be specified.

What seems to be happening is that when processing the pipeline input, it is determining that the matching parameter set is "add".  I can't say why exactly this is.

You may be coming up against some limitations with what you can do with parameter restrictions.  You may be better off doing some checks on variables at the start of the script to handle the various combinations.

However, one solution that seems to work is to follow the guidance which DansDadUK posted, which is to make sure that you have at least one unique parameter for each set.  For example:
[CmdletBinding(SupportsShouldProcess=$TRUE)]
 Param(
     [parameter(ValueFromPipeline=$TRUE)]
     $ComputerName=[System.Net.Dns]::GetHostName(),
     $group="Administrators",
   [parameter(Mandatory=$true,ParameterSetName="add")]
     [System.Security.SecureString] $Password,
     [parameter(Mandatory=$true,ParameterSetName="add")]
      $add,
   [parameter(Mandatory=$true,ParameterSetName="delete")]
   [Parameter(ParameterSetName="add")]
    $delete,
    [parameter(Mandatory=$true,ParameterSetName="delete")]
    [switch]$confirmd
 )

 Write-Output "Delete: $Delete"
 Write-Output "Add: $Add"

Open in new window

When you want to use the -delete parameter without the -add parameter, you need to specify the -confirmd parameter.

In some scenarios, specify a default parameter set can also work.
[CmdletBinding(SupportsShouldProcess=$TRUE, DefaultParameterSetName = "delete")]

Open in new window

0
 

Author Closing Comment

by:rsts_support
ID: 40532051
Thanks guys. I will use a default parameter set for now (or possibly adding an optional parameter to "Delete" that essentially will not be used but will give the parameters set a unique parameter).

I must say that Powershell parameter's are at the very least very awkward to use.  If I run into any other issues with them I will probably just chuck the lot and resort to variables with if/then statements. Thanks for your help.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This script checks a path to see if a folder exists. If the folder does exist you will get output "The folder has previously been created. No action taken" If not it will create the folder. Then adds one user modify permission to the folder. It …
Set OWA language and time zone in Exchange for individuals, all users or per database.
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now