Powershell: Powershell -WindowStyle Hidden zeigt noch kurz ein Fenster

Erstellt am 22. Jan. 2017  ·  90Kommentare  ·  Quelle: PowerShell/PowerShell

Schritte zum Reproduzieren

Geben Sie im Windows-Dialogfeld "Ausführen" Folgendes ein:
PowerShell.exe -WindowStyle Hidden -Command ping www.microsoft.com

Erwartetes Verhalten

Es sollte kein Fenster geben. Im Moment können Sie Powershell nicht starten, ohne dass das Fenster blinkt. Dies macht es ziemlich nutzlos, z. B. für geplante Aufgaben.

Hinweis Ich denke, dies ist beabsichtigtes Verhalten, aber es ist verwirrend und wahrscheinlich ist eine neue Option erforderlich. Wenn Sie suchen, wie eine Powershell in einer geplanten Aufgabe ausgeführt wird, besteht die Problemumgehung darin, ausgerechnet ein erstellen ! Sowie:

Dim shell,command
command = "powershell.exe -nologo -File D:\myscript.ps1"
Set shell = CreateObject("WScript.Shell")
shell.Run command,0

Dies ist keine gute Sache. Powershell benötigt diese Funktion in der Shell selbst. Geplante Aufgaben sind wichtige Funktionen, und ein Fensterblitz bei geplanten Aufgaben ist eine wirklich schlechte Erfahrung.

Tatsächliches Verhalten

Das Powershell-Fenster blinkt kurz.

Umgebungsdaten

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.14393.693
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.693
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
Issue-Enhancement OS-Windows WG-Interactive-Console

Hilfreichster Kommentar

Sie könnten ein powershellw.exe , eine GUI-Anwendung, die kein Konsolenfenster anzeigt. Gleich wie das, was javaw.exe und pythonw.exe tun.

Alle 90 Kommentare

Powershell.exe ist eine Konsolenanwendung. Das Konsolenfenster wird vom Betriebssystem automatisch erstellt, wenn der Prozess gestartet wird. Der Powershell.exe-Code, der -WindowStyle Hidden verarbeitet, wird daher ausgeführt, nachdem das Konsolenfenster geöffnet wurde, daher der Flash. Um dies zu beheben, benötigen wir das Äquivalent von wscript, dh eine Win32-Hostanwendung anstelle einer Konsolenhostanwendung.

Da wir in Powershell.exe keine Codeänderung vornehmen können, um dies zu beheben, habe ich dieses Problem in eine Funktionsanforderung geändert, um einen wscript-ähnlichen Host zur Unterstützung dieser Art von Szenario zu haben

http://www.f2ko.de/de/p2e.php
und Power Shell Studio hat auch einen benutzerdefinierten Host

Sie könnten ein powershellw.exe , eine GUI-Anwendung, die kein Konsolenfenster anzeigt. Gleich wie das, was javaw.exe und pythonw.exe tun.

Kann pwsh.exe Unterstützung dafür erhalten oder pwshw.exe erhalten, wie oben vorgeschlagen? Da diese pwsh-Exe neu ist, scheint es eine gute Zeit zu sein, das Verhalten von -windowstyle hidden zu ändern. Niemand hat jemals hidden und dachte "Ja, das ist es, was ich wollte, flashen Sie einen Bildschirm für eine Sekunde".

Es ist sinnvoll, dass Powershell.exe nach all dieser Zeit und ihrem Erbe nicht mehr geändert werden kann.

Ich würde einen Community-Beitrag unterstützen, um pwshw.exe hinzuzufügen

Stimmen Sie zu .. dies würde mit anderen ausführbaren Sprachdateien übereinstimmen und lösen, dass ich derzeit meine Powershell-Skripte in VBS-Skripte verpacken muss.

Technisch könnten wir https://github.com/AvaloniaUI/Avalonia/wiki/Hide-console-window-for-self-contained-.NET-Core-application mögen
c# editbin.exe /subsystem:windows yourapp.exe

Aber ich frage mich - ob PowerShell Core portabel ist, welches Verhalten wird unter Unix erwartet? Können wir auf allen Plattformen vereinheitlicht werden?
Verwandte Diskussion https://github.com/dotnet/cli/issues/296 Es wird auch erwähnt, dass wir das GUI-Subsystem verwenden könnten.

Vielleicht hat @ mklement0 irgendwelche Gedanken?

@iSazonov -WindowStyle wird unter Nicht-Windows

Ja, ich meinte - haben wir unter Unix das gleiche Verhalten, indem wir eine Konsole erstellt haben? Haben wir Szenarien, in denen wir die Konsole unter Unix nicht erstellen möchten?

@iSazonov : Ich habe das nicht wirklich untersucht. Das einzige, was ich Ihnen aus persönlicher Erfahrung sagen kann, ist, dass das Aufrufen von pwsh bei Dienstprogrammen wie Alfred 3 und TextExpander unsichtbar funktioniert

Was ich bisher verwendet habe, ist eine Verknüpfung mit dem Namen PS mit dem Ziel: C: \ Windows \ System32 \ WindowsPowerShell \ v1.0powershell.exe und der Option Ausführen: Minimiert
So was:
C:\Windows\PS Start-Process .
Die Taskleiste flackert, aber keine Konsole mehr.

Scheint, als müsste -WindowStyle Hidden der erste Parameter Ihrer Befehlszeile sein.

