在PowerShell中提示用户输入

AJ.*_*AJ. 195 powershell

我想提示用户输入一系列输入,包括密码和文件名.

我有一个使用的例子host.ui.prompt,这似乎是明智的,但我无法理解回报.

有没有更好的方法来获得PowerShell中的用户输入?

Ryn*_*ant 305

Read-Host 是从用户获取字符串输入的简单选项.

$name = Read-Host 'What is your username?'
Run Code Online (Sandbox Code Playgroud)

要隐藏密码,您可以使用:

$pass = Read-Host 'What is your password?' -AsSecureString
Run Code Online (Sandbox Code Playgroud)

要将密码转换为纯文本:

[Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))
Run Code Online (Sandbox Code Playgroud)

至于返回的类型$host.UI.Prompt(),如果你在@Chris's评论中发布的链接上运行代码,你可以通过管道来找出返回类型Get-Member(例如$results | gm).结果是一个Dictionary,其中键是FieldDescription提示中使用的对象的名称.要访问链接示例中第一个提示的结果,您可以键入:$results['String Field'].

要在不调用方法的情况下访问信息,请禁用括号:

PS> $Host.UI.Prompt

MemberType          : Method
OverloadDefinitions : {System.Collections.Generic.Dictionary[string,psobject] Pr
                    ompt(string caption, string message, System.Collections.Ob
                    jectModel.Collection[System.Management.Automation.Host.Fie
                    ldDescription] descriptions)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.Collections.Generic.Dictionary[string,psobject] Pro
                    mpt(string caption, string message, System.Collections.Obj
                    ectModel.Collection[System.Management.Automation.Host.Fiel
                    dDescription] descriptions)
Name                : Prompt
IsInstance          : True
Run Code Online (Sandbox Code Playgroud)

$Host.UI.Prompt.OverloadDefinitions将为您提供方法的定义.每个定义显示为<Return Type> <Method Name>(<Parameters>).

  • 仅供参考,如果您获得用户名和密码,也可以使用Get-Credential. (3认同)

Sta*_*ing 74

使用参数绑定绝对是这里的方法.它不仅编写速度非常快(只需添加[Parameter(Mandatory=$true)]到您的强制参数之上),而且它也是您以后不会讨厌自己的唯一选择.

更多信息:

[Console]::ReadLinePowerShell 的FxCop规则明确禁止使用.为什么?因为它只适用于PowerShell.exe,而不适用于PowerShell ISE,PowerGUI等.

简而言之,Read-Host是糟糕的形式.Read-Host不受控制地停止脚本以提示用户,这意味着您永远不会有另一个脚本包含使用Read-Host的脚本.

你正试图要求参数.

您应该使用该[Parameter(Mandatory=$true)]属性并更正键入,以询问参数.

如果你在a上使用[SecureString]它,它将提示输入密码字段.如果在Credential类型([Management.Automation.PSCredential])上使用此选项,则会弹出凭据对话框(如果参数不存在).字符串将成为一个普通的旧文本框.如果将HelpMessage添加到参数属性(即),[Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]则它将成为提示的帮助文本.

  • 我认为user1499731有一个好点......有些时候你需要从用户那里获取只能在*显示某些信息或执行其他操作后才能有意义地提供的输入.在这种情况下,您不能使用参数,这里给出的"读取主机"为"错误形式"的原因不适用.此外,`.ShouldProcess()`具有"Read-Host"不具有的限制,例如仅限于几个答案.但是我同意`.ShouldProcess()`更好,当它适用时. (6认同)
  • 这是最灵活和用户友好的解决方案,但我几乎忽略了你的建议,因为没有明确的代码示例,如[Rynant的](http://stackoverflow.com/a/8184861/111424)答案.你能提供一些格式很好的例子吗? (5认同)
  • "读取主机是非常简单的糟糕形式"......除非您使用它来有条件地接受由于某人没有使用任何参数调用您的脚本而遗漏的输入.繁荣. (4认同)
  • 不,那时还是不好的形式.这就是您将参数标记为必需的原因. (2认同)
  • 如果您*想要*写一个交互式脚本怎么办?说这是一个脚本,仅在满足某些条件时才需要用户输入。例如,如果您的脚本是要为SDK设置目标目录,则可能要确认用户要删除该目录(如果该目录已经存在)。 (2认同)

小智 14

将它放在脚本的顶部.它将导致脚本提示用户输入密码.然后,可以通过$ pw在脚本的其他位置使用生成的密码.

   Param(
     [Parameter(Mandatory=$true, Position=0, HelpMessage="Password?")]
     [SecureString]$password
   )

   $pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
Run Code Online (Sandbox Code Playgroud)

如果要调试并查看刚刚读取的密码值,请使用:

   write-host $pw
Run Code Online (Sandbox Code Playgroud)