Prompt for user input in PowerShell

前端 未结 4 809
鱼传尺愫
鱼传尺愫 2020-11-29 15:51

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,

相关标签:
4条回答
  • 2020-11-29 16:05

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

    $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'].

    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>).

    0 讨论(0)
  • 2020-11-29 16:11

    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
          )
    
    0 讨论(0)
  • 2020-11-29 16:12

    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.

    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.

    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.

    You're trying to ask for parameters.

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

    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.

    0 讨论(0)
  • 2020-11-29 16:18

    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.

       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
    
    0 讨论(0)
提交回复
热议问题