Author Posts

July 23, 2014 at 8:59 am

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?

July 23, 2014 at 9:40 am

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.

July 23, 2014 at 9:43 am

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

July 23, 2014 at 11:22 am

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!

July 23, 2014 at 5:08 pm

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.