Tag Archives: splatting

Create Self-Signed Certificate and Export

Yesterday, I found myself walking through the usage of a couple of the cmdlets in the PKIClient (or PKI) module. Due to a project I’m working on, I may soon find myself needing and creating a self-signed certificate. Because I’m not yet ready to implement this code, I thought it made sense to use my blog to store it, until I am. While it’s for me, this could be helpful for you too.

$NewCertCreateParameters = @{
	Subject = 'powershell.functiontemplate.mydomain.com'
	CertStoreLocation = 'Cert:\CurrentUser\My'
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
	OutVariable = 'Certificate'
} # End.
New-SelfSignedCertificate @NewCertCreateParameters | Out-Null

In this first code section seen above, I used splatting. This allows me to create a hash table full of parameters and parameter values — key-value pairs*. Once created, it can be used — or splatted — as a part of a command’s invocation. In this instance, we’re splatting the hash table we created and stored in the $NewCertCreateParameters variable on the New-SelfSignedCertificate cmdlet. Noticed that we’re piping our command to Out-Null to keep the default output of this command from displaying. There’s still a way to see it, however.

This bit of PowerShell creates a new self-signed certificate on the computer, which is associated with the current user. Since we included the OutVariable parameter in our hash table, we have the data returned by our cmdlet invocation stored in the $Certificate variable, even though we used Out-Null. While the below output only shows three properties by default, there’s plenty more that can be reviewed by piping $Certificate to Select-Object -Property *.

[PS7.1.0] C:\> $Certificate

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
56DA4F187DF396CCCB67B5C93F6F0CA7848C5E66  CN=powershell.funct… {Client Authentication, Server Authentication}

Using the code in the second section, we can view our self-signed certificate after it’s been created by the previous command.

Get-ChildItem -Path $NewCertCreateParameters.CertStoreLocation |
	Where-Object Thumbprint -eq $Certificate.Thumbprint |
	Select-Object -Property *

The final section, has a few things happening. First, we create a secure string that holds a password. This isn’t a real password, so don’t bother. You get the idea, though, and really, for me, this is just about storing some code I may, or may not, use. The reason for the password is because we’re about to export the certificate to a Personal Information Exchange file — a PFX file, and we want it to be secure.

Second, we create a second parameter hash table and splat it onto the Export-PfxCertifcate cmdlet. Just as we did before, we pipe this command to Out-Null to suppress its output. Lastly, I’ve included three commands. The first one shows the .pfx file in the file system, the second one removes the .pfx file from the file system, and the third one removes the self-signed certificate from the system completely.

$CertPassword = ConvertTo-SecureString -String 'canoN Beach 44$09' -Force -AsPlainText

$NewCertExportParameters = @{
	Cert = "Cert:\CurrentUser\My\$($Certificate.Thumbprint)"
	FilePath = "$env:USERPROFILE\Documents\PowerShellFunctionTemplate.pfx"
	Password = $CertPassword
} # End.
Export-PfxCertificate @NewCertExportParameters | Out-Null

Get-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.Cert

And finally, here’s all the code in a single code block.

$NewCertCreateParameters = @{
	Subject = 'powershell.functiontemplate.arizona.edu'
	CertStoreLocation = 'Cert:\CurrentUser\My'
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
	OutVariable = 'Certificate'
} # End.
New-SelfSignedCertificate @NewCertCreateParameters | Out-Null

Get-ChildItem -Path $NewCertCreateParameters.CertStoreLocation |
	Where-Object Thumbprint -eq $Certificate.Thumbprint |
	Select-Object -Property *

$CertPassword = ConvertTo-SecureString -String 'canoN Beach 44$09' -Force -AsPlainText

$NewCertExportParameters = @{
	Cert = "Cert:\CurrentUser\My\$($Certificate.Thumbprint)"
	FilePath = "$env:USERPROFILE\Documents\PowerShellFunctionTemplate.pfx"
	Password = $CertPassword
} # End.
Export-PfxCertificate @NewCertExportParameters | Out-Null

Get-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.Cert

* Before closing, unless you got down here sooner, I wanted to mention a couple of the parameters I opted to use in the first command invocation. The New-SelfSignedCertificate cmdlet included the NotAfter and the KeyExportPolicy parameters, as shown below. The NotAfter parameter allowed us to include the preferred expiration of the self-signed certificate. Mine used March 3, 2031, as I added 10 years to my date value. If this parameter isn’t included, it will default to a one-year expiration. The KeyExportPolicy parameter allowed us to make the private key exportable. This is not a default, so it must be included if you suspect it’ll need to be exported, which is something we did.

...
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
...

Read-Host Prompt inside Hash Table

