Làm cách nào để chạy tập lệnh PowerShell mà không hiển thị cửa sổ?


127

Làm thế nào có thể chạy tập lệnh PowerShell mà không hiển thị cửa sổ hoặc bất kỳ dấu hiệu nào khác cho người dùng?

Nói cách khác, tập lệnh nên chạy lặng lẽ trong nền mà không có bất kỳ dấu hiệu nào cho người dùng.

Tín dụng bổ sung cho câu trả lời không sử dụng các thành phần của bên thứ ba :)


Kiểm tra câu hỏi này nếu bạn quan tâm đến việc học: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt

Giải pháp này cũng hoạt động với Trình lập lịch tác vụ: stackoverflow.com/a/51007810/571591
Hilydrow

Câu trả lời:


128

Bạn có thể chạy nó như thế này (nhưng điều này hiển thị một cửa sổ trong một thời gian):

PowerShell.exe -windowstyle hidden { your script.. }

Hoặc bạn sử dụng tệp trợ giúp mà tôi đã tạo để tránh cửa sổ có tên PsRun.exe thực hiện chính xác điều đó. Bạn có thể tải xuống tệp nguồn và exe Chạy các tác vụ theo lịch trình với GUI WinForm trong PowerShell . Tôi sử dụng nó cho các nhiệm vụ theo lịch trình.

Đã chỉnh sửa: như Marco lưu ý thông số -windowstyle này chỉ khả dụng cho V2.


6
Tôi đã biên dịch PsRun, tuy nhiên, nếu tôi thêm nó vào tác vụ theo lịch trình, nó cũng nhấp nháy một cửa sổ ...
Ciantic

2
Tương tự ở đây, cũng không hoạt động vì cửa sổ vẫn bật lên để chạy tập lệnh. Nó thoát ra nhanh chóng nhưng chúng tôi đang cố chạy cái này trong nền mà không bị gián đoạn.
Nathan McKaskle

1
Vâng, đó là lý do tại sao có "nhưng điều này cho thấy một cửa sổ trong một thời gian" trong phản hồi.
stej

21
@ThomasBratt Đối với các tác vụ theo lịch trình, tôi đã thấy các tập lệnh PowerShell chạy âm thầm mà không có -WindowStyle Hiddentác vụ được đặt thành Run whether user is logged on or nottrên tab Chung trong phần "Tùy chọn bảo mật".
adam

1
Sử dụng Tài khoản người dùng để HỆ THỐNG cũng tránh một cửa sổ được hiển thị.
Jon Eldridge

27

Tôi đã có vấn đề tương tự. Tôi phát hiện ra nếu bạn đi đến công tác trong Task Scheduler đang chạy các powershell.exe kịch bản, bạn có thể bấm vào nút " Run liệu người dùng được đăng nhập hay không " và điều đó sẽ không bao giờ hiển thị cửa sổ PowerShell khi nhiệm vụ chạy.


3
Giải pháp tốt nhất mà không phụ thuộc vào phần mở rộng của bên thứ ba, tập lệnh thực thi hoặc trình bao bọc.
đảo ngược

1
Lưu ý rằng tùy chọn này yêu cầu người dùng phải có đặc quyền "Đăng nhập theo công việc hàng loạt"
gb96

Giải pháp này làm cho kịch bản của tôi không chạy đúng .
Martin Argerami

18

Bạn có thể sử dụng Tiện ích mở rộng cộng đồng PowerShell và thực hiện việc này:

start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden

Bạn cũng có thể làm điều này với VBScript: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-schediated-powershell/

(Thông qua chủ đề diễn đàn này .)


Có nhịp đập NuGet cho việc này để tôi có thể chạy nó từ Visual Studio không?
Piotr Kula

13

Đây là một cách tiếp cận không yêu cầu đối số dòng lệnh hoặc trình khởi chạy riêng. Nó không hoàn toàn vô hình vì một cửa sổ hiển thị trong giây lát khi khởi động. Nhưng rồi nó nhanh chóng tan biến. Theo tôi, đây là cách tiếp cận dễ nhất nếu bạn muốn khởi chạy tập lệnh của mình bằng cách nhấp đúp vào trình thám hiểm hoặc thông qua phím tắt menu Bắt đầu (tất nhiên bao gồm cả menu con Khởi động). Và tôi thích rằng đó là một phần của mã của chính kịch bản, không phải là thứ gì đó bên ngoài.

Đặt cái này ở phía trước kịch bản của bạn:

$t = '[DllImport("user32.dll")] public static extern bool ShowWindow(int handle, int state);'
add-type -name win -member $t -namespace native
[native.win]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0)

