Nhắc về đầu vào của người dùng trong PowerShell


209

Tôi muốn nhắc người dùng về một loạt các đầu vào, bao gồm mật khẩu và tên tệp.

Tôi có một ví dụ về việc sử dụng host.ui.prompt, có vẻ hợp lý, nhưng tôi không thể hiểu được sự trở lại.

Có cách nào tốt hơn để nhận đầu vào của người dùng trong PowerShell không?

Câu trả lời:


333

Read-Host là một tùy chọn đơn giản để nhận đầu vào chuỗi từ người dùng.

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

Để ẩn mật khẩu, bạn có thể sử dụng:

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

Để chuyển đổi mật khẩu thành văn bản thuần túy:

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

Đối với loại được trả về bởi $host.UI.Prompt(), nếu bạn chạy mã tại liên kết được đăng trong bình luận của @ Christian, bạn có thể tìm ra loại trả về bằng cách chuyển nó tới Get-Member(ví dụ $results | gm:). Kết quả là một từ điển trong đó khóa là tên của một FieldDescriptionđối tượng được sử dụng trong lời nhắc. Để truy cập kết quả cho lời nhắc đầu tiên trong ví dụ được liên kết, bạn sẽ gõ : $results['String Field'].

Để truy cập thông tin mà không cần gọi một phương thức, hãy bỏ dấu ngoặc đơn:

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.OverloadDefinitionssẽ cung cấp cho bạn định nghĩa của phương thức. Mỗi định nghĩa hiển thị như <Return Type> <Method Name>(<Parameters>).


Cảm ơn, @Rynant. Câu trả lời được chấp nhận vì là người duy nhất thực sự trả lời câu hỏi chính của tôi! ;) Tất cả các thông tin khác cũng thực sự hữu ích, đặc biệt là khi tôi vẫn đang mò mẫm tìm đường trong PS.
AJ.

Không vấn đề gì, @AJ. Một cách khác để có được thông tin về một phương thức là bỏ dấu ngoặc đơn. Tôi sẽ thêm một ví dụ cho câu trả lời của tôi.
Rynant

3
FYI bạn cũng có thể sử dụng Get-Credential nếu bạn nhận được tên người dùng và mật khẩu.
Matt Lyons

75

Sử dụng ràng buộc tham số chắc chắn là cách để đi đến đây. Nó không chỉ rất nhanh để viết (chỉ cần thêm vào [Parameter(Mandatory=$true)]trên các tham số bắt buộc của bạn), mà còn là lựa chọn duy nhất mà bạn sẽ không ghét bản thân mình sau này.

Thêm bên dưới:

[Console]::ReadLinebị cấm rõ ràng bởi các quy tắc FxCop cho PowerShell. Tại sao? Bởi vì nó chỉ hoạt động trong PowerShell.exe, không phải PowerShell ISE , PowerGUI , v.v.

Read-Host là, khá đơn giản, hình thức xấu. Máy chủ đọc không thể kiểm soát dừng tập lệnh để nhắc người dùng, điều đó có nghĩa là bạn không bao giờ có thể có tập lệnh khác bao gồm tập lệnh sử dụng Máy chủ lưu trữ.

Bạn đang cố gắng yêu cầu thông số.

Bạn nên sử dụng [Parameter(Mandatory=$true)]thuộc tính và gõ chính xác để yêu cầu các tham số.

Nếu bạn sử dụng điều này trên một [SecureString], nó sẽ nhắc cho một trường mật khẩu. Nếu bạn sử dụng điều này trên loại Thông tin xác thực, ( [Management.Automation.PSCredential]), hộp thoại thông tin đăng nhập sẽ bật lên, nếu tham số không có ở đó. Một chuỗi sẽ chỉ trở thành một hộp văn bản cũ đơn giản. Nếu bạn thêm HelpMessage vào thuộc tính tham số (nghĩa là [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]) , thì nó sẽ trở thành văn bản trợ giúp cho lời nhắc.


5
Đây là giải pháp linh hoạt và thân thiện với người dùng nhất, nhưng tôi gần như bỏ qua lời khuyên của bạn vì không có ví dụ mã rõ ràng như trong câu trả lời của Rynant . Bạn có thể cung cấp một số ví dụ định dạng độc đáo?
Iain Samuel McLean Elder

4
"Máy chủ đọc là, khá đơn giản, là hình thức xấu" ... trừ khi bạn đang sử dụng nó để chấp nhận một cách có điều kiện đầu vào bị bỏ qua vì ai đó không gọi tập lệnh của bạn với bất kỳ tham số nào. BÙM.

2
Không: đó vẫn là hình thức xấu. Đó là lý do tại sao bạn đánh dấu các tham số là bắt buộc.
Bắt đầu tự động hóa

2
Nếu bạn muốn viết một kịch bản tương tác thì sao? Nói rằng đó là một tập lệnh chỉ yêu cầu đầu vào của người dùng nếu đáp ứng một số điều kiện nhất định. Chẳng hạn, nếu tập lệnh của bạn là để thiết lập thư mục đích cho SDK, bạn có thể muốn xác nhận rằng người dùng muốn xóa thư mục nếu nó đã tồn tại.
Jason Goemaat

6
Tôi nghĩ rằng user1499731 đã có một điểm tốt ... Có những lúc bạn cần lấy đầu vào từ người dùng chỉ có thể được cung cấp một cách có ý nghĩa sau khi một số thông tin được hiển thị hoặc một thao tác khác được thực hiện. Trong trường hợp đó, bạn không thể sử dụng một tham số và các lý do được đưa ra ở đây Read-Hostlà "hình thức xấu" không được áp dụng. Hơn nữa, .ShouldProcess()có những hạn chế Read-Hostkhông, chẳng hạn như chỉ giới hạn trong một vài câu trả lời. Tuy nhiên tôi đồng ý rằng điều đó .ShouldProcess()tốt hơn khi áp dụng.
LarsH

14

Đặt cái này ở đầu tập lệnh của bạn. Nó sẽ khiến tập lệnh nhắc người dùng nhập mật khẩu. Mật khẩu kết quả sau đó có thể được sử dụng ở nơi khác trong tập lệnh của bạn thông qua $ pw .

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

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

Nếu bạn muốn gỡ lỗi và xem giá trị của mật khẩu bạn vừa đọc, hãy sử dụng:

   write-host $pw

3

Thay vào đó, bạn có thể thêm nó làm tham số tập lệnh cho đầu vào như một phần của thực thi tập lệnh

 param(
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
      )
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.