繁体   English   中英

使用Where-Object后使用Get-Random创建空值表达式

[英]Using Get-Random after using Where-Object creates a null valued expression

我正在尝试创建一个10个字符的密码,其中包含数字,字母(大写和小写)和符号的混合。

以下是我在函数中使用的脚本:

Function Get-TempPassword {

$TempPassword = $null

$ascii = $NULL;For ($a = 33;$a –le 126;$a++) {$ascii +=, ([char][byte]$a | Where-Object {$_ -notin "'",'`','|','_',"`;",'"',','})}

Do {$TempPassword += $ascii | Get-Random; $loop++}

Until ($loop -eq 11)

return $TempPassword

}

如果我删除以下部分:

| Where-Object {$ _ -notin“'”,'`','|','_',“;”,'“',','}

密码的创建工作正常,尽管包含了我不想包含的符号。

具有Where-Object函数会使Get-Random函数仅使用数组中的前5个字符,因此,我不会得到任何大小写类型的字母,数字或任何其他符号。

我发现如果我使用$ascii[26] (是数组中的第25个字符),则会得到一个空值,但是我认为这将允许使用该字符之前的任何字符,或者根本不使用任何字符,不只是前5个字符。第25个字符恰好是一个; (ASCII值编号59)。 我尝试将符号添加到Where-Object排除项中,并将其从数组中删除,但第25个字符仍显示为空值。

我对where两侧的每个字符的ascii值[int[]][char[]]进行了反向查找。 符号将出现,并且返回值58和60,这使我认为是值59令人反感,但此时应将该符号排除在外。

向'where-object'排除列表中添加字符应将其从数组中删除,并且看来,但是运行$ascii.Count显示49个字符,无论我是向Where-Object排除列表中添加还是删除字符。

我一直在网上寻找信息,但似乎找不到任何信息,尽管这可能是我正在使用的搜索字词,因为这是一个复杂的案例,很少有人在报告。

任何帮助表示赞赏。

简短版本(对我来说最好的方法):

$possible=36..38 + 40..43 + 45..58 + 60..94 + 97..123 + 125..126 + 33
(get-random -count 10 -input $possible | % {[char]$_}) -join ''

我没有写这个,我不记得我从哪里得到的,但是我已经将它内置到任何脚本中以创建随机的安全Windows密码,您可以指定参数[int]$PasswordLength (i已经将其设置为10)。

function New-SWRandomPassword {
    [CmdletBinding(DefaultParameterSetName='FixedLength',ConfirmImpact='None')]
    [OutputType([String])]
    Param
    (
        # Specifies minimum password length
        [Parameter(Mandatory=$false,
                   ParameterSetName='RandomLength')]
        [ValidateScript({$_ -gt 0})]
        [Alias('Min')] 
        [int]$MinPasswordLength = 8,

        # Specifies maximum password length
        [Parameter(Mandatory=$false,
                   ParameterSetName='RandomLength')]
        [ValidateScript({
                if($_ -ge $MinPasswordLength){$true}
                else{Throw 'Max value cannot be lesser than min value.'}})]
        [Alias('Max')]
        [int]$MaxPasswordLength = 11,

        # Specifies a fixed password length
        [Parameter(Mandatory=$false,
                   ParameterSetName='FixedLength')]
        [ValidateRange(1,2147483647)]
        [int]$PasswordLength = 10,

        # Specifies an array of strings containing charactergroups from which the password will be generated.
        # At least one char from each group (string) will be used.
        [String[]]$InputStrings = @('abcdefghijkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789', '!"#%&'),

        # Specifies a string containing a character group from which the first character in the password will be generated.
        # Useful for systems which requires first char in password to be alphabetic.
        [String] $FirstChar,

        # Specifies number of passwords to generate.
        [ValidateRange(1,2147483647)]
        [int]$Count = 1
    )
    Begin {
        Function Get-Seed{
            # Generate a seed for randomization
            $RandomBytes = New-Object -TypeName 'System.Byte[]' 4
            $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider'
            $Random.GetBytes($RandomBytes)
            [BitConverter]::ToUInt32($RandomBytes, 0)
        }
    }
    Process {
        For($iteration = 1;$iteration -le $Count; $iteration++){
            $Password = @{}
            # Create char arrays containing groups of possible chars
            [char[][]]$CharGroups = $InputStrings

            # Create char array containing all chars
            $AllChars = $CharGroups | ForEach-Object {[Char[]]$_}

            # Set password length
            if($PSCmdlet.ParameterSetName -eq 'RandomLength')
            {
                if($MinPasswordLength -eq $MaxPasswordLength) {
                    # If password length is set, use set length
                    $PasswordLength = $MinPasswordLength
                }
                else {
                    # Otherwise randomize password length
                    $PasswordLength = ((Get-Seed) % ($MaxPasswordLength + 1 - $MinPasswordLength)) + $MinPasswordLength
                }
            }

            # If FirstChar is defined, randomize first char in password from that string.
            if($PSBoundParameters.ContainsKey('FirstChar')){
                $Password.Add(0,$FirstChar[((Get-Seed) % $FirstChar.Length)])
            }
            # Randomize one char from each group
            Foreach($Group in $CharGroups) {
                if($Password.Count -lt $PasswordLength) {
                    $Index = Get-Seed
                    While ($Password.ContainsKey($Index)){
                        $Index = Get-Seed                        
                    }
                    $Password.Add($Index,$Group[((Get-Seed) % $Group.Count)])
                }
            }

            # Fill out with chars from $AllChars
            for($i=$Password.Count;$i -lt $PasswordLength;$i++) {
                $Index = Get-Seed
                While ($Password.ContainsKey($Index)){
                    $Index = Get-Seed                        
                }
                $Password.Add($Index,$AllChars[((Get-Seed) % $AllChars.Count)])
            }
            Return $(-join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value))
        }
    }
}

New-SWRandomPassword

编辑:::

https://gallery.technet.microsoft.com/scriptcenter/Generate-a-random-and-5c879ed5

脚本可以在这里找到。

尝试这样的事情:

Function random-password ($length = 10)
{
  $possible=36..38 + 40..43 + 45..58 + 60..94 + 97..123 + 125..126  + 33

  $password = get-random -count $length -input $possible |
            % -begin { $aa = $null } -process {$aa += [char]$_} -end {$aa}

  return $password
}

random-password

使用以下脚本似乎完全符合我的要求。

我在这行的+ =之后删除了逗号(,):

$ascii = $NULL;For ($a = 33;$a –le 126;$a++) {$ascii +=, ([char][byte]$a | Where-Object {$_ -notin "'",'`','|','_',";",'"',','})}

我在将数组添加到之前创建了一个空白数组: $ascii = @()

完整的代码块如下:

Function Get-TempPassword {

    $TempPassword = $null

    $ascii = @()
    For ($a = 33;$a –le 126; $a++) { $ascii += ([char][byte]$a | Where-Object { $_ -notin "'",'`','|','_',";",'"',',' }) }

    Do {$TempPassword += $ascii | Get-Random; $loop++}

    Until ($loop -eq 11)

    return $TempPassword
}

我已经纠正了其他命题,但是我提出了另一种方法:)

Function random-password2 ($length = 10)
{

$Assembly = Add-Type -AssemblyName System.Web
$password = [System.Web.Security.Membership]::GeneratePassword(50, 2)

$possible=36..38 + 40..43 + 45..58 + 60..94 + 97..123 + 125..126 + 33    
$newchar=[char](get-random -count 1 -input $possible)
$password=$password -replace "[`'|_;,]",  $newchar
$password.Substring(0, $length)


}

random-password2

递归方法:

Function random-password ($length = 10)
{

$Assembly = Add-Type -AssemblyName System.Web
$password = [System.Web.Security.Membership]::GeneratePassword($length, 2)

$desablechar = "[``'|_;,`"]"

  if ($password -match $desablechar )
  {
    random-password $length
  }
  else
  {
    $password
  }
}

random-password

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM