Frage Überprüfen Sie, ob die Eingabe des Benutzerpassworts im Powershell-Skript gültig ist


Ich arbeite mit einem Powershell-Skript, das geplante Aufgaben zu Systemen in unserer Domäne hinzufügt. Wenn ich dieses Skript ausführe, werde ich nach meinem Passwort gefragt. Ich ficke manchmal fett das Passwort und der Prozess startet, wodurch mein Account gesperrt wird. Gibt es eine Möglichkeit, meine Anmeldeinformationen zu überprüfen, um sicherzustellen, dass das, was ich eingegeben habe, mit der Domain validiert wird?

Ich möchte eine Möglichkeit finden, den Domänencontroller abzufragen. Ich habe einige Google-Suchen durchgeführt und sollte eine WMI-Abfrage durchführen und einen Fehler abfangen können. Ich möchte diesen Stil der Validierung wenn möglich vermeiden.

Irgendwelche Ideen? Danke im Voraus.


27
2018-06-01 22:29


Ursprung




Antworten:


Ich habe das in meiner Bibliothek:

$cred = Get-Credential #Read credentials
 $username = $cred.username
 $password = $cred.GetNetworkCredential().password

 # Get current domain using logged-on user's credentials
 $CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
 $domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password)

if ($domain.name -eq $null)
{
 write-host "Authentication failed - please verify your username and password."
 exit #terminate the script.
}
else
{
 write-host "Successfully authenticated with domain $domain.name"
}

25
2018-06-01 22:59



Genau danach suche ich. Vielen Dank! - Doltknuckle
Wenn ich mich nicht irre, würde dies das Passwort im Klartext über das Netzwerk senden, richtig? Wenn es so ist, habe ich recht, wenn ich das voraussetze AccountManagement.PrincipalContext.ValidateCredentials() nicht (wenn Sie eine sichere Zeichenfolge für das Passwort angeben)? - Code Jockey
Warum benutzt du nicht das? ActiveDirectory Modul für Ihre LDAP-Abfrage? - Kolob Canyon
Vor 6 Jahren gab es kein Active Directory Modul - Jim B
Dieses Skript hilft auch in Situationen, in denen Sie die AD PowerShell-Module aus dem einen oder anderen Grund nicht installieren können. - Dodzi Dzakuma


Das habe ich in der Vergangenheit benutzt; Es sollte für lokale Computerkonten und 'Anwendungsverzeichnis' funktionieren, aber bisher habe ich es nur erfolgreich mit AD-Anmeldeinformationen verwendet:

    function Test-Credential {
    <#
    .SYNOPSIS
        Takes a PSCredential object and validates it against the domain (or local machine, or ADAM instance).

    .PARAMETER cred
        A PScredential object with the username/password you wish to test. Typically this is generated using the Get-Credential cmdlet. Accepts pipeline input.

    .PARAMETER context
        An optional parameter specifying what type of credential this is. Possible values are 'Domain','Machine',and 'ApplicationDirectory.' The default is 'Domain.'

    .OUTPUTS
        A boolean, indicating whether the credentials were successfully validated.

    #>
    param(
        [parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [System.Management.Automation.PSCredential]$credential,
        [parameter()][validateset('Domain','Machine','ApplicationDirectory')]
        [string]$context = 'Domain'
    )
    begin {
        Add-Type -assemblyname system.DirectoryServices.accountmanagement
        $DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::$context) 
    }
    process {
        $DS.ValidateCredentials($credential.UserName, $credential.GetNetworkCredential().password)
    }
}

14
2017-07-01 00:33



Ich würde gerne hören, wenn jemand dies bemerkt - ich glaube, wenn ich ValidateCredentials () auf diese Weise mit einem falschen Passwort benutze, scheint es zwei (2) schlechte Passwortversuche auszulösen - ich kann den Schwellenwert für die Anzahl der Versuche nicht kontrollieren auf unserer Domain, und es ist niedrig, also würde ich lieber nicht zwei schlechte Versuche haben, wenn ich einen einzigen Anruf mache ... kann das jemand auch sehen? - Code Jockey
Verwenden Sie das Format Domäne \ Benutzer oder UPN (Benutzer @ Domäne)? Ich bin nicht in der Lage, dies zu replizieren, aber die folgende URL beschreibt ein ähnliches Problem: social.msdn.microsoft.com/Forum/vstudio/en-US/... - jbsmith
Du solltest in der Lage sein, einfach zu bestehen $context als Argument für den Konstruktor. PowerShell konvertiert Strings automatisch in eine Enumeration. Besser noch, mach einfach [System.DirectoryServices.AccountManagement.ContextType]die Art von $context. Auch, warum benutzt du begin und process Hier? Die Pipeline scheint eine seltsame Art zu sein, diese Funktion zu verwenden. - jpmc26
@ jpmc26: tippe die $context Parameter [System.DirectoryServices.AccountManagement.ContextType] ist keine Option, da die Assembly, die enthält, erst bei der Funktion geladen wird Karosserie wird ausgeführt; Die Verwendung der Pipeline ist hilfreich, wenn Sie mehrere Anmeldeinformationen validieren möchten. - mklement
@mklement Es gibt keinen Grund, die Add-Type Aufruf kann nicht außerhalb der Funktion verschoben werden, bevor die Definition ausgeführt wird. Ich zögere, eine zu haben Add-Type Rufen Sie unbedingt bedingungslos wiederholt in der Funktion auf, auch wenn sie ohnehin schon geladen ist. Die gleichzeitige Überprüfung mehrerer Anmeldeinformationen scheint von Anfang an eine merkwürdige Situation zu sein. In dem seltenen Fall, dass Sie das möchten, können Sie den Anruf einfach einwickeln ForEach-Object, deshalb sehe ich keinen Grund, die Funktion damit zu komplizieren. - jpmc26


