The Surly Admin

Father, husband, IT Pro, cancer survivor

Secure Credentials Function

This particular function rose out of another script I wrote a little while back, the Restart Computers with Firm Confirmation.  I wanted to make a particular piece of it available for others to use in their own scripts or at least something I can always refer to within my own.

Secure Credentials

One of the more interesting aspects of Powershell is it’s ability to use secure credentials.  The idea is you enter a password and the script will keep and use that without ever knowing what it is.  If you try to look at the password it will be jibberish.  For those with security on their mind, this is a great feature as you can now have passwords in your script without them being stored in plain text!

The primary object behind this ability is the PSCredential object.  This securely stores the domain, username and password in the object and can be used with pretty much any cmdlet that uses the -Credential parameter.  To create the PSCredential object we use the Get-Credential cmdlet.  If you run it by itself you’ll get a pretty familiar pop-up window where you can enter your username and password.

Let’s assign the object to a variable so we can look at it more closely:

$a = Get-Credential

$a.GetType()
IsPublic    IsSerial    Name                  BaseType
--------    --------    ----                  --------
True        False       PSCredential          System.Object

$a | Get-member
TypeName: System.Management.Automation.PSCredential

Name                  MemberType   Definition
----                  ----------   ----------
Equals                Method       bool Equals(System.Object obj)
GetHashCode           Method       int GetHashCode()
GetNetworkCredential  Method       System.Net.NetworkCredential GetNetworkCredential()
GetType               Method       type GetType()
ToString              Method       string ToString()
Password              Property     System.Security.SecureString Password {get;}
UserName              Property     System.String UserName {get;}

So there’s not really a lot we can do to a PSCredential object, but we can pull the Password property (which is a SecureString) and the Uesrname.  For the purposes of this function we’re only interested in the password as we’ll be getting the user name either from the local environment (the old %username% for you DOS people) or from a parameter set by the script calling the function.

The purpose of this function is so you can plug it into your own script and easily use secure credentials without necessarily having to answer a password prompt every time.  The function will save the password in a secure file and recall it to create the PSCredential object you need.

First we need to set some parameters and their defaults:

Param (
 [String]$AuthUser = $env:USERNAME,
 [String]$PathToCred = "c:\utils"
 )

Pretty simple, the user name you want to use (or by default the username of the person running the script) and a path to where the script can find the secure files.

Next we need to create a path to the user specific credential file and test if it exists.  If it doesn’t then we need to prompt the user for the information, pass the .Password property down the pipeline to the ConvertFrom-SecureString–wait, what?  Definitely sounds like we’re taking our nice secure PSCredential object and stripping the security from it, doesn’t it?  Luckily that’s not the case.  The ConvertFrom-SecureString, and excuse me for quoting the help file, the cmdlet converts a secure string into a encrypted standard string.  Unlike a secure string, an encrypted standard string can be saved in a file for later use. 

$File = $PathToCred + "\Credentials-$AuthUser.crd"
If (-not (Test-Path $File))
 { (Get-Credential).Password | ConvertFrom-SecureString | Set-Content $File
 }

Now, we’ve saved the file it’s time to read it back in.  Technically we don’t have to do this since we have the information already, but this is a little way of reusing code.  The function just reads the file in and deals with it, I don’t have to do any testing to see if I created the file already, etc.  It’s one of those things that’s probably not as efficient as it could be but it’s going to run so fast anyway no one will every notice.

Read the secure file, convert it back to a Secure string then create a new PSCredential object using the user name and the password and return it back to the main script.

$Password = Get-Content $File | ConvertTo-SecureString
 $Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)
 Return $Credential

That’s it.  How do you use it?  Well, download the entire source from Spiceworks here.  Then simply paste the function towards the top of your script.  In Powershell, unlike vbScript, functions actually go at the top of the script, right under any Param statements you have.  From there you can use it in your script like so:

$Cred = GetCredentials -AuthUser Administrator
Get-ADUser Martin9700 -Credential $Cred

This would allow you to use the Administrator user ID to get the Active Directory object for user Martin9700.

Hope you found this interesting!  Questions are always welcome.

October 3, 2012 - Posted by | PowerShell | , ,

5 Comments »

  1. […] use them.  Powershell gives us the ability to save passwords in a secure manner, and I wrote the GetCredentials function to take advantage of that fact.  This was a fun little project because I got to use […]

    Pingback by Report When New Users are Added to Active Directory « The Surly Admin | October 22, 2012 | Reply

  2. […] is the Secure Credential object, or PSCredential object.  I even wrote about using it here and here.  But a recent script request over at Spiceworks has shed some light on the PSCredential and now […]

    Pingback by PSCredential Object Secure? « The Surly Admin | October 29, 2012 | Reply

  3. […] is we need to use the Credential parameter and we need to save it, which is where I pull up my GetCredentials function I wrote awhile back.  One change I made to it was to add a custom encryption key, which is […]

    Pingback by Report All Snapshots in Your VMware Environment « The Surly Admin | March 18, 2013 | Reply

  4. […] to save the username and password in clear text so that means we need to bust out our old friend, Secure Credentials Function.  I’ve used this function a couple of times now and it works well but I noticed something […]

    Pingback by New Version: Simple Server Status « The Surly Admin | May 7, 2013 | Reply

  5. […] had several independent domains–what were they thinking?!  I had an immediate idea to use my Get-SavedCredential function and figured I could modify things pretty quickly and easily to get what he wanted.  At […]

    Pingback by Parameter Sets « The Surly Admin | February 10, 2014 | Reply


Leave a comment