Es gibt Unmengen an Funktionen die das könne. Allerdings wird der BadLogonCount bei den meisten direkt um 2 erhöht. Das liegt daran, dass die meisten einen Bind machen und dann einen Befehl im Context absetzten. Das wollte ich aber nicht!
Hier eine einfache Funktion als Gist:
#requires -Version 2.0 -Modules ActiveDirectory
function Test-ADCredentials
{
<#
.SYNOPSIS
Check a given PSCredential against the Active Directory
.DESCRIPTION
Check a given PSCredential against the Active Directory by a single shot.
.PARAMETER Credential
The Credential Object. Create by Get-Credential
.PARAMETER Domain
The Domain Full name, e.g. hochwald.net
.EXAMPLE
# Check a given PSCredential in the variable $credentials against the Active Directory
PS C:\> Test-ADCredentials -Credential $credentials
.NOTES
There are a lot of other functions and tools that could do the same,
but most of them raise the bad counter by 2 (one for a bind and the other
for the try itself). I wanted a easy to use function that can do the
same with just ONE (1) shot.
LICENSE: Public Domain ;-)
#>
[OutputType([bool])]
param
(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1,
HelpMessage = 'The Credential Object.')]
[System.Management.Automation.Credential()]
[ValidateNotNullOrEmpty()]
[Alias('PSCredential')]
[pscredential]
$Credential,
[Parameter(ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[ValidateNotNullOrEmpty()]
[Alias('DomainFQDN')]
[string]
$Domain = 'hochwald.net'
)
begin
{
# Make sure we have waht we want
if (-not ($DomainFQDN))
{
$DomainFQDN = $Domain
}
# Transform the PSCredential object to make it human readable
$networkCredential = $Credential.GetNetworkCredential()
try
{
# Bad Login counter
$parameters = @{
Identity = $networkCredential.UserName
Properties = 'BadLogonCount'
ErrorAction = 'Stop'
}
$count_tmp = (Get-ADUser @parameters)
$count = (($count_tmp).BadLogonCount)
Write-Verbose -Message ('Count: {0}' -f $count)
# Cleanup
$count_tmp = $null
$count = $null
}
catch
{
# Send the Info that the User does NOT exist in the Active Directiry
Write-Warning 'unable to find your user, please check and retry!'
break
}
}
process
{
# Checks user credentials against the domain
try
{
# Connection String
$DomainObj = 'LDAP://' + $DomainFQDN
# Create the new object and connect
$parameters = @{
TypeName = 'System.DirectoryServices.DirectoryEntry'
ArgumentList = ($DomainObj, $networkCredential.UserName, $networkCredential.Password)
}
$DomainBind = (New-Object @parameters)
# Test variable
$DomainName = $DomainBind.distinguishedName
if ($DomainName)
{
# Good
return $true
break
}
else
{
# Bad
retun $false
break
}
# Bad Login counter
$parameters = @{
Identity = $networkCredential.UserName
Properties = 'BadLogonCount'
ErrorAction = 'SilentlyContinue'
}
$count_tmp = (Get-ADUser @parameters)
$count = (($count_tmp).BadLogonCount)
Write-Verbose -Message ('Count: {0}' -f $count)
# Cleanup
$count_tmp = $null
$count = $null
}
catch
{
# Bad, very bad!
return $false
break
}
finally
{
# Cleanup
$networkCredential = $null
$DomainBind = $null
}
}
end
{
# Cleanup
$networkCredential = $null
$DomainBind = $null
}
}
# Read credentials into the $checkcreds variable
$checkcreds = (Get-Credential)
# Just a minor check.
if ((Test-ADCredentials -Credential $checkcreds))
{
#TODO: Everything is good
Write-Output -InputObject 'Great'
}
else
{
#TODO: Error handler here
Write-Warning -Message 'Not good'
}
Und es gibt ein Gist.