Ich habe festgestellt, dass dieser Beitrag nützlich ist, aber er hat mein Problem nicht gelöst, da ich versucht habe, es aus einem Skript mit dem lokalen Administratorkonto auszuführen, das angemeldet ist. Es scheint nicht als lokaler Administrator zu funktionieren (nur wenn er als Domänenbenutzer angemeldet ist).

Jedoch habe ich es geschafft, eine funktionierende Lösung zu bekommen und da es so viel Ärger war, dachte ich, ich würde es hier teilen, so dass jeder andere mit diesem Problem die Antwort hier haben wird. Beide Antworten auf der einen Seite richten sich nach Ihren Bedürfnissen.

Beachten Sie, dass upg im scipt (hier nicht enthalten, da dies nur der Abschnitt get-credentials ist) powergui installiert ist und eine Voraussetzung für diesen Code ist (sowie für die Zeile "Add-PSSnapin Quest.ActiveRoles.ADManagement"). Nicht sicher, was Powergui ist das ist anders, aber niemand könnte mir sagen, und es funktioniert.

Setzen Sie in den Abschnitten "Domänenname" Ihren eigenen Domänennamen ein.

#Get credentials
$credential_ok = 0
while ($credential_ok -ne 1)
{
    $credential = get-credential
    $result = connect-qadservice -service *domain_name* -credential $credential
    [string]$result_string = $result.domain
    if ($result_string -eq "*domain_name*")
    {
        $credential_ok = 1
        #authenticated
    }
    else
    {
        #failed
    }     
}
$username = $credential.username 
$password = $credential.GetNetworkCredential().password 

$date = get-date
Add-Content "c:\lbin\Install_log.txt" "Successfully authenticated XP script as $username $date"

0
2017-10-10 00:27





(Noch) Eine andere Version:

param([string]$preloadServiceAccountUserName = "")

function HarvestCredentials()
{

        [System.Management.Automation.PSCredential]$credentialsOfCurrentUser = Get-Credential -Message "Please enter your username & password" -UserName $preloadServiceAccountUserName

        if ( $credentialsOfCurrentUser )
        {
            $credentialsOfCurrentUser = $credentialsOfCurrentUser
        }
        else
        {
            throw [System.ArgumentOutOfRangeException] "Gui credentials not entered correctly"          
        }

    Try
    {


        # see https://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.path(v=vs.110).aspx
        # validate the credentials are legitimate
        $validateCredentialsTest = (new-object System.DirectoryServices.DirectoryEntry ("WinNT://"+$credentialsOfCurrentUser.GetNetworkCredential().Domain), $credentialsOfCurrentUser.GetNetworkCredential().UserName, $credentialsOfCurrentUser.GetNetworkCredential().Password).psbase.name
        if ( $null -eq  $validateCredentialsTest)
        {
            throw [System.ArgumentOutOfRangeException] "Credentials are not valid.  ('" + $credentialsOfCurrentUser.GetNetworkCredential().Domain + '\' + $credentialsOfCurrentUser.GetNetworkCredential().UserName + "')"
        }
        else
        {
            $t = $host.ui.RawUI.ForegroundColor
            $host.ui.RawUI.ForegroundColor = "Magenta"
            Write-Output "GOOD CREDENTIALS"
            $host.ui.RawUI.ForegroundColor = $t
        }
    }
    Catch
    {

        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        $StackTrace = $_.Exception.StackTrace

        $t = $host.ui.RawUI.ForegroundColor
        $host.ui.RawUI.ForegroundColor = "Red"

        Write-Output "Exception - $ErrorMessage"
        Write-Output "Exception - $FailedItem"
        Write-Output "Exception - $StackTrace"

        $host.ui.RawUI.ForegroundColor = $t

        throw [System.ArgumentOutOfRangeException] "Attempt to create System.DirectoryServices.DirectoryEntry failed.  Most likely reason is that credentials are not valid."
    }

}


Try
{

    HarvestCredentials

}
Catch
{
    $ErrorMessage = $_.Exception.Message
    $FailedItem = $_.Exception.ItemName
    $StackTrace = $_.Exception.StackTrace

    $t = $host.ui.RawUI.ForegroundColor
    $host.ui.RawUI.ForegroundColor = "Red"

    Write-Output "Exception - " + $ErrorMessage
    Write-Output "Exception - " + $FailedItem
    Write-Output "Exception - " + $StackTrace

    $host.ui.RawUI.ForegroundColor = $t

    Break
}
Finally
{
    $Time=Get-Date
    Write-Output "Done - " + $Time
}

und

.\TestCredentials.ps1 -preloadServiceAccountUserName "mydomain\myusername"

0
2018-02-26 21:07