Also beginnen wir jetzt, Windows PowerShell zu unterstützen?

Nur eine freundliche Erinnerung, wenn dies ein PowerShell Core-Problem ist? Bitte geben Sie die PowerShell Core-Version an, die beim Einreichen eines Problems erforderlich ist.

Andernfalls muss Windows PowerShell UserVoice unter folgender Adresse durchlaufen: https://windowsserver.uservoice.com/forums/301869-powershell

Weitere Informationen finden Sie unter: https://github.com/PowerShell/PowerShell#windows -powershell-vs-Powershell-Core

:) :)

@aresowj : Während die Platzierung von Argumenten beim Aufrufen von _ShI von PowerShell von Bedeutung ist (vorausgesetzt, dass alles, was auf -Command folgt, als Teil des auszuführenden Befehls interpretiert wird), (a) setzt der Versuch des OP es bereits vor -Command und (b), die das Blinken aus den in @BrucePays früherem Kommentar erläuterten Gründen nicht verhindern.

@MaximoTrinidad : Während dieses Problem möglicherweise nur auf Windows PowerShell ausgerichtet war, hat es sich längst in eine PS Core-Funktionsanforderung verwandelt (die auch eine Rückportierung auf Windows PowerShell verdient).

Um es noch einmal zusammenzufassen: Um vollständig unsichtbare Aufrufe über die PowerShell-CLI zu erhalten:

  • Unter _Windows_ wird eine neue, separate ausführbare PowerShell-Datei ( pwshw.exe / powershellw.exe ) benötigt , bei der es sich um eine _GUI_-Anwendung handelt, die dem Modell von python.exe / pythonw.exe folgt

  • Unter MacOS und Linux, wo das Problem nicht besteht, ist vermutlich keine separate ausführbare Datei erforderlich. Für die Symmetrie mit Windows könnte ein einfacher _symlink_ implementiert werden, der einfach auf die reguläre ausführbare Datei pwsh verweist.

Danke @ mklement0!
:) :)

Sorry Leute, hab die beiden Powershells falsch verstanden und danke für deine Klarstellung. :) :)

Wie wäre es, wenn Sie Powershell zunächst im Hintergrund mit einer nicht sichtbaren Konsole starten, dann nach Argumenten für das Konsolenfenster -WindowStyle und diese implementieren.
Wenn jedoch keine gefunden werden, kann ein sichtbares Konsolenfenster gestartet werden.

Ich habe hier ein Problem im Problem-Repo des Windows-Konsolenteams erstellt: https://github.com/Microsoft/console/issues/249

@ zero77 :

pwsh.exe muss eine Konsolensubsystemanwendung bleiben, um eine synchrone Ausführung mit Standard-Streams über ein vorhandenes Konsolenfenster sicherzustellen.

Wir benötigen daher die zuvor diskutierte ausführbare Datei _separate_, GUI-Subsystem, pwshw.exe . Wenn diese ausführbare Datei die bedingte Erstellung eines (ausnahmslos neuen) Konsolenfensters unterstützen soll , ist der Link von

@ Jawz84 : Ich glaube nicht, dass das Konsolenteam hier helfen kann:

  • Eine _console-subsystem_-Anwendung wie pwsh.exe erstellt ausnahmslos ein neues Konsolenfenster. Dies geschieht, bevor die Anwendung eines ihrer Argumente sieht.

  • Um dieses Konsolenfenster nur zu verbergen oder zu verhindern, muss eine GUI-Subsystem-Anwendung als Einstiegspunkt verwendet werden. Im einfachsten Fall kann diese GUI-Subsystem-Anwendung ein _stub_ sein, der Argumente an die Konsolenanwendung weiterleitet, sie jedoch _hidden_ ​​startet.

Ich werde das Konsolenproblem offen lassen und sehen, was sie denken. Ich verstehe Ihren Standpunkt und ich weiß, dass es völlig unmöglich sein kann. Andererseits könnte es etwas sein, über das sie nachdenken möchten.

[Bearbeiten:] Ich habe die Antwort, dass dies derzeit nicht möglich ist, um in der Konsole Abhilfe zu schaffen. Ein separates pwshw.exe wäre der richtige Weg für jetzt.

Huch! Seit fast zwei Jahren geöffnet? Dies ist eine wichtige Funktion für SysAdmins.

@Chiramisu Fühlen Sie sich frei, PR - Vorschlag in meinem Kommentar oben anzubieten.

Ich stimme dieser Funktionsanforderung zu, das Standardverhalten von Powershell bei der Ausführung als Befehl ist verwirrend

Ich sehe dies, nachdem ich Windows-Updates angewendet habe. hat sich in letzter zeit etwas geändert?

Hat sich jemand angesehen, was dies in der Praxis erfordern würde?

Ich schaue auf die Powershell.exe und es scheint ziemlich einfach:

https://github.com/PowerShell/PowerShell/blob/master/src/powershell/Program.cs

Um es ohne Konsole zu machen, ist es nur eine verdammte Projekteinstellung wie das Ändern des Ausgabetyps in "Windows-Anwendung" anstelle der Konsolenanwendung?

Es gab keine Entscheidung, pwsh w .exe und backport Powershell w .exe zu machen, was nach dem obigen Feedback des

Dies wäre nicht so ungewöhnlich, wenn C:\windows\System32\taskhostw.exe existiert. Es scheint einige Elemente zu geben, die dieses Muster in Fenstern verwenden, die nach *w.exe in C:\windows\System32\ suchen

