# 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: 2925 # x-derived-from-id: 2926 # x-archived: 2011-11-05T15:52:35 # x-published: 2011-08-21T16:20: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) { 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. #> }