Reputation: 1
So in my script I want to not only have the user enter and store credentials in a variable but be able to verify that the password matches the admin password on the target system. So far the only way I have found to do this is by putting the actual password unecrypted in the script and comparing it to the one the user enters. That is a huge security flaw and to remedy it I was wondering if I could get the admin password using a gwmi query (SID?) as an object and compare that to the secure string the user enters.
Here is my flawed code I am using right now.
Do
{
$password = $null
$password = read-host "Enter the Administrator Password" -assecurestring
$AdminPass = ConvertTo-SecureString "adminpassword" -AsPlainText -Force
$pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
$pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($AdminPass))
if ($pwd1_text -cne $pwd2_text) {Write-Host -ForegroundColor Red "Incorrect Password"; $password = $null}
$count ++
$tries = 3 - $count
if ($password -eq $null) {Write-Host -ForegroundColor Yellow "$tries Attempts Remaining"}
if ($count -eq 3) {Write-Host -ForegroundColor Red "$count Unsuccessful Password Attempts. Exiting..."; exit}
}While ($password -eq $null)
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "$ComputerName\Administrator",$password
Upvotes: 0
Views: 5871
Reputation: 1666
Here's a function I wrote that tests a PSCredential object, against a Domain or a local Machine:
function Test-Credential {
<#
.SYNOPSIS
Takes a PSCredential object and validates it against the domain (or local machine, or ADAM instance).
.PARAMETER cred
A PScredential object with the username/password you wish to test. Typically this is generated using the Get-Credential cmdlet. Accepts pipeline input.
.PARAMETER context
An optional parameter specifying what type of credential this is. Possible values are 'Domain' for Active Directory accounts, and 'Machine' for local machine accounts. The default is 'Domain.'
.OUTPUTS
A boolean, indicating whether the credentials were successfully validated.
.NOTES
Created by Jeffrey B Smith, 6/30/2010
#>
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[System.Management.Automation.PSCredential]$credential,
[parameter()][validateset('Domain','Machine')]
[string]$context = 'Domain'
)
begin {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::$context)
}
process {
$DS.ValidateCredentials($credential.GetNetworkCredential().UserName, $credential.GetNetworkCredential().password)
}
}
If you want to test against local accounts on a remote machine, you'll need to load this function on the remote machine and test the credential against the 'local' machine via remoting (Invoke-Command), but it should be possible.
Upvotes: 3