I’m working with Plaster and in doing so, have a few hash tables in my workspace. Suddenly, and out of nowhere, I had a thought: Can I put a Read-Host command, as the value of a key-value pair inside of a hash table? Yes, but before we get too far into this, here’s a simple hash table example without any Read-Host commands.

$Params = @{
    meal = 'lunch'
    food = 'Ramen'
    drink = 'Tea'
}
$Params

Name                           Value
----                           -----
drink                          Tea
food                           Ramen
meal                           lunch

Okay, that was simple: Choose a variable name, prefix it with a dollar sign, create the hash table structure as @{}, and then add key-value pairs as <key> = <value>.

Now, on to a Read-Host example. Read-Host is a cmdlet that can be used to interactively prompt a user for a value. It’s not always preferred, or the right to do, but there are times when it can be useful, and where its use is acceptable. In the next example, we’ll create a single key-value pair ourselves, then we’ll prompt the user for a value to assign to the Number key. As you will also determine, when prompted, the word “five” is entered, and sure enough, the entry ends up as the value for the Number key in our hash table.

Remove-Variable -Name Params
$Params = @{
    Color = 'red'
    Number = Read-Host -Prompt 'Enter spelled out number'
}
$Params
Enter spelled out number: five

Name                           Value
----                           -----
Number                         five
Color                          red

This example was one of those “can I do this moments?” Sure, I was able to return the $Params hash table with the correct value in the Number key after having been prompted for that value. This occurred, as the hash table was being defined and built. I didn’t even know if that would work, but now we both know that it does.

In the next example, we try something even more obscure, but as suspected, it doesn’t work. We first assign the Random key the value of a Read-Host prompt. As we’ve seen, that does work. Next, while still creating keys and values, we take the value assigned to the Random key in the $Params hash table and attempt to assign it to the Number key, as well. Again, this doesn’t work. As suspected, we can’t use the $Params hash table until it’s done being created. It’s not a shock, but it was worth a try, of course.

Remove-Variable -Name Params
$Params = @{
    DayOfWeek = 'Friday'
    Random = Read-Host -Prompt 'Enter spelled out number'
    Number = $Params.Random
}
$Params
Enter spelled out number: three

Name                           Value                                                                                                                             
----                           -----                                                                                                                             
Random                         three
Number
DayOfWeek                      Friday

Even if this did work, I’m not sure how this would ever really serve a purpose, but it’s always worth trying something even if doesn’t seem plausible. And if it did work, I don’t expect that we’d even need duplicate values in different keys anyway, and that’s all we’d be doing. But all that said, we absolutely can use Read-Host to assign a value to a key in a hash table, as it’s being created.

Alright, that was it. Enjoy the week!

Array (Not Hash Table) Splatting


Welcome to the 298th post on tommymaynard.com. It’s countdown to 300!


I’ve been interested… okay fine, consumed with PowerShell for five, maybe six years. At some point along the way, I learned how to splat. That’s where you create a hash table of keys and values (think parameters and parameter values), and include those when invoking a cmdlet or function. Here’s an example of not splatting, and splatting, a hash table.

Get-Process -Name firefox -FileVersionInfo -OutVariable FirefoxProcess

The above example shows how we might typically write this command. The below example uses splatting. To be more specific, it uses hash table splatting.

$Params = @{
    Name = 'firefox'
    FileVersionInfo = $true
    OutVariable = 'FirefoxProcess'
}
Get-Process @Params

Well today, many years since I started this journey, I find myself suddenly exposed to array splatting. Huh? You might be able to guess how this works. We’re still going to issue a command, and we’re still going to use the at sign (@) in front of our variable name, but this time, our variable is going to contain an array, not a hash table. Let’s take a look at a few more examples.

Get-ChildItem -Path '.\Documents\test\' -Filter '*.rtf'
Get-ChildItem '.\Documents\test\' '*.rtf'

In the first above Get-ChildItem example, you can see how we might typically issue this command. In the example below that one, we’re running the same above command; however, we’re doing so without including the Path and Filter parameter names. Because this still works, we know these two parameters are positional (or because we read the help first). This means they can be used correctly without the need to include their matching parameter names. Because they’re positional, we can use array splatting. Take a look at the final below example.

$Params = '.\Documents\test\','*.rtf'
Get-ChildItem @Params

Just a quick reminder. We should always use parameter names in code we expect to been seen, or used, more than once, such as code inside functions and scripts. It’s good to know about this, but it might be something to avoid. Using hash table splatting may still be the way to go, as it keeps our parameter names around.

PSMonday #6: Monday, June 6, 2016

Topic: Splatting and Hash Tables Continued

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

