Creating Explicit Credentials in PowerShell for WMI, Exchange, Lync, Remoting, etc.

When creating PowerShell cmdlets for any Microsoft technology - WMI, Exchange, Lync, etc. - it is common to need to provide credentials that are different from the default credentials. This can be even more important when you are using PowerShell remoting to connect to a remote computer.

However, using the built-in cmdlet Get-Credential causes a dialog box to be opened on the console! (And it will simply fail in some cases, when the internal PowerShell $host.UI.PromptForCredential interface has not been implemented.) This is certainly not something that you want to happen when your PowerShell script is being called with remote PowerShell or from a service, or in many other scenarios.

The solution is to pass in the full credential, already containing the secure password and the user names and (optionally) the domain or a user principal name. This is a bit challenging, as the constructor for a secure string doesn't provide you an option for passing in an entire password. Therefore, you must build the secure string one character at a time.

The two functions below make the process easy.

Note: the $username parameter to newPSCredential can be in several formats: a plain username, a domain\username, or username@domain.com, or computername\username (for a local user).

Note 2: some functions want a NetworkCredential instead of a PSCredential. Creating one of those is as simple as changing System.Management.Automation.PSCredential to System.Net.NetworkCredential.

Note 3: as a security best practice, after you call the newPSCredential function, you should ensure that the plain text password is no longer available in the calling routine.

Enjoy!

function newSecurePassword( [string]$password )
{
                ###
                ### newSecurePassword
                ###
                ### Take the normal string password provided and turn it into a 
                ### secure string that can be used to set credentials.
                ###

                $secure = new-object System.Security.SecureString

                $password.ToCharArray() |% { $secure.AppendChar( $_ ) }

                return $secure
}

function newPSCredential( [string]$username, [string]$password )
{
		###
		### newPSCredential
		###
		### Create a new PSCredential object containing the provided
		### username and plain-text password.
		###

                $pass = newSecurePassword $password

                $cred = new-object System.Management.Automation.PSCredential( $username, $pass )

                $cred
}

Until next time...

If there are things you would like to see written about, please let me know.

Published Monday, November 07, 2011 8:58 AM by michael
Filed under: , ,

Comments

No Comments