जांचें कि क्या उपयोगकर्ता पासवर्ड इनपुट पॉवर्सहेल स्क्रिप्ट में मान्य है


30

मैं Powershell स्क्रिप्ट के साथ काम कर रहा हूं जो हमारे डोमेन में सिस्टम में अनुसूचित कार्यों को जोड़ता है। जब मैं यह स्क्रिप्ट चलाता हूं, तो यह मेरे पासवर्ड के लिए संकेत देगा। मैं कभी-कभी पासवर्ड को मोटा कर देता हूं और प्रक्रिया शुरू हो जाती है, जो मेरे खाते को बंद कर देती है। क्या यह सुनिश्चित करने के लिए मेरे क्रेडेंशियल्स को सत्यापित करने का एक तरीका है कि मैंने जो टाइप किया है वह डोमेन के साथ मान्य होगा?

मैं डोमेन नियंत्रक को क्वेरी करने का एक तरीका खोजना चाहता हूं। मैंने कुछ Google खोजें की हैं और मुझे एक त्रुटि के लिए WMI क्वेरी और ट्रैप करने में सक्षम होना चाहिए। यदि संभव हो तो मैं सत्यापन की उस शैली से बचना चाहूंगा।

कोई विचार? अग्रिम में धन्यवाद।

जवाबों:


26

मेरी लाइब्रेरी में यह है:

$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"
}

1
अगर मैं गलत नहीं हूं, तो यह पूरे नेटवर्क में सादे पाठ में पासवर्ड भेजना होगा, है ना? यदि ऐसा होता है, तो क्या मैं यह मानने में सही हूं कि AccountManagement.PrincipalContext.ValidateCredentials()क्या ऐसा नहीं है (यदि आप पासवर्ड के लिए एक गोपनीयता प्रदान करते हैं)?
कोड जॉकी

आप ActiveDirectoryअपनी LDAP क्वेरी करने के लिए मॉड्यूल का उपयोग क्यों नहीं कर रहे हैं ?
कोलब कैन्यन

6 साल पहले कोई सक्रिय निर्देशिका मॉड्यूल नहीं था
जिम बी

यह स्क्रिप्ट उन स्थितियों के लिए भी मदद करती है जहाँ आप AD PowerShell मॉड्यूल को एक या दूसरे कारण से स्थापित नहीं कर सकते हैं।
डोडज़ी डेजाकुमा

16

यह वही है जो मैंने अतीत में उपयोग किया है; यह स्थानीय मशीन खातों और 'एप्लिकेशन डायरेक्टरी' के लिए काम करने वाला है, लेकिन अब तक मैंने इसे केवल AD क्रेडेंशियल्स के साथ सफलतापूर्वक उपयोग किया है:

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

मुझे यह सुनकर अच्छा लगेगा कि कोई इसे नोटिस करता है - मेरा मानना ​​है कि जब मैं गलत पासवर्ड के साथ इस तरीके से ValidateCredentials () का उपयोग करता हूं, तो यह दो (2) खराब पासवर्ड के प्रयासों को ट्रिगर करता है - मैं थ्रेशोल्ड की संख्या को नियंत्रित नहीं कर सकता हमारे डोमेन पर, और यह कम है, इसलिए जब मैं एक कॉल कर रहा हूं तो दो बुरे प्रयास नहीं करना चाहूंगा ... क्या कोई इसे भी देख सकता है?
कोड जॉकी

क्या आप डोमेन \ उपयोगकर्ता या UPN (उपयोगकर्ता @ डोमेन) प्रारूप का उपयोग कर रहे हैं? मैं इसे दोहराने की स्थिति में नहीं हूं, लेकिन निम्न URL एक समान समस्या का वर्णन करता है: social.msdn.microsoft.com/Forums/vstudio/en-US/…
jbsmith

आपको बस $contextकंस्ट्रक्टर के तर्क के रूप में पारित करने में सक्षम होना चाहिए । PowerShell स्वचालित रूप से स्ट्रिंग्स को एक एनम में बदल देगा। बेहतर अभी तक, बस [System.DirectoryServices.AccountManagement.ContextType]के प्रकार बनाते हैं $context। इसके अलावा, आप यहां beginऔर क्यों इस्तेमाल कर रहे processहैं? इस फ़ंक्शन का उपयोग करने के लिए पाइपलाइन एक अजीब तरीके की तरह लगता है।
jpmc26

@ jpmc26: $contextपैरामीटर टाइप करना [System.DirectoryServices.AccountManagement.ContextType]एक विकल्प नहीं है, क्योंकि फ़ंक्शन बॉडी निष्पादित होने तक असेंबली लोड नहीं होती है; यदि आप कई क्रेडेंशियल्स को मान्य करना चाहते हैं, तो पाइपलाइन का उपयोग करना उपयोगी है।
mklement

@mklement कोई कारण Add-Typeनहीं है कि इसकी परिभाषा निष्पादित होने से पहले कॉल को फ़ंक्शन से बाहर नहीं ले जाया जा सकता है। मुझे यह Add-Typeकहते हुए संकोच हो रहा है कि एक कॉल बिना फ़ंक्शन के बार-बार चल रही है, भले ही वह पहले से लोड हो, फिर भी। एक साथ कई क्रेडेंशियल्स को मान्य करना पहली जगह में एक विषम स्थिति की तरह लगता है। इस मामले में कि आप क्या चाहते हैं, आप कॉल को आसानी से लपेट सकते हैं ForEach-Object, इसलिए मुझे इसके साथ फ़ंक्शन को जटिल करने का कोई कारण नहीं दिखता है।
jpmc26

1

मुझे यह पोस्ट उपयोगी लगी है, लेकिन इसने मेरी समस्या को हल नहीं किया क्योंकि मैं इसे स्क्रिप्ट से स्थानीय व्यवस्थापक खाते के साथ लॉग ऑन करने का प्रयास कर रहा था। यह स्थानीय व्यवस्थापक के रूप में काम नहीं करता है (केवल जब एक डोमेन उपयोगकर्ता के रूप में लॉग ऑन किया जाता है)।

हालांकि मैंने आखिरकार एक काम करने वाला समाधान प्राप्त करने का प्रबंधन किया और चूंकि यह बहुत परेशानी थी, इसलिए मैंने सोचा कि मैं इसे यहां साझा करूंगा, इसलिए इस समस्या के साथ किसी और का भी जवाब होगा। आपकी आवश्यकताओं के आधार पर दोनों एक पृष्ठ पर उत्तर देते हैं।

ध्यान दें कि स्काइप में उच्चतर (यहां शामिल नहीं है क्योंकि यह सिर्फ गेट-क्रेडेंशियल्स सेक्शन है) पॉवरगुई स्थापित है और नीचे दिए गए इस कोड के लिए एक आवश्यकता है (साथ ही "एड-पीएसनैपिन क्वेस्ट। एक्टिव रॉल्स। प्रबंधन" लाइन)। निश्चित नहीं है कि पॉवरगुई क्या अलग है लेकिन कोई और मुझे नहीं बता सकता है और यह काम करता है।

"Domain_name" अनुभागों में अपने स्वयं के डोमेन नाम को सब्सक्राइब करें।

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

1

(अभी तक) एक और संस्करण:

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
}

तथा

.\TestCredentials.ps1 -preloadServiceAccountUserName "mydomain\myusername"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.