11

Let's say I have a PSCrendential object in PowerShell that I created using Get-Credential.

How can I validate the input against Active Directory ?

By now I found this way, but I feel it's a bit ugly :

[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")


function Validate-Credentials([System.Management.Automation.PSCredential]$credentials)
{
    $pctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, "domain")
    $nc = $credentials.GetNetworkCredential()
    return $pctx.ValidateCredentials($nc.UserName, $nc.Password)
}

$credentials = Get-Credential

Validate-Credentials $credentials

[Edit, two years later] For future readers, please note that Test-Credential or Test-PSCredential are better names, because Validate is not a valid powershell verb (see Get-Verb)

Steve B
  • 36,818
  • 21
  • 101
  • 174

2 Answers2

10

I believe using System.DirectoryServices.AccountManagement is the less ugly way:

This is using ADSI (more ugly?):

$cred = Get-Credential #Read credentials
$username = $cred.username
$password = $cred.GetNetworkCredential().password

# Get current domain using logged-on user's credentials
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password)

if ($domain.name -eq $null)
{
 write-host "Authentication failed - please verify your username and password."
 exit #terminate the script.
}
else
{
 write-host "Successfully authenticated with domain $domain.name"
}
CB.
  • 58,865
  • 9
  • 159
  • 159
  • I understand that PSCredentials is authentication provider agnostic (it's basically a simple container for username /password), but this requirement sounds very common for me. – Steve B May 30 '12 at 07:53
  • @SteveB It's a really common task for sysadmin and developper especially for those working in AD that's why (IMO) microsoft do AccountManagement. Here you can see a variety of way used in c# to do this task: http://stackoverflow.com/questions/290548/c-sharp-validate-a-username-and-password-against-active-directory – CB. May 30 '12 at 08:00
  • In fact, general development best practices applies here. Especially I can hide the complexity in this function and then simply call the function :) – Steve B May 30 '12 at 09:38
2

I was having a similar issue with an installer and required to verify the service account details supplied. I wanted to avoid using the AD module in Powershell as I wasn't 100% this would be installed on the machine running the script.

I did the test using the below, it is slightly dirty but it does work.

try{
    start-process -Credential $c -FilePath ping -WindowStyle Hidden
} catch {
    write-error $_.Exception.Message
    break
}
xenon8
  • 41
  • 3
  • 2
    Neither my question nor @cb. answer requires having the AD module loaded. It actually relies on some .Net classes related to AD, which are always available in PowerShell. – Steve B May 28 '17 at 12:09