检查用户密码输入在Powershell脚本中是否有效


30

我正在使用Powershell脚本,该脚本将计划任务添加到我们域中的系统。当我运行此脚本时,它将提示我输入密码。有时我会不小心输入密码,然后开始该过程,这将我的帐户锁定了。有没有一种方法可以验证我的凭据,以确保我输入的内容可以通过域进行验证?

我想找到一种查询域控制器的方法。我已经完成了一些Google搜索,并且应该能够执行WMI查询并捕获错误。如果可能的话,我想避免这种验证方式。

有任何想法吗?提前致谢。

Answers:


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()不正确(如果您提供密码的安全字符串)?
赛马会2015年

为什么不使用该ActiveDirectory模块进行LDAP查询?
Kolob峡谷

6年前没有活动目录模块
Jim B

此脚本还可以解决由于某种原因而无法安装AD PowerShell模块的情况。
Dodzi Dzakuma

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)次错误的密码尝试-我无法控制尝试次数阈值在我们的域上,而且价格很低,所以我不希望在打一个电话时进行两次错误尝试……任何人都可以看到吗?
赛马会

您使用的是domain \ user还是UPN(user @ domain)格式?我无法复制此内容,但是以下URL描述了类似的问题:social.msdn.microsoft.com/Forums/vstudio/en-US/…–
jbsmith

您应该能够将其$context作为参数传递给构造函数。PowerShell将自动将字符串转换为枚举。更好的是,只需[System.DirectoryServices.AccountManagement.ContextType]输入的类型$context。另外,为什么您使用的beginprocess在这里?管道似乎是使用此功能的一种奇怪方法。
jpmc26,2017年

@ jpmc26:键入$context参数[System.DirectoryServices.AccountManagement.ContextType]不是一种选择,因为包含的程序集要等到函数执行后才加载;如果要验证多个凭据,使用管道很有帮助。
mklement

@mklement没有理由Add-Type不能在执行其定义之前将调用移到该函数之外。我很犹豫是否要Add-Type在函数中无条件地重复运行某个调用,即使它已经被加载也是如此。首先,同时验证多个凭据似乎很奇怪。在极少数情况下,这是您想要的,您可以轻松地将调用包装在中ForEach-Object,因此我看不出将函数复杂化的原因。
jpmc26,2016年

1

我发现这篇文章很有用,但是并没有解决我的问题,因为我试图通过登录了本地管理员帐户的脚本来运行它。它似乎不能以本地管理员身份工作(仅当以域用户身份登录时)。

但是,我终于设法得到了一个可行的解决方案,并且由于遇到了太多麻烦,我想在这里分享它,因此遇到此问题的任何人都可以在这里找到答案。根据您的需要,两个答案都在一页上。

请注意,在scipt中的较高位置(此处不包含此内容,因为这只是get-credentials部分),已经安装了powergui,这是下面的代码(以及“ Add-PSSnapin Quest.ActiveRoles.ADManagement”行)的要求。不知道powergui做什么,这是不同的,但是没有人能告诉我,它是否有效。

在“ 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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.