1

I am trying to write what seems very simple but I've been going at this for hours and still not able to get what I need.

I have a PowerShell script which will be used for starting up OR shutting down virtual machines. I want to user to specify either a ResourceGroup name, an individual VM name or a text file with the names of the VMs.

This script is used for Azure but the question is specific to the param() declaration.

I have tried every combination I can think of here, making parameters parts of parameter sets, making them mandatory, not mandatory, etc. but I have not been able to get this right.

Any help is appreciated!

param (
    [Parameter (Mandatory = $true, ParameterSetName = 'ByResourceGroup')]
    [string]$ResourceGroup,

    [Parameter (Mandatory = $true, ParameterSetName = 'ByFile')]
    [string]$File,

    [Parameter (Mandatory = $true, ParameterSetName = 'ByName')]
    [string]$Name,

    [Parameter (Mandatory = $false, ParameterSetName = 'ByResourceGroup')]
    [Parameter (Mandatory = $false, ParameterSetName = 'ByFile')]
    [Parameter (Mandatory = $false, ParameterSetName = 'ByName')]
    [switch]$Start,

    [Parameter (Mandatory = $false, ParameterSetName = 'ByResourceGroup')]
    [Parameter (Mandatory = $false, ParameterSetName = 'ByFile')]
    [Parameter (Mandatory = $false, ParameterSetName = 'ByName')]
    [switch]$Stop
)

The user should be able to pass in EITHER: -ResourceGroup OR -File OR -Name

AND

pass in either: -Start OR -Stop

Not both!

I think I have this correct for the first set but I can't get the -Start and -Stop to be exclusive.

Get-help says this:

SYNTAX
    C:\Set-AzureVM.ps1 -ResourceGroup <String> [-Start] [-Stop] [<CommonParameters>]

    C:\Set-AzureVM.ps1 -File <String> [-Start] [-Stop] [<CommonParameters>]

    C:\Set-AzureVM.ps1 -Name <String> [-Start] [-Stop] [<CommonParameters>]


I am looking for something more like this:

SYNTAX
    C:\Set-AzureVM.ps1 -ResourceGroup <String> -Start [<CommonParameters>]

    C:\Set-AzureVM.ps1 -File <String> -Start [<CommonParameters>]

    C:\Set-AzureVM.ps1 -Name <String> -Start [<CommonParameters>]

    C:\Set-AzureVM.ps1 -ResourceGroup <String> -Stop [<CommonParameters>]

    C:\Set-AzureVM.ps1 -File <String> -Stop [<CommonParameters>]

    C:\Set-AzureVM.ps1 -Name <String> -Stop [<CommonParameters>]

Just to close this out... I wound up changing this a bit (needs changed and so did the code). As others suggested, I agree that what I was trying to do probably wasn't possible anyway. Also, I am handling the possibility that the user will choose both -Start and -Stop or neither in code. Thanks to everyone for your comments!

SYNTAX
    C:\Set-AzureVM.ps1 -Name <String> -ResourceGroup <String> [-Start] [-Stop] [<CommonParameters>]

    C:\Set-AzureVM.ps1 -File <String> [-Start] [-Stop] [<CommonParameters>]
3
  • 1
    Parameter sets are unique from each other. Commented Jul 8, 2019 at 16:31
  • I would personally just have a single switch with a ValidateSet('Stop','Start'). You can also just have both with logic in the script that handles the discrepancy. I feel you can't do what you want with the number of parameters you have. Commented Jul 8, 2019 at 16:41
  • please format your code Commented Jul 8, 2019 at 17:18

1 Answer 1

2

I don't think what you are trying to do is possible. You might consider breaking the functionality up into two separate scripts.

  • Start-AzureVM.ps1
  • Stop-AzureVM.ps1

Alternatively you can use the switch -stop to do both starting and stopping. by default -stop will evaluate to $false in your script or function.

# implicitly start the vm
Set-AzureVM.ps1 -Name <String>

# explicitly stop the vm
Set-AzureVM.ps1 -Name <String> -stop
function Set-AzureVM () {
    param(
        [Parameter (Mandatory, ParameterSetName = 'ByFile')]
        [string]$File,

        [Parameter (Mandatory, ParameterSetName = 'ByName')]
        [string]$Name,

        [switch]$Stop
    )
    if($Stop){
        Write-Host 'Stopping VM'
    }
    if(!$stop){
        Write-Host 'Starting VM'
    }
}

Get-Command Set-AzureVM -Syntax
Set-AzureVM -File <string> [-Stop] [<CommonParameters>]

Set-AzureVM -Name <string> [-Stop] [<CommonParameters>]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your suggestions. FYI, the code was originally in two different scripts but the work item acceptance criteria was for one script.

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.