# 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: 2927 # x-archived: 2015-10-26T02:00:12 # x-published: 2011-08-23T14:24: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 Domain If this flag is set the user credentials should be a domain user account. .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. .LINK http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.principalcontext.aspx .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)