为何我的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
相关产品推荐
相关产品推荐

