Câu hỏi Cách chuyển đối số dòng lệnh tới tệp ps1 PowerShell


Trong nhiều năm, tôi đã sử dụng cmd/DOS/Windows trình bao và thông qua các đối số dòng lệnh cho các tệp lô. Ví dụ, tôi có một tập tin, zuzu.bat và trong đó, tôi truy cập %1, %2, v.v. Bây giờ, tôi muốn làm như vậy khi tôi gọi PowerShell kịch bản when I am in a Cmd.exe shell. Tôi có một kịch bản, xuxu.ps1 (và tôi đã thêm PS1 vào biến PATHEXT của tôi và các tệp PS1 được liên kết với PowerShell). Nhưng dù tôi có làm gì đi chăng nữa, tôi dường như không thể lấy bất cứ thứ gì từ $args biến. Nó luôn có chiều dài 0.

Nếu tôi ở trong một PowerShell vỏ, thay vì cmd.exe, nó hoạt động (tất nhiên). Nhưng tôi chưa đủ thoải mái để sống trong môi trường PowerShell toàn thời gian. Tôi không muốn gõ powershell.exe -command xuxu.ps1 p1 p2 p3 p4. Tôi muốn gõ xuxu p1 p2 p3 p4.

Điều này có thể, và nếu có, làm thế nào?

Mẫu tôi không thể làm việc là tầm thường, foo.ps1:

Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
    Write-Host "Arg: $arg";
}

Kết quả luôn như sau:

C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>

76
2017-08-18 13:37


gốc




Các câu trả lời:


bài viết này giúp. Đặc biệt, phần này:

-Tập tin

Chạy tập lệnh được chỉ định trong phạm vi cục bộ ("dot-sourced"), để các hàm và biến mà tập lệnh tạo ra có sẵn trong phiên hiện tại. Nhập đường dẫn tệp tập lệnh và bất kỳ tham số nào. Tệp phải là tham số cuối cùng trong lệnh, vì tất cả các ký tự được nhập sau tên thông số Tệp được hiểu là đường dẫn tệp tập lệnh theo sau là tham số tập lệnh.

I E.

powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3

có nghĩa là chạy tệp myfile.ps1 và arg1 arg2 & arg3 là các tham số cho tập lệnh PowerShell.


27
2018-03-28 00:35



Điều này vẫn không giúp với những gì op muốn ("Tôi muốn gõ xuxu p1 p2 p3 p4"). - thdoan


OK, vì vậy trước tiên, điều này sẽ phá vỡ một tính năng bảo mật cơ bản trong PowerShell. Với sự hiểu biết đó, đây là cách bạn có thể làm điều đó:

  1. Mở một Windows Explorer cửa sổ
  2. Thực đơn Công cụ -> Tùy chọn thư mục -> tab Loại tập tin
  3. Tìm loại tệp PS1 và nhấp vào nút nâng cao
  4. Nhấp vào nút Mới
  5. Đối với hành động đặt: Mở
  6. Đối với các ứng dụng đặt: "C: \ WINNT \ system32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-file" "% 1"% *

Bạn có thể muốn đặt -NoProfile đối số trong đó quá tùy thuộc vào những gì hồ sơ của bạn làm.


16
2017-08-18 14:10



