powershellpowershell-core

Adding default parameter to Powershell Core script


I am very much new to Powershell and I am trying to add a default value to two parameters in a script file but I am still being asked to enter the missing parameter at execution.

The parameters are

param(
    [string]
    $Build = "production",

    [bool]
    $Deploy = 1
)

So when I do ./script.ps1 -Build I get an error as

/Users/akshayrajgollahalli/GitHub/gollahalli.com/script.ps1 : Missing an argument for parameter 'Build'. Specify a parameter of type 'System.String' and try again.

But according to the Microsoft blog that is what I am doing. I am not sure what's the mistake here.

Update 1:

Another case would be I might want something like ./script.ps1 -Build local which should override the production value.


Solution

  • When defining optional parameters with a default value, you can either leave out the parameter in the call to have the script use this default value, or use it to have the script use something else instead of the default value.

    As an example. This script will simply output whatever is used for the $Build and $Deploy parameters:

    param(
        [string]
        $Build = "production",
    
        [bool]
        $Deploy = 1
    )
    
    Write-Host "Using Build value:  $Build"
    Write-Host "Using Deploy value: $Deploy"
    

    If I use it like this:

    & 'D:\script1.ps1'
    

    It does not receive any alternative values for $Build and $Deploy, so the output will be:

    Using Build value:  production
    Using Deploy value: True
    

    Whenever you would like to run the script with values other that their defaults, you add the parameter(s) and value(s) to the call like this:

    & 'D:\script1.ps1' -Build "something else"
    

    Output:

    Using Build value:  something else
    Using Deploy value: True
    

    Hope this explains


    To go into the comment of john v kumpf:

    If you need something that would act as a three-state parameter, you need to build the logic for that inside the script or function yourself.
    For instance like this:

    param(
        [string]$log = 'Some\Default\Value'
    )
    if (!$PSBoundParameters.ContainsKey("log")) { 
        # the script was called without passing the -log parameter
        Write-Host ('Parameter $log was not passed; will use the default value: {0}' -f $log)
    }
    elseif([string]::IsNullOrWhiteSpace($log)) { 
        # parameter -log was used but passed as empty string
        Write-Host 'Parameter $log is empty; no logfile will be created'
    }
    else { 
        # parameter -log was used sending the path for the logfile (or whatever)
        Write-Host ('Parameter $log is passed with a custom value: {0}' -f $log)
    }
    

    Mind you, you cannot call this using .\script.ps1 -log because PowerShell will complain:
    Missing an argument for parameter 'log'. Specify a parameter of type 'System.String' and try again.
    This is why the test for a Null or whitespace-only value is there and you need to pass .\script.ps1 -log '' or .\script.ps1 -log $null for that