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.
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