- Export and import to and from Excel with the PowerShell module ImportExcel - Thu, Apr 21 2022
- Getting started with the PSReadLine module for PowerShell - Thu, Feb 24 2022
- SecretsManagement module for PowerShell: Save passwords in PowerShell - Tue, Dec 22 2020
Overview
The PowerShell team at Microsoft has been working on the SecretsManagement module for over a year and has already released several versions. Each release has included additional features, functionality, and stronger security.
Secrets management in PowerShell is broken up into two parts: the engine and the storage vault. The SecretsManagement module is the engine and is responsible for the management and encryption of passwords and other secrets. The secrets are then stored in a vault. I will demo the SecretsManagement module and the SecretStore vault, which is a vault offered from Microsoft.
There are other vaults available for LastPass, KeePass, HashiCorp Vault, Keychain, and the Windows Credential Manager. These vaults are built by the open-source community, and more become available all the time. Sydney Smith from the PowerShell team at Microsoft wrote an excellent blog post explaining this in further detail. I encourage you to read her article, as it contains useful tips for working with the vault.
At the time of writing, the current modules from Microsoft are preview versions. They're not officially considered "production ready," but I have used these modules in my production environment for over a month now with no bugs, hiccups, or gotchas. Let's roll up our sleeves and see how these modules work.
Installation
I will be installing the Preview6 version of the SecretsManagement module and Preview4 of the SecretStore. Both modules work in Windows PowerShell (version 5.x) and PowerShell Core (versions 6.x and 7.x). Installation of the modules is easy to do, but there are two potential gotchas to watch for.
The first is that since these are preview modules, you need to use the -AllowPrelease parameter during installation. That parameter isn't available with the default version of WindowsPowerShell v5.x. To get around that issue, you need to update your version of the PowerShellGet module to the latest version. PowerShellGet is the module that handles installing modules. The syntax for the PowerShellGet module update is:
$params = @{ Name = 'PowerShellGet' Repository = 'PSGallery' AllowClobber = $true Force = $true } Install-Module @Params
The second point to be aware of is that these latest versions of the modules contain breaking changes. You need to uninstall any old module versions before installing these recent versions. With that out of the way, let's install the SecretsManagement module, which I mentioned is the engine that does all the processing and encryption:
$params = @{ Name = 'Microsoft.PowerShell.SecretManagement' AllowPreRelease = $true Repository = 'PSGallery' } Install-Module @Params
Then you will install a vault that will store your secrets. I will be using the SecretStore module:
$params = @{ Name = 'Microsoft.PowerShell.SecretStore' AllowPreRelease = $true Repository = 'PSGallery' } Install-Module @Params
Creating the Secrets Vault
After installation is completed, the next step is to create a vault for storing your secrets. This process is called "registering a vault":
$params = @{ Name = 'VaultDemo' ModuleName = 'Microsoft.PowerShell.SecretStore' DefaultVault = $true AllowClobber = $true } Register-SecretVault @params
The vault you create needs a master password assigned. But notice that it's not assigned when the vault is registered. While that may seem odd, that's the expected behavior because the vault doesn't exist until you attempt to store a secret. Registering a vault only adds the settings to the registry. It builds the vault on the fly when the first secret is saved to the vault.
Remember that the SecretStore vault is only one of a few different vault providers that you can use to store your secrets. The syntax to create and manage secrets is identical across vaults because the SecretsManagement module does all the work. You can have multiple vaults installed on your computer, and they can be different vaults.
Creating your first secret
Creating and storing your first secret is a simple task. The help file included with the module is a great way to start, and I recommend you use it to become familiar with the cmdlets. Let's generate a list of available commands:
get-command -module 'Microsoft.PowerShell.SecretManagement'
To create a secret, use the Set-Secret cmdlet.
Set-Secret -name "TestSecret" -secret "MySecretData"
As I mentioned earlier, the vault is instantiated when the first secret is saved to it. You are also prompted to set the master password; this is a one-time process. After saving a secret, you can view the vault by typing:
Get-SecretInfo
You're probably wondering though, "Secrets are great, but I need to save credentials."
In the earlier example, the cmdlet only accepted a secret; there were no parameters to accept a username AND a password. It's not obvious at first, but secrets can be more than a simple string of characters, and it is possible to save credentials to a vault. Remember that in PowerShell, we store credentials as a PSCredential object. The PSCredential object is one object that contains two pieces of information.
The trick here is to understand that a credential object (a username and password) is one secret. That secret can then be passed into the vault with the correct syntax. To store a credential object in the vault, you need to build the object first and pass the object to the vault cmdlet. That sounds harder than it is. Let me show you how.
Set-Secret -name MyAdminCred -secret (get-credential MyDomain\Admin)
Once the credential is saved to the vault, you can view the vault to confirm that the new credential was added. I saved the PSCredential object in the old-school domain format, but I could have used UPN format instead (username@domainname). The vault stores data you type; it doesn't impose limits on what you type or validate the data.
To take that point one step further, that username and password combination I typed was not validated against a domain. If I typed a bad password, the vault will save it. If I attempt to log in with faulty credentials, it will fail. The vault is a storage mechanism; it saves whatever you type for a secret.
Vaults have a default timeout value of 15 minutes. It will prompt you to enter the master password the first time you try to access a vault or if 15 minutes have passed with no activity. The timeout value can be changed, and you can also choose to remove the vaults' requirement of a master password. I would not recommend that, as I am sure you can imagine that would be a major security risk.
Recalling a secret from the vault
Once you have data saved to the vault, retrieving a secret from the vault is another process that is simple to execute. The syntax to recall a secret is easy to understand:
Get-secret -Name MyAdminCred
I retrieved the secret from the vault. I was also prompted for my master password because the vault hadn't been accessed in the last 15 minutes.
You can recall the secret and save to a variable:
$Cred = Get-Secret MyAdminCred
Saving your credentials to a variable for reuse is a common scenario, but it's also one that doesn't need to happen at all. Instead, you can use the pipeline to recall a secret from the secret vault and pass it to a cmdlet.
You can see in the example below that I am logged in as a user named mkadmin. I am recalling a credential named CredVagrant, which contains the username and password for a user named Vagrant. I then pass that credential from the vault to the New-PSSession cmdlet, which sets up a session as the user named Vagrant. I then use that pssession cmdlet to connect to a domain controller as the user named Vagrant.
Subscribe to 4sysops newsletter!
Summary
We have seen how the SecretsManagement and SecretStore modules from Microsoft enable you to safely and securely store encrypted passwords on your computer and recall them for use later on. This functionality allows anyone to secure not just passwords, but any type of information that may not be wise to save in unencrypted form in something like a plain-text script. Now we have a way to save API keys, GUID strings, pass phrases, and others in a simple-to-use and efficient tool that integrates effortlessly into our scripts and command-line tools.
Has that Microsoft.PowerShell.SecretManagement been pulled or something? I'm not seeing it out on the PSGallery
I've been waiting for this to come out for a while. 🙂
Thanks,
David F.
Hi David. Yes searching for the module can be problematic. Use the syntax I included in the article.
The syntax below finds a match when I search by specific name from PS7
Some Alpha/preview modules have been retired. But v.1 (which is GA) is still there.
PowerShell Gallery | Microsoft.PowerShell.SecretManagement 1.0.0
Cheers. Emanuel
P.S. Or yes, you can use allowprerelease 🙂
Just dont touch it in secret manager in gui.
But this was introduced at Ignite last year….
Hi Wena,
I think you may be talking about Credential Manager in GUI. This is different than credential mgr and the secrets saved through this module wont appear in the Credential Mgr in the Windows GUI.
Hi Mike,
Great information, thank you!
On an semi-related note, what configuration are you using for your Windows Terminal profile as I really love the "Elevated" tags for the prompt. Anywhere you could point to?
Hi Cameron. Sure I can point you in the right direction!
My customized cmd prompt will be the next set of articles on 4sysops. I am finalizing the write-up but right now it is a long article (almost 3000 words), so we'l probably split it up into a series of smaller reads.
So, just hang tight and you should see the articles in the next week or two (depending on holiday posting schedule).
Cameron,
I ended up writing extensively about customizing your PowerShell command prompt at my site. The reason for this is that the post is very detailed and longer than the posts we usually do on 4sysops. If you would like to know more check out my article here:
https://www.commandline.ninja/customize-pscmdprompt/
Hi Mike,
Thank you very much! Much appreciated!
I forgot the allowprerelease.. that's what I was missing.
Thanks Mike!
David F.
When you created a Vault, where was it created at? On local machine? Can this be used with Azure Key Vaults?
@Mike K. – I got it installed, and put in the BitWarden vault component. When I do the Set-Secret component, it complains about not being able to find the BitWarden executable. Is there something I need to do to point it that executable?
Thanks!
David F.
I haven’t tried the Bitwarden module yet but looking at the maintainers github site, it says you need to install the BitWarden-CLI for the extension to work properly.
Did you install the Bitwarden CLI ?
I hadn't, good find & thank you! Downloaded & unzipped.. off to the races 🙂
Thanks yet again 🙂
Looking forward to the next RTSP event 🙂
David F.
Was just wondering if the module offers a REST API interface.
So that someone can send commands to it remotely via HTTP (to get/set secrets)
Of course that would mean ,that this needs to be running as a service obviously.
On another note, is there any functionality for auditing maybe ?
(ex. who opened what secret and when, who created/deleted which secret and when, etc…)
And finally is there a source control mechanism on the vault contents ?
(ex. this secret was changed from this to that by that account on that date)
Finally does it support any kind of tree structure, like categories or folders for the secrets
(ex. a folder for my AD secrets, and another folder for my AWS secrets, etc..)
In that sense, can we tag the secrets ?
(just like any AWS/Azure resource for example)
I would simply say that answer to all your questions is no.
Its a PowerShell module which loads when you call it. It does not run/cant run as a service anywhere.
For the other points – those are a bit advanced features which cannot be expected to be implemented in such module. Most of the points you asked for (except such deep auditing like who access what) are included in great freeware called KeePass.
Cheers
I find it quite confusing how one gets the installed vault extensions like
SecretManagement.Chromium SecretManagement.Lastpass SecretManagement.KeyChain
etc registered and used.
I want Keychain to be the default vault on a Mac, or possibly Lastpass, and Chromium or Lastpass on a windows machine, what are the steps to achieve that?
Hey BigBear!
So a few things to keep in mind. This article was written for preview6 and now the module is a release candidate. When it was preview version you would need to search with a special tag in order to find the prerelease versions. That’s no longer necessary. Here’s some commands you can use to help you along.
Finding modules to install:
find-module -tag "secretManagement"
Set Default Vault (only can be run after the credman vault module is installed:
Set-DefaultVault -Name CredMan
If you have more questions, reply here. Also, I did a live demo of these modules a few weeks ago. If you would like to watch the video, then visit this link:
https://youtu.be/5Za02Y8jCBw
@Mike K, Is there a way to link windows authentication when retrieving passwords from the local secret store? I have a backgroud process running that needs to retrieve secret and don't want to prompt user from time to time for the master password.
Thank you,
Sylvia
Hi Sylvia,
This is probably the most common question I get with secrets mgmt.
Short Answer:
Yes! There are options to solve your issue but they come with a serious reduction in security
Long Answer:
You can configure the local vault to have no master password and you can also configure the vault to not be stored in the AllUsers profile instead of inside a specific user profile. Those two settings are not coupled together, meaning you can do one, or the other, or both. However, you are seriously reducing the security when you enable these options.
Some extra info to consider…
This solution from Microsoft has an intended use: password mgmt for a user. If you need more options to support things like automating scripts without user interaction, then the long term answer is a 3rd party vault or AZ KeyVault, which have better authentication methods.
The SecretStore vault was built to fill a need for users who are struggling managing passwords on their local systems. A cloud based vault will have better options and choices. That is why there are multiple vaults available that work with the SecretManagement module. Pick the right one for the task, instead of trying to bend the SecretStore vault to your needs..
One last point…
There is talk in the community of using a certificate as the AUTH method for a local password vault. This would solve your problem AND ALSO maintain a high level of security but it doesn't exist as of the time of this comment…
Hoped that helps!
Ahhh, this was my main question as well after reading the article. Was hoping for a secure way to pass secrets to scripts that run automatically via scheduled task when no one is here. Unfortunately I work in offline environments too so they cloud options won’t work for me unless AZ KeyVault can be brought into such an environment.