Reputation: 153
I have a cmdlet Append-SecureString.ps1
which provides padding of a desired length/size to a SecureString with a particular character('o' just for demonstration sake). And I am using another cmdlet Decode-SecureString.ps1
which obtains the plaintext from the SecureString.
The cmdlet Decode-SecureString.ps1
#Decode-SecureString.ps1
param([SecureString]$SecureString)
Write-Information -MessageData "Retrieving string..." -Verbose -InformationAction Continue
try{
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$length = [Runtime.InteropServices.Marshal]::ReadInt32($bstr, -4)
[Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
}
finally{
if ( $bstr -ne [IntPtr]::Zero ) {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
}
The cmdlet Append-SecureString.ps1
#Append-SecureString.ps1
param(
[Parameter(mandatory=$true)]
[System.Management.Automation.PSCredential]$Credential,
[Parameter(mandatory=$false)]
[int]$Length
)
while($Credential.Password.Length -lt $Length){
$Credential.Password.AppendChar('o')
}
$Credential.Password.Length
$Credential.GetNetworkCredential().Password
.\Decode-SecureString.ps1 -SecureString $Credential.Password #Custom cmdlet provided above.
And the result is:
$cred=Get-Credential -Message "Enter the credentials."
$cred.UserName
picachu
$cred.Password.Length
14
$cred.GetNetworkCredential().Password
THISISPASSWORD
.\AppendTo-SecureString.ps1 -Credential $cred -Length 64
64
THISISPASSWORD
Retrieving string...
THISISPASSWORDoooooooooooooooooooooooooooooooooooooooooooooooooo
So, as we see, $Credential.GetNetworkCredential().Password
didnot display the complete string of the $Credential.Password which is a SecureString by the way. But my custom cmdlet Decode-SecureString
successfully obtained the complete padded string from the $Credential.Password which is the SecureString.
So, can anybody pin out why GetNetworkCredential().Password
didnot displayed the complete string, and if possible, how do you exactly make GetNetworkCredential().Password
display the string behind the $Credential.Password
without using my custom cmdlet Decode-SecureString.ps1
?
Upvotes: 1
Views: 9076
Reputation: 153
I have edited the cmdlet AppendTo-SecureString.ps1
to workaround as below. It doesn't require Decode-SecureString.ps1
to display the characters anymore. The problem was that as @PetSerAl pointed out, the GetNetworkCredential()
doesnot rebuild the cache for an already existing PSCredential
object. So I decided to build another credential using the new SecureString
and return it.
param(
[Parameter(mandatory=$true)]
[System.Management.Automation.PSCredential]$Credential,
[Parameter(mandatory=$false)]
[int]$Length
)
$secureString=$Credential.Password
while($secureString.Length -lt $Length){
$secureString.AppendChar('@')
}
$tempCred=New-Object System.Management.Automation.PSCredential -ArgumentList $Credential.UserName,$secureString
#Comment out below for returning the new credential.
$tempCred.Password.Length
#Comment out below for returning the new credential.
$tempCred.GetNetworkCredential().Password
#UnComment out below for returning the new credential.
###Return $tempCred
Or, you can skip rebuilding a new PSCredential
object and use NetworkCredential
as below:
$tempCred=([System.Net.NetworkCredential]::new($Credential.UserName,$secureString))
#Comment out below for returning the new credential.
$tempCred.Password.Length
#Comment out below for returning the new credential.
$tempCred.Password
#UnComment out below for returning the new credential.
###Return $tempCred
Upvotes: 1