Mandatory only in a specific parameterset

This topic contains 4 replies, has 4 voices, and was last updated by Profile photo of Raymond Slieff Raymond Slieff 2 years, 4 months ago.

  • Author
    Posts
  • #17418
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    Let's say I have some params like this:

    [CmdletBinding()]
    param (
    [Parameter(Mandatory)]
    [string]$Param1,
    [Parameter(Mandatory)]
    [string]$Param2,
    [Parameter(ParameterSetName = 'Set1',
    [switch]$Param3,
    [Parameter(ParameterSetName = 'Set1',
    Mandatory)]
    [string]$Param4
    )
    

    I'm forced to set params $Param1 and $Param2 always which I understand. However, I want to make the $Param4 only mandatory if I've used the $Param3 switch param. Is this possible? I'm trying this and finding that if I use Mandatory on the $Param4 switch, it's enforcing this all the time regardless of which params I choose. Am I going to have to go to dynamic params for this?

  • #17419
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The main problem with your example is that you haven't defined a default parameter set, and PowerShell sometimes get confused there. If you add DefaultParameterSetName = 'AnyStringOtherThanSet1' to your CmdletBinding attribute, it'll work as you expect. Though there may not be any point in having a $Param3 switch, at that point; if you specify $Param4, you're in the Set1 parameter set, and the switch isn't really doing anything extra anyway.

    Keep in mind, though, that you also wind up in Set1 if someone calls your command with -Param3:$false . If you need to modify Param4's behavior based on the [i]value[/i] of Param3, rather than on its [i]presence[/i], then you need to use dynamic parameters.

    • #17425
      Profile photo of Adam Bertram
      Adam Bertram
      Participant

      Dave,

      I did try to add a default parameter set with no parameters in it as well but the same behavior persisted. However, you do have a point where I didn't even really need $Param3 at all. I removed it and by doing that negated my reason for using parameter sets in the first place so I've removed the parameter set as well and it's now working as I need. Thanks!

  • #17420
    Profile photo of Richard Siddaway
    Richard Siddaway
    Moderator

    You can decorate the parameters like this

    function test {
    
    [CmdletBinding()]
    param (
    [Parameter(Mandatory)]
    [string]$Param1,
    
    [Parameter(Mandatory)]
    [string]$Param2,
    
    [Parameter(ParameterSetName = 'Set1')]
    [switch]$Param3,
    
    [Parameter(ParameterSetName = 'Set1',Mandatory)]
    [Parameter(ParameterSetName = 'Set2')]
    [string]$Param4,
    
    [Parameter(ParameterSetName = 'Set2')]
    [string]$param5
    )
    
    
    }
    

    £> test -Param1 xx -Param2 yy -Param3
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    Param4:

    £> test -Param1 x -Param2 y -param5 z

  • #17433
    Profile photo of Raymond Slieff
    Raymond Slieff
    Participant

    Adam, see if this helps, this is the param set I ended up with when doing my inactive computer script. I'm not a fan of the massive param set, but when I got done with the whole ordeal it produced what I needed. What you'll notice is I have things set in a default, but then also in the email param set.

    Param
    (
    	# Machines older than this date will be included on the report
    	[Parameter(Mandatory = $false, Position = 0, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[datetime] $ReportDate = (get-date).AddDays(-45),
    	# Machines older than this date will be moved to the Holding OU
    	[Parameter(Mandatory = $false, Position = 1, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[datetime] $MoveDate = (get-date).AddDays(-60),
    	# Machines older than this date will be disabled if within the proper Holding OU
    	[Parameter(Mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[datetime] $DisableDate = (get-date).AddDays(-60),
    	# Machines older than this date, previously disabled, and in the Holding OU will be removed
    	[Parameter(Mandatory = $false, Position = 3, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[datetime] $RemoveDate = (get-date).AddDays(-90),
    	# Name of OU to place machines in to older than the MoveDate, will be found with Get-ADOrganizationUnit -Filter {name -eq $HoldingOU}
    	[Parameter(Mandatory = $false, Position = 4, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[string] $HoldingOU = $null,
    	# Text that will be used to exclude computers by name from the 'To be reviewed' portion of the report.
    	[Parameter(Mandatory = $false, Position = 5, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[string[]] $IgnoreComputerName = '',
    	# Text that will be used to exclude computers by description from the 'To be reviewed' portion of the report.
    	[Parameter(Mandatory = $false, Position = 6, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[string[]] $IgnoreComputerDescription = '',
    	# The output path of the HTML report document
    	[Parameter(Mandatory = $false, Position = 7, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[string] $OutFilePath = $null,
    	# If the report should be sent out as an email
    	[Parameter(Mandatory = $false, Position = 8, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Email Param Set")]
    	[switch] $SendEmail,
    	# Used with $SendEmail, determines the SMTP server to use for relaying the email message
    	[Parameter(Mandatory = $true, Position = 9, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Email Param Set")]
    	[string] $SMTPServer,
    	# Sets the EMail Subject line
    	[Parameter(Mandatory = $false, Position = 10, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Email Param Set")]
    	[string] $EmailSubject = "Inactive Computer Report",
    	# List of Email Recpients in the form of NAME 
    	[Parameter(Mandatory = $true, Position = 11, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Email Param Set")]
    	[string[]] $EmailRecpients,
    	# Sets the Sender information for the email in the form of NAME 
    	[Parameter(Mandatory = $false, Position = 12, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Email Param Set")]
    	[string] $EmailSender = "Do Not Reply ",
    	# Will not move the machines to the Active Directory specified holding OU, but will include them on the report.
    	[Parameter(Mandatory = $false, Position = 13, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[switch] $DoNotMove = $false,
    	# Will not disable machines in Active Directory, but will include them on the report.
    	[Parameter(Mandatory = $false, Position = 14, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[switch] $DoNotDisable = $false,
    	# Will not delete machines from Active Directory, but will include them on the report.
    	[Parameter(Mandatory = $false, Position = 15, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Default Param Set")]
    	[Parameter(ParameterSetName = "Email Param Set")]
    	[switch] $DoNotDelete = $false
    )
    

    edit: some how entirely skipped over the fact that Richard answered in the same way already.

You must be logged in to reply to this topic.