I use Windows PowerShell to query and validate the user's Windows credentials during an installation process. That worked well until yesterday. Now the IT department in my company has changed some configuration of the domain controller and now I get the following exception.
Exception calling "ValidateCredentials" with "2" argument(s): "The server cannot handle directory requests." At line:32 char:5 + if ($pc.ValidateCredentials($username, $credential.GetNetworkCredenti ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DirectoryOperationException
From my research I already found out that it has to do with the missing SSL connection. I have to add ContextOptions.SecureSocketLayer
somewhere in the code. The question is: Where is the right place to put this parameter? I cannot find any examples for PowerShell.
Here's the script I used to check the credentials:
$credential = $Host.UI.PromptForCredential("Need credentials.", "For using Windows Integrated Authentication please provide the login information for the user that has access to the Microsoft SQL Server database.", "", "")
if (!$credential) {
Write-Output "No credentials provided"
return
}
[System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement')
$system = Get-WmiObject -Class Win32_ComputerSystem
if ($credential.GetNetworkCredential().Domain) {
Write-Output "Credentials contain domain"
if ($credential.GetNetworkCredential().Domain -eq $system.Name) {
Write-Output "Domain is local system"
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Machine', $system.Name
} else {
Write-Output "Domain is network domain"
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Domain', $credential.GetNetworkCredential().Domain
}
$username = $credential.UserName
} elseif (0, 2 -contains $system.DomainRole) {
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Machine', $system.Name
$username = $system.Name + '\' + $credential.GetNetworkCredential().UserName
} else {
$pc = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext 'Domain', $system.Domain
$username = $system.Domain + '\' + $credential.GetNetworkCredential().UserName
}
if ($pc.ValidateCredentials($username, $credential.GetNetworkCredential().Password)) {
Write-Output "Validation successfull"
} else {
Write-Output "Validation failed"
}
As mentioned by Kiran in the comments, you can pass a
ContextOptions
value to thePrincipalContext
constructor:An authentication option (
Negotiate
orSimpleBind
) must be specified, thus the'SecureSocketLayer,Negotiate'
value