Hintergrund:
Mitten in einem PowerShell-Skript beim Kunden steht “Get-Credentials” – wenn bei der Erfassung der credentials ein Fehler unterläuft, bricht das Skript ab und man kann von vorne beginnen…
Die Anforderung:
Nach erfassen der Credentials sollen diese auf Gültigkeit überprüft werden.
Es gibt die eine oder andere Frage und auch eine Lösung in der TechNet-Gallery…
Mir war das leider nicht “generell” genug. Hier ist meine Lösung:
function Test-Credential { | |
<# | |
.SYNOPSIS | |
checks some credentials. | |
.PARAMETER Credential | |
The Credentials to check | |
.PARAMETER Retry | |
retry on fail. | |
.EXAMPLE | |
Get-Credential dev\developer | Test-Credential -Verbose -Retry | |
#> | |
[OutputType([System.Management.Automation.PSCredential])] | |
[CmdletBinding()] | |
Param ( | |
[Parameter( | |
Mandatory = $true, | |
ValueFromPipeLine = $true, | |
ValueFromPipelineByPropertyName = $true | |
)] | |
[Alias( 'PSCredential' )] | |
[ValidateNotNull()] | |
[System.Management.Automation.PSCredential] | |
[System.Management.Automation.Credential()] | |
$Credential = [System.Management.Automation.PSCredential]::Empty, | |
[switch]$Retry=$false | |
) | |
$processing = $true; | |
while($processing) { | |
$UserName = $Credential.username | |
$networkCred = $Credential.GetNetworkCredential(); | |
$password = $networkCred.Password | |
$domain = $networkCred.Domain | |
Write-Verbose "Credentials supplied for user: $UserName" | |
if(!$domain) { | |
if($UserName -match "@") { | |
# user was foo@bar.baz... | |
Write-Verbose "User in UPN-Form. No domain-parsing will be done.." | |
} else { | |
# current domain | |
$domain = "LDAP://" + ([ADSI]"").DistinguishedName | |
Write-Verbose "No domain given. DistinguishedName of current domain: $domain" | |
} | |
} else { | |
Write-Verbose "domain given as $domain in old NT-syntax." | |
$test = Get-Command Get-ADDomain -ErrorAction SilentlyContinue | |
if($test -eq $null) { | |
$guess = "$($UserName.Substring($domain.length+1))@$domain"; | |
Write-Verbose "CMDLet Get-ADDomain is not available. Guessing UPN-form for user as $guess"; | |
$UserName = $guess; | |
$domain = ""; | |
} else { | |
Write-Verbose "CMDLet Get-ADDomain is available. Fetching DistinguishedName.."; | |
$domain = Get-ADDomain $domain -ErrorAction Stop; | |
$domain = "LDAP://" + $domain.DistinguishedName; | |
Write-Verbose "DistinguishedName of domain is: $domain"; | |
} | |
} | |
# now re-fetch the current domain using the supplied credentials. | |
Write-Verbose "Validating credentials" | |
$entry = New-Object System.DirectoryServices.DirectoryEntry($domain,$UserName,$Password) | |
if ($entry.name -eq $null) | |
{ | |
Write-Verbose "Authentication failed." | |
$abort = $false; | |
if($Retry) { | |
$Credential = Get-Credential -UserName $user -Message "Failed. Please rety..." -ErrorAction SilentlyContinue | |
if($Credential -eq $null) { | |
$abort = $true; | |
} | |
} | |
if(!$Retry -or $abort) { | |
throw "Validation failed..." | |
return $null; | |
} | |
} | |
else | |
{ | |
Write-Verbose "Authentication succeeded." | |
$processing = $false; | |
return $Credential; | |
} | |
} | |
} |