1

This has been posted once before, but the proposed solution didn't solve my problem. I'm writing a script, and I want one of my parameters to be mandatory, but I only want it to be mandatory if one of the earlier parameters has a certain value.

Example:

param([Parameter(Mandatory=$true, Position=0)]
  [ValidateSet("Add","Delete")]
  [string]$Command,

  [Parameter(Mandatory=$true)]
  [string]$Subject
)

I want the Subject parameter to be required only if the Command parameter has the value "Add".

I've tried using a ParameterSetName value, but that didn't seem to work.

2

2 Answers 2

2

You can make Subject optional and handle the requirement at the beginning of the body of your script, simulating a mandatory parameter, as follows:

param(
  [parameter(Mandatory=$true)][ValidateSet("Add","Delete")] [string]$Command,
  [string] $Subject
)
if (($Command -eq 'Add') -and ($PSBoundParameters['Subject'] -eq $null)) {
  $Subject = Read-Host 'Supply value for the parameter "Subject" (mandatory when the value of "Command" is "Add")'
}

The condition $PSBoundParameters['Subject'] -eq $null evaluates to True if the parameter Subject wasn't specified. Note that you can't simply use $Subject -eq $null, because $Subject is initialized as an empty string if the parameter is omitted. If you don't typecast $Subject (i.e., leave out the [string]), then it will be null if it's omitted, but I presume you don't want to do that.

Note that this will allow the user to simply hit [ENTER] when prompted, leaving $Subject blank, but that's standard behavior for mandatory parameters. If you don't want to allow that, you could do one of the following (this is another advantage of handling complex parameter requirements like this in the body rather than the parameter declaration).

Throw an error:

param(
  [parameter(Mandatory=$true)][ValidateSet("Add","Delete")] [string]$Command,
  [string] $Subject
)
if (($Command -eq 'Add') -and ($PSBoundParameters['Subject'] -eq $null)) {
  $Subject = Read-Host 'Supply value for the parameter "Subject" (mandatory when the value of "Command" is "Add"'
  if (-not $Subject) {
    throw "The Subject may not be blank."
  }
}

Keep prompting until a value is provided:

param(
  [parameter(Mandatory=$true)][ValidateSet("Add","Delete")] [string]$Command,
  [string] $Subject
)
if (($Command -eq 'Add') -and ($PSBoundParameters['Subject'] -eq $null)) {
  do {
    $Subject = Read-Host 'Supply value for the parameter "Subject" (mandatory when the value of "Command" is "Add"'
    if (-not $Subject) {
      Write-Host -NoNewline "The Subject may not be blank. "
    }
  } until ($Subject)
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a more robust implementation so I will most likely be using this, thank you.
2

You could try doing your parameters like this:

param (
    [Parameter(ParameterSetName="Add")][switch]$Add,
    [Parameter(ParameterSetName="Delete")][switch]$Delete,
    [Parameter(ParameterSetName="Add",Mandatory=$true)] [Parameter(ParameterSetName="Delete")] [string]$Subject
)

When you have the switch "Add" then the Subject is mandatory, when you have the switch "Delete" then the Subject parameter is optional.

4 Comments

This is not a bad idea, but I don't think you can have duplicate parameters with the same name.
You can add a parameter to multiple parameter sets this way: [Parameter(ParameterSetName="Add";Mandatory=$true)] [Parameter(ParameterSetName="Delete")] [string]$Subject. But see the answer I just posted for a way to make it work with the parameters you wanted to use.
Edited. It should work as expected. Changed the Subject Parameter to include both parameter sets. Thanks to Adi Inbar for the correction.
I had actually figured this out yesterday, but forgot to post it. Still your original post got me 95% there, so thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.