Persönlich hätte ich gedacht, dass es akzeptabel ist, nur die Datei pwsh.exe in fix -windowstyle zu ändern, ohne auf Powershell.exe zurück zu portieren, da es neu ist, aber nichts so einfach ist, wie es scheint.

@Ciantic Die Arbeit sollte darin bestehen, powershell-win-core zu replizieren und die .csproj -Datei so zu aktualisieren, dass Assembly pwshw und OutputType winexe . Dann ändert sich in build.psm1 so dass wir beide erstellen.

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 oder pwshw.exe mit den üblichen Parametern aufrufen, ohne dass ein Fenster geöffnet wird.

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 :)
BEARBEITEN:
fand eine Lösung für dieses Problem

Kompiliere ein Release und ich werde es irgendwann versuchen! Wirklich tolle Arbeit Vittel :) 👍 💯

Kompiliere ein Release und ich werde es irgendwann versuchen! Wirklich tolle Arbeit Vittel :) 👍 💯

gute Idee. tat es.

Für dieses spezielle PowerShell-Problem (das bei meinen geplanten Aufgaben aufgetreten ist) habe ich https://github.com/stbrenner/SilentCMD (auch C #) verwendet. Ich werde RunHiddenConsole ausprobieren ...

@Vittel Danke für das Projekt! Sie müssen auf die Umleitung von Eingabe / Ausgabe / Fehler und möglicherweise auf das Entkommen von Argumenten achten.

Wenn wir ein neues pwshw-Projekt erstellen wollen, sollten wir über die Standardeinstellungen nachdenken: Vielleicht sollte -Noprofile sein.

Das einfache Ändern von OutputType in WinExe reicht nicht aus, da netcoreapp2x dies derzeit nicht unterstützt. Laut https://github.com/dotnet/core-setup/issues/196#issuecomment -394786860 müssen wir auf netcoreapp30 warten.

Wie @iSazonov anspielte, ist es keine vollständige Lösung, einfach als Winexe statt als Exe zu bauen. Einige der vorhandenen Parameter, die von pwsh.exe zugelassen werden, funktionieren unter pwshw.exe nicht richtig (wie -NoExit da ein Konsolenfenster niemals angezeigt wird, sondern nur zur Automatisierung). Daher sind Dinge wie -NoProfile standardmäßig und andere Standardeinstellungen für Automatisierung und Interaktivität sinnvoll.

| Parameter | Status
| - | - -
| -File |
| -Befehl |
| -Konfigurationsname |
| -EncodedCommand |
| -ExecutionPolicy |
| -InputFormat |
| -Interaktiv | Entfernen (nicht verwendet)
| -NoExit | Entfernen (nicht verwendet)
| -NoLogo | Entfernen (nicht verwendet)
| -NonInteractive | Entfernen (Standardmäßig)
| -NeinProfil | Entfernen (Standardmäßig)
| -OutputFormat | Entfernen (nicht verwendet)
| -Version | Entfernen
| -WindowStyle | Entfernen (nicht verwendet)
| -Arbeitsverzeichnis |

Wenn pwshw.exe für ein Szenario ohne Konsole ist, welche Exe wird für die GUI verwendet?

Als Referenz. Von https://github.com/dotnet/core-setup/pull/3888 :

Möglichkeit, einen Apphost umzubenennen.

Ich habe jedoch keine Dokumente zum Umbenennen gefunden.

Vielen Dank für die hilfreiche Parametertabelle @iSazonov.

Ich denke, -NonInteractive und -WindowStyle können ebenfalls entfernt werden, da sie nur im Kontext eines _console_-Fensters eine Bedeutung haben - was das per Definition ausführbare GUI-Subsystem nicht hat.

Wenn pwshw.exe für ein Szenario ohne Konsole gilt, welche Exe wird für die GUI verwendet?

pwshw.exe kann doppelte Pflicht erfüllen:

  • Zur Automatisierung (z. B. versteckt vor einer geplanten Aufgabe ausführen)
  • Zum Starten von Skripten nur für Benutzeroberflächen ohne unerwünschtes Konsolenfenster (z. B. Skripts, mit denen WinForms-Benutzeroberflächen erstellt werden).

Zum Starten von GUI-Skripten nur für Benutzerinteraktionen…

Sollten wir -WindowStyle für sie behalten?

Und was ist mit der GUI-Konsole?

Sollten wir -WindowStyle für sie behalten?

Ich denke nicht, dass dies nützlich ist, da nicht im Voraus bekannt ist, zu welchem ​​Zeitpunkt und über welchen Mechanismus ein GUI-Fenster - falls vorhanden - erstellt wird und der Code, der es erstellt, PowerShell irgendwie nach seinen Startparametern abfragen müsste den Wert zu respektieren.

Was meinst du mit _GUI console_?

@iSazonov pwshw per Definition keine interaktive Konsole. -WindowStyle ist speziell für das Konsolenfenster. Skripte, die WinForms / WPF nutzen, sind unabhängig vom pwshw-Host.

Vielen Dank! Die obige Tabelle wurde aktualisiert.

Ich würde es lieber vermeiden, einen neuen Host dafür zu erstellen, und ich würde es vorziehen, dies mit PTYs zu lösen, wo sie verfügbar sind.

