Yet another way to handle authentication with PowerShell secure strings

I realize there are tons of articles out there about handling authentication. What I don’t see are a lot of examples where the methods are demonstrated within a set of tools. Authentication schemes can turn a simple shell task into a chore. You can find a wide range of methods to secure a password for a Schedule Task that’s manageable for one or two jobs, though are probably not simple enough to help you speed things up for routine tasks.

I’ve been using Secure-String to hash passwords for a long time. Here is a basic credential stash that prompts you for your password when you launch a shell and then stores the secure-string in a variable. Later you can fetch the variable for various other commands that can accept a credential or user/pass as an argument.

# popup a login prompt
[string]$username = $env:USERNAME
[string]$message = "mycreds for mysql"
$creds = get-credential -Message $message -UserName $username
# store the secure string
$global:myCred = $creds.Password | ConvertFrom-SecureString

This code will popup a Windows credential dialog where I can securely type my password. Since my MySQL user name is the same as my $env:username variable, I’ll just use that. I like to make that a little easier to handle from a shell prompt, so I can call them efficiently when I need them.

function Set-myCreds{
 param(
 [string]$username = $env:USERNAME,
 [string]$message = "mycreds for mysql"
 )
 $creds = get-credential -Message $message -UserName $username
 $global:myCred = $creds.Password | ConvertFrom-SecureString
}

Now I can store them with a single command

set-mycreds-login-prompt.png

The function stashes my hashed password in the variable $global:myCred, it’s available in the shell as $myCred, also.

set-mycreds-global-var

Now I can recreate the credential object pretty easily:


$myCreds = [PSCredential]::new(
  $env:USERNAME,($myCred | ConvertTo-SecureString)
 )

Thats it… I’ve used several similar schemes where the password was stored in a txt file to be read using Get-Content. But I don’t mind typing a password when I open a new shell, if I need to. And, just like the set-mycreds funtion, having a tool to get a credential object makes it handy.


function Get-myCreds {
    [PSCredential]::new(
       $env:USERNAME,($myCred | ConvertTo-SecureString)
    )
}

I can add a little safety to this but checking to see if $myCred has anything in it before creating the credential, like this:


function Get-myCreds {
    if(-not $myCred){ set-mycreds }
    [PSCredential]::new(
        $env:USERNAME,($myCred | ConvertTo-SecureString)
    )
}

That way, if the $myCred variable isn’t set (like the first time I use it) it prompts me to set a password for the $myCred variable. By itself, it is already useful for cmdlets that take a PSCrendtial object like the VMware tools.


Connect-ViServer -Server some.vc.com -Credential (get-mycreds)

To use the stored password for something like MySQL it has to be decoded into plain text. The PSCredential class has a method named GetNetworkCredentail() just for that purpose. Once you have the credential object you can convert it like this.

$mycreds = Get-myCreds
$mycreds.GetNetworkCredential().password
brendansPassword

 

In a previous article I discussed connection accessing MySQL with PowerShell programmatically. I put a poorly introduced function I use to configure connection strings for MySQL. If can easily be ported to other platforms like SQL Server and Oracle. Anyway, it’s worth a (simplified) repost. This time I’ll use the Get-myCreds function I just created.


filter myCStr {
    param (
        [String]$Server,
        [String]$uid = $env:USERNAME,
        [String]$pwd = (Get-myCreds).GetNetworkCredential().password
    )

    if ($Server -eq "myFavServer") {
        $myCStr = "Server=$Server;port=23306;uid=$uid;pwd=$pwd"
    }
    if ($Server -eq "my2ndFavServer") {
        $myCStr = "Server=$Server;port=33306;uid=$uid;pwd=$pwd;"
    }
    else {
        $myCStr = "Server=$Server;port=3306;uid=$uid;pwd=$pwd;"
    }
    $myCStr
}

The difference now is that I will only be prompted for a password the first time I connect to a MySQL instance with the connection string generator. This is extremely handy when you run a process, like an inventory, since I only have to enter my password one time!

Storing credentials for use in your shell can simplify authentication for shell tools you may use. Storing the credentials in memory can help you avoid unnecessary security concerns over storing credentials written in a text file. You can use a tool like this for PowerCLI, UCS Manager, or homegrown code like my MySQL connection string function.  Having a means to streamline authentication can make your daily tasks easier.

Advertisements
This entry was posted in powershell. Bookmark the permalink.

One Response to Yet another way to handle authentication with PowerShell secure strings

  1. Pingback: PowerShell classes and password gizmos… | brendan62269

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s