Tag Archives: $PSBoundParameters

Potentially Avoid Logging Plain Text Passwords

A few weeks ago I spoke at the Arizona PowerShell Saturday event where I introduced the newest version of my Advanced Function template — the 2.0 version. You can check it out here: http://tommymaynard.com/an-advanced-function-template-2-0-version-2017. It’s headed toward 200 downloads — not bad. Well, there’s going to need to be a newer version sooner rather than later, and here’s why.

The Advanced Function template writes out a few informational lines at the top of its log files. If you didn’t know, a big part of my template is the logging it performs. These lines indicate what, when, who, and from where, a function was invoked. In addition, it also logs out every parameter name and every parameter value, or values, that are included, as well. This was all very helpful until I pulled a password out of AWS’ EC2 parameter store — it’s secure — and fed it to the function with the logging enabled. It was a parameter value to a parameter named password, and it ended up in the clear, in a text file.

I know. I know. The function should only accept secure strings, and it will, but until then, I took a few minutes to write something I’ll be adding to the 2.1 version of my Advanced Function template. You see, I can’t always assume other people will use secure strings. My update will recognize if a parameter name has the word password, and if it does, it will replace its value in the logging with asterisks.

More or less, let’s start with the code that failed me. For each key-value pair in the $PSBoundParameters hash table, we write the key and its corresponding value to the screen.

Alright, now that we have our function in memory, let’s invoke the function and check out the results.

In the above results, my password is included on the screen. That means it could end up inside of an on disk file. We can’t have that.

Now, here’s the updated code concept I’ll likely add to my Advanced Function template. In this example, if the key includes the word password, then we’re going to replace its value with asterisks. The results of this function are further below.

In these results, our password parameter value isn’t written in plain text. With that, I guess I’ll need to add this protection. By the way, if you didn’t notice, Password is underlined in green in the first and third image. This is neat; it’s actually PSScriptAnalyzer recognizing that I should use a SecureString based on the fact that the parameter is named Password. I can’t predict what everyone will do, so what’s a couple more lines to potentially protect someone from storing something secure, in an insecure manner.

The $PSBoundParameters Automatic Variable

I had a recent run in with $PSBoundParameters and thought, hey, I should write about that. $PSBoundParameters is an automatic variable. You can read more about it, and others, in Get-Help -Name about_Automatic_Variables, but before you do, let’s chat about it here. This variable contains key-value pairs of the parameters and the corresponding values that are passed to a function, or script. Consider the function declared below.

Function Show-Parameter {
    Param (
        [string]$Text,
        [int]$Number
    )

    $PSBoundParameters
}

Now that we have our function declared, we can invoke it (think, run it), by entering its name.

PS> Show-Parameter
PS> # ^ No parameters and values included,...
PS> # so the function does nothing.
PS> Show-Parameter -Text 'hi'

Key                                                         Value
---                                                         -----
Text                                                        hi

PS> Show-Parameter -Text 'hello' -Number 5

Key                                                         Value
---                                                         ----
Text                                                        hello
Number                                                      5

PS> Show-Parameter -Number 10

Key                                                         Value
---                                                         -----
Number                                                      10

It’s important to remember that all our function did was echo the value(s) stored in $PSBoundParameters. Now that we know we can do this, why might we want to do this? In scripting, we often need to make decisions based on information we’ve collected, and in this case, we make our decisions based on whether or not a parameter was used when a function was invoked. Let’s modify the function first and run it a few more times.

Function Show-Parameter {
    Param (
        [string]$Text,
        [int]$Number
    )

    If ($PSBoundParameters.ContainsKey('Text')) {
        Write-Output -InputObject "Text has been included as: '$Text'"
    }

    If ($PSBoundParameters.ContainsKey('Number')) {
        Write-Output -InputObject "Number has been included as: '$Number'"
    }
}

Now our function, when invoked, will take a specific action when a parameter(s) is included. Here’s a few examples.

PS> Show-Parameter -Text 'sample text'
Text has been included as: 'sample text'
PS>
PS> Show-Parameter -Number 20
Number has been included as: '20'
PS>
PS> Show-Parameter -Text 'more sample text' -Number 25
Text has been included as: 'more sample text'
Number has been included as: '25'

Here’s one final modification. In the example below, we’ve removed the -Number parameter and the If statement that checks if that parameter was included. Then, we added a switch statement inside the If statement that checks if the -Text parameter was included. Based on the value provided to the -Text parameter, we’ll take specific actions (up to a point). If the string ‘hello’ is included as the parameter’s value, we’ll reply with one message, if the string ‘hi’ is included as the parameter’s value, we’ll reply with another message, and if anything else is included, we’ll simply reply with the value provided to the parameter.

Function Show-Parameter {
    Param (
        [string]$Text
    )

    If ($PSBoundParameters.ContainsKey('Text')) {
        switch ($Text) {
            {$_ -eq 'hello'} {Write-Output -InputObject 'Hello to you, as well.'; break}
            {$_ -eq 'hi'} {Write-Output -InputObject 'Hi.'; break}
            default {"You entered: $Text"}
        }
    }
}

With $PSBoundParameters, we can check if a parameter is used, as well as, work with the value that’s provided to that parameter. Below are three examples of using the above function.

PS> Show-Parameter -Text hi
Hi.

PS> Show-Parameter -Text hello
Hello to you, as well.

PS> Show-Parameter -Text adios
You entered: adios

That’s it. Enjoy the rest of the weekend and have a great week!