Tag Archives: Out-Null

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

An Array of Hash Tables


Welcome to the 293rd post on tommymaynard.com. It’s countdown to 300!


If you’ve ever looked into Pester and TestCases, then maybe you’ve seen what I’m about to mention. While today’s post has nothing to do with Pester, this feature in Pester uses an array of hash tables. Neat, right? While adding a couple New-PSDrive commands to my PowerShell profile, I moved from this first option,…

$Param = @{
    Name = 'IDT'
    Root = '\\tommymaynard.com\Windows\Internal\Users\tommymaynard'
}
New-PSDrive @Param -PSProvider FileSystem | Out-Null

$Param = @{
    Name = 'IDI'
    Root = '\\tommymaynard.com\Windows\Internal'
}
New-PSDrive @Param -PSProvider FileSystem | Out-Null

…to something else.

While the use of splatting is a bit more grown-up than creating long, multi-line wrapping commands, there’s no reason why we should be executing the same command — New-PSDrive, in this instance — outside of a looping construct. That was my thought today, anyway. If we need to invoke the same cmdlet or function more than once, it should only be entered into our code, once. It is possible there’s an exception here, but for the most, I stick to this belief.

But how do I combine multiple hash tables in to looping construct? Well, my solution had everything to do with my quick remembrance of Pester and TestCases. For fun, we’ll link to a quick example from a Pester issue I recently created in GitHub. This offers us a good example. See the third It block in the Pester example in number 4 (“Current Behavior”). Do you see that? It’s an array of hash tables. Perfect example for what I needed.

As we create our hash tables, we need to ensure they’re being added to an array. Then we can loop through our array elements with ForEach, or ForEach-Object. I’ll include examples for both. First, however, let’s create our array of hash tables.

$HashTableArray = @(
    @{
        Name = 'IDT'
        Root = '\\tommymaynard.com\Windows\Internal\Users\tommymaynard'
    },
    @{
        Name = 'IDI'
        Root = '\\tommymaynard.com\Windows\Internal'
    }
)

And now, let’s ensure what we have, is where we want it, and want we want.

PS > $HashTableArray

Name                           Value
----                           -----
Root                           \\tommymaynard.com\Windows\Internal\Users\tommymaynard
Name                           IDT
Root                           \\tommymaynard.com\Windows\Internal
Name                           IDI

As mentioned, there’s a couple way to loop though these. One is using a Foreach construct — which is the first below example — and one is using the ForEach-Object cmdlet. They’re both below, and listed in the respective order in which they were discussed. So yes, if you’re calling the same command outside of looping construct, you need to consider how to do better, if you can. There’s no reason in my instance that New-PSDrive should be in a our code more than once.

Foreach ($HashTable in $HashTableArray) {
    New-PSDrive @HashTable -PSProvider FileSystem | Out-Null
}

$HashTableArray | ForEach-Object {
    New-PSDrive -Name $_.Name -PSProvider FileSystem -Root $_.Root | Out-Null
}

If you didn’t notice, I’ve piped my New-PSDrive commands to Out-Null. This was done in order to remove the output that would’ve otherwise been produced.