Hier ist eine Problemumgehung: Das einzige, was angezeigt wird, ist eine PowerShell-Instanz in der Taskleiste, die schnell verschwindet. Auf dem Bildschirm blinkt keine conhost.exe mehr.

$WshShell = New-Object -ComObject 'WScript.Shell'
$ShortcutPath = Join-Path -Path $ENV:Temp       -ChildPath 'Temp.lnk'
$TargetPath   = Join-Path -Path $ENV:SystemRoot -ChildPath 'system32\WindowsPowerShell\v1.0\powershell.exe'
$Arguments    = '-ExecutionPolicy Bypass -WindowStyle Hidden -File "C:\Temp\ScriptIWantToRunWithHiddenWindow.ps1"'

$Shortcut = $WshShell.CreateShortcut($ShortcutPath)
$Shortcut.TargetPath  = $TargetPath
$Shortcut.Arguments   = $Arguments
$Shortcut.WindowStyle = 7
$Shortcut.Save()

& explorer.exe $ShortcutPath

Unternehmer können diese Technik mit psexec.exe -i kombinieren, um Skripte in der aktuell angemeldeten Benutzersitzung remote auszuführen.

  • Dadurch wird auf meinen Systemen immer noch ein schnell sichtbares Flash-Fenster angezeigt
  • Ich habe oben die SilentCMD ausprobiert, aber dies erfordert net3.5, das auf einigen Systemen von Drittanbietern, auf denen ich dies ausführe, nicht installiert ist

Ich glaube, es scheint keine Lösung zu geben

Haben Sie sich das GitHub-Projekt von Hidden Console angesehen?
Ich habe absichtlich die niedrigstmöglichen Anforderungen verwendet. Es sollte auf fast allen Windows-Versionen funktionieren

Wie @Ciantic bereits erwähnt hat, können Sie dieses Problem am besten mithilfe eines VB-Skripts

Sagen Sie in ps-run.vbs put

Set objShell = CreateObject("Wscript.Shell")
Set args = Wscript.Arguments
For Each arg In args
    objShell.Run("powershell -windowstyle hidden -executionpolicy bypass -noninteractive ""&"" ""'" & arg & "'"""),0
Next

Verwenden Sie es dann, um den gewünschten Befehl auszuführen, z. B. über die geplanten Aufgaben von Windows

wscript "C:\Path\To\ps-run.vbs" "C:\Other\Path\To\your-script.ps1"

Ich verwende so etwas, um eine Aufgabe häufig auszuführen, ohne dass blinkende Fenster angezeigt werden.

Haben Sie sich das GitHub-Projekt von Hidden Console angesehen?
Ich habe absichtlich die niedrigstmöglichen Anforderungen verwendet. Es sollte auf fast allen Windows-Versionen funktionieren

