Запрос на введення користувача в PowerShell


209

Я хочу попросити користувача про ряд входів, включаючи пароль та ім’я файлу.

У мене є приклад використання host.ui.prompt, який здається розумним, але повернення не можу зрозуміти.

Чи є кращий спосіб отримати вклад користувача в PowerShell?

Відповіді:


333

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(), якщо ви запустите код за посиланням, розміщеним у коментарі @ Крістіана, ви можете дізнатися тип повернення, перейшовши на нього 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>).


Дякую, @ Rynant. Прийняв відповідь за те, що єдиний, хто насправді відповів на моє головне питання! ;) Вся інша інформація теж дуже корисна, тим більше, що я все-таки пробиваюся в PS.
AJ.

Без проблем, @AJ. Ще один спосіб отримати інформацію про метод - це залишити дужки. Я додам приклад до своєї відповіді.
Рінант

3
Ви можете також використовувати Get-Credential, якщо отримуєте імена користувачів та паролі.
Метт Лайонс

75

Використання прив'язки параметрів, безумовно, є способом перейти сюди. Це не тільки те, що дуже швидко писати (просто додайте [Parameter(Mandatory=$true)]вище своїх обов'язкових параметрів), але це також єдиний варіант, який ви не будете ненавидіти себе пізніше.

Більше нижче:

[Console]::ReadLineявно заборонено правилами FxCop для PowerShell. Чому? Тому що він працює лише в PowerShell.exe, а не PowerShell ISE , PowerGUI тощо.

Прочитати-хост - це дуже просто погана форма. Read-Host безконтрольно зупиняє скрипт для сповіщення користувача, а це означає, що ви ніколи не можете мати іншого сценарію, що включає сценарій, який використовує Read-Host.

Ви намагаєтеся запитати параметри.

Вам слід скористатись [Parameter(Mandatory=$true)]атрибутом та правильно вводити текст, щоб запитати про параметри.

Якщо ви використовуєте це на a [SecureString], воно запропонує поле для введення пароля. Якщо ви користуєтесь цим типом Повноваження, ( [Management.Automation.PSCredential]), діалогове вікно облікових даних з'явиться, якщо параметр відсутній. Рядок просто стане звичайним старим текстовим полем. Якщо додати параметр HelpMessage до атрибута параметра (тобто [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]), він стане довідковим текстом для підказки.


5
Це найбільш гнучке та зручне для користувача рішення, але я майже ігнорував вашу пораду, оскільки не було чітких прикладів коду, як, наприклад, у відповіді Райнанта . Чи можете ви надати кілька добре відформатованих прикладів?
Ієн Самуель Маклін Старший

4
"Прочитати-хост - це дуже просто - це погана форма" ... якщо ви не використовуєте його для умовного прийняття вводу, який був залишений, тому що хтось не викликав ваш сценарій з будь-якими параметрами. БУМ.

2
Ні: тоді це все ще погана форма. Ось чому ви позначаєте параметри як обов’язкові.
Автоматизація старту

2
Що робити, якщо ви хочете написати інтерактивний сценарій? Скажіть, що це сценарій, який вимагає введення користувачем лише у випадку виконання певних умов. Наприклад, якщо ваш скрипт повинен встановити цільовий каталог для SDK, ви можете підтвердити, що користувач хоче видалити каталог, якщо він уже існує.
Джейсон Гімаат

6
Я думаю, що користувач1499731 мав добру думку ... Бувають випадки, коли вам потрібно взяти дані від користувача, які можуть бути змістовно надані лише після того, як відображається якась інформація або виконується інша операція. У такому випадку ви не можете скористатися параметром, і причини, наведені тут для Read-Host"неправильної форми", не застосовуються. Більше того, .ShouldProcess()є обмеження, яких Read-Hostнемає, наприклад обмежуючись лише кількома відповідями. Однак я згоден, що .ShouldProcess()краще, коли це застосовується.
ЛарШ

14

Розмістіть це вгорі вашого сценарію. Це призведе до того, що сценарій запропонує користувачеві ввести пароль. Отриманий пароль потім може бути використаний в іншому місці вашого сценарію через $ pw .

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

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

Якщо ви хочете налагоджувати і бачити значення пароля, який ви тільки що прочитали, скористайтеся:

   write-host $pw

3

Як альтернативу, ви можете додати його як параметр сценарію для введення як частини виконання сценарію

 param(
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
      )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.