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.

Here is a little Gist for that:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#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'
}

You need JavaScript enable to see the Gist. If you see nothing, click here.