10

Đây là một lót:

mshta vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoLogo -Command """"& 'C:\Example Path That Has Spaces\My Script.ps1'"""""", 0 : window.close")

Mặc dù điều này có thể làm chớp cửa sổ rất nhanh, nhưng đó là một điều hiếm khi xảy ra.


Trong hầu hết các trường hợp, việc chạy Powershell.exe trong ngữ cảnh người dùng đã đăng nhập sẽ hiển thị toàn bộ cửa sổ hoặc flash nhanh nếu bạn sử dụng -windowstyle ẩn. Để xóa hoàn toàn cửa sổ, bạn có thể thực hiện một trong hai điều sau: 1: Chạy trong ngữ cảnh người dùng khác, chẳng hạn như tài khoản quản trị viên (sẽ không hiển thị bất kỳ cửa sổ nào cho người dùng đã đăng nhập). Hoặc 2: Sử dụng vbscript với objshell.run với cờ cửa sổ ẩn để khởi chạy cmd.exe / c powersrc.exe -file c: \ script.ps1. Khi powershell được gọi từ cmd, nó sẽ chạy trong cửa sổ cmd hiện có đã bị ẩn bởi wscript.exe // b / nologo c: \ launcher.vbs.
Iconiu 26/03/19

wow, đột nhiên Tôi thậm chí không nhận thấy câu trả lời của bạn lúc đầu. Tôi đã trả lời với một kịch bản rất giống nhau. Thật tuyệt khi thấy một người hiểu biết, người đưa ra một câu trả lời thực sự.
Gosha

Đây phải là câu trả lời được chấp nhận, nó là một phương pháp dường như hoạt động trong mọi tình huống (bao gồm cả bên trong bộ lập lịch nhiệm vụ, đó là vấn đề của tôi).
Martin Argerami

6

Tôi gặp vấn đề này khi chạy từ c #, trên Windows 7, dịch vụ "Phát hiện dịch vụ tương tác" đã bật lên khi chạy một cửa sổ quyền hạn ẩn dưới dạng tài khoản HỆ THỐNG.

Việc sử dụng tham số "CreateNoWindow" đã ngăn dịch vụ ISD bật lên cảnh báo.

process.StartInfo = new ProcessStartInfo("powershell.exe",
    String.Format(@" -NoProfile -ExecutionPolicy unrestricted -encodedCommand ""{0}""",encodedCommand))
{
   WorkingDirectory = executablePath,
   UseShellExecute = false,
   CreateNoWindow = true
};

5

Tôi nghĩ rằng cách tốt nhất để ẩn màn hình bảng điều khiển của PowerShell khi bạn đang chạy tập lệnh nền là mã này ( câu trả lời " Bluecakes ").

Tôi thêm mã này vào đầu tất cả các tập lệnh PowerShell mà tôi cần chạy ở chế độ nền.

# .Net methods for hiding/showing the console in the background
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
function Hide-Console
{
    $consolePtr = [Console.Window]::GetConsoleWindow()
    #0 hide
    [Console.Window]::ShowWindow($consolePtr, 0)
}
Hide-Console

Nếu câu trả lời này là giúp bạn, vui lòng bỏ phiếu cho "Bluecakes" trong câu trả lời của anh ấy trong bài đăng này.


Đối với tôi giao diện điều khiển vẫn hiển thị trong khoảng một giây.
thdoan

3

ps1 bị ẩn khỏi Trình lập lịch tác vụ và phím tắt

    mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -ExecutionPolicy Bypass & 'C:\PATH\NAME.ps1'"", 0:close")

2

Tôi đã tạo một công cụ nhỏ chuyển cuộc gọi đến bất kỳ công cụ giao diện điều khiển nào bạn muốn bắt đầu không có cửa sổ thông qua tệp gốc:

https://github.com/Vittel/RunHiddenConsole

Sau khi biên dịch, chỉ cần đổi tên tệp thực thi thành "<targetExecutableName> w.exe" (nối thêm "w") và đặt nó bên cạnh tệp thực thi ban đầu. Sau đó, bạn có thể gọi eG powershellw.exe với các tham số thông thường và nó sẽ không bật lên một cửa sổ.

Nếu ai đó có ý tưởng làm thế nào để kiểm tra xem quy trình đã tạo có đang chờ đầu vào hay không, vui lòng đưa vào giải pháp của bạn :)


