Як запустити скрипт PowerShell без відображення вікна?


127

Як можна запустити скрипт PowerShell без відображення вікна або будь-якого іншого знаку для користувача?

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

Додатковий кредит за відповідь, що не використовує сторонні компоненти :)


Ознайомтесь із цим питанням, якщо вас цікавить навчання: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt

Це рішення працює для планувальника завдань , а також: stackoverflow.com/a/51007810/571591
Hilydrow

Відповіді:


128

Ви можете запустити його так (але це показує вікно на деякий час):

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

Або ви використовуєте файл-помічник, який я створив, щоб уникнути вікна під назвою PsRun.exe, який робить саме це. Ви можете завантажити вихідний і EXE-файл. Виконайте заплановані завдання за допомогою графічного інтерфейсу WinForm в PowerShell . Я використовую його для планових завдань.

Відредаговано: як зазначив Марко, цей параметр віконця доступний лише для V2.


6
Я склав PsRun, однак, якщо додати його до запланованого завдання, він також спалахне вікном ...
Ciantic

2
Те саме тут, також не працює, тому що для запуску сценарію все-таки з'являється вікно. Він швидко виходить, але ми намагаємося це виконувати у фоновому режимі без перешкод.
Натан Маккаскле

1
Так, саме тому у відповіді є "але це показує вікно на деякий час".
stej

21
@ThomasBratt Для запланованих завдань я виявив, що сценарії PowerShell запускаються безшумно, -WindowStyle Hiddenякщо завдання встановлено Run whether user is logged on or notна вкладці Загальні в розділі "Параметри безпеки".
адам

1
Використання облікового запису користувача для системи SYSTEM також дозволяє уникнути відображення вікна.
Джон Елдрідж

27

У мене виникло те саме питання. Я дізнався, що якщо ви перейдете до " Завдання в програмі планування завдань", який працює за допомогою скрипта powershell.exe , ви можете натиснути " Запустити, чи користувач увійшов чи ні ", і це ніколи не відображатиме вікно "панцирної панелі" при запуску завдання.


3
Найкраще рішення, не залежно від сторонніх розширень, виконуваного файлу або обгорткового сценарію.
інвертувати

1
Зауважте, що ця опція вимагає від користувача привілею "Увійти як пакетна робота"
gb96

Це рішення змушує мій сценарій не працювати належним чином .
Мартін Арджерамі

18

Ви можете використовувати розширення спільноти PowerShell і зробити це:

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

Ви також можете це зробити за допомогою VBScript: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/

(Через цю тему на форумі .)


Чи є для цього пакунок NuGet, щоб я міг запустити його з Visual Studio?
Пьотр Кула

13

Ось підхід, який не вимагає аргументів командного рядка або окремого запуску. Це не зовсім непомітно, тому що вікно миттєво відображається при запуску. Але це швидко зникає. Якщо це нормально, це, я думаю, найпростіший підхід, якщо ви хочете запустити свій сценарій, двічі клацнувши в Explorer, або за допомогою ярлика меню «Пуск» (включаючи, звичайно, підменю «Запуск»). І мені подобається, що це частина самого коду сценарію, а не щось зовнішнє.

Поставте це внизу сценарію:

$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

Ось один вкладиш:

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

Хоча можливо, що це вікно прошиває дуже коротко, це має бути рідкісним явищем.


У більшості випадків запуск Powershell.exe в контексті, на якому зареєстровані користувачі, або покаже повне вікно, або коротко прошиве, якщо ви використовуєте -windowstyle приховано. Щоб повністю видалити вікно, ви можете зробити одне з двох: 1: Запустити в іншому користувальницькому контексті, такому як обліковий запис адміністратора (не відображатиметься жодне вікно для зареєстрованого користувача). Або 2: Використовуйте vbscript з objshell.run із прихованим прапором вікна, щоб запустити cmd.exe / c powershel.exe -file c: \ script.ps1. При виклику посилань з cmd він запускатиметься у наявному вікні cmd, яке вже приховано wscript.exe // b / nologo c: \ launcher.vbs.
Іконіу

вау, раптом. Я спочатку навіть не помітив вашої відповіді. Я відповів дуже схожим сценарієм. Приємно бачити знаючу людину, яка дає справжню відповідь.
Гоша