So, back to splatting: If you ever have a parameter that doesn’t need an assigned value, where the value is equal to true if the parameter is included, and false if it’s not — a switch parameter — then use $true or $false as the parameter value in the hash table. You can see an example of this below. Notice that in the example one of the parameter values wasn’t hardcoded, and instead was assigned using the value from another variable. Doing this isn’t always necessary, but it’s being shown, as an example for a time when it may be needed.

$Command = 'Get-ADUser'
$Params = @{
    Name = $Command
    ShowWindow = $true
}

Get-Help @Params

It should be said, that if you don’t include a switch parameter in the hash table, that it won’t be included when the cmdlet is run, and will therefore be false by default.

Let’s splat Send-MailMessage. This command, and its need for so many parameters and parameter values, makes it a great candidate for splatting, unlike the above Get-Help command where there was only two included parameters.

$MailParams = @{
    From = 'noreply@mydomain.domain.com'
    To = 'tommymaynard@mydomain.domain.com'
    Subject = 'Using Send-MailMessage and Splatting'
    Body = "This email sent from $env:USERNAME."
    SmtpServer = 'smtp.mydomain.domain.edu'
}

Send-MailMessage @MailParams

Bonus: If you have more parameters to add to a command, and they’re not included in the hash table (for whatever reason), you can still add them to the command.

Send-MailMessage @MailParams -Attachments 'C:\file.txt'

Second Bonus: What could be done instead of adding a separate parameter and parameter value to the command, as we saw in the above Bonus section, is adding another key-value pair to our hash table using the .Add() method.

$MailParams.Add('Attachments','C:\File.txt')

$MailParams

Name              Value
----              -----
Attachments       C:\File.txt
SmtpServer        smtp.mydomain.domain.com
Subject           Using Send-MailMessage and Splatting
Body              This email sent from tommymaynard.
From              noreply@mydomain.domain.com
To                tommymaynard@mydomain.domain.com

Send-MailMessage @MailParams

That’s it. Enjoy your Monday.

PSMonday #5: Monday, May 30, 2016

Topic: Splatting and Hash Tables

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

There are a couple things in Windows PowerShell that have a strange name. One of them, is splatting.

Consider one of those cmdlets that requires several parameters and parameter values. The below command is an older, modified command that was used to create a PowerShell Web Access authorization rule. This command, is likely going to take up some space and either wrap in the console, or add the need to scroll horizontally in the ISE.

# This example is a lengthy, single command.

Add-PswaAuthorizationRule -RuleName SharePoint-AppAdmins-Rule -ComputerName 'SPCA01' -UserGroupName MYDOMAIN\SP-AppAdmins -ConfigurationName Tools.SharePoint

The length of this command makes it difficult to read and comprehend. Some might be inclined to use the backtick (`) as a line continuation character to help make it more readable.

# This example uses backticks as line continuation characters.

Add-PswaAuthorizationRule `
-RuleName SharePoint-AppAdmins-Rule `
-ComputerName 'SPCA01' `
-UserGroupName MYDOMAIN\SP-AppAdmins `
-ConfigurationName Tools.SharePoint

This option helps some, but I’d recommend not using the backtick as a line continuation character in about 99% of instances. It’s tiny, it’s difficult to see, and if there’s a space after it, the command will throw an error.

Back to splatting. When you splat your parameters and parameter values, you first create a hash table, as signified by @{}. For those that may not know, a hash table contains key-value pairs. The first key in the below example, is RuleName. The associated, first value is ‘SharePoint-AppAdmins-Rule’. Hash tables are also called dictionary objects, or more often, associative arrays. Here’s an example of creating and storing a hash table in a variable with the same parameters and parameter values used in the above examples.

$Parameters = @{
    RuleName = 'SharePoint-AppAdmins-Rule'
    ComputerName = 'SPCA01'
    UserGroupName = 'MYDOMAIN\SP-AppAdmins'
    ConfigurationName = 'Tools.SharePoint'
}

Now, that’s easy on the eyes. Enter the variable name to see the key-value pairs stored in the hash table.

$Parameters

Name                           Value
----                           -----
RuleName                       SharePoint-AppAdmins-Rule
ComputerName                   SPCA01
UserGroupName                  MYDOMAIN\SP-AppAdmins
ConfigurationName              Tools.SharePoint

Now when you run the command, you enter the cmdlet name, the @ symbol, and the name used for the variable (without the dollar sign), as seen in the below example.

Add-PswaAuthorizationRule @Parameters

Now, when this command is run, it will include all the parameters and parameter values defined in our hash table. That’s it for this week. We’ll pick up next week and talk a little more about splatting.