Wie führe ich ein PowerShell-Skript aus, ohne ein Fenster anzuzeigen?

127

Wie ist es möglich, ein PowerShell- Skript auszuführen, ohne dem Benutzer ein Fenster oder ein anderes Zeichen anzuzeigen?

Mit anderen Worten, das Skript sollte leise im Hintergrund ausgeführt werden, ohne dass der Benutzer ein Zeichen dafür hat.

Zusätzliches Guthaben für eine Antwort, bei der keine Komponenten von Drittanbietern verwendet werden :)

Thomas Bratt
quelle
Überprüfen Sie diese Frage, wenn Sie am Lernen interessiert sind: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt
Diese Lösung funktioniert auch für Task Scheduler: stackoverflow.com/a/51007810/571591
Hilydrow

Antworten:

128

Sie können es entweder so ausführen (dies zeigt jedoch für eine Weile ein Fenster):

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

Oder Sie verwenden eine von mir erstellte Hilfsdatei, um das Fenster PsRun.exe zu vermeiden, das genau das tut. Sie können die Quell- und Exe-Datei herunterladen. Geplante Aufgaben mit der WinForm-Benutzeroberfläche in PowerShell ausführen . Ich benutze es für geplante Aufgaben.

Bearbeitet: Wie Marco bemerkte, ist dieser Parameter im Fensterstil nur für V2 verfügbar.

stej
quelle
6
Ich habe den PsRun kompiliert, aber wenn ich ihn zur geplanten Aufgabe hinzufüge, blinkt auch ein Fenster ...
Ciantic
2
Das gleiche funktioniert hier auch nicht, da das Fenster immer noch geöffnet wird, um das Skript auszuführen. Es wird schnell beendet, aber wir versuchen, dies ohne Unterbrechung im Hintergrund auszuführen.
Nathan McKaskle
1
Ja, deshalb steht in der Antwort "aber dies zeigt ein Fenster für eine Weile".
Stej
21
@ThomasBratt Bei geplanten Aufgaben wurde festgestellt, dass PowerShell-Skripts unbeaufsichtigt ausgeführt werden, ohne -WindowStyle Hiddendass die Aufgabe Run whether user is logged on or notauf der Registerkarte Allgemein im Abschnitt "Sicherheitsoptionen" festgelegt ist.
Adam
1
Durch die Verwendung des Benutzerkontos für SYSTEM wird auch vermieden, dass ein Fenster angezeigt wird.
Jon Eldridge
27

Ich hatte das gleiche Problem. Ich fand heraus , wenn Sie unterwegs Aufgabe in Taskplaner , der das läuft powershell.exe Skript, können Sie „klicken Run , ob Benutzer angemeldet ist oder nicht “ , und das wird nie die Powershell - Fenster zeigen , wenn die Aufgabe ausgeführt wird .

Yusha
quelle
3
Beste Lösung ohne Abhängigkeit von einer Erweiterung, ausführbaren Datei oder einem Wrapper-Skript eines Drittanbieters.
invertieren
1
Beachten Sie, dass für diese Option der Benutzer die Berechtigung "Als
Stapeljob anmelden
Diese Lösung führt dazu, dass mein Skript nicht richtig ausgeführt wird .
Martin Argerami
18

Sie können die PowerShell-Community-Erweiterungen verwenden und Folgendes tun:

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

Sie können dies auch mit VBScript tun: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/

(Über diesen Forenthread .)

Axt.
quelle
Gibt es dafür ein NuGet-Paket, damit ich es in Visual Studio ausführen kann?
Piotr Kula
13

Hier ist ein Ansatz, für den keine Befehlszeilenargumente oder ein separater Starter erforderlich sind. Es ist nicht vollständig unsichtbar, da beim Start vorübergehend ein Fenster angezeigt wird. Aber es verschwindet dann schnell. Wo das in Ordnung ist, ist dies meiner Meinung nach der einfachste Ansatz, wenn Sie Ihr Skript durch Doppelklicken im Explorer oder über eine Verknüpfung zum Startmenü (einschließlich natürlich des Untermenüs Start) starten möchten. Und ich mag es, dass es Teil des Codes des Skripts selbst ist, nicht etwas Äußeres.

Fügen Sie dies an die Vorderseite Ihres Skripts ein:

$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)
Andy Lowry
quelle
10

Hier ist ein Einzeiler:

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

Obwohl es möglich ist, dass ein Fenster sehr kurz blinkt, sollte dies selten vorkommen.

Adam Taylor
quelle
In den meisten Fällen wird beim Ausführen von Powershell.exe im Kontext des angemeldeten Benutzers entweder ein vollständiges Fenster angezeigt oder es blinkt kurz, wenn Sie -windowstyle hidden verwenden. Um das Fenster vollständig zu entfernen, haben Sie zwei Möglichkeiten: 1: In einem anderen Benutzerkontext wie dem Administratorkonto ausführen (dem angemeldeten Benutzer werden keine Fenster angezeigt). Oder 2: Verwenden Sie ein vbscript mit objshell.run mit einem versteckten Fenster-Flag, um cmd.exe / c Powershel.exe-Datei c: \ script.ps1 zu starten. Wenn Powershell von cmd aufgerufen wird, wird es in dem vorhandenen cmd-Fenster ausgeführt, das bereits von wscript.exe // b / nologo c: \ launcher.vbs ausgeblendet wird.
Iconiu
Wow, plötzlich. Ich habe Ihre Antwort zunächst gar nicht bemerkt. Ich antwortete mit einem sehr ähnlichen Skript. Es ist schön, eine sachkundige Person zu sehen, die eine echte Antwort gibt.
Gosha
Dies sollte die akzeptierte Antwort sein, es ist die einzige Methode, die in jeder Situation zu funktionieren scheint (auch innerhalb des Taskplaners, was mein Problem war).
Martin Argerami
6

