Playing with Secure Strings

There are three ways you can store a password in Powershell.

  • String: stored as plain text
  • System.Security.SecureString: encrypted in memory, can be reversed only by the principle that encrypted it.
  • System.Management.Automation.PSCredential: a Powershell class composed of username and password
#To prompt for a Secure Password
$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString

#To convert a string to a Secure Password:
"Pa$$w0rd" | ConvertTo-SecureString -AsPlainText -Force

#To create a PSCredential for use in some cmdlet
$UserName = "Domain\User"
$Credentials = New-Object System.Management.Automation.PSCredential `
-ArgumentList $UserName, $SecurePassword

#Same again but using the New() method.
$PSCred = [System.management.automation.PSCredential]::new('username',$SecurePassword)

 

You can also retrieve the encrypted password as a string again so that it can be used for unattended use. If you save an encrypted password as a string you will need to convert it back to a secure string for use in the unattended script. Its worth noting here that only the user that encrypted the cleartext first can convert the ciphertext back into a secure string correctly.

"password" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
$password = "01000000d08c9ddf0115d1118c7a00c04fc297eb010b9fe0ca1...."
$SecureString = $pass | Convertto-SecureString

 

You can retrieve the cleartext password from a secure string in one of two ways

#Create a PSCredential and call the GetNetworkCredentials method
$secstr = 'pa$$w0rd' | ConvertTo-SecureString -AsPlainText -Force
$PSCred = [System.management.automation.PSCredential]::new('scottsan',$secstr)
$PSCred.GetNetworkCredential() | fl *

#Convert the SecureString into a BinaryString and then back to cleartext
$BStr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secstr)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BStr)

Parsing Command Line Output

Here is a useful way to parse text based output into an object for powershell to consume using the Switch statement with the -Regex parameter.

Sample Output:

Deployment Image Servicing and Management tool
Version: 10.0.10240.16384

Image Version: 10.0.10240.16384
Obtaining list of 3rd party drivers from the driver store...

Driver packages listing:

Published Name : oem0.inf
Original File Name : msdokub.inf
Inbox : No
Class Name : MEDIA
Provider Name : Microsoft
Date : 24/10/2014
Version : 1.31.35.7

Published Name : oem1.inf
Original File Name : intcdaud.inf
Inbox : No
Class Name : MEDIA
Provider Name : Intel(R) Corporation
Date : 23/02/2015
Version : 6.16.0.3172

...

Parsing with Powershell
Here we use the -Regex switch to test the different regex cases against each line fed into the switch statement. The first case is important as it defines all of the properties you want to pick out. It will also act as a sort of delimiter, creating a NEW object each time the match is valid. Because of this it also outputs $obj BEFORE creating a new one.

#Get the output to be parsed into a variable
$DismOutput = dism /Online /Get-Drivers | %{$_.Trim()}

$obj = $null

Switch -Regex ($DismOutput){
   '^Published Name : (?<pub>.+)' {
      $obj
      $obj = [PSCustomObject]@{
         PublishedName = $Matches.pub
         ProviderName = $null
         Date = $null
         Version = $null
      }
   }
   '^Provider Name : (?<prov>.+)' {$obj.providername = $Matches.prov}
   '^Date : (?<date>.+)' {$obj.date = $Matches.date}
   'Version : (?<ver>.+)' {$obj.version = $Matches.ver}
}
#Last $obj wont be output by the Switch so we output it here.
$obj