# encoding: ascii
# api: powershell
# title: Test-UserCredential
# description: A function to test a user’s credentials. Return true/false. Works for local or domain user accounts.
# version: 0.1
# type: function
# author: Andy Arismendi
# license: CC0
# function: Test-UserCredential
# x-poshcode-id: 2926
# x-derived-from-id: 2927
# x-archived: 2011-11-05T16:39:25
# x-published: 2011-08-21T21:13:00
#
#
function Test-UserCredential {
[CmdletBinding(DefaultParameterSetName = "set1")]
[OutputType("set1", [System.Boolean])]
[OutputType("PSCredential", [System.Boolean])]
param(
[Parameter(Mandatory=$true, ParameterSetName="set1", position=0)]
[ValidateNotNullOrEmpty()]
[String] $Username,
[Parameter(Mandatory=$true, ParameterSetName="set1", position=1)]
[ValidateNotNullOrEmpty()]
[System.Security.SecureString] $Password,
[Parameter(Mandatory=$true, ParameterSetName="PSCredential", ValueFromPipeline=$true, position=0)]
[ValidateNotNullOrEmpty()]
[Management.Automation.PSCredential] $Credential,
[Parameter(position=2)]
[Switch] $Domain,
[Parameter(position=3)]
[Switch] $UseKerberos
)
Begin {
try { $assem = [system.reflection.assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement') }
catch { throw 'Failed to load assembly "System.DirectoryServices.AccountManagement". The error was: "{0}".' -f $_ }
$system = Get-WmiObject -Class Win32_ComputerSystem
if (0, 2 -contains $system.DomainRole -and $Domain) {
throw 'This computer is not a member of a domain.'
}
}
Process {
try {
switch ($PSCmdlet.ParameterSetName) {
'PSCredential' {
if ($Domain) {
$Username = $Credential.UserName.TrimStart('\')
} else {
$Username = $Credential.GetNetworkCredential().UserName
}
$PasswordText = $Credential.GetNetworkCredential().Password
}
'set1' {
# Decrypt secure string.
$PasswordText = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
)
}
}
if ($Domain) {
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Domain', $system.Domain
} else {
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Machine', $env:COMPUTERNAME
}
if ($Domain -and $UseKerberos) {
return $pc.ValidateCredentials($Username, $PasswordText)
} else {
return $pc.ValidateCredentials($Username, $PasswordText, [DirectoryServices.AccountManagement.ContextOptions]::Negotiate)
}
} catch {
throw 'Failed to test user credentials. The error was: "{0}".' -f $_
} finally {
Remove-Variable -Name Username -ErrorAction SilentlyContinue
Remove-Variable -Name Password -ErrorAction SilentlyContinue
}
}
<#
.SYNOPSIS
Validates credentials for local or domain user.
.PARAMETER Username
The user's username.
.PARAMETER Password
The user's password.
.PARAMETER Credential
A PSCredential object created by Get-Credential. This can be pipelined to Test-UserCredential.
.PARAMETER UseKerberos
By default NTLM is used. Specify this switch to attempt kerberos authentication.
This is only used with the 'Domain' parameter.
You may need to specify domain\user.
.EXAMPLE
PS C:\> Test-UserCredential -Username andy -password (Read-Host -AsSecureString)
.EXAMPLE
PS C:\> Test-UserCredential -Username 'mydomain\andy' -password (Read-Host -AsSecureString) -domain -UseKerberos
.EXAMPLE
PS C:\> Test-UserCredential -Username 'andy' -password (Read-Host -AsSecureString) -domain
.EXAMPLE
PS C:\> Get-Credential | Test-UserCredential
.INPUTS
None.
.OUTPUTS
System.Boolean.
.NOTES
Revision History
2011-08-21: Andy Arismendi - Created.
2011-08-22: Andy Arismendi - Add pipelining support for Get-Credential.
2011-08-22: Andy Arismendi - Add support for NTLM/kerberos switch.
#>
}
Test-UserCredential -user andy -password (Read-Host -AsSecureString)