Solved

Why is this messing up my parameter set?

Posted on 2015-01-04
5
134 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Microsoft Windows Server Update Service (WSUS) is free for everyone, but it lacks of some desirable features like send an e-mail to the administrator with the status of all computers on the WSUS server. This article is based on my PowerShell script …
In this previous article (https://oddytee.wordpress.com/2016/05/05/provision-new-office-365-user-and-mailbox-from-exchange-hybrid-via-powershell/), we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
Learn the basics of modules and packages in Python. Every Python file is a module, ending in the suffix: .py: Modules are a collection of functions and variables.: Packages are a collection of modules.: Module functions and variables are accessed us…
The viewer will learn how to count occurrences of each item in an array.

863 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

21 Experts available now in Live!

Get 1:1 Help Now