Cách xử lý các đối số dòng lệnh trong PowerShell


494

Cách "tốt nhất" để xử lý các đối số dòng lệnh là gì?

Có vẻ như có một số câu trả lời về cách "tốt nhất" là gì và kết quả là tôi bị mắc kẹt về cách xử lý một cái gì đó đơn giản như:

script.ps1 /n name /d domain

script.ps1 /d domain /n name.

Có một plugin có thể xử lý này tốt hơn? Tôi biết tôi đang phát minh lại bánh xe ở đây.

Rõ ràng những gì tôi đã không đẹp và chắc chắn không phải là "tốt nhất", nhưng nó hoạt động .. và đó là UGLY.

for ( $i = 0; $i -lt $args.count; $i++ ) {
    if ($args[ $i ] -eq "/n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "/d"){ $strDomain=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-d"){ $strDomain=$args[ $i+1 ]}
}
Write-Host $strName
Write-Host $strDomain

Câu trả lời:


917

Bạn đang phát minh lại bánh xe. Các tập lệnh PowerShell bình thường có các tham số bắt đầu bằng- , nhưscript.ps1 -server http://devserver

Sau đó, bạn xử lý chúng trong param phần ở đầu tập tin.

Bạn cũng có thể gán giá trị mặc định cho thông số của mình, đọc chúng từ bảng điều khiển nếu không có sẵn hoặc dừng thực thi tập lệnh:

 param (
    [string]$server = "http://defaultserver",
    [Parameter(Mandatory=$true)][string]$username,
    [string]$password = $( Read-Host "Input password, please" )
 )

Bên trong kịch bản, bạn có thể chỉ cần

write-output $server

vì tất cả các tham số trở thành các biến có sẵn trong phạm vi tập lệnh.

Trong ví dụ này, $servernhận được một giá trị mặc định nếu tập lệnh được gọi mà không có nó, tập lệnh dừng nếu bạn bỏ qua -usernametham số và yêu cầu đầu vào đầu cuối nếu-password bị bỏ qua.

Cập nhật: Bạn cũng có thể muốn chuyển một "cờ" (tham số đúng / sai boolean) cho tập lệnh PowerShell. Chẳng hạn, tập lệnh của bạn có thể chấp nhận "lực" trong đó tập lệnh chạy ở chế độ cẩn thận hơn khi không sử dụng lực.

Từ khóa cho điều đó là [switch] loại tham số:

 param (
    [string]$server = "http://defaultserver",
    [string]$password = $( Read-Host "Input password, please" ),
    [switch]$force = $false
 )

Trong kịch bản, bạn sẽ làm việc với nó như thế này:

if ($force) {
  //deletes a file or does something "bad"
}

Bây giờ, khi gọi tập lệnh, bạn đặt tham số switch / flag như thế này:

.\yourscript.ps1 -server "http://otherserver" -force

Nếu bạn rõ ràng muốn nói rằng cờ không được đặt, có một cú pháp đặc biệt cho điều đó

.\yourscript.ps1 -server "http://otherserver" -force:$false

Liên kết đến tài liệu Microsoft có liên quan (đối với PowerShell 5.0; tho phiên bản 3.0 và 4.0 cũng có sẵn tại các liên kết):


58
Thật vậy, một trong những lợi thế lớn của PowerShell là nó cung cấp một cấu trúc phân tích cú pháp phân tích tham số tiêu chuẩn dễ sử dụng.
Keith Hill

14
@naivists, từ PowerShell 2.0 thay vì [string]$username = $(throw "-username is required.")có cú pháp cho các tham số bắt buộc : [Parameter(Mandatory=$true)][string]$username. Dưới đây là thông tin thêm về sự khác biệt giữa các kỹ thuật này: blog.technet.com/b/heyscriptingguy/archive/2011/05/22/ợi
v.karbovnichy

7
Hãy cảnh giác với lỗi khi một arg không được cung cấp; powershell sẽ chỉ lấy bất kỳ văn bản bổ sung nào từ dòng lệnh :. \ ubcript.ps1 -server " serv " -password "mypass" typo Điều này sẽ gán phép 'typo' cho tên người dùng $.
sheamus

4
Tuy nhiên, việc sử dụng một khối param dường như có những hậu quả không lường trước khác: stackoverflow.com/questions / 4040409/21
Logan

1
@sheamus: đó không phải là lỗi! Powershell sẽ xử lý và gán các đối số theo thứ tự chúng được đưa ra, trừ khi bị ghi đè bằng cách sử dụng tên tham số thích hợp, ví dụ: nếu khối param của bạn liệt kê: $ user $ pass $ server và bạn thực thi yourcript.ps1 abc, a sẽ thiết lập thành $ user, b thành $ pass và c vào $ server, UNLESS bạn chỉ định cụ thể cho họ! Vì vậy, nếu bạn nói: yourcript.ps1 -pass abc, $ pass sẽ được đặt thành a và các tham số (chưa đặt tên) còn lại sẽ được sử dụng để điền vào những cái còn thiếu, theo thứ tự được liệt kê trong khối tham số, vì vậy $ user = b, $ máy chủ = c.
Fernando Madruga
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.