Це має бути прийнята відповідь, це один метод, який, здається, працює у будь-якій ситуації (включаючи всередині планувальника завдань, яка була моєю проблемою).
Мартін Арджерамі

6

У мене виникала ця проблема під час роботи з c #, в Windows 7 служба «Інтерактивне виявлення послуг» вискакувала під час запуску прихованого вікна в якості скриньки як облікового запису SYSTEM.

Використання параметра "CreateNoWindow" запобігло появі послуги ISD, яка з'являється попередженням.

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

5

Я думаю, що найкращий спосіб приховати екран консолі PowerShell, коли у вас запущені фонові сценарії - це цей код (відповідь " Bluecakes ").

Я додаю цей код на початку всіх моїх скриптів PowerShell, які мені потрібно запустити у фоновому режимі.

# .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

Якщо ця відповідь допомогла вам, будь ласка, проголосуйте за "Блакитні" у його відповіді в цій публікації.


Для мене консоль все ще відображається приблизно на секунду.
thoan

3

ps1, прихований від планувальника завдань і ярлик також

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

2

Я створив невеликий інструмент, який передає дзвінок до будь-якого консольного інструменту, до якого потрібно запустити вікно, до вихідного файлу:

https://github.com/Vittel/RunHiddenConsole

Після компіляції просто перейменуйте виконуваний файл у "<targetExecutableName> w.exe" (додайте "w") і поставте його поруч з оригінальним виконуваним файлом. Потім ви можете зателефонувати в eG powershellw.exe за допомогою звичайних параметрів, і це звичайне спливаюче вікно.

Якщо у когось є ідея, як перевірити, чи створений процес очікує на вхід, буду радий включити ваше рішення :)


1
Це найкраща відповідь, якщо ви хочете запускати сценарії повноважень, використовуючи MessageBoxбез будь-якого спалаху вікна при запуску (для цього потрібен EXE, скомпільований як Winexe, а не консольний додаток, і вимагає встановлення планувальника завдань на "Запускати лише тоді, коли користувач зареєстрований" на тему "так показано діалогові вікна в поточному сеансі робочого столу.) Дякую за те, що впроваджую це, powershellw.exe був у моєму списку бажань роками!
Карл Уолш

PS: Я включив рішення для "очікування на введення" деякий час тому назад (а також пару помилок)!
Кріс

@CarlWalsh Я припускаю, що ви маєте на увазі, що це не консольний додаток, а натомість виграє додаток, що є правильним. просто він не включає будь-які вікна. але тип проекту слід визначати у файлі csproj, і вам не потрібно буде встановлювати конкретний тип виводу після відкриття його з візуальною студією
Кріс,

2

Ось робоче рішення у Windows 10, яке не включає сторонні компоненти. Він працює, загортаючи скрипт PowerShell у VBScript.

Крок 1: нам потрібно змінити деякі функції Windows, щоб дозволити VBScript запускати PowerShell та відкривати .ps1 файли за допомогою PowerShell за замовчуванням.

-го запустити та введіть "regedit". Клацніть на ОК, а потім дозвольте йому працювати.

-вставте цей шлях "HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell" і натисніть клавішу Enter.

-відкрийте запис праворуч і змініть значення на 0.

-відкрийте PowerShell в якості адміністратора і введіть "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned", натисніть клавішу Enter і підтвердіть зміни за допомогою "y", а потім введіть.

Крок 2: Тепер ми можемо почати обгортання нашого сценарію.

-збережіть свій скрипт Powershell як файл .ps1.

-створіть новий текстовий документ і вставте цей сценарій.

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

-змініть шлях до файлу до місця розташування вашого сценарію .ps1 та збережіть текстовий документ.

-Зараз натисніть на файл правою кнопкою миші та перейдіть до перейменування. Потім змініть розширення імені файлу на .vbs і натисніть клавішу Enter, а потім натисніть кнопку ОК.

Зроблено! Якщо зараз відкрити .vbs, ви не побачите вікна консолі, коли сценарій працює у фоновому режимі.

не забудьте подати заявку, якщо це працювало для вас!


1

Ось весела демонстрація контролю різних станів консолі, включаючи мінімізацію та приховані.

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"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.