Private/Get-ParameterValue.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function Get-ParameterValue {
    #.Synopsis
    # Get the actual values of parameters which have manually set (non-null) default values or values passed in the call
    #.Description
    # Unlike $PSBoundParameters, the hashtable returned from Get-ParameterValues includes non-empty default parameter values.
    # NOTE: Default values that are the same as the implied values are ignored (e.g.: empty strings, zero numbers, nulls).
    #.Example
    # function Test-Parameters {
    # [CmdletBinding()]
    # param(
    # $Name = $Env:UserName,
    # $Age
    # )
    # $Parameters = . Get-ParameterValues
    #
    # # This WILL ALWAYS have a value...
    # Write-Host $Parameters["Name"]
    #
    # # But this will NOT always have a value...
    # Write-Host $PSBoundParameters["Name"]
    # }
    [CmdletBinding()]
    param(
        # Pass $MyInvocation.MyCommand.Parameters to function, powershell 7 seems to only populate variables with dot sourcing
        [parameter(mandatory = $true)]
        $Parameters
        ,
        [parameter(mandatory = $true)]
        $BoundParameters,

        [string[]]$DefaultExcludeParameter = @("id", "download",'Debug', 'Verbose')
    )

    if ($MyInvocation.Line[($MyInvocation.OffsetInLine - 1)] -ne '.') {
        throw "Get-ParameterValue must be dot-sourced, like this: . Get-ParameterValues"
    }


    $ParameterValues = @{}
    foreach ($parameter in $Parameters.GetEnumerator()) {
        # gm -in $parameter.Value | Out-Default
        try {
            $key = $parameter.Key
            if ($key -notin $DefaultExcludeParameter) {
                #Fill in default parameters values
                if ($null -ne ($value = Get-Variable -Name $key -ValueOnly -ErrorAction Ignore )) {
                    if ($value -ne ($null -as $parameter.Value.ParameterType)) {
                        $ParameterValues[$key] = $value
                    }
                }
                #Fill in all given parameters even empty
                if ($BoundParameters.ContainsKey($key)) {
                    $ParameterValues[$key] = $BoundParameters[$key]
                }

            }
        }
        finally {}
    }

    #Convert switch parameters to booleans so it converts nicely to json
    foreach ( $key in @($ParameterValues.Keys)) {
      if ($true -eq $ParameterValues[$key].IsPresent){
        $ParameterValues[$key]=$true;
      }
    }

    return $ParameterValues
}