Creating Multiple Credential Objects

Download the complete function: https://gist.github.com/tommymaynard/98031ccd5de67005bf3063db06a33851

There are times when you made need to use additional credentials, other than those used to begin the Windows PowerShell session. When I need to PSRemote to another domain’s computer, I quickly run a function I have stored in my $PROFILE to create a variable that contains a credential object for the second domain. It’s a bit more specific for my environment, so I won’t bother sharing that exact function. What I will do, however, is share and explain a function I’ve written to create up to 10 credential objects. You’ll soon see where that can be changed (if for some reason someone would want more than that many). Realistically, 10 seems much too high anyway. Moving on.

Now, it might be important to know a bit more about how this started. The unfortunate thing about that function (the one in the link) is that it is maxed out at three credential sets (and it continually used the word ‘domain’). As well, it wasn’t as flexible as it should’ve been and it didn’t have any comment-based help or any verbose statements. So, a couple of days after publishing that post, I copied the function back into the PowerShell ISE and started working on a “1.1” version. That’s what we’ll discuss in this post.

First, we’ll write some basic, structural code for the advanced function.

Function New-TMMultiCred {
    [CmdletBinding()]
    Param ()

    Begin {
    } #End Begin

    Process {
    } #End Begin
} #End Function

Now, let’s add the parameter that will define how many credential objects the function will create. The variable we’ll use is $Set and we’ll cast it as an integer (Set will, therefore, also be the name of the parameter). In addition, we’ll add code to define the -Set parameter as being mandatory (it must be included when the function is run), and make the parameter positional (the value for -Set can be entered without providing the -Set parameter name). In addition, we’ll add the ValidateRange validation attribute that will require that the integer entered, as the value for the -Set parameter, must be 1 through 10. This can be changed if necessary.

Function New-TMMultiCred {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$True,Position=0)]
        [ValidateRange(1,10)]
        [int]$Set
    )

    Begin {
    } #End Begin

    Process {
    } #End Begin
} #End Function

We won’t need to do anything in the Begin block, so we’ll focus on the Process block next. In there, we’ll need to prompt for a user name and password as many times as the value of the parameter -Set indicates. Since we know the number of times we’ll be looping (to prompt for the username and password), I recommend we use a for statement. For statements work this way: set a variable ($i in our case) as a counter variable, add a comparison to determine how many times to loop (while $i is less than or equal to $Set), and finally, include a way to increment the counter variable (that’s what $i++ does), so that we only loop the proper number of times.

Function New-TMMultiCred {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$True,Position=0)]
        [ValidateRange(1,10)]
        [int]$Set
    )

    Begin {
    } #End Begin

    Process {
        For ($i = 1; $i -le $Set; $i++) {

        }
    } #End Begin
} #End Function

The final piece is adding the parts necessary to prompt for usernames and passwords, and creating variables to store each of the credential objects. We’ll do this as part of a try-catch.

Line 15 below, first runs the Get-Credential cmdlet. We know this because it is in parenthesis. These parentheses indicate that this cmdlet needs to run before it’s used as the value of the Set-Variable‘s -Value parameter. If for some reason the user presses Cancel, or presses the X in the top-right corner of the prompt dialog, the try portion of the try-catch will fail, and the catch portion will run. It will indicate that no credential was created for that iteration through the loop.

If the user enters, at minimum a username (because a password can be blank), then it will set a variable called $CredSet# (the hash mark (#) indicates a number). If we indicate we want to create two credential objects when we run the function (New-TMMultiCred 2), then $CredSet1 will be the variable that holds the first credential object, and $CredSet2 will hold the second.

Still on line 15, notice that the -Scope parameter is being used with the Set-Variable cmdlet. If we didn’t include this parameter and its value, Global, then the variables created (or modified, if the variable(s) already existed) by this command would not be available after the function was done executing.

Function New-TMMultiCred {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$True,Position=0)]
        [ValidateRange(1,10)]
        [int]$Set
    )

    Begin {
    } #End Begin

    Process {
        For ($i = 1; $i -le $Set; $i++) {
            try {
                Set-Variable -Name CredSet$($i) -Value (Get-Credential -Credential $null) -Scope Global
                Write-Output -Verbose "SUCCESS: Credential Set $i stored in `$CredSet$($i)"
            } catch {
                Write-Warning -Verbose "No credential object was created for set $($i)."
            }
        }
    } #End Begin
} #End Function

Here’s a look at the function in progress. The first image shows that three credential objects were requested. The first credential object has already been created and is stored in $CredSet1, the second wasn’t created, since the user pressed Cancel on the second prompt, and the third credential object will be created when the user presses OK. The second image shows the end result.

Function for Creating Multiple Credential Objects-01

Function for Creating Multiple Credential Objects-02

Once this is complete, the user can run cmdlets that have an optional -Credential parameter and supply the fitting credential object, as seen in the example below. You can return all the cmdlets and functions that have the -Credential parameter using Get-Command: Get-Command -ParameterName Credential.

PS C:\> Invoke-Command -ComputerName dc01 -ScriptBlock {Get-Date} -Credential $CredSet3

Download the complete function: https://gist.github.com/tommymaynard/98031ccd5de67005bf3063db06a33851

Leave a Reply

Your email address will not be published. Required fields are marked *