You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的PowerShell密码生成脚本会出现未列入的字符?

问题分析:PowerShell密码生成脚本意外出现禁用字符\

问题场景

我为工作编写了一款PowerShell密码生成脚本,用于生成符合某管理网站特定要求的密码。该网站禁止密码包含以下字符:< > * % & : \ ?,因此这些字符已被排除在密码生成的可用字符数组$possibleCharsArray之外。但多次运行脚本后,生成的密码中意外出现了被禁止的\字符,有时还不止一次。希望了解该字符出现的原因,而非仅增加检查逻辑来过滤它。

脚本代码

$Length = 15

$possibleCharsArray = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ123456789!@#$^".ToCharArray()
$repeats = 'aa|bb|cc|dd|ee|ff|gg|hh|ii|jj|kk|ll|mm|nn|oo|pp|qq|rr|ss|tt|uu|vv|ww|xx|yy|zz|11|22|33|44|55|66|77|88|99|00' # repeating characters are not allowed

$validPassword = $false

while($validPassword -eq $false){ #this block both generates the password and checks that it's valid

    $password = "" # start blank

    For($i=0;$i -lt $Length;$i++){ #create the password
        $randChar = Get-Random -InputObject $possibleCharsArray
        $password += $randChar
    }

    #checks to make sure the password contains numbers, uppercase letters, and special characters
    $containsNumbers = $password -match '[0-9]' # check to see if string contains numbers
    $containsCapLetters = $password -cmatch '[A-Z]' # check to see if string contains capital letters
    #$containsLowLetters = $password -cmatch '[a-z]' # check to see if string contains lowercase letters
    $containsSpecChars = $password -match '.*\W+.*' # check to see if string contains characters

    #checks how many of each type the password has
    $totalNums = ($password | Select-String -Pattern '[0-9]' -AllMatches).Matches.Count # this is to make sure there aren't too many numbers
    $totalCaps = [regex]::Matches($password,'[A-Z]').Count # this is to make sure there aren't too many capital letters
    $totalChars = ($password | Select-String -Pattern '[!@#$^]' -AllMatches).Matches.Count # this is to make sure there aren't too many special characters

    #if the password has all 3 mandatory character types, doesn't have too many of each character type, and doesn't contain any repeating characters, the password is valid and gets generated.
    if(($containsNumbers -and $containsCapLetters -and $containsSpecChars) -and (($totalNums -le 2) -and ($totalCaps -le 2) -and ($totalChars -le 2)) -and ($password -notmatch $repeats)){
        $validPassword = $true
    }
}

Write-Host "The new password is:`t $password"

原因分析

核心问题出在PowerShell双引号字符串的变量解析特性:

  • 你定义$possibleCharsArray时使用了双引号字符串,其中的$^是PowerShell的自动变量,它存储上一次正则匹配操作中捕获组的内容。如果当前会话之前执行过涉及转义字符(比如\)的正则匹配,$^的值就可能包含\,导致这个字符被混入可用字符数组。
  • 即使没有之前的匹配操作,双引号字符串中PowerShell会尝试解析所有$开头的标识,当$^未被正确识别为字面量时,也可能在字符串处理过程中引入意外字符。

根本解决方法

将定义字符集的字符串改为单引号包裹,这样PowerShell会将其视为纯字面量,不会解析任何变量或特殊符号:

$possibleCharsArray = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ123456789!@#$^'.ToCharArray()

内容的提问来源于stack exchange,提问作者yikes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:50:02