【问题标题】:My New-RandomPassword function suddenly doesn't work我的 New-RandomPassword 功能突然不起作用
【发布时间】:2019-11-12 17:00:18
【问题描述】:

为了好玩,我决定创建一个函数,该函数会根据用户决定他们想要的数量生成一些随机密码。我正在使用 Begin 和 Process 块来运行脚本。 Begin 块有一个 $characterPool 变量,其中字母数字和特殊字符作为潜在字符。 Process 块询问用户想要多少个密码并创建许多随机的 12 个字符的密码。当我第一次创建该函数时,它运行良好。现在,无论我请求多少密码,都只会创建两个密码,然后它会重新提出问题。之后,使用空字符串按回车键或添加另一个数字会导致打印出一个密码。

Begin
    {
        $characterPool = "!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray()
    }
    Process
    {
        [pscustomobject]@{
            Password = -join ($characterPool | Get-Random -Count 12)
            }
        $counter = Read-Host -Prompt "How many passwords do ya want, buddy?"
        1..$counter | New-RandomPassword
    }

我希望这会生成我请求的密码数量。没有产生错误,它只是显示如下:

Begin
    {
        $characterPool = "!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray()
    }
    Process
    {
        [pscustomobject]@{
            Password = -join ($characterPool | Get-Random -Count 12)
            }
        $counter = Read-Host -Prompt "How many passwords do ya want, buddy?"
        1..$counter | New-RandomPassword
    }

How many passwords do ya want, buddy?: 5
Password    
--------    
1z@p8Jgl52yU
1#K8z2@iA!&o
How many passwords do ya want, buddy?: 
Pw!C#d2xTjMu
How many passwords do ya want, buddy?: 
fo*Oca9HbRQr
How many passwords do ya want, buddy?: 
omzCRpwqdOfM
How many passwords do ya want, buddy?: 
u5lMN!kjhzfe
How many passwords do ya want, buddy?: 6
vLaxHq945K$D
How many passwords do ya want, buddy?:

【问题讨论】:

  • 这个 PowerShell 对我不起作用,因为我收到“无法识别术语 'New-RandomPassword'”。您发布的脚本是否完整?
  • @UnhandledExcepSean:看起来New-RandomPassword 是正在定义的函数的名称(即使代码没有显示),并且您看到的是递归调用 - 这就是问题出在哪里。

标签: powershell


【解决方案1】:

Read-Host提示函数移到开头,将密码生成逻辑移入循环:

function New-RandomPassword {
    param()

    [int]$counter = Read-Host -Prompt "How many passwords do ya want, buddy?"
    $characterPool = "!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray()
    $i = 0;
    while($i++ -lt $counter)
    {
        [pscustomobject]@{
            Password = -join ($characterPool | Get-Random -Count 12)
        }
    }
}

这样你就不必递归调用函数了。


我会亲自将$counter 变量转换为参数,然后在内部调用 New-RandomPassword 的脚本中提示用户

function New-RandomPassword {
    param(
        [ValidateRange(1,500)]
        [int]$Count
    )

    $characterPool = "!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray()
    $i = 0;
    while($i++ -lt $count)
    {
        [pscustomobject]@{
            Password = -join ($characterPool | Get-Random -Count 12)
        }
    }
}

作为mklement0 pointed out,您还可以使用Read-Host 调用作为参数的默认值来分配表达式:

param(
    [ValidateRange(1,500)]
    [int]$Count = $(Read-Host 'How many passwords do ya want, buddy?')
)

我个人认为这是一种反模式,并且宁愿坚持默认为1 或标记参数Mandatory

# If the caller omits the argument, 1 password is returned
param(
    [ValidateRange(1,500)]
    [int]$Count = 1
)

# Caller _must_ supply a parameter argument (the default console host will prompt the user if not, but depends on the host application)
param(
    [Parameter(Mandatory = $true)]
    [ValidateRange(1,500)]
    [int]$Count
)

【讨论】:

  • 谢谢,马蒂亚斯。至于它是一种反模式:在这样的简单情况下(标量输入,隐式转换为目标类型有效),我认为它实际上优于Mandatory,因为后者提供的用户体验很差 -见github.com/PowerShell/PowerShell/issues/4068。由于Read-Host 也因-noninteractive 而失败(正如您在此处所希望的那样),因此没有真正的缺点。但总的来说,更好的解决方案显然是修复自动提示机制(或者,如果失败,则完全摆脱它)。
  • @mklement0 公平点。但是,在这种特殊情况下,从用户体验的角度来看,当我调用一个没有参数的函数 New-RandomPassword 时,我希望它只是,你知道的……为我提供一个新的随机密码:D
  • :) 这也是一个好点;所以这里真正的 UX 问题是提示正在显示根本,而不是它是如何实现的。
猜你喜欢
  • 2019-11-04
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 2015-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
相关资源
最近更新 更多