【问题标题】:PowerShell New-ADUser creating disabled user anywaysPowerShell New-ADUser 仍然创建禁用用户
【发布时间】:2021-09-05 04:37:07
【问题描述】:

这是对Powershell New-ADUser error handling password complexity (ActiveDirectory module) 的背负,因为它涉及在执行此类操作时不满足密码复杂性规则并且无论如何都会创建新(禁用)用户的场景:

New-ADUser test1 -Givenname test -surname test -AccountPassword (ConvertTo-SecureString "abc" -AsPlainText -Force)

我已经尝试try/catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException] 以及$ErrorAction = Stop 与链接帖子中建议的New-ADUser... -ErrorAction Stop 一起使用,以防止在密码未通过复杂性检查无济于事时创建新(禁用)用户.

我使用的环境是 Server 2019 和 PS 5.1

我很想知道为什么在过去使用$ErrorAction = "Stop"New-ADUser... -ErrorAction Stop 显然可以防止创建禁用用户,但现在却不行。我到处搜索,找不到解决方案,或更重要的是,我无法理解为什么在任何情况下使用ErrorAction 都不能按照我期望的方式在这种特定情况下工作。任何人都可以帮助我这一天的这段时间不要白痴吗?

-更新了下面的问题文本-

为了在 prod 环境中应用它,我有动力遵循复杂性规则,因为它们是正式的 documented,具体来说:

“任何归类为字母字符但不是大写或小写的 Unicode 字符。该组包括来自亚洲语言的 Unicode 字符。”

我遇到了一个post,它实现了相当可靠的正则表达式模式,但正如用户在底部评论的那样 - 版权符号(其中包括 pi π)应该是有效的,但提供的正则表达式模式不' t 占 unicode 字符的子集。追求 2 个解决方案中的 1 个似乎是合理的,以便允许所有接受的字符:

  1. 制作完美的正则表达式来解释 MS 文档中描述的所有允许的 Unicode 字符
  2. 使用 try/catch [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException],因为这应该可靠地拒绝不完全符合复杂性规则的密码。

对于 prod 中的密码复杂性规则合规性(以及在密码不被接受时避免创建新的禁用用户),与手动考虑所有已知异常相比,#2 似乎是一种更合理的方法。我是不是从一个糟糕的角度来解决这个问题?

【问题讨论】:

    标签: powershell active-directory passwords


    【解决方案1】:

    为避免由于密码不符合域密码复杂性规则而创建禁用用户,您可以使用此辅助函数:

    function Test-DomainPassword {
        # see: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/password-must-meet-complexity-requirements
        [CmdletBinding()]
        Param (
            [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
            [ValidateNotNullOrEmpty()]
            [string]$Password,
    
            [string]$SamAccountName = $null,
            [string]$DisplayName = $null
        )
        $PasswordPolicy = Get-ADDefaultDomainPasswordPolicy -ErrorAction SilentlyContinue
    
        if ($Password.Length -lt $PasswordPolicy.MinPasswordLength) {
            Write-Verbose "Password '$Password' is too short. Minimal length is $($PasswordPolicy.MinPasswordLength)"
            return $false
        }
        if (($SamAccountName) -and ($Password -match [regex]::Escape($SamAccountName))) {
            Write-Verbose "The password '$Password' includes the users SamAccountName"
            return $false
        }
        if ($DisplayName) {
            # The displayName is parsed for delimiters: commas, periods, dashes or hyphens, underscores, spaces, pound signs, and tabs.
            # If any of these delimiters are found, the displayName is split and all parsed sections (tokens) are confirmed not to be
            # included in the password.
            # Tokens that are shorter than three characters are ignored, and substrings of the tokens aren't checked.
            $tokens = $DisplayName.Split(",.-,_ #`t")
            foreach ($token in $tokens) {
                if (($token) -and ($token.Length -ge 3) -and ($Password -match [regex]::Escape($token))) {
                    Write-Verbose "The password '$Password' includes (part of) the users DisplayName"
                    return $false
                }
            }
        }
        if ($PasswordPolicy.ComplexityEnabled) {
            # see: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/bb726984(v=technet.10)?redirectedfrom=MSDN
            # chapter 'Passwords Must Meet Complexity Requirements':
            # Passwords must use three of the four available character types:
            # lowercase letters, uppercase letters, numbers, and symbols.
    
            $failures = @()
            # check for presence of
            # - Uppercase: A through Z, with diacritic marks, Greek and Cyrillic characters
            if ($Password -cnotmatch "[A-Z\p{Lu}\s]") {
                $failures += "- The password is missing Uppercase characters"
            }
            # - Lowercase: a through z, sharp-s, with diacritic marks, Greek and Cyrillic characters
            if ($Password -cnotmatch "[a-z\p{Ll}\s]") {
                $failures += "- The password is missing Lowercase characters"
            }
            # - Base 10 digits (0 through 9)
            if ($Password -notmatch "[\d]") {
                $failures += "- The password is missing digits (0-9)"
            }
            # - Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/
            if ($Password -notmatch "[^\w]") {
                $failures += "- The password is missing Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;`"'<>,.?/"
            }
            # test if we have more than 1 mismatch (password needs at least 3 out of 4 to be OK)
            if ($failures.Count -gt 1) {
                Write-Verbose "The password '$Password' failed because:`r`n{0}" -f ($failures -join "`r`n")
                return $false
            }
        }
    
        $true
    }
    

    像这样使用它:

    # both parameters -SamAccountName and -DisplayName are optional
    if (Test-DomainPassword -Password 'abc' -SamAccountName 'test1' -DisplayName 'Paul Test' -Verbose) {
        # the password is OK, create the new user here:
        $userParams = @{
            SamAccountName        = 'test1'
            GivenName             = 'Paul'
            Surname               = 'Test'
            DisplayName           = 'Paul Test'
            AccountPassword       = ConvertTo-SecureString -String 'abc' -AsPlainText -force
            Enabled               = $true
            # etcetera
        }
    
        New-ADUser @userParams
    }
    else {
        Write-Warning "User 'test1' NOT created because the password did not pass the test"
    }
    

    【讨论】:

    • 感谢您的回复,西奥!这是为了避免在密码不符合脚本中的条件时创建新用户。我尝试使用密码“1234aBπ”测试您的代码,但不幸的是它拒绝了该密码(我能够使用相同的密码在 ADUC 中手动创建一个新用户)。我已经用更详细的信息更新了我原来的问题。
    • @Paul 请看我的编辑版本。在this old microsoft page 上,我发现密码必须满足 4 条复杂性规则中的至少 3 条。如果不满足 4 条规则中的任何一条,该函数现在尊重它以前返回 $false 的位置。这就是为什么密码1234aBπ之前没有通过测试的原因。
    • docs.microsoft.com/en-us/windows/security/threat-protection/… 这是我指的当前文档链接,其中包括 unicode。在无法按预期工作的尝试/捕获范围内,我并不坚如磐石。我对您提供的解决方案没有不满,但为了我自己的学习,我很想知道此时为什么捕获特定异常 [Microsoft.ActiveDirectory.Management.ADPasswordComplexityException] 不起作用。您对为什么这不起作用有任何见解吗?
    • @Paul 好吧,看来如果其他参数足够好,用户创建的。只有这样才能设置密码,但可能会因事先未检查的复杂性规则而失败。如果失败,新创建的用户将被禁用,而不是删除,并且在使用 New-ADUser cmdlet 时永远不会引发 ADPasswordComplexityException。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多