Powershell prompt for password convert securestring to plain text - Svendsen Tech
Jump to page sections
To prompt a user for a password, you can use the cmdlet ''Read-Host'' with the parameter -AsSecureString. The problem I ran into was when I wanted to use it in conjunction with a COM method call that needed the password in plain text. Specifically, I wanted to specify alternate credentials for mapping a network drive. The cmdlet ''New-PSDrive'' doesn't accept the -Credential parameter in PowerShell v2.

I searched the web for a while, but didn't find a way to convert the secure string back into plain text. A helpful person I came across had done it and had the magic incantation required, which I am now making easily available for others who might not run into this same helpful person. He said he thought he found it buried deep in an Exchange cmdlet somewhere. Another helpful person later made me aware that this left an unfreed pointer, so make sure you check out the example function for properly handling the pointer.

A Generic Function for Converting Security.SecureString Objects to Plain Text Strings

This is a simple function that takes a System.Security.SecureString object (a secure string) and returns it in plain text (as a string). It also makes sure to clean up (free) the password pointer.

function ConvertFrom-SecureToPlain {
    param( [Parameter(Mandatory=$true)][System.Security.SecureString] $SecurePassword)
    # Create a "password pointer"
    $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
    # Get the plain text version of the password
    $PlainTextPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)
    # Free the pointer
    # Return the plain text password

Getting the password out of a Get-Credential object

This demonstrates how you can get the password out of a PowerShell credentials object that you get from Get-Credential in your own session.
PS C:\> $cred = Get-Credential

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:

PS C:\> $cred | ft -AutoSize

UserName Password -------- -------- dummy\someuser System.Security.SecureString PS C:\> $cred.GetNetworkCredential().Password SomeSecretPassword!

Demonstration of Converting SecureString to Plain Text

As you can see below, the [Runtime.InteropServices.Marshal] class is where the most relevant stuff seems to be. This guy uses some methods that seem to be Unicode-specific from the same class in a related article.

'''NB!''' ''Be aware that you should not normally use this one-liner, as it leaves an unfreed pointer; instead see the example function above.''
PS C:\> $SecureString = Read-Host -AsSecureString 'Enter password'
Enter password: *********
PS C:\> $SecureString
PS C:\> ConvertFrom-SecureString $SecureString
PS C:\> [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString))

Example Script for Mapping a Network Drive With Alternate Credentials

This demonstrates how you could check if a server is available for mapping network drives against. The script will exit if a connection can not be made. It doesn't do anything useful now if a successful drive mapping is performed; it's just an example.
Set-StrictMode -Version Latest

function ConvertFrom-SecureToPlain {
    param( [Parameter(Mandatory=$true)][System.Security.SecureString] $SecurePassword)
    # Create a "password pointer".
    $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
    # Get the plain text version of the password.
    $PlainTextPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)
    # Free the pointer.
    # Return the plain text password.

$Share = '\\2008r2esxi\admin$'
$DriveLetter = 'X:'

$Username = Read-Host 'Please enter a username and domain in the form DOMAIN\USERNAME'
$Password = Read-Host -AsSecureString 'Please enter your password (it will not be displayed)'

$PlainTextPassword = ConvertFrom-SecureToPlain $Password

# Try to map the drive and hide errors (will be displayed later). $Drive = New-Object -ComObject WScript.Network $ErrorActionPreference = 'SilentlyContinue' $Drive.MapNetworkDrive($DriveLetter, $Share, 'false', $Username, $PlainTextPassword) | Out-Null # Check if it failed, exit if it did, and print the error. if (-not $?) { "Failed to map $Share to drive ${DriveLetter}: $($error[0].ToString())" exit 1 } # Make errors visible again. $ErrorActionPreference = 'Continue' # If we get here, the mapping was successful "Successfully mapped $Share to drive letter $DriveLetter" # ... more stuff
    Powershell     Windows     All Categories

Google custom search of this website only

Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.

If you want to reward my efforts