#PSTip Storing of credentials

I frequently use different credentials to connect to some of my servers. Oh man, I wish I have just one account J As Configuration Manager is based on WMI, my most frequently used cmdlet is Get-WmiObject. And I use its Credential parameter to pass credentials I need for specific server. You can save your credentials to a variable by using the Get-Credential cmdlet.

PS> $cred = Get-Credential domain\makovec

But after some time it’s boring to do this every time I start my session. So, I am saving my credentials to a file and load it in $profile. I have three functions for working with credentials.

  1. New-DMCredential – creates a new file with credentials stored inside.
  2. Get-DMCredential – load credentials from a file (and then save it to a variable).
  3. Show-DMCredential – ehh, sometimes I forgot current password (especially after holiday). This one shows me password in clear text.

I got this idea of storing it this way from Lee Holmes’s PowerShell Cookbook. I’ve just written a function around his code. You can see dDM alias used in the following examples. This alias is used as a file name for stored credentials (used as output of New-DMCredential function and input of Get-DMCredential). The name of variable holding credential object is also based on this alias name.

PS> New-DMCredential -UserName domain\makovec -Alias dDM

It creates file with credentials. To be clear – the file doesn’t contain data in a clear text. It’s encrypted using Data Protection API.

I can use this stored credentials to assign them to a variable (this is the line I have in my $profile):

PS> Get-DMCredential -UserName domain\makovec -Alias dDM

When I want to connect to one of my servers I can use this variable:

PS> Connect-ConfigMgrProvider -ComputerName MyServer -Credential $dDM

Or I can see my password when needed:

PS> Show-DMCredential $dDM
Pa$$w0rd

Here are the functions I use. I’ve commented it inline.

function New-DMCredential
{
	[CmdletBinding()]

	param(
		[Parameter(
			Mandatory = $true,
			Position = 0
		)]
		[string]$UserName,
		[Parameter(
			Mandatory = $true,
			Position = 1
		)]
		[string]$Alias
	)

	# Where the credentials will be stored
	$path = 'c:\Scripts\Resources\cred\'

	# get credentials for given username
	$cred = Get-Credential $UserName

	# and save encrypted text to a file
	$cred.Password | ConvertFrom-SecureString | Set-Content -Path ("$path\$Alias")
}

function Get-DMCredential
{
	[CmdletBinding()]

	param(
		[Parameter(
			Mandatory = $true,
			Position = 0
		)]
		[string]$UserName,
		[Parameter(
			Mandatory = $true,
			Position = 1
		)]
		[string]$Alias
	)

	# where to load credentials from
	$path = 'c:\Scripts\Resources\cred\'

	# receive cred as a PSCredential object
	$pwd = Get-Content -Path ("$path\$Alias") | ConvertTo-SecureString
	$cred = New-Object System.Management.Automation.PSCredential $UserName, $pwd

	# assign a cred to a global variable based on input
	Invoke-Expression &quot;<code>$Global:$($Alias) = </code>$cred&quot;
	Remove-Variable -Name cred
	Remove-Variable -Name pwd
}

function Show-DMCredential
{
	param($cred)

	# Just to see password in clear text
	[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.Password))
}

I can probably change this script to module and make it a bit more user friendly. I will do that soon. At the moment–you can do that as your homework :).

About the author: David Moravec

I am in IT industry for 15 years, last 10 years working mainly with Microsoft management technologies. I Work in one of the biggest international accounting companies as administrator responsible for System Center Configuration Manager. I like to automate my infrastructure-related tasks with windows PowerShell. Author and speaker for Microsoft Czech Republic. I'm Running my own blog at PowerShell.cz. You can reach me on Twitter at @makovec

Related Posts

%d bloggers like this: