Skip to content

Ein PSCredential gegen Active Directory validieren

Ich wollte eine einfache Möglichkeit eine per Get-Credential in eine Variable gespeichertes PSCredential Objekt.
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:

  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'
}

JavaScript wird zur Anzeige des Gist benötigt.

This content is older than 2 years. It might be outdated.
Published inPowerShell

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2018 by Joerg Hochwald. All rights reserved. ● Site is powered by Author