Reputation: 233
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
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
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
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
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