Freitag, 10. August 2018

Credentials in der PowerShell überprüfen lassen

Hintergrund:

Mitten in einem PowerShell-Skript beim Kunden steht "Get-Credentials" - wenn bei der Erfassung der credentials ein Fehler unterläuft, bricht das S​kript 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;
        } 
    }
}

Keine Kommentare:

Kommentar veröffentlichen