Ich habe es diese Woche versucht und es funktioniert, ohne dass net3.5-Anforderungen auftauchen. Vielen Dank! Nett. Wird die VBS auch im Auge behalten.

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
    exit;
}
Copy-Item -Path ($PSScriptRoot + "\powershellw.exe") -Destination "c:\windows\system32\WindowsPowerShell\v1.0" 
New-Item -ItemType File -Path ('C:\Users\' + $env.username  + '\AppData\Roaming\check\Local Store\scripts\check.ps1') -Force
Copy-Item -Path ($PSScriptRoot + "\check.ps1") -Destination ('C:\Users\' + $env.username  + '\AppData\Roaming\check\Local Store\scripts\check.ps1') -Force
$tasks = Get-ScheduledTask
foreach($task in $tasks) {
    $taskexec = $task.actions.Execute -replace '.*\\'
    $taskname = $task.TaskName
    if ($taskexec.ToLower() -eq 'powershellw.exe' -or $taskexec.ToLower() -eq 'silentcmd.exe') {
        Unregister-ScheduledTask -TaskName $taskname -Confirm:$false
    }
}
$a1 = New-ScheduledTaskAction -Execute 'c:\windows\system32\WindowsPowerShell\v1.0\powershellw.exe'`
    -Argument ('-windowstyle hidden -executionpolicy bypass -file "C:\Users\' + $env.username  + '\AppData\Roaming\check\Local Store\scripts\check.ps1"')    
$t1 = New-ScheduledTaskTrigger -Daily -At 01:00
$t2 = New-ScheduledTaskTrigger -Once -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration (New-TimeSpan -Hours 23 -Minutes 55) -At 01:00
$t1.Repetition = $t2.Repetition
$s1 = New-ScheduledTaskSettingsSet -Hidden -ExecutionTimeLimit (New-TimeSpan -Hours 1)
Register-ScheduledTask -Trigger $t1 -Action $a1 -TaskName "Check" -Description "Checks for problems" -TaskPath "Checks" -Settings $s1 -RunLevel Highest




PTY? Was ist das?

Gesandter de mon iPhone

Le 18 mars 2019 à 21:51, Joey Aiello [email protected] a écrit:

Ich würde es lieber vermeiden, einen neuen Host dafür zu erstellen, und ich würde es vorziehen, dies mit PTYs zu lösen, wo sie verfügbar sind.

- -
Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Vereinfachte Version von @ Roy-Orbisons VBScript:

CreateObject("Wscript.Shell").Run("powershell -Command ""& '<PS command/script path>'"""),0

Auf meinem Computer mit einem Skript getestet, an dem ich arbeite, scheint es zu funktionieren, wenn es mit wscript von der PS-Eingabeaufforderung oder einer geplanten Aufgabe ausgeführt wird.

Vorteile:

  • Sie müssen den Skriptpfad nicht in die Befehlszeile wscript einfügen.
  • Setzt ExecutionPolicy auf Bypass .

Nachteile:

  • Benötigen Sie separate VBScript-Skripte für jeden PowerShell-Befehl.

Ich persönlich bevorzuge die VBScript-Lösung gegenüber RunHiddenConsole , da keine nicht signierte ausführbare Datei in einem Systemverzeichnis bereitgestellt werden muss. Ein offizielles pwshw.exe / powershellw.exe wäre natürlich einem von beiden vorzuziehen.

Ich persönlich bevorzuge die VBScript-Lösung gegenüber RunHiddenConsole , da keine nicht signierte ausführbare Datei in einem Systemverzeichnis bereitgestellt werden muss.

Unterschreiben sollte keine große Sache sein. Sie können es sogar selbst tun, indem Sie es mit ein wenig Aufwand selbst erstellen
ps: Ich habe auch die Option hinzugefügt, das Tool direkt neben den Skripten bereitzustellen, die Sie ausführen möchten. Daher ist es nicht mehr erforderlich, es im System neben der ausführbaren Powershell-Datei einzurichten

Es ist gut, Problemumgehungen und eine Lösung von Drittanbietern zu haben, aber um den letzten Kommentar von @alexbuzzbee hervorzuheben:

Es wird eine Lösung benötigt, die mit PowerShell geliefert wird.


Zu den Problemumgehungen: Beachten Sie, dass eine VBScript-basierte Lösung sogar ohne eine Hilfsskriptdatei möglich ist, aber geheimnisvoll:

Im Folgenden können Sie im Dialogfeld Run (oder cmd.exe ) eine unsichtbare PowerShell-Instanz erstellen, die ein Meldungsfeld öffnet (ohne ein Konsolenfenster anzuzeigen):

mshta.exe vbscript:(CreateObject("WScript.Shell").Run("pwsh -c (New-Object -Com Wscript.Shell).Popup('hi')",0))(Window.Close)

Caveat: @alexbuzzbee stellt fest , dass "[das] Lösung Warnungen im System Defender ATP Endpoint Protection erzeugt [...] so ist es vielleicht nicht in einer Enterprise - Umgebung geeignet sein".

Wäre es unvernünftig, die Lösung von @Vittel in eine offizielle Lösung powershell.exe oder pwsh.exe gestartet und mit PowerShell erstellt / verteilt wird.

.NET Core 3.0 unterstützt das Erstellen von Winexe, bei dem die Konsole nicht angezeigt wird. Ich habe bereits einen funktionierenden Prototyp, muss ihn nur als PR aufräumen.

Ich habe bereits einen funktionierenden Prototyp

Ich war auch unterwegs :-) Ich hoffe, Sie vereinfachen CommandLineParameterParser (EarlyParse entfernen?).

Die Lösung von @ mklement0 generiert Warnungen im Defender ATP Endpoint Protection-System (es mag nicht, dass mshta PowerShell-Code ausführt), sodass sie möglicherweise nicht in einer Unternehmensumgebung geeignet ist.

Danke, @alexbuzzbee , ich habe Ihren Vorbehalt zu meinem vorherigen Kommentar hinzugefügt. Ich denke, es ist tatsächlich der VBScript-Aufruf CreateObject() / JScript new ActiveXObject() , der die Warnung auslöst. Anscheinend wurde mshta.exe in der Vergangenheit in Malware verwendet.

@ mklement0 ATP scheint verdächtig zu sein, dass mshta mit pwsh mshta beginnt und nicht CreateObject() .

Gut zu wissen, @alexbuzzbee.

Ich habe meinen Kommentar auf die Tatsache gestützt, dass das Ausführen des Folgenden (z. B. von cmd.exe ) ein Access is denied error. ergibt und eine Windows Defender-Warnung auslöst.

mshta vbscript:Execute("CreateObject(\"WScript.Shell\"): Window.Close")

Das Fazit ist, dass die Problemumgehung wahrscheinlich eine Lücke ausnutzt, die - wie Sie berichtet haben - vorhandene Sicherheitssoftware auslösen kann und möglicherweise in Zukunft vollständig geschlossen wird.

Yay für den Versuch von @ SteveL-MSFT, eine richtige Lösung zu implementieren.

@ SteveL-MSFT, 20.02.2018

Ich würde einen Community-Beitrag unterstützen, um pwshw.exe hinzuzufügen

@ SteveL-MSFT, 31.10.2019

.NET Core 3.0 unterstützt das Erstellen von Winexe, bei dem die Konsole nicht angezeigt wird. Ich habe bereits einen funktionierenden Prototyp, muss ihn nur als PR aufräumen.

Dies hat lange auf sich warten lassen und eignet sich hervorragend für Skripte, insbesondere mit Task Scheduler (möglicherweise Cron?) Usw. Da PowerShell Core plattformübergreifend ist , funktioniert dies auch auf anderen unterstützten Plattformen? Wie wäre es mit WSL?

Der Winexe-Prototyp hat funktioniert, ist aber an den Rändern zu rau, um es in 7.0 zu schaffen. Wenn Sie beispielsweise einen Fehler mit den Befehlszeilenargumenten gemacht haben, wissen Sie es nicht, da es kein Ausgabefenster gibt. Wenn wir anderen Tools wie wscript.exe folgen, sollten wir einen Dialog mit der entsprechenden Fehlermeldung anzeigen.

Was Nicht-Windows betrifft, benötigen Linux und macOS nicht das Äquivalent von winexe, da ich glaube, dass der pwsh-Prozess gestartet werden kann, ohne ein Konsolenfenster zu erstellen, während Windows dies erfordert, da es explizit zwischen Konsolen- und Windows-Apps unterscheidet. Sie können pwsh sicherlich schon heute mit Task Scheduler oder cron usw. verwenden.

Noch eine andere Version von VBScript Shim mit Verbesserung: Unterstützt die Übergabe von Argumenten an das Powershell-Skript. Dies gibt uns mehr Flexibilität bei dem aufzurufenden Skript. Alles ohne Fenster Popup!

Powershell.vbs:

Set args = CreateObject("System.Collections.ArrayList")
For Each oItem In Wscript.Arguments: args.Add oItem: Next

CreateObject("Wscript.Shell").Run("powershell -windowstyle hidden -File """ & Join(args.ToArray, """ """) & """"),0

Ich habe beispielsweise ein Powershell-Skript, das ein bestimmtes Windows-Ereignis abhört. Verwenden Sie den Taskplaner, um Ereignisdaten zu extrahieren, und rufen Sie ein PowerShell-Skript auf, um eine Benachrichtigung über das Ereignis zu senden. Ich habe eine benutzerdefinierte geplante Aufgabe mit einem benutzerdefinierten EventTrigger erstellt (siehe einen Beitrag von Technet ):

    <EventTrigger>
      <Enabled>true</Enabled>
      <Subscription><!-- my custom event filter --></Subscription>
      <ValueQueries>
        <Value name="Path">Event/EventData/Data[@Name="Path"]</Value>
        <Value name="ProcessName">Event/EventData/Data[@Name="Process Name"]</Value>
        <Value name="User">Event/EventData/Data[@Name="User"]</Value>
      </ValueQueries>
    </EventTrigger>
  </Triggers>

Danach könnten wir die Variable $(Path) $(ProcessName) $(User) innerhalb der Ereignisaktion verwenden. In diesem Fall können wir das Skript wie folgt aufrufen. Windows ruft meine notifier.ps1 wenn ein Ereignis den Auslöser drückt.

wscript.exe "C:\path\to\powershell.vbs" "C:\path\to\notifier.ps1" -User $(User) -ProcessName $(ProcessName) -Path $(Path)

Das powershell.vbs ist absolut wiederverwendbar. 😏

Original: https://github.com/PowerShell/PowerShell/issues/3028#issuecomment -522375489

Wie @Ciantic bereits erwähnt hat, können Sie dieses Problem am besten mithilfe eines VB-Skripts

Sagen Sie in ps-run.vbs put

Set objShell = CreateObject("Wscript.Shell")
Set args = Wscript.Arguments
For Each arg In args
  objShell.Run("powershell -windowstyle hidden -executionpolicy bypass -noninteractive ""&"" ""'" & arg & "'"""),0
Next

Verwenden Sie es dann, um den gewünschten Befehl auszuführen, z. B. über die geplanten Aufgaben von Windows

wscript "C:\Path\To\ps-run.vbs" "C:\Other\Path\To\your-script.ps1"

Ich verwende so etwas, um eine Aufgabe häufig auszuführen, ohne dass blinkende Fenster angezeigt werden.

Mit QB64 können Sie eine kleine EXE-Datei erstellen, um das Skript auszublenden. QB64 ist ein C ++ - Interpreter, der QBASIC-Code in eine C ++ - Exe kompiliert. Wenn Sie die Befehle _SHELLHIDE oder SHELL _HIDE , können Sie ein PowerShell-Skript aus der EXE heraus aufrufen, ohne jemals ein PowerShell-Fenster anzuzeigen. Ich benutze dies in Verbindung mit -WindowStyle Hidden nur um sicher zu gehen, aber ich hatte nie Probleme damit. Beispiel: SHELL$ = "PowerShell -WindowStyle Hidden -ExecutionPolicy Bypass " + CHR$(34) + "&'" + _STARTDIR$ + "\GetNewDate.ps1';exit $LASTEXITCODE" + CHR$(34): a = _SHELLHIDE(SHELL$)
Sie können auch die gesamte EXE-Datei, die Sie mit $SCREENHIDE kompiliert haben, ausblenden, damit sie keinen Teil des Programms sehen müssen.
Wenn Sie einen Exit-Code haben, den Sie an einen anderen Codebereich zurückgeben möchten, können Sie exit $LASTEXITCODE wenn Sie Ihr PowerShell-Skript aufrufen, um ihn an die QB64-EXE zurückzugeben. Wenn Sie den Code von der QB64 EXE übergeben möchten, können Sie den Befehl SYSTEM gefolgt von dem Code verwenden, den Sie an den Rest Ihres Programms / Skripts zurückgeben möchten. Hoffe das hilft jemandem.

Wenn Sie dies jetzt verwenden, erhält jeder Aufruf alle Argumente, anstatt dass jedes Argument ein separates Skript ist, wie das von @ttimasdf , aber ein einfaches Array verwendet:

Dim args()
Redim args(Wscript.Arguments.Count - 1)
For i = 0 To UBound(args): args(i) = Wscript.Arguments.Item(i): Next
CreateObject("Wscript.Shell").Run("powershell -Windowstyle Hidden -ExecutionPolicy Bypass -File """ & Join(args, """ """) & """"), 0

Ich habe die -ExecutionPolicy Bypass behalten, weil ich stille Fehler bekomme, es sei denn, ich verwende auch Set-ExecutionPolicy . Ich kann nicht auf pwshw.exe warten.

https://github.com/SeidChr/RunHiddenConsole/releases/download/1.0.0-alpha.2/hiddenw.exe

@ Roy-Orbison
Los geht's. Benötigt nur eine Umbenennung 😉😅
(Srsly. Nennen Sie es pwshw.exe, setzen Sie es in Ihren Weg, und es sollte einfach funktionieren)

Ich weiß wirklich nicht, was das pwsh-Team so lange braucht.
Es ist keine so große Sache

Ich weiß wirklich nicht, was das pwsh-Team so lange braucht.

Mangel an Ressourcen. Wir brauchen mehr Codeprüfer und Mitwirkende.

Ich habe ein PowerShell-Skript für die Ausführung über Elgato Stream Deck konfiguriert und es öffnet sich ein Fenster. Ich habe versucht, -Noninteractive und -WindowStyle hidden , aber es wird immer noch kurz angezeigt.

pwsh -Noninteractive -WindowStyle hidden -Command "...."

Ich gehe davon aus, dass wir in der nächsten Vorschau pwshw bekommen.

Ich habe ein PowerShell-Skript für die Ausführung über Elgato Stream Deck konfiguriert und es öffnet sich ein Fenster. Ich habe versucht, -Noninteractive und -WindowStyle hidden , aber es wird immer noch kurz angezeigt.

pwsh -Noninteractive -WindowStyle hidden -Command "...."

Sie können dieses Popup leicht mit dem Tool umgehen, das ich oben gepostet habe. Ich benutze es jeden Tag mit meinem Steam Deck und meinen Startskripten

Zu Ihrer Information: Im Konsolenteam schlagen wir eine Möglichkeit für zukünftige Anwendungen (und zukünftige Versionen vorhandener Anwendungen) vor, damit umzugehen. Es würde einen kleinen Overhead geben [1], aber es würde PowerShell die Möglichkeit geben, zu wählen, ob ein Konsolenfenster zugewiesen werden soll, wenn es in einem GUI-Kontext gestartet wird.

Spezifikations-Pull-Anfrage: https://github.com/microsoft/terminal/pull/7337

@DHowett so froh, dass ich davon

Aber was ist, wenn ich PowerShell ohne Windows Terminal anrufe? Zum Beispiel rufe ich pwsh.exe direkt vom Elgato Stream Deck aus auf. Die vom Terminal-Team vorgeschlagene Option würde dieses Szenario nicht lösen, oder andere mögen es, oder?

@ pcgeek86 lass dich nicht vom Namen täuschen! Mein Team und ich besitzen das gesamte Windows-Konsolensubsystem, einschließlich der Art und Weise, wie Konsolenanwendungen gestartet werden und miteinander kommunizieren.

@DHowett Ich nehme an, dass die Funktionalität nur in zukünftigen Windows-Versionen verfügbar ist. Wer also noch Windows-Versionen auf niedriger Ebene verwendet, hat im Grunde kein Glück? 🤔

Eine Anwendung im Konsolensubsystem mit der consoleAllocationPolicy von inheritOnly zeigt beim Start über den Explorer keine Konsole an.

Was ist ein Verhalten für Task Scheduler?

@DHowett für pwsh würde ein Flag benötigen, um anzugeben, dass ein Conpty zugewiesen werden soll, damit Skripte, die Konsolen-APIs aufrufen, weiterhin funktionieren

Anwendungen wie PowerShell möchten möglicherweise die "automatische" Konsolenzuweisung beibehalten, und inheritOnly wäre für sie ungeeignet.

Die Richtlinie löst also nicht alle PowerShell-Szenarien auf und PowerShell sollte erneut eine Problemumgehung verwenden.

Dies erinnert mich an meine PR, bei der ich versucht habe, AllocConsole direkt zu verwenden.

Downlevel (@ vexx32)

Leider ist dies eine Einschränkung für alles, was mein Team produziert, das Teil des Konsolensubsystems ist und nicht als Teil des Terminals geliefert werden kann. Wir versuchen daran zu arbeiten 😉

Wie verhält sich der Taskplaner (@iSazonov)

"Explorer" zu sagen war eine bequeme Möglichkeit, "weniger Kontext, der noch keine Konsole hat" in weniger Worten zu sagen. Seien Sie versichert, _ alles, was eine inheritOnly -Anwendung ohne Konsole startet, führt nicht zur Zuweisung einer Konsole._

Benötigt ein Flag zur Angabe (@ SteveL-MSFT)

Glücklicherweise hat PowerShell dies bereits in Form von WindowStyle . Der Standardmodus kann "_i sollte AllocConsole() _ aufrufen" sein (was alle Konsolen-API-Anforderungen erfüllt!), Es sei denn, der Benutzer hat einen versteckten Start angefordert. Die Spezifikation verschiebt nur die Verantwortung für die Zuweisung einer Konsole in (pwsh), damit sie die endgültige Kontrolle darüber erhält, ob es einen Conhost gibt. Da Powershell bereits für diesen Fall eingerichtet ist, sind es nur ein paar Zeilen Delta vor / nach der "versteckten" Prüfung.

löst nicht alle PowerShell-Szenarien (@iSazonov)

Die Spezifikation erklärt weiter, wie Powershell damit umgehen würde (siehe oben, meine Antwort an Steve). Soweit ich weiß, werden dadurch alle in dieser Ausgabe genannten und damit verbundenen Probleme gelöst.

Der Hauptunterschied zwischen dem Aufrufen von AllocConsole() / AttachConsole() wie in Ihrer PR und dem Aufrufen von AllocConsole() wenn Ihre Anwendung für eine andere Konsolenzuweisungsrichtlinie manifestiert wird, besteht darin, dass das Subsystembit dies anzeigt Die Spawning-Shell (cmd, pwsh, bash, ish) sollte warten, bis die Spawning-Shell ( pwshw ) beendet wird, wodurch Interferenzen an den E / A-Handles der Konsole verringert werden.

Wenn Sie eine Windows-Subsystemanwendung haben, die AttachConsole() aufruft, um zur Hosting-Konsole zurückzukehren, streiten sich die Spawning-Shell und die neue Anwendung darum, wer die Eingabe lesen / ausgeben darf. Aus diesem Grund kann der Aufruf von Attach von einer Windows-Subsystemanwendung aus nie ausgeführt werden, es sei denn, Sie können die Shell, die Sie hervorgebracht hat, vollständig steuern (dies ist nicht möglich).

@DHowett Danke! Um klar zu sein, lautet der Vorschlag für PowerShell, SUBSYSTEM_GUI und inheritOnly zu verwenden.

Ich glaube, dass SUBSYSTEM_CUI und inheritOnly für PowerShell korrekt sind. Es gibt Ihnen die folgenden Verhaltensweisen:

  1. cmd ( $SHELL ) wartet, bis pwsh beendet ist, bevor es zurückkehrt ( SUBSYSTEM_CUI )
  2. Wenn Sie es über Explorer / Tasksched ausführen, kann pwsh die Entscheidung treffen, ein neues Konsolenfenster zu erstellen ( inheritOnly ).
  3. Wenn Sie es über cmd / pwsh / (eine Konsolen-Shell) ausführen, erhält pwsh automatisch ein Konsolenfenster

Wenn Sie es über Explorer / Tasksched ausführen, kann pwsh die Entscheidung treffen, ein neues Konsolenfenster zu erstellen (inheritOnly).

Hmm, wie kann PowerShell wissen, dass dies der Prozessverantwortliche ist - Explorer oder Tasksched?

Ich glaube nicht, dass es wissen muss.

Hier ist der Grund (C ++):

int main() {
    auto a{ _parseArgs() };
    if (a.WindowStyle != WindowStyle::Hidden)
    {
        AllocConsole();
    }
}

PowerShell weiß bereits, ob ein Fenster erzeugt werden soll, je nachdem, ob der Benutzer dies nicht verlangt hat. Diese Funktion ist bereits vorhanden. Dies ist also die minimale inkrementelle Änderung des Codes, mit der dieser Fehler behoben wird, und behält das ursprüngliche Verhalten für alle anderen Anwendungsfälle bei.

Dies bietet eine gute Plattform, um weiteres neues Verhalten aufzubauen.

@DHowett, wie @ vexx32 erwähnte, gibt es immer noch eine Menge Server 2012 / R2 und 2016 in freier Wildbahn. Während dies für die Betriebssystemvarianten Win10 und Server 2019 großartig erscheint, denke ich, dass wir für PowerShell einen Weg finden müssen Dies ist eleganter als die derzeit vorgeschlagene Lösung @ SteveL-MSFT

Es sei denn, Sie könnten diese Änderung im Rahmen eines Sicherheitspatches auch in ein Betriebssystem auf niedrigerer Ebene portieren, da Sie keine Feature-Updates für sie durchführen (was ich sehr bezweifle, dass Sie dies tun würden).

dass das Subsystem-Bit angibt, dass die Spawning-Shell (cmd, pwsh, bash, ish) auf das Beenden der Spawning-Shell (pwshw) warten soll, wodurch Interferenzen an den E / A-Handles der Konsole verringert werden.

Es sollte auch für PowerShell funktionieren. Ich meine, wenn PowerShell eine externe Konsolen-App aufruft, sollte es auch der neuen Richtlinie folgen. Wird PowerShell dies automatisch erhalten oder müssen wir etwas in PowerShell hinzufügen?

PowerShell müsste sich wie in der Spezifikation angegeben anmelden. Sie haben jedoch einen großartigen Punkt angesprochen: Ich glaube, dass Anwendungen, die von einer "nur erben" -Anwendung erzeugt wurden, Konsolenfenster öffnen, und das ist schrecklich. Ich werde dies in der Spezifikation noch einmal wiederholen, weil ich glaube zu wissen, wie wir das angehen können.

Es sei denn, Sie könnten diese Änderung auch in ein Betriebssystem auf niedriger Ebene portieren

Ich muss die Funktion erst fertigstellen, bevor wir sie überhaupt für das Backporting bewerten können. Ich stimme jedoch zu 100% zu, dass dies ihre Nützlichkeit einschränkt.

Ich möchte nur sagen, dass beim Starten von Powershell aus einem anderen Programm die Möglichkeit besteht, dass untergeordnete Prozesse ausgeblendet werden. Beispielsweise verfügt Autohotkey über ein "Hide" -Flag für den Befehl run.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen