- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
There are many different ways to handle passwords in your PowerShell scripts. The main point is not to store them in plain text! Please don't. Just don't. It only takes a few more lines of code to decrypt encrypted strings and use them in PowerShell, so let's do that.
One of the easiest ways to encrypt and decrypt passwords in your PowerShell scripts is to use secure strings. Secure strings are an easy and built-in way to manage sensitive information in PowerShell. Secure strings are easy to create using the ConvertTo-SecureString cmdlet.
Let's say you need to prompt a user for a password in your script. One way to do this is to use Read-Host. The Read-Host command prompts a user for input and then returns that input. The Read-Host command AsSecureString parameter not only obfuscates what you type in but also saves it as a secure string.
You can see below that when I use the AsSecureString parameter, I can save my password as an encrypted secure string.
Unless you get lucky and the service you're working with accepts secure strings, chances are you're going to have to decrypt it back again before passing the password to something else. Not a problem. We can do that too. At first glance, you may think ConvertFrom-SecureString would do this, but you'd be mistaken.
PS> $mypassword = $pw | ConvertFrom-SecureString PS> $mypassword 01000000d08c9ddf0115d1118c7a00c04fc297eb010000008c9435141716494d9426986c90f68166000000000200000000001066000000010000200000001193597f27759d6c27c14c833f7fc977364733368224a4a624f3e7dee1cd122a000000000e80000000020000200000005bbaa1f752f376e9ebbc00b9496d54600ab5bda3836f5e27e71f806d6709bb85600000004607d3b1f2556528fe04d710065635db025ea96b61f6aa2c158a3244ccc61240a4865b1be3dc7fad972735fe1ddfd73f34b6693bb1ab504124f59fe66195e0d02288074d420ef2a089cb5f1ade7299514d6bde6297f1d885565075dee93c179d40000000f45aff3e0659543639dcb16243c0609699ec7fcc6c5c4ef4e4c383f5c567a236bb5ce30e8e6c3345edc1628810c435904eb13eb5570fe2742101e342d51bd887
That doesn't look right. This is because converting it from a secure string back to a string doesn't decrypt it. To decrypt it, we're going to have to use some .NET juju and use the secure string.
PS> [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw)) This is my secret password you can't see now.
Now that you know how to encrypt and decrypt a string, it's not much good if you can't reuse that password across different scripts. As it is, you'll have to be running it in the same session. Let's save the encrypted password to a file and then recall it again from disk.
To save our encrypted secure string to a file, we can export the entire object with Export-CliXml. You can see that when we do this, it remains encrypted while on disk.
PS> $pw | Export-Clixml -Path 'C:\MyPassword.xml' PS> Get-Content C:\MyPassword.xml <Objs Version="220.127.116.11" xmlns="http://schemas.microsoft.com/powershell/2004/04"> <SS>01000000d08c9ddf0115d1118c7a00c04fc297eb010000008c9435141716494d9426986c90f6816600000000020000000000106600000001000020000000cda15d7d3aad8a5134d2875256ce01b71c6f8c8887c441ae39b433c7cd55104b000000000e8000000002000020000000198b64b12916864f2a536e8d17617e862290aa4592afe2ec605a9084f7afbbf660000000b4edfef5bbe12cbafdc3c87780ad23d530e4a70f40d2dcccb85636c154c6f07d803b0ad3231e31e470362d6df20fd13dc1a4e7d50aec0042d09d6b80e9da1e27f2d60f4adce58ab6d8d47ea5dea10bcdf4a27c74c7f9db4be4e74f1bc0e8137d400000003fec35f08b9c7b207afadcf0bbc5b5b764cf98725510675e3fbfb6af424d2a0ed12d0d5a3e27d5b917ae9565c7d4bac6d1677604dfa42d997c4e12ba34096f27</SS> </Objs>
Now let's say we've got another PowerShell script that needs to reference this password. In another PowerShell script, I can import that PowerShell object from the file with Import-CliXml, which will turn it into a secure string object I can work with.
PS> $pw = Import-CliXml -Path 'C:\MyPassword.xml'
Once I have the password in a secure string object, I can then decrypt it again with our .NET juju.
Subscribe to 4sysops newsletter!
PS> $plaintextpassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw)) PS> $plaintextpassword This is my secret password you can't see now.
Using secure strings in PowerShell is just one way to encrypt and decrypt strings as passwords in PowerShell. If you'd like an in-depth look on other ways to make this happen, including encrypting with AES keys and user certificates, I encourage you to check out my Pluralsight course Building Security Tools in a Windows Environment.