Summary: Microsoft Windows PowerShell MVP, Sean Kearney, teaches how to use passwords in a script and talk to legacy systems.
Microsoft Scripting Guy, Ed Wilson, here. This week we will have one guest blogger for the entire week. Sean Kearney has written a series of blog posts about Windows PowerShell and the Legacy. I am not going to be redundant by reposting his biography each and every day.
Take it away, Sean.
First off—this is NOT a good idea…
Leaving clear passwords in a script of any kind is about as bad as an idea can be. Except for maybe writing your PIN number on your bank machine card, or writing your network password on a piece of paper and taping it to your monitor…you get the idea.
This having been said, there are situations where it happens, especially when you need to manage legacy setups. In fact, this is a very common question that I receive when I talk to users.
Many old VBScript scripts and console application .bat files or CDMs will already be doing this. You may have to pass these to a Windows PowerShell script—or the other way around—you may be running a Windows PowerShell script and need to pass the credentials down to the legacy application.
Here’s example one. You’ve got a Windows PowerShell script that gets credentials as per normal:
$MyCredentials=GET-CREDENTIAL –credential CONTOSO\UberSecretUserName
And of course, as normal, you will see Windows PowerShell pop up the old familiar box shown here.
You would key in the password as normal, which gives you a nice variable to pass into various cmdlets that require secure credentials.
Now here is a thought…
Let’s pretend that you need to pass those same credentials to a legacy VBScript script or CDM (or something else from the console world). Can you get the password out of this? Normally, you would type the variable on the screen and get output similar to the following.
PS C:\> $MyCredentials | format-list
UserName : CONTOSO\UberSecretUserName
Password : System.Security.SecureString
But the System.Security.SecureString is absolutely useless as a password to a legacy system.
I was playing about, and I ran Get-Member on the value and found that there is a method available called GetNetworkCredential. Running this method against $MyCredentials will reveal the Username, Password, and Domain as three separate, clear text values:
With this method, I can pull out the username and password like so:
With this in clear text, we could pass it directly back to a legacy application.
But now the flipside. Let’s pretend we have a legacy application that is already passing user IDs and passwords. You need to call a cmdlet in Windows PowerShell from a legacy setup. But it requires the output of Get-Credential. What to do?
This is not an issue. If you ran Get-Member against the $MyCredentials variable, you would see the class that it’s associated with in .NET as shown in the following image.
If you go to msdn.microsoft.com, you’ll see that to make this, you have to re-create the object by specifying the class and the values it needs.
$SecurePassword=Converto-SecureString –String $MyClearTextPassword –AsPlainText –force
$CredentialsMadeFromClearText=New-object System.Management.Automation $MyUsernameDomain $SecurePassword
Now you can build that needed secure credential in Windows PowerShell from the legacy environment.
There are far more secure ways to get this done. But the important point is knowing how to get the two worlds to happily coexist.
The Power of Shell is in you.
Guest blogger week will continue tomorrow when Sean will continue to talk about Windows PowerShell and the Legacy. A special thank you to Sean for writing this week’s blog posts. Hope you enjoy them.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy