Я хочу запросить у пользователя серию входов, включая пароль и имя файла.
У меня есть пример использования host.ui.prompt
, который кажется разумным, но я не могу понять возврат.
Есть ли лучший способ получить пользовательский ввод в PowerShell?
Я хочу запросить у пользователя серию входов, включая пароль и имя файла.
У меня есть пример использования host.ui.prompt
, который кажется разумным, но я не могу понять возврат.
Есть ли лучший способ получить пользовательский ввод в PowerShell?
Read-Host
- это простой способ получения строкового ввода от пользователя.
$name = Read-Host 'What is your username?'
Чтобы скрыть пароли, вы можете использовать:
$pass = Read-Host 'What is your password?' -AsSecureString
Чтобы преобразовать пароль в обычный текст:
[Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))
Что касается типа, возвращаемого $host.UI.Prompt()
, если вы запустите код по ссылке, опубликованной в комментарии @Christian, вы можете узнать тип возврата, связав его с Get-Member
(например, $results | gm
). Результатом является словарь, в котором ключ является именем объекта 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
$Host.UI.Prompt.OverloadDefinitions
даст вам определение (определения) метода. Каждое определение отображается как <Return Type> <Method Name>(<Parameters>)
.
Использование привязки параметров - определенно путь сюда. Не только очень быстро писать (просто добавьте [Parameter(Mandatory=$true)]
над вашими обязательными параметрами), но это также единственный вариант, который вы не будете ненавидеть позже.
Далее ниже:
[Console]::ReadLine
явно запрещен правилами FxCop для PowerShell. Зачем? Поскольку он работает только в PowerShell.exe, а не PowerShell ISE, PowerGUI и т.д.
Read-Host - довольно простая и плохая форма. Read-Host неконтролируемо останавливает script, чтобы запросить пользователя, а это значит, что у вас никогда не будет другого script, который включает script, который использует Read-Host.
Вы пытаетесь задать параметры.
Вы должны использовать атрибут [Parameter(Mandatory=$true)]
и правильную типизацию, чтобы запросить параметры.
Если вы используете это в [SecureString]
, оно предложит ввести пароль. Если вы используете это в типе Credential, ([Management.Automation.PSCredential]
), появится диалоговое окно учетных данных, если параметр отсутствует. Строка станет просто старым текстовым полем. Если вы добавите HelpMessage в атрибут параметра (то есть [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]
), он станет справочным текстом для подсказки.
Поместите это вверху вашего script. Это приведет к тому, что script предложит пользователю ввести пароль. Полученный пароль можно затем использовать в другом месте в script через $pw.
Param(
[Parameter(Mandatory=$true, Position=0, HelpMessage="Password?")]
[SecureString]$password
)
$pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
Если вы хотите отлаживать и видеть значение пароля, которое вы только что прочитали, используйте:
write-host $pw
В качестве альтернативы вы можете добавить его как параметр script для ввода как часть выполнения script
param(
[Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
[Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
)