Tag Archives: Hash table

Quickly and securely storing your credentials – PowerShell

During the last PowerShell event I quickly demo’ed the Export-CliXml functionality to quickly, easily, and most importantly, securely store credentials to a file. In this article I will describe the following three steps:

  • Store credentials in a variable
  • Export the variable to a file
  • Import the credential object from the file into a variable

To get a credential object we can either manually create one or use the Get-Credential cmdlet to prompt for the account details:

1
$Credential = Get-Credential

To store the credentials into a .cred file:

1
$Credential | Export-CliXml -Path "${env:\userprofile}\Jaap.Cred"

And to load the credentials from the file and back into a variable:

1
2
$Credential = Import-CliXml -Path "${env:\userprofile}\Jaap.Cred"
Invoke-Command -Computername 'Server01' -Credential $Credential {whoami}

StoreCredentials

The advantage of this methodology is that you can leverage the versitility of PowerShell to ensure that the data is not only exported, but also stored in a secure manner using secure strings. It should be noted that these credential files that are created can only be opened by the same user on the same system. It can be used to store any type of credentials, both local accounts and domain accounts can be saved in this manner.

Note that you are not limited to storing a single set of credentials in this manner, you could use any number of accounts, for example the following example will prompt for 3 different sets and store them in a hash table. This can then be exported/imported in a similar manner:

1
2
3
4
5
6
7
8
9
10
$Hash = @{
    'Admin'      = Get-Credential -Message 'Please enter administrative credentials'
    'RemoteUser' = Get-Credential -Message 'Please enter remote user credentials'
    'User'       = Get-Credential -Message 'Please enter user credentials'
}
$Hash | Export-Clixml -Path "${env:\userprofile}\Hash.Cred"
$Hash = Import-CliXml -Path "${env:\userprofile}\Hash.Cred"
Invoke-Command -ComputerName Server01 -Credential $Hash.Admin -ScriptBlock {whoami}
Invoke-Command -ComputerName Server01 -Credential $Hash.RemoteUser -ScriptBlock {whoami}
Invoke-Command -ComputerName Server01 -Credential $Hash.User -ScriptBlock {whoami}

Share

Quicktip: Use a Csv file to splat parameters into a function

I recently received a question on Reddit that asked if it is possible to use a csv file to create a hash table that can be used for splatting parameters into a function. The goal of this exercise is to be able to specify a csv file and to pass on the proper arguments to a function.

For example there is a csv file with the following contents:

SplatCsv

So based on this the New-Server function should be called as such:

1
New-Server -Templare 2012R2 -Spec DomainJoinSpec -Datastore Production2 -Cpus 1

In order to achieve this, the first step would be to remove the empty fields from the equasion as such:

1
2
$Csv = Import-Csv -Path Parameters.csv
$Csv.psobject.Properties | Where-Object {$_.Value}

This will import the csv and only display the colums in the csv that actually contain data. To ensure this data is stored in a hash table we can use the ForEach-Object. This cmdlet can be used to loop through the remaining results and to create a hashtable:

1
2
3
4
5
6
$Csv = Import-Csv c:\temp\params.csv
$Csv.psobject.Properties | Where-Object {$_.Value} | ForEach-Object -Begin {
$SplatParams = @{}
} -Process {
$SplatParams[$_.Name] = $_.Value
}

Now that the hash table has been created this can be used for splatting into the New-Server function:

1
New-Server @SplatParams

By combining the ForEach-Object cmdlet and the PSObject property that is piped into Where-Object it is possible to construct a custom hashtable that can be used for splatting. This can provide an easy alternative for non-technical users to provide parameters and arguments into a PowerShell function.

Share

Quicktip: Create an object that refers to its own properties

Recently I received the question the /r/PowerShell community if it was possible to create an object that refers to its own properties when it is created. The user specified that they would prefer to create this as a one-liner.

Using the Add-Member cmdlet in combination with the -Passthru parameter this is quite simple to do, for example:

1
2
3
$Object = New-Object PSObject -property @{
    Property1 = 'Hello World'
} | Add-Member ScriptProperty GetProperty1 {$This.Property1} -PassThru

To make this slightly more interesting it is also possible to manipulate this object by using the manipulating the property. In the following example a property ‘Today’ is created and the script property uses this property to calculate the next week. For example:

1
2
3
$Object = New-Object PSObject -Property @{
        Today = (Get-Date).Date
} | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru

ScriptPropertyNextWeek

It is also possible to create a ScriptMethod that uses the previously defined property, in the next example I create a ScriptMethod that can add or substract a week from the Today property:

1
2
3
4
$Object = New-Object PSObject -Property @{
        Today = (Get-Date).Date
} | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru |
Add-Member ScriptMethod AddWeeks {param([int]$Week) $This.Today.AddDays($Week*7)} -PassThru

ScriptMethodAddWeeks

Share

QuickTip: Automate variable creation using New-Variable

Occasionally I get the question: “But what if I want to create fifty variables, how do I do that in PowerShell?”. My initial thought usually is: “Why?”, but seeing as there might be some scenarios in which it can be useful to batch create a large number of variables. Aside from that it is also just interesting to see how to do things like this in PowerShell.

For example if we would like to create group A-Z as empty arrays the following code can be used:

65..90 | ForEach-Object {
 New-Variable "Group$([char]$_)" -Value @()
}

Personally I would prefer creating a hash table which contains all these arrays as it is easier to work with. If you would like to automatically create a hash table that can be done in a similar manner using the following code:

65..90 | ForEach-Object -Begin {
 $HashTable = @{}
} -Process {
 $HashTable."Group$([char]$_)" = @()
}

Storing the arrays in a hash table has the advantage of having a single point of access, for example by accessing the GetEnumerator() method to display the key – value pairs that are contained in the hash table:

$HashTable.GetEnumerator()
Share