PowerShell - 密码生成器 - 如何始终在字符串中包含数字?

时间:2016-05-16 14:19:17

标签: powershell passwords generator

我有以下PowerShell脚本,它创建一个15位的随机字符串,用作Active Directory密码。

麻烦的是,这在大多数情况下都很有用,但在某些情况下它不使用数字或符号。我刚收到15封信。这不能用作Active Directory密码,因为它必须至少包含一个数字或符号。

$punc = 46..46
$digits = 48..57
$letters = 65..90 + 97..122
$YouShallNotPass = get-random -count 15 `
-input ($punc + $digits + $letters) |
% -begin { $aa = $null } `
-process {$aa += [char]$_} `
-end {$aa}

Write-Host "Password is $YouShallNotPass"

如何将脚本修改为始终至少包含一个随机数或符号?

谢谢。

8 个答案:

答案 0 :(得分:12)

您可以调用Get-Random cmdlet三次,每次使用不同的input参数(punc,数字和字母),连接结果字符串并使用另一个Get-Random调用对其进行随机播放:

 (Get-Random -Count 15 -InputObject ([char[]]$yourPassword)) -join ''

但是,你为什么要重新发明轮子?请考虑使用以下GeneratePassword函数:

[Reflection.Assembly]::LoadWithPartialName("System.Web")
[System.Web.Security.Membership]::GeneratePassword(15,2)

并且为了确保,它至少包含一个随机数(您已经指定了符号数):

do {
   $pwd = [System.Web.Security.Membership]::GeneratePassword(15,2)
} until ($pwd -match '\d')

答案 1 :(得分:8)

正如jisaak所建议的那样,Error when saving @Lob with hibernate java mysql没有100%保证会生成符合Membership.GeneratePassword Method的密码。

这就是我重新发明轮子的原因:

Function MakeUp-String([Int]$Size = 8, [Char[]]$CharSets = "ULNS", [Char[]]$Exclude) {
    $Chars = @(); $TokenSet = @()
    If (!$TokenSets) {$Global:TokenSets = @{
        U = [Char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ'                                #Upper case
        L = [Char[]]'abcdefghijklmnopqrstuvwxyz'                                #Lower case
        N = [Char[]]'0123456789'                                                #Numerals
        S = [Char[]]'!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~'                         #Symbols
    }}
    $CharSets | ForEach {
        $Tokens = $TokenSets."$_" | ForEach {If ($Exclude -cNotContains $_) {$_}}
        If ($Tokens) {
            $TokensSet += $Tokens
            If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random}             #Character sets defined in upper case are mandatory
        }
    }
    While ($Chars.Count -lt $Size) {$Chars += $TokensSet | Get-Random}
    ($Chars | Sort-Object {Get-Random}) -Join ""                                #Mix the (mandatory) characters and output string
}; Set-Alias Create-Password MakeUp-String -Description "Generate a random string (password)"

<强>用法:

  • Size参数定义密码的长度。
  • CharSets参数定义字符U的复杂程度, LNS代表大写,小写,数字和符号。 如果以小写字母(ulns)提供,则返回的字符串 可能包含相关字符集中的任何字符,如果 提供大写字母(ULNS)返回的字符串 包含相关字符中的至少一个字符 集。
  • Exclude参数可让您排除可能包含的特定字符。 导致混淆,如字母数字O和数字0(零)。

<强>示例:

创建一个长度为8个字符的密码,该密码可能包含任何大写字符,小写字符和数字:

Create-Password 8 uln

创建一个长度为12个字符的密码,其中包含至少一个大写字符,一个小写字符,一个数字和一个符号,并且不包含字符OLIoli01:

Create-Password 12 ULNS "OLIoli01"

有关最新的Create-Password版本,请参阅:AD complexity requirements

答案 2 :(得分:1)

使用现有功能生成随机密码的命令:

[system.web.security.membership]::GeneratePassword(x,y)

x =密码长度
y =复杂度

常规错误:

  

无法找到类型[system.web.security.membership]。确保包含此类型的程序集已加载。

解决方案:

运行以下命令:

Add-Type -AssemblyName System.web;

答案 3 :(得分:0)

另一种解决方案:

function New-Password() {
    param(
        [int] $Length = 10,
        [bool] $Upper = $true,
        [bool] $Lower = $true,
        [bool] $Numeric = $true,
        [string] $Special
    )

    $upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    $lowerChars = "abcdefghijklmnopqrstuvwxyz"
    $numericChars = "0123456789"

    $all = ""
    if ($Upper) { $all = "$all$upperChars" }
    if ($Lower) { $all = "$all$lowerChars" }
    if ($Numeric) { $all = "$all$numericChars" }
    if ($Special -and ($special.Length -gt 0)) { $all = "$all$Special" }

    $password = ""
    for ($i = 0; $i -lt $Length; $i++) {
        Write-Host "password: [$password]"
        $password = $password + $all[$(Get-Random -Minimum 0 -Maximum $all.Length)]
    }

    $valid = $true
    if ($Upper -and ($password.IndexOfAny($upperChars.ToCharArray()) -eq -1)) { $valid = $false }
    if ($Lower -and ($password.IndexOfAny($lowerChars.ToCharArray()) -eq -1)) { $valid = $false }
    if ($Numeric -and ($password.IndexOfAny($numericChars.ToCharArray()) -eq -1)) { $valid = $false }
    if ($Special -and $Special.Length -gt 1 -and ($password.IndexOfAny($Special.ToCharArray()) -eq -1)) { $valid = $false }

    if (-not $valid) {
        $password = New-Password `
            -Length $Length `
            -Upper $Upper `
            -Lower $Lower `
            -Numeric $Numeric `
            -Special $Special
    }

    return $password
}