Tôi nghĩ rằng chìa khóa là trong bước 6 của bạn, nơi bạn vượt qua trong các tham số để powershell.exe. Daniel nói rằng anh ta đã liên kết các tệp PS1 với PowerShell nhưng không vượt qua các đối số mà không cần thêm% 1% * thông số kỹ thuật. Cũng lưu ý rằng tham số -File không có sẵn trong V1. Nó là mới với V2. - Keith Hill
Tốt bắt liên quan đến tham số -file tôi đã quên điều đó. - EBGreen
Tôi sẽ phải cài đặt V2 trước khi tôi có thể thử đề xuất của bạn. Cảm ơn. Khi bạn nói điều này là phá vỡ một tính năng bảo mật cơ bản, những gì hiện "này" bạn có nghĩa là gì? Gọi một tập lệnh PowerShell từ Cmd.exe như thể nó là một tập tin .com / .bat / .exe? Truyền tham số cho tập lệnh? - Daniel 'Dang' Griffith
Xin lỗi tôi nên rõ ràng hơn. Việc gọi kịch bản mà không cần gọi rõ ràng powershell.exe. Tôi không nói đó là một tính năng bảo mật quan trọng đối với cá nhân bạn và nó là bảo mật thông qua sự tối tăm mà tôi không phải lúc nào cũng là một fan hâm mộ. - EBGreen
Để thêm vào nhận xét của EBGreen, vấn đề bảo mật cơ bản mà PowerShell cố gắng tránh là người bấm đúp vào các tệp PS1 được đính kèm vào email và chạy tập lệnh. Đó là lý do tại sao các tệp PS1 chỉ được liên kết với trình chỉnh sửa theo mặc định. Microsoft thực sự không muốn có phiên bản PowerShell của vi-rút ILoveYou, v.d. "LOVE-LETTER-FOR-YOU.TXT.ps1" - Keith Hill


Sau khi tìm hiểu thông qua tài liệu PowerShell, tôi đã phát hiện một số thông tin hữu ích về vấn đề này. Bạn không thể sử dụng $args nếu bạn sử dụng param(...) ở đầu tệp của bạn; thay vào đó bạn sẽ cần phải sử dụng $PSBoundParameters. Tôi sao chép / dán mã của bạn vào một kịch bản PowerShell, và nó hoạt động như bạn mong đợi trong PowerShell phiên bản 2 (Tôi không chắc bạn đang sử dụng phiên bản nào khi chạy vào vấn đề này).

Nếu bạn đang sử dụng $PSBoundParameters (và CHỈ này hoạt động nếu bạn đang sử dụng param(...) ở đầu script của bạn), sau đó nó không phải là một mảng, nó là một bảng băm, vì vậy bạn sẽ cần phải tham khảo nó bằng cách sử dụng cặp khóa / giá trị.

param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
    $Script:args+= "`$$key=" + $PSBoundParameters["$key"] + "  "
}
write-host $Script:args

Và khi được gọi với ...

PS> ./foo.ps1 a b c d

Kết quả là...

Num Args:  4
$p1=a  $p2=b  $p3=c  $p4=d

13
2017-07-25 21:24





Khai báo các tham số của bạn trong tệp, như param ([string] $ para1 ....... [string] $ param2).

Bây giờ hãy gọi tệp PowerShell như temp.ps1 para1 para2....para10, v.v.


8
2017-08-24 11:41





Có thể bạn có thể gói lời gọi PowerShell trong .battệp như vậy:

rem ps.bat
@echo off
powershell.exe -command "%*"

Nếu bạn đặt tệp này dưới một thư mục trong PATH, bạn có thể gọi các kịch bản PowerShell như sau:

ps foo 1 2 3

Việc trích dẫn có thể hơi lộn xộn, mặc dù:

ps write-host """hello from cmd!""" -foregroundcolor green

6
2018-01-21 00:19



1 để hiển thị dấu ngoặc kép. đã khiến tôi bị mắc kẹt trong một thời gian. - DeanOC


Bạn có thể không nhận được "xuxu p1 p2 p3 p4". Nhưng khi bạn đang ở trong PowerShell và bạn thiết lập

PS > set-executionpolicy Unrestricted -scope currentuser

Bạn có thể chạy các tập lệnh như sau:

./xuxu p1 p2 p3 p4

hoặc là

.\xuxu p1 p2 p3 p4

hoặc là

./xuxu.ps1 p1 p2 p3 p4

Tôi hy vọng rằng bạn sẽ cảm thấy thoải mái hơn với PowerShell.


1
2018-05-27 18:41