brianary
brianary

Reputation: 9322

Can $PSDefaultParameterValues send default parameter values to scripts?

According to the about_Parameters_Default_Values documentation,

The $PSDefaultParameterValues preference variable lets you specify custom default values for any cmdlet or advanced function.

However, in practice, this does not appear to work for script advanced functions (see the Example section in the script below).

Using both the Script and Local scope, default values for core PowerShell Cmdlets (i.e. Write-Host) works fine, but none of the parameters for the script itself are received from $PSDefaultParameterValues, whether there is a default defined or not, or whether a common parameter or not.

Test-DefaultParam.ps1
<#
.Synopsis
    Test the handling of $PSDefaultParameterValues.

.Parameter UnspecifiedParam
    A parameter with no default.

.Parameter DefaultParam
    A parameter with a default.

.Example
    Test-DefaultParam.ps1


    Name                           Value
    ----                           -----
    InitialPSBoundParameters       {}
    InitialUnspecifiedParam
    InitialDefaultParam            DefinedDefaultValue
    Script:PSDefaultParameterValues:Write-Host
    WARNING: UnspecifiedParam default was not received
    WARNING: DefaultParam default was not received
    WARNING: Verbose default was not received
    PSDefaultParameterValues       {Test-DefaultParam:Verbose, Test-DefaultParam:DefaultParam, Test-DefaultParam:UnspecifiedParam}
    PSDPVUnspecifiedParam          Script:PSDefaultParameterValues:UnspecifiedParam
    PSDPVDefaultParam              Script:PSDefaultParameterValues:DefaultParam
    PSDPVVerbose                   True
    PSDPVWriteHost                 Script:PSDefaultParameterValues:Write-Host
    PSBoundParameters              {}
    UnspecifiedParam
    DefaultParam                   DefinedDefaultValue
    Local:PSDefaultParameterValues:Write-Host
    WARNING: UnspecifiedParam default was not received
    WARNING: DefaultParam default was not received
    WARNING: Verbose default was not received
    PSDefaultParameterValues       {Test-DefaultParam:Verbose, Test-DefaultParam:DefaultParam, Test-DefaultParam:UnspecifiedParam}
    PSDPVUnspecifiedParam          Local:PSDefaultParameterValues:UnspecifiedParam
    PSDPVDefaultParam              Local:PSDefaultParameterValues:DefaultParam
    PSDPVVerbose                   True
    PSDPVWriteHost                 Local:PSDefaultParameterValues:Write-Host
    PSBoundParameters              {}
    UnspecifiedParam
    DefaultParam                   DefinedDefaultValue

.Link
    https://technet.microsoft.com/library/hh847819.aspx
#>

[CmdletBinding()] Param(
[string]$UnspecifiedParam,
[string]$DefaultParam = 'DefinedDefaultValue'
)

$psdpv = @{}
$PSDefaultParameterValues.GetEnumerator() |
    ? Name -like 'Test-DefaultParam:*' |
    % {[void]$psdpv.Add($_.Name,$_.Value)}
if(!$psdpv.Count)
{
    [ordered]@{
        InitialPSBoundParameters = $PSBoundParameters
        InitialUnspecifiedParam  = $UnspecifiedParam
        InitialDefaultParam      = $DefaultParam 
    }
    $Script:PSDefaultParameterValues = @{
        'Test-DefaultParam:UnspecifiedParam' = 'Script:PSDefaultParameterValues:UnspecifiedParam'
        'Test-DefaultParam:DefaultParam'     = 'Script:PSDefaultParameterValues:DefaultParam'
        'Test-DefaultParam:Verbose'          = $true
        'Write-Host:Object'                  = 'Script:PSDefaultParameterValues:Write-Host'
    }
    Test-DefaultParam.ps1
    $Local:PSDefaultParameterValues = @{
        'Test-DefaultParam:UnspecifiedParam' = 'Local:PSDefaultParameterValues:UnspecifiedParam'
        'Test-DefaultParam:DefaultParam'     = 'Local:PSDefaultParameterValues:DefaultParam'
        'Test-DefaultParam:Verbose'          = $true
        'Write-Host:Object'                  = 'Local:PSDefaultParameterValues:Write-Host'
    }
    Test-DefaultParam.ps1
}
else
{
    Write-Verbose "PSDefaultParameterValues exist"
    Write-Host
    if(!$UnspecifiedParam)                        {Write-Warning 'UnspecifiedParam default was not received'}
    if($DefaultParam -eq 'DefinedDefaultValue')   {Write-Warning 'DefaultParam default was not received'}
    if($VerbosePreference -eq 'SilentlyContinue') {Write-Warning 'Verbose default was not received'}
    [ordered]@{
        PSDefaultParameterValues = $psdpv
        PSDPVUnspecifiedParam    = $PSDefaultParameterValues['Test-DefaultParam:UnspecifiedParam']
        PSDPVDefaultParam        = $PSDefaultParameterValues['Test-DefaultParam:DefaultParam']
        PSDPVVerbose             = $PSDefaultParameterValues['Test-DefaultParam:Verbose']
        PSDPVWriteHost           = $PSDefaultParameterValues['Write-Host:Object']
        PSBoundParameters        = $PSBoundParameters
        UnspecifiedParam         = $UnspecifiedParam
        DefaultParam             = $DefaultParam 
    }
}

Upvotes: 1

Views: 740

Answers (1)

user4003407
user4003407

Reputation: 22102

Yes, it can:

PS> Set-Content .\Test\FileName.ps1 @'
>>> [CmdletBinding()]
>>> param(
>>>     $ParameterName='DefaultValue'
>>> )
>>> $ParameterName
>>> '@
PS> .\Test\FileName.ps1
DefaultValue
PS> $PSDefaultParameterValues['FileName.ps1:ParameterName']='DifferentValue'
PS> .\Test\FileName.ps1
DifferentValue

Upvotes: 4

Related Questions