足够灵活,可以设置长度,打开/关闭上,下和数字,以及设置特价商品列表。

答案 4 :(得分:0)

我遇到了同样的问题,这是我用来创建字母数字密码的代码段,我所做的所有操作都很简单,就是使用ASCII正则表达式替换来使其变得美观。

Function Password-Generator ([int]$Length)
{
# Generate passwords just call password-generator(lenght of password)
$Assembly = Add-Type -AssemblyName System.Web
$RandomComplexPassword = [System.Web.Security.Membership]::GeneratePassword($Length,2)
$AlphaNumericalPassword = $RandomComplexPassword -replace '[^\x30-\x39\x41-\x5A\x61-\x7A]+'
Write-Output $AlphaNumericalPassword
}

答案 5 :(得分:0)

我根据在这里和互联网中发现的内容在PowerShell中生成密码:

#Requires -Version 4.0
[CmdletBinding(PositionalBinding=$false)]
param (
    [Parameter(
        Mandatory = $false,
        HelpMessage = "Minimum password length"
    )]
    [ValidateRange(1,[int]::MaxValue)]
    [int]$MinimumLength = 24,

    [Parameter(
        Mandatory = $false,
        HelpMessage = "Maximum password length"
    )]
    [ValidateRange(1,[int]::MaxValue)]
    [int]$MaximumLength = 42,

    [Parameter(
        Mandatory = $false,
        HelpMessage = "Characters which can be used in the password"
    )]
    [ValidateNotNullOrEmpty()]
    [string]$Characters = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@#%*-_+:,.'
)

(1..(Get-Random -Minimum $MinimumLength -Maximum $MaximumLength) `
| %{ `
    $Characters.GetEnumerator() | Get-Random `
}) -join ''

与使用System.Web相比,我更喜欢这样做,而不是引入依赖关系,而依赖关系可能会随.Net / .Net Core版本而改变。
我的变化形式还允许密码长度随机(在指定范围内),非常简洁(除了参数部分,该部分非常冗长,可以强制进行一些验证并提供默认值),并允许重复字符(与问题中的代码相反,永远不会重复相同的字符)。

我知道,这不能保证密码中的数字。但是,这可以通过不同的方式解决。例如。如建议的那样,重复生成直到密码符合要求(包含数字)为止。我的看法是:

  • 生成随机密码。
  • 如果不包含数字(或始终包含):
    • 使用随机函数获得1个随机数字。
    • 将其添加到随机密码。
    • 随机排列结果的顺序(因此数字不一定总是在末尾)。

假定上面的脚本将被命名为“ Get-RandomPassword.ps1”,它看起来可能像这样:

$pass = .\Get-RandomPassword.ps1
$pass += (0..9 | Get-Random)
$pass = (($pass.GetEnumerator() | Get-Random -Count $pass.Length) -join '')
Write-Output $pass

这可以概括为使用任何字符类别强制实施:

$sets = @('abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789', '()-_=+[{]};:''",<.>/?`~')
$pass = .\Get-RandomPassword.ps1 -Characters ($sets -join '')
foreach ($set in $sets) {
    $pass += ($set.GetEnumerator() | Get-Random)
}
$pass = (($pass.GetEnumerator() | Get-Random -Count $pass.Length) -join '')
Write-Output $pass

答案 6 :(得分:0)

我在PowerShell中编写了一个安全的密码生成器函数,也许这对某人有用。

类似于接受的答案,该脚本还使用Get-Random(两次),并且还使用正则表达式匹配来确保输出的安全性。 该脚本的区别在于密码长度也可以随机设置。

(要硬设置密码长度,只需将MinimumPasswordLength和MaximumPasswordLength值设置为相同的长度。)

Example

它还允许轻松地编辑字符集,并具有正则表达式以确保已生成具有以下所有特征的体面密码:

(?=。* \ d)必须至少包含一个数字字符

(?=。* [a-z])必须至少包含一个小写字符

(?=。* [A-Z])必须至少包含一个大写字符

(?=。* \ W)必须至少包含一个非单词字符

关于在生成的输出中始终包含数字的问题的答案可以通过使用正则表达式匹配项检查输出来解决(只需根据需要使用正则表达式的各个部分,上面的说明),此处的示例检查大写,小写和数字:

$Regex = "(?=.*\d)(?=.*[a-z])(?=.*[A-Z])"

do {
        $Password = ([string]($AllowedPasswordCharacters |
        Get-Random -Count $PasswordLength) -replace ' ')
    }    until ($Password -cmatch $Regex)

$Password

以下是完整的脚本:

Function GeneratePassword
{
    cls
    $MinimumPasswordLength = 12
    $MaximumPasswordLength = 16
    $PasswordLength = Get-Random -InputObject ($MinimumPasswordLength..$MaximumPasswordLength)
    $AllowedPasswordCharacters = [char[]]'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?@#£$%^&'
    $Regex = "(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)"

    do {
            $Password = ([string]($AllowedPasswordCharacters |
            Get-Random -Count $PasswordLength) -replace ' ')
       }    until ($Password -cmatch $Regex)

    $Password

}

GeneratePassword

答案 7 :(得分:0)

我已经创建了这个。您可以选择要创建多少个Pwd

$howoften = Read-Host "How many would you like to create: "
$i = 0
do{
    (-join(1..42 | ForEach {((65..90)+(97..122)+(".") | % {[char]$_})+(0..9)+(".") | Get-Random}))
    $i++
} until ($i -match $howoften)

要更改密码的长度,只需在第4行中编辑“ 42”

(-join(1..**42** | ForEach ...