在PowerShell中提示用户输入

时间:2022-10-11 21:23:29

I want to prompt the user for a series of inputs, including a password and a filename.

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

I have an example of using host.ui.prompt, which seems sensible, but I can't understand the return.

我有一个使用host.ui.prompt的例子,这看起来很明智,但我无法理解返回。

Is there a better way to get user input in PowerShell?

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

4 个解决方案

#1


256  

Read-Host is a simple option for getting string input from a user.

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

$name = Read-Host 'What is your username?'

To hide passwords you can use:

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

$pass = Read-Host 'What is your password?' -AsSecureString

To convert the password to plain text:

要将密码转换为纯文本:

[Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))

As for the type returned by $host.UI.Prompt(), if you run the code at the link posted in @Christian's comment, you can find out the return type by piping it to Get-Member (for example, $results | gm). The result is a Dictionary where the key is the name of a FieldDescription object used in the prompt. To access the result for the first prompt in the linked example you would type: $results['String Field'].

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

To access information without invoking a method, leave the parentheses off:

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

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

$Host.UI.Prompt.OverloadDefinitions will give you the definition(s) of the method. Each definition displays as <Return Type> <Method Name>(<Parameters>).

$ Host.UI.Prompt.OverloadDefinitions将为您提供方法的定义。每个定义显示为 <返回类型> <方法名称> ( <参数> )。

#2


68  

Using parameter binding is definitely the way to go here. Not only is it very quick to write (just add [Parameter(Mandatory=$true)] above your mandatory parameters), but it's also the only option that you won't hate yourself for later.

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

More below:

更多如下:

[Console]::ReadLine is explicitly forbidden by the FxCop rules for PowerShell. Why? Because it only works in PowerShell.exe, not PowerShell ISE, PowerGUI, etc.

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

Read-Host is, quite simply, bad form. Read-Host uncontrollably stops the script to prompt the user, which means that you can never have another script that includes the script that uses Read-Host.

简单来说,Read-Host是糟糕的形式。 Read-Host无法控制地停止脚本以提示用户,这意味着您永远不会有另一个脚本包含使用Read-Host的脚本。

You're trying to ask for parameters.

你正试图要求参数。

You should use the [Parameter(Mandatory=$true)] attribute, and correct typing, to ask for the parameters.

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

If you use this on a [SecureString], it will prompt for a password field. If you use this on a Credential type, ([Management.Automation.PSCredential]), the credentials dialog will pop up, if the parameter isn't there. A string will just become a plain old text box. If you add a HelpMessage to the parameter attribute (that is, [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]) then it will become help text for the prompt.

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

#3


13  

Place this at the top of your script. It will cause the script to prompt the user for a password. The resulting password can then be used elsewhere in your script via $pw.

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

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

   $pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))

If you want to debug and see the value of the password you just read, use:

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

   write-host $pw

#4


3  

As an alternative, you could add it as a script parameter for input as part of script execution

作为替代方案,您可以将其添加为脚本参数,以作为脚本执行的一部分进行输入

 param(
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
      )

#1


256  

Read-Host is a simple option for getting string input from a user.

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

$name = Read-Host 'What is your username?'

To hide passwords you can use:

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

$pass = Read-Host 'What is your password?' -AsSecureString

To convert the password to plain text:

要将密码转换为纯文本:

[Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))

As for the type returned by $host.UI.Prompt(), if you run the code at the link posted in @Christian's comment, you can find out the return type by piping it to Get-Member (for example, $results | gm). The result is a Dictionary where the key is the name of a FieldDescription object used in the prompt. To access the result for the first prompt in the linked example you would type: $results['String Field'].

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

To access information without invoking a method, leave the parentheses off:

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

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

$Host.UI.Prompt.OverloadDefinitions will give you the definition(s) of the method. Each definition displays as <Return Type> <Method Name>(<Parameters>).

$ Host.UI.Prompt.OverloadDefinitions将为您提供方法的定义。每个定义显示为 <返回类型> <方法名称> ( <参数> )。

#2


68  

Using parameter binding is definitely the way to go here. Not only is it very quick to write (just add [Parameter(Mandatory=$true)] above your mandatory parameters), but it's also the only option that you won't hate yourself for later.

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

More below:

更多如下:

[Console]::ReadLine is explicitly forbidden by the FxCop rules for PowerShell. Why? Because it only works in PowerShell.exe, not PowerShell ISE, PowerGUI, etc.

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

Read-Host is, quite simply, bad form. Read-Host uncontrollably stops the script to prompt the user, which means that you can never have another script that includes the script that uses Read-Host.

简单来说,Read-Host是糟糕的形式。 Read-Host无法控制地停止脚本以提示用户,这意味着您永远不会有另一个脚本包含使用Read-Host的脚本。

You're trying to ask for parameters.

你正试图要求参数。

You should use the [Parameter(Mandatory=$true)] attribute, and correct typing, to ask for the parameters.

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

If you use this on a [SecureString], it will prompt for a password field. If you use this on a Credential type, ([Management.Automation.PSCredential]), the credentials dialog will pop up, if the parameter isn't there. A string will just become a plain old text box. If you add a HelpMessage to the parameter attribute (that is, [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]) then it will become help text for the prompt.

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

#3


13  

Place this at the top of your script. It will cause the script to prompt the user for a password. The resulting password can then be used elsewhere in your script via $pw.

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

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

   $pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))

If you want to debug and see the value of the password you just read, use:

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

   write-host $pw

#4


3  

As an alternative, you could add it as a script parameter for input as part of script execution

作为替代方案,您可以将其添加为脚本参数,以作为脚本执行的一部分进行输入

 param(
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
      )