Back
Featured image of post Ein PSCredential gegen Active Directory validieren

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:

#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.