1
Đây là câu trả lời tốt nhất nếu bạn muốn chạy các tập lệnh powershell bằng cách sử dụng MessageBoxmà không cần bất kỳ đèn flash nào của cửa sổ khi khởi động (yêu cầu EXE được biên dịch dưới dạng Winexe, không phải ứng dụng bảng điều khiển và yêu cầu Trình lập lịch tác vụ được đặt thành "Chỉ chạy khi người dùng đăng nhập trên "vì vậy các hộp thoại hiển thị trong phiên máy tính để bàn hiện tại.) Cảm ơn bạn đã thực hiện điều này, powershellw.exe đã nằm trong danh sách mong muốn của tôi trong nhiều năm!
Carl Walsh

PS: tôi đã bao gồm giải pháp "chờ đầu vào" cách đây một thời gian (cũng như một vài lỗi)!
Chris

@CarlWalsh tôi giả sử bạn có nghĩa là nó không phải là một ứng dụng giao diện điều khiển, mà là một ứng dụng win form thay vào đó là chính xác. chỉ là nó không bao gồm bất kỳ cửa sổ. nhưng loại dự án nên được xác định trong tệp csproj và bạn không cần phải đặt loại đầu ra cụ thể sau khi mở bằng studio trực quan
Chris

2

Đây là một giải pháp hoạt động trong windows 10 không bao gồm bất kỳ thành phần bên thứ ba nào. Nó hoạt động bằng cách gói tập lệnh PowerShell vào VBScript.

Bước 1: chúng ta cần thay đổi một số tính năng của windows để cho phép VBScript chạy PowerShell và mở tệp .ps1 bằng PowerShell theo mặc định.

-để chạy và gõ "regedit". Bấm vào ok và sau đó cho phép nó chạy.

-Tạo đường dẫn này "HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell" và nhấn enter.

-Bây giờ hãy mở mục bên phải và thay đổi giá trị thành 0.

-open PowerShell với tư cách quản trị viên và nhập "Set-ExecutPolicy -ExecutPolicy RemoteSign", nhấn enter và xác nhận thay đổi bằng "y" và sau đó nhập.

Bước 2: Bây giờ chúng ta có thể bắt đầu gói kịch bản của chúng tôi.

-lưu tập lệnh Powershell của bạn dưới dạng tệp .ps1.

-Tạo một tài liệu văn bản mới và dán tập lệnh này.

Dim objShell,objFSO,objFile

Set objShell=CreateObject("WScript.Shell")
Set objFSO=CreateObject("Scripting.FileSystemObject")

'enter the path for your PowerShell Script
 strPath="c:\your script path\script.ps1"

'verify file exists
 If objFSO.FileExists(strPath) Then
   'return short path name
   set objFile=objFSO.GetFile(strPath)
   strCMD="powershell -nologo -command " & Chr(34) & "&{" &_
    objFile.ShortPath & "}" & Chr(34)
   'Uncomment next line for debugging
   'WScript.Echo strCMD

  'use 0 to hide window
   objShell.Run strCMD,0

Else

  'Display error message
   WScript.Echo "Failed to find " & strPath
   WScript.Quit

End If

-Biết thay đổi đường dẫn tệp đến vị trí của tập lệnh .ps1 của bạn và lưu tài liệu văn bản.

-Bây giờ, nhấp chuột phải vào tệp và đổi tên. Sau đó thay đổi phần mở rộng tên tệp thành .vbs và nhấn enter và sau đó nhấp vào ok.

LÀM XONG! Nếu bây giờ bạn mở .vbs, bạn sẽ thấy không có cửa sổ giao diện điều khiển trong khi tập lệnh của bạn đang chạy trong nền.

đảm bảo upvote nếu điều này làm việc cho bạn!


1

Đây là một bản demo thú vị về việc kiểm soát các trạng thái khác nhau của bảng điều khiển, bao gồm thu nhỏ và ẩn.

Add-Type -Name ConsoleUtils -Namespace WPIA -MemberDefinition @'
   [DllImport("Kernel32.dll")]
   public static extern IntPtr GetConsoleWindow();
   [DllImport("user32.dll")]
   public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'@

$ConsoleMode = @{
 HIDDEN = 0;
 NORMAL = 1;
 MINIMIZED = 2;
 MAXIMIZED = 3;
 SHOW = 5
 RESTORE = 9
 }

$hWnd = [WPIA.ConsoleUtils]::GetConsoleWindow()

$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.MAXIMIZED)
"maximized $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.NORMAL)
"normal $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.MINIMIZED)
"minimized $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.RESTORE)
"restore $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.HIDDEN)
"hidden $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.SHOW)
"show $a"
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.