Jonathan Byrd
Jonathan Byrd

Reputation: 1

Powershell Verify local Credentials

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

Answers (1)

jbsmith
jbsmith

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

Related Questions