Alex Flora
Alex Flora

Reputation: 233

powershell mandatory parameter with default value shown

I am looking for a way to have an PowerShell script ask for an parameter which needs to be mandatory, but shown with an default value, e.g.:

    .\psscript
    Supply values for the following parameters:
    parameter1[default value]:
    parameter2[1234]:

I want to ask for input but provide some default values.

If I use the mandatory option it asks for the values nicely but doesn't show the default value or process the given value. If I don't make it mandatory then PowerShell doesn't ask for the value at all.

Here's some script examples I tried:

    [CmdletBinding()]
    Param(
        [parameter(Mandatory=$true)] $SqlServiceAccount = $env:computername + "_sa",
        [parameter(Mandatory=$true)] $SqlServiceAccountPwd
    )

This script asks for parameters but does not show or process the default value if I just press enter on the first parameter.

    [CmdletBinding()]
    Param(
        [parameter(Mandatory=$false)] $SqlServiceAccount = $env:computername + "_sa",
        [parameter(Mandatory=$true)] $SqlServiceAccountPwd
    )

This script doesn't ask for the first parameter, but processes the default value.

Upvotes: 23

Views: 79085

Answers (4)

Kellen Stuart
Kellen Stuart

Reputation: 8893

I'd do it this way

param(
    [Parameter(Mandatory)][string]$aString
)

if([string]::IsNullOrWhiteSpace($aString))
{
   $aString = "A Default Value"
}

In my opinion, if you're using Read-Host in a param() block, then you're doing something wrong. At that point, what's the point of using param() at all?

Upvotes: 7

Burt_Harris
Burt_Harris

Reputation: 6874

Here's a short example that might help:

    [CmdletBinding()]
    Param(
        $SqlServiceAccount = (Read-Host -prompt "SqlServiceAccount ($($env:computername + "_sa"))"),
        $SqlServiceAccountPwd = (Read-Host -prompt "SqlServiceAccountPwd")
    )
    if (!$SqlServiceAccount) { $SqlServiceAccount = $env:Computername + "_sa" }
    ...

Upvotes: 11

BartekB
BartekB

Reputation: 8650

By definition: mandatory parameters don't have default values. Even if you provide one, PowerShell will prompt for value unless specified when the command is called. There is however a 'hacky' way to get what you ask for. As variables (and as consequence - parameters) can have any name you wish, it's enough to define command with parameters that match the prompt you would like to see:

function foo {
    param (
        [Parameter(Mandatory = $true)]
        [Alias('Parameter1')]
        [AllowNull()]
        ${Parameter1[default value]},
        [Parameter(Mandatory = $true)]
        [Alias('Parameter2')]
        [AllowNull()]
        ${Parameter2[1234]}
    )
    $Parameter1 = 
        if (${Parameter1[default value]}) {
            ${Parameter1[default value]}
        } else {
            'default value'
        }
    $Parameter2 = 
        if (${Parameter2[1234]}) {
            ${Parameter2[1234]}
        } else {
            1234
        }
    [PSCustomObject]@{
        Parameter1 = $Parameter1
        Parameter2 = $Parameter2
    }
}

When called w/o parameters, function will present user with prompt that match parameter names. When called with -Parameter1 notDefaultValue and/or with -Parameter2 7, aliases will kick in and assign passed value to the selected parameter. As variables named like that are no fun to work with - it makes sense to assign value (default or passed by the user) to variable that matches our alias/ fake parameter name.

Upvotes: 8

briantist
briantist

Reputation: 47792

There isn't a way to do what you want with a mandatory parameter and powershell prompting for you.

You would instead have to make it optional (remove mandatory), then implement the prompting code yourself (Read-Host, but take blank response as a default; something like that).

Upvotes: 3

Related Questions