Can’t we really see the text/password entered through -AsSecureString or with Get-Credential? What I have to do if I got a requirement to compare the passwords? The example scenario for me as a System administrator is, if I have a script which resets admin password acrosss a list of hosts, I will prefer the script to ask for the password two times in secure format and inturn my script should compare these two passwords and proceed only if the passwords entered at two attempts is matched.
In one of the powershell blog author talked about seeing the secure text in plain format. I used that and developed below script for comparing the passwords using powershell.
Write-Host "Hey..!! I am here to compare the password you are entering..." $pwd1 = Read-Host "Passowrd" -AsSecureString $pwd2 = Read-Host "Re-enter Passowrd" -AsSecureString $pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd1)) $pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd2)) if ($pwd1_text -ceq $pwd2_text) { Write-Host "Passwords matched" } else { Write-Host "Passwords differ" }
Let me know if you have any comments/questions…
Comments on this entry are closed.
Very Good!
Thanks!!
Hi – nice script but one small problem, you’re not handling case sensitivity – i.e. ABC and abc and AbC are all coming out as matching passwords. If you used:
if ($pwd1_text.compareTo($pwd2_text) -eq 0) it’ll work.
That is very good point. I think using case sensitive equal comparator in Powershell is very easy. I updated the code to include -ceq instead of -eq.
Thanks for highlighting that.
An even smaller problem, you have a typo in password. Unless you were planning on developing a new cereal, pass-o-wrds. And if you are, I would certainly like some.
Thanks for the script. Can you elaborate where “[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR” comes from?
This is great.
I’ve been trying to put this into a function or a loop, so that if passwords differ, it runs again and keeps running until the password are the same (or ctrl C). I have tried ‘while’ and called it as a function, but even when the passwords are the same it keeps asking to enter a password again.
Any ideas?
thanks
Roger
Roger, please post your code here. It is easy to comment that way.
Here is the while loop I use
$Matched = $False
Do {
$SecurePassword1 = Read-Host -Prompt “Enter Password ” -AsSecureString
$SecurePassword2 = Read-Host -Prompt “Confirm Password” -AsSecureString
If (([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword2))) -eq ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword1)))) {$Matched = $True}
Else {Write-Warning “Passwords do not match!!! They must match to continue.”;$Matched = $False}
}
While ($Matched -ne $True)
Jerry, Have you faced any problems running the code?
The one issue I see with the code is the fact that it incorrectly uses ‘-eq’ instead the correct ‘-ceq’. As it stands test123 and Test123 would be considered equal, even though it is not accurate. Otherwise works quite well. Thank you.
The code was corrected back in 2012 to address that. Since then -CEQ is in the code. Where you saw -eq?
Of course the reason to use securestring in the first place, so that the text isn’t plain text is negated when we assign it to $pwd1_text and $pwd2_text. It still gets convert to plain text in memory but no variable is possibly left if we do the comparisons as such:
if ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd1)) -ceq [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd2)))
Sure it is a little ungainly, but avoids the two plain text variables.
Thank you for commenting. I felt it is a bit difficult to read, agree?