craig
craig

Reputation: 26262

Use PowerShell session variables as default values for parameters

Can values that are stored in a PowerShell session variable be used to populate a parameter's default value?

In this example, the session variables are populate the first time the script is run, but aren't used in subsequent executions:

function Get-Authetication
{

    [cmdletbinding()]
    param(
        [parameter(Mandatory=$true)]
        [string]$Server = { if ($PSCmdlet.SessionState.PSVariable.Get('Server').Value) { $PSCmdlet.SessionState.PSVariable.Get('Server').Value } },

        [parameter(Mandatory=$true)]
        [pscredential]$Credential = (Get-Credential)

    )

    # store
    $PSCmdlet.SessionState.PSVariable.Set('Server',$Server)
    $PSCmdlet.SessionState.PSVariable.Set('Credential',$Credential)

    # return for testing
    [PsCustomObject]@{
        Server=$PSCmdlet.SessionState.PSVariable.Get('Server').Value;
        Username=($PSCmdlet.SessionState.PSVariable.Get('Credential').Value).Username
    }
}

Get-Authetication

Upvotes: 1

Views: 3138

Answers (2)

adamt8
adamt8

Reputation: 357

This looks like the question you're asking is:

I am always going to run this script/function as the same person. But after I run it the first time, I want it to remember that one credential.

If that is in fact your question, then it's not clear that this approach won't do that. You're trying to persist a value to use later, and it happens to be a credential. There are several ways to accomplish this, and this is a great article that includes all your options:

https://purple.telstra.com.au/blog/using-saved-credentials-securely-in-powershell-scripts#:~:text=From%20that%20perspective%20your%20process%20to%20have%20a,and%20store%20that%20in%20a%20file%20More%20items

Basically, you're going to need to save an encrypted value in a file the first time, then access that file in subsequent runs.

HOWEVER, if you are intending for multiple people to be able to do this, or YOU want to run this on more than one server, you'll have many additional things to contend with, like using a network share to store the file, or keeping track of different users.

Good luck researching.

Upvotes: 0

briantist
briantist

Reputation: 47832

This should be done by the caller using $PSDefaultParameterValues.

Or, do it in the function instead of using a default value:

function Get-Authetication
{

    [cmdletbinding()]
    param(
        [parameter()]
        [string]$Server,

        [parameter()]
        [pscredential]$Credential = (Get-Credential)

    )
    if (!$PSCmdlet.SessionState.PSVariable.Get('Server').Value -and !$Server) {
        $Server = Read-Host 'Enter server'
        # Alternatively
        # throw [System.ArgumentException]'You must supply a Server value'
    }
    if ($Server) {
        $PSCmdlet.SessionState.PSVariable.Set('Server',$Server)
    }
    $myServer = $PSCmdlet.SessionState.PSVariable.Get('Server').Value

    # return for testing
    [PsCustomObject]@{
        Server=$myServer;
    }
}

(abbreviated example)

Upvotes: 2

Related Questions