Ich hatte dieses Problem beim Ausführen von c #. Unter Windows 7 wurde der Dienst "Interactive Services Detection" angezeigt, wenn ein verstecktes Powershell-Fenster als SYSTEM-Konto ausgeführt wurde.

Durch die Verwendung des Parameters "CreateNoWindow" wurde verhindert, dass der ISD-Dienst seine Warnung anzeigt.

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

Ich denke, dass der beste Weg, den Konsolenbildschirm der PowerShell auszublenden, wenn Sie ein Hintergrundskript ausführen, dieser Code ist ( Antwort " Bluecakes ").

Ich füge diesen Code am Anfang aller meiner PowerShell-Skripts hinzu, die ich im Hintergrund ausführen muss.

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

Wenn diese Antwort Ihnen geholfen hat, stimmen Sie in seiner Antwort in diesem Beitrag für "Bluecakes".

Gavraham
quelle
Für mich wird die Konsole noch etwa eine Sekunde lang angezeigt.
2.
3

ps1 im Taskplaner und auch in der Verknüpfung ausgeblendet

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

Ich habe ein kleines Tool erstellt, das den Aufruf an jedes Konsolentool weiterleitet, das Sie fensterlos bis zur Originaldatei starten möchten:

https://github.com/Vittel/RunHiddenConsole

Benennen Sie die ausführbare Datei nach dem Kompilieren einfach in "<targetExecutableName> w.exe" um (fügen Sie ein "w" hinzu) und platzieren Sie sie neben der ursprünglichen ausführbaren Datei. Sie können dann eG Powershellw.exe mit den üblichen Parametern aufrufen und es wird kein Fenster geöffnet.

Wenn jemand eine Idee hat, wie er überprüfen kann, ob der erstellte Prozess auf Eingaben wartet, kann ich Ihnen gerne Ihre Lösung hinzufügen :)

Chris
quelle
1
Dies ist die beste Antwort , wenn Sie Powershell - Skripte ausführen möchten , MessageBoxohne jeden Blitz des Fensters beim Start (erfordert eine EXE - Datei kompiliert als winexe, nicht eine Konsolenanwendung und erfordert Taskplaner werden auf „Run nur , wenn der Benutzer angemeldet ist on "So werden Dialoge in der aktuellen Desktop-Sitzung angezeigt.) Vielen Dank für die Implementierung. Powershellw.exe ist seit Jahren auf meiner Wunschliste!
Carl Walsh
PS: Ich habe vor einiger Zeit die Lösung für "Warten auf Eingabe" (sowie ein paar Bugfixes) aufgenommen!
Chris
@CarlWalsh Ich nehme an, Sie meinen, dass es keine Konsolen-App ist, sondern eine Win-Forms-App, was richtig ist. Nur enthält es keine Fenster. Der Projekttyp sollte jedoch in der csproj-Datei definiert sein und Sie sollten keinen bestimmten Ausgabetyp festlegen müssen, nachdem Sie ihn mit Visual Studio geöffnet haben
Chris
2

Hier ist eine funktionierende Lösung in Windows 10, die keine Komponenten von Drittanbietern enthält. Es funktioniert, indem das PowerShell-Skript in VBScript eingeschlossen wird.

Schritt 1: Wir müssen einige Windows-Funktionen ändern, damit VBScript PowerShell ausführen und standardmäßig .ps1-Dateien mit PowerShell öffnen kann.

-go ausführen und "regedit" eingeben. Klicken Sie auf OK und lassen Sie es dann laufen.

- Fügen Sie diesen Pfad "HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell" ein und drücken Sie die Eingabetaste.

-Nun öffne den Eintrag rechts und ändere den Wert auf 0.

-Öffnen Sie PowerShell als Administrator und geben Sie "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned" ein, drücken Sie die Eingabetaste und bestätigen Sie die Änderung mit "y" und geben Sie dann ein.

Schritt 2: Jetzt können wir mit dem Umschließen unseres Skripts beginnen.

-Speichern Sie Ihr Powershell-Skript als .ps1-Datei.

- Erstellen Sie ein neues Textdokument und fügen Sie dieses Skript ein.

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

- Ändern Sie jetzt den Dateipfad an den Speicherort Ihres .ps1-Skripts und speichern Sie das Textdokument.

- Klicken Sie jetzt mit der rechten Maustaste auf die Datei und benennen Sie sie um. Ändern Sie dann die Dateinamenerweiterung in .vbs, drücken Sie die Eingabetaste und klicken Sie auf OK.

GETAN! Wenn Sie jetzt die .vbs öffnen, sollte kein Konsolenfenster angezeigt werden, während Ihr Skript im Hintergrund ausgeführt wird.

Stellen Sie sicher, dass Sie positiv stimmen, wenn dies für Sie funktioniert hat!

neobihli
quelle
1

Hier ist eine unterhaltsame Demo zur Steuerung der verschiedenen Zustände der Konsole, einschließlich Minimieren und Ausblenden.

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"
js2010
quelle