Powershell: Powershell -WindowStyleHiddenはまだウィンドウを短時間表示します

作成日 2017年01月22日  ·  90コメント  ·  ソース: PowerShell/PowerShell

再現する手順

Windowsの[ファイル名を指定して実行]ダイアログで、次のように入力します。
PowerShell.exe -WindowStyle Hidden -Command ping www.microsoft.com

予想される行動

ウィンドウがないはずです。現在、ウィンドウが点滅しないとPowerShellを起動できないため、スケジュールされたタスクなどではかなり役に立ちません。

私は、これは動作を意図していると思いますが、それは混乱だと新しいオプションがおそらく必要とされます。 スケジュールされたタスクでPowerShellを実行する方法を検索する場合、回避策はすべてのvbsスクリプトを実行することです。 といった:

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

これは良いことではありません。PowerShellはシェル自体にこの機能を必要とします。スケジュールされたタスクは重要な機能であり、スケジュールされたタスクでウィンドウをフラッシュするのは本当に悪い経験です。

実際の動作

PowerShellウィンドウが短時間点滅します。

環境データ

> $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

最も参考になるコメント

powershellw.exeを使用すると、コンソールウィンドウを表示しないGUIアプリケーションになります。 javaw.exepythonw.exe行うことと同じです。

全てのコメント90件

powershell.exeはコンソールアプリケーションです。 コンソールウィンドウは、プロセスの開始時にOSによって自動的に作成されます。 したがって、-WindowStyle Hiddenを処理するpowershell.exeコードは、コンソールウィンドウが開かれた後、つまりフラッシュの後に実行されます。 これを修正するには、wscriptに相当するもの、つまりコンソールホストアプリケーションではなくwin32ホストアプリケーションが必要になります。

これに対処するためにpowershell.exeで実行できるコード変更がないため、この問題を機能要求に変更して、このタイプのシナリオをサポートするwscriptのようなホストを用意しました。

http://www.f2ko.de/en/p2e.php
Power Shell Studioにもカスタムホストがあります

powershellw.exeを使用すると、コンソールウィンドウを表示しないGUIアプリケーションになります。 javaw.exepythonw.exe行うことと同じです。

pwsh.exeはこれのサポートを取得できますか、または上記のようにpwshw.exeを取得できますか? このpwshexeは新しいので、 -windowstyle hidden動作を変更する絶好の機会のようです。 誰もhiddenを使ったことがなく、「うん、それが私が欲しかったものだ。画面を一瞬フラッシュする」と思ったことはない。

powershell.exeは、この時間とそのレガシーの後で変更できないことは理にかなっています。

pwshw.exeを追加するコミュニティの貢献をサポートします

同意する..これは他の言語の実行可能ファイルと一致し、現在PowerShellスクリプトをvbsスクリプトでラップする必要があることを解決します。

技術的には、 https://github.com/AvaloniaUI/Avalonia/wiki/Hide-console-window-for-self-contained-.NET-Core-applicationのようにすることができ
c# editbin.exe /subsystem:windows yourapp.exe

しかし、PowerShell Coreが移植可能である場合、Unixで期待される動作は何でしょうか。 すべてのプラットフォームで統合できますか?
関連するディスカッションhttps://github.com/dotnet/cli/issues/296また、GUIサブシステムを使用できることにも言及しています。

たぶん@ mklement0は何か考えがありますか?

@iSazonov -WindowStyleWindows以外でいません

はい、つまり、コンソールを作成することで、Unixでも同じ動作をすることができますか? Unixでコンソールを作成したくないシナリオはありますか?

@iSazonov :私はこれを実際には調べていません。 私は個人的な経験から、あなたを伝えることができる唯一のことは、呼び出すことですpwsh目に見えないようなユーティリティから罰金を作品アルフレッド3のTextExpander

これまで使用してきたのは、ターゲットがC:\ Windows \ System32 \ WindowsPowerShell \ v1.0powershell.exeでオプションがRun:MinimizedのPSという名前のショートカットです。
このような:
C:\Windows\PS Start-Process .
タスクバーはちらつきますが、コンソールは表示されません。

-WindowStyle Hiddenをコマンドラインの最初のパラメーターにする必要があるようです。

それで、私たちは今Windows PowerShellをサポートし始めていますか?

これがPowerShellCoreの問題である場合は、わかりやすいリマインダーです。 問題を送信するときに必要なPowerShellCoreバージョンを提供してください。

それ以外の場合、Windows PowerShellは次のUserVoiceを経由する必要があります//windowsserver.uservoice.com/forums/301869-powershell

詳細については、 https

:)

@aresowj :PowerShellの_CLI_を呼び出すときは引数の配置は重要ですが( -Command続くものは実行するコマンドの一部として解釈される場合)、(a)OPの試行ではすでに-Command前に配置されています@BrucePayの以前のコメントで説明されている理由により、点滅を防止しません。

@MaximoTrinidad :この問題はWindows PowerShellのみに焦点を当てたものとして始まった可能性がありますが、PS Core機能要求(Windows PowerShellへのバック

要約すると、PowerShell CLIを介して完全に非表示の呼び出しを取得するには、次のようにします。

  • _Windows_では、 python.exe / pythonw.exeのモデルに従って、_GUI_アプリケーションである新しい個別のPowerShell実行可能ファイル( pwshw.exe / powershellw.exe )が必要です。ペア

  • 問題が存在しないmacOSおよびLinuxでは、個別の実行可能ファイルは必要ないと_推測_します。 Windowsとの対称性のために、通常のpwsh実行可能ファイルを指す単純な_symlink_を実装できます。

ありがとう@ mklement0!
:)

申し訳ありませんが、2つのPowershellを間違えて、説明していただきありがとうございます。 :)

最初にPowershellを非表示のコンソールでバックグラウンドで起動し、次にコンソールウィンドウの引数-WindowStyleをチェックして、それらを実装するのはどうでしょうか。
ただし、何も見つからない場合は、表示されているコンソールウィンドウを開始できます。

ここでWindowsコンソールチームの問題リポジトリに問題を作成しました: https

@ zero77

pwsh.exeは、既存のコンソールウィンドウからの同期的な標準ストリーム接続の実行を保証するために、コンソールサブシステムアプリケーションのままである必要があります。

したがって、前述の_separate_、GUIサブシステム実行可能ファイルpwshw.exeです。 その実行可能ファイルが(常に新しい)コンソールウィンドウの_条件付き_作成をサポートするようにしたい場合は、 @ iSazonovのリンクが出発点として役立ちます。

@ Jawz84 :コンソールチームがここで役立つとは思わない:

  • pwsh.exeなどの_console-subsystem_アプリケーションは、常に新しいコンソールウィンドウを作成します。これは、アプリケーションが引数を認識する前に発生します。

  • このコンソールウィンドウを_非表示_または_作成防止_する唯一の方法は、エントリポイントとして_GUIサブシステム_アプリケーションを使用することです。 最も単純なケースでは、このGUIサブシステムアプリケーションは、引数をコンソールアプリケーションに中継する_stub_にすることができますが、それを_hidden_​​で開始します。

コンソールの問題は開いたままにしておきます。彼らの考えを見てください。 私はあなたの主張を理解しています、そして私はそれが完全に不可能かもしれないことを知っています。 それでもまた、それは彼らが検討したいことかもしれません。

[編集:]これは現在、コンソールで修正することは不可能であるという答えがあります。 今のところ、別のpwshw.exeを使用する方法があります。

うわぁ! ほぼ2年間営業していますか? これは、SysAdminsにとって非常に重要な機能です。

@Chiramisu上記のコメントで

私はこの機能要求に同意します。コマンドとして実行したときのPowershellのデフォルトの動作は混乱しています

Windows Updateを適用した後、これが表示され始めます。 最近何か変わった?

これが実際に何を必要とするかを見た人はいますか?

私はpowershell.exeを見ていますが、それはかなり単純なようです。

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

さて、コンソールなしで作成するには、出力タイプをコンソールアプリケーションではなく「Windowsアプリケーション」に変更するようなプロジェクト設定ですか?

後に唯一の合理的な選択のように思える.exeのワット.exeファイルとバックポートのPowerShell wはpwshを作るための意思決定が行われていなかったですコンソールチームのフィードバック以上。

C:\windows\System32\taskhostw.exeが存在することを考えると、これはそれほど珍しいことではありません。 C:\windows\System32\ *w.exeを検索しているウィンドウで、このパターンを使用しているアイテムがいくつかあるようです。

個人的には、powershell.exeにバックポートせずに-windowstyleを修正するようにpwsh.exeを変更するだけで、新しいので許容できると思っていましたが、見た目ほど単純なものはありません。

@Cianticの作業は、 powershell-win-coreを複製し、 Assemblypwshwなり、 OutputTypewinexeなるように.csprojファイルを更新することです。 winexe 。 次に、 build.psm1変更して、両方を構築します。

ウィンドウレスで開始するコンソールツールへの呼び出しを元のファイルに渡す小さなツールを作成しました。

https://github.com/Vittel/RunHiddenConsole

コンパイル後、実行可能ファイルの名前を「<targetExecutableName> w.exe」に変更し(「w」を追加)、元の実行可能ファイルの横に配置します。
その後、通常のパラメータを使用してeG powershellw.exeまたはpwshw.exeを呼び出すことができ、ウィンドウがポップアップしません。

作成されたプロセスが入力を待っているかどうかを確認する方法を誰かが知っている場合は、ソリューションを含めてください:)
編集:
その問題の解決策を見つけました

リリースをコンパイルして、いつか試してみます! 本当に素晴らしい仕事ヴィッテル:)👍💯

リリースをコンパイルして、いつか試してみます! 本当に素晴らしい仕事ヴィッテル:)👍💯

良いアイデア。 そうしました。

その特定のPowerShellの問題(スケジュールされたタスクで発生)については、 https://github.com/stbrenner/SilentCMD (これもC#)を使用することになりました。RunHiddenConsoleを試してみます...

@Vittelプロジェクトありがとうございます! 入力/出力/エラーのリダイレクトと、おそらく引数のエスケープに注意を払う必要があります。

新しいpwshwプロジェクトを作成する場合は、デフォルトについて考える必要があります。おそらく-Noprofile必要です。

netcoreapp2xは現在これをサポートしていないため、 OutputTypeWinExe変更するだけでは不十分です。 https://github.com/dotnet/core-setup/issues/196#issuecommentによると、-394786860はnetcoreapp30を待つ必要があるようです。

@iSazonovがほのめかしたように、exeではなくwinexeとしてビルドするだけでは、完全なソリューションにはなりません。 pwsh.exeで許可されている既存のパラメーターの一部は、pwshw.exeでは正しく機能しません(コンソールウィンドウが表示されないため、 -NoExitなど、自動化のみを目的としています)。 したがって、デフォルトで-NoProfileようなものや、自動化とインタラクティブに固有の他のデフォルトを検討するのは理にかなっています。

| パラメータ| 状態
| -| -
| -ファイル|
| -コマンド|
| -ConfigurationName |
| -EncodedCommand |
| -ExecutionPolicy |
| -InputFormat |
| -インタラクティブ| 削除(未使用)
| -NoExit | 削除(未使用)
| -NoLogo | 削除(未使用)
| -非インタラクティブ| 削除(デフォルト)
| -NoProfile | 削除(デフォルト)
| -OutputFormat | 削除(未使用)
| -バージョン| 削除する
| -WindowStyle | 削除(未使用)
| -WorkingDirectory |

pwshw.exeがコンソールなしのシナリオ用である場合、GUI用のexeは何になりますか?

参考のため。 https://github.com/dotnet/core-setup/pull/3888から:

apphostの名前を変更する機能。

しかし、名前を変更する方法についてのドキュメントが見つかりません。

役立つパラメータテーブル@iSazonovをありがとう。

-NonInteractive-WindowStyleも削除できると思います。これらは、定義上GUIサブシステム実行可能ファイルにはない_console_ウィンドウのコンテキストでのみ意味があるためです。

pwshw.exeがコンソールなしのシナリオの場合、GUIのexeはどのようになりますか?

pwshw.exeは二重の義務を果たすことができます:

  • 自動化の場合(たとえば、スケジュールされたタスクから非表示で実行)
  • 不要なコンソールウィンドウなしでGUIユーザーインタラクションのみのスクリプトを起動する場合(たとえば、WinForms UIを作成するスクリプト)。

GUIユーザーインタラクションのみのスクリプトを起動する場合…

彼らのために-WindowStyleを保持する必要がありますか?

そして、GUIコンソールはどうですか?

彼らのために-WindowStyleを保持する必要がありますか?

GUIウィンドウ(存在する場合)がどの時点でどのメカニズムを介して作成されるかを事前に知ることはできず、それを作成するコードは、PowerShellに起動パラメーターを順番に照会する必要があるため、これは有用ではないと思います。値を尊重します。

_GUIコンソール_とはどういう意味ですか?

@iSazonov pwshw 、定義上、インタラクティブコンソールを備えていません。 -WindowStyleは、特にコンソールウィンドウ用です。 WinForms / WPFを利用するスクリプトは、pwshwホストから独立しています。

ありがとう! 上記の表が更新されました。

このために新しいホストを作成することは避けたいので、利用可能なPTYを使用してこれを解決したいと思います。

今のところ回避策は次のとおりです-表示されるのはタスクバーのPowerShellインスタンスだけで、すぐに消えます-画面にconhost.exeが点滅しなくなります。

$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

進取の気性のある個人は、この手法をpsexec.exe -iと組み合わせて、現在ログオンしているユーザーセッションでスクリプトをリモートで実行できます。

  • これでも、システムにすばやく表示されるフラッシュウィンドウが表示されます
  • 上記のsilentCMDを試しましたが、これを実行するサードパーティシステムの一部にインストールされていないnet3.5が必要です

私が思う解決策はないようです

私の実行された隠しコンソールGitHubプロジェクトをチェックアウトしましたか?
私は意図的に可能な限り低い要件を使用しました。 ほぼすべてのWindowsバージョンで動作するはずです

@Cianticが述べたように、この問題を回避する最善の方法は、VBスクリプトを使用することです。

で、 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

次に、それを使用して、たとえばWindowsのスケジュールされたタスクから必要なコマンドを実行します。

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

私はこのようなものを使用して、ウィンドウが点滅することなくタスクを頻繁に実行します。

私の実行された隠しコンソールGitHubプロジェクトをチェックアウトしましたか?
私は意図的に可能な限り低い要件を使用しました。 ほぼすべてのWindowsバージョンで動作するはずです

私は今週それを試しました、そしてそれはnet3.5要件をポップアップすることなく動作します。 ありがとう! いいね。 VBSも念頭に置いてください。

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? それは何ですか?

EnvoyédemoniPhone

ル18火星2019年21時51分à、ジョー・アイエロ[email protected] Aécrit:

このために新しいホストを作成することは避けたいので、利用可能なPTYを使用してこれを解決したいと思います。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

@ Roy-OrbisonのVBScriptの簡略版:

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

私が取り組んでいるスクリプトを使用してマシンでテストしたところ、PSプロンプトまたはスケジュールされたタスクからwscriptして実行すると機能するようです。

利点:

  • wscriptコマンドラインにスクリプトパスを配置する必要はありません。
  • ExecutionPolicyBypass設定しません。

欠点:

  • PowerShellコマンドごとに個別のVBScriptスクリプトが必要です。

個人的には、 RunHiddenConsoleよりもVBScriptソリューションの方が好きです。これは、署名されていない実行可能ファイルをシステムディレクトリに展開する必要がないためです。 ただし、公式のpwshw.exe / powershellw.exeを持っている方が、どちらよりも明らかに望ましいでしょう。

個人的には、 RunHiddenConsoleよりもVBScriptソリューションの方が好きです。これは、署名されていない実行可能ファイルをシステムディレクトリに展開する必要がないためです。

署名は大したことではありません。 あなたはそれを自分で構築する少しの努力でそれを自分で行うことさえできます
ps:実行するスクリプトのすぐ隣にツールをデプロイするオプションも追加しました。 そのため、PowerShell実行可能ファイルの隣のシステムでセットアップする必要はありません。

回避策とサードパーティのソリューションがあるのは良いことですが、 @ alexbuzzbeeの最後のコメントを強調し

_PowerShellに付属する_ソリューションが必要です。


回避策について:VBScriptベースのソリューションは、ヘルパースクリプトファイルがなくても可能ですが、それは難解です。

以下は、 Runダイアログ(またはcmd.exe )から実行でき、(コンソールウィンドウを表示せずに)メッセージボックスをポップアップする非表示のPowerShellインスタンスを作成します。

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

警告@alexbuzzbeeは、「[この]ソリューションはDefender ATPエンドポイント保護システム[...]でアラートを生成するため、エンタープライズ環境には適さない可能性がある」と述べています。

@Vittelのソリューションを公式のソリューションに変えるのは不合理でしょうか? コードをPowerShellリポジトリに移動し、 powershell.exeまたはpwsh.exeのみを起動するように変更し、PowerShellでビルド/配布することは難しくありません。

.NET Core 3.0は、コンソールを表示しないwinexeのビルドをサポートしています。 私はすでに実用的なプロトタイプを持っています。PRとしてクリーンアップする必要があります。

私はすでに実用的なプロトタイプを持っています

私も途中CommandLineParameterParserを単純化してください(EarlyParseを削除しますか?)。

@ mklement0のソリューションは、Defender ATP Endpoint Protectionシステムでアラートを生成するため(PowerShellコードを実行するmshtaは好きではありません)、エンタープライズ環境には適さない可能性があります。

おかげで、 @ alexbuzzbee 、私は私の前のコメントにあなたの警告を追加しました。 アラートをトリガーするのは、実際にはVBScript CreateObject() / JScript new ActiveXObject()呼び出しだと思います。 どうやら、 mshta.exeは過去にマルウェアで使用されたことがあります。

@ mklement0 ATPは、 CreateObject()呼び出しではなく、 pwshから始まるmshta特に疑っているようです。

知っておきたい、@ alexbuzzbee。

以下を実行すると(たとえば、 cmd.exeAccess is denied error.が生成され、WindowsDefenderアラートがトリガーされるという事実に基づいてコメントしました。

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

肝心なのは、回避策はおそらく抜け穴を利用しているということです。これは、あなたが報告したように、既存のセキュリティソフトウェアをトリガーする可能性があり、将来的には完全に閉鎖される可能性があります。

@SteveLに賛成-MSFTが適切なソリューションを実装しようとしました。

@ SteveL-MSFT、2018-02-20

pwshw.exeを追加するコミュニティの貢献をサポートします

@ SteveL-MSFT、2019-10-31

.NET Core 3.0は、コンソールを表示しないwinexeのビルドをサポートしています。 私はすでに実用的なプロトタイプを持っています。PRとしてクリーンアップする必要があります。

これは久しぶりで、特にタスクスケジューラ(おそらくcron?)などを使用したスクリプト作成に最適です。PowerShellCoreはクロスプラットフォームなので、サポートされている他のプラットフォームでも機能しますか? WSLはどうですか?

winexeプロトタイプは機能しましたが、7.0にするにはエッジが粗すぎます。 たとえば、コマンドライン引数を間違えた場合、出力ウィンドウがないためわかりません。 wscript.exeのような他のツールに従う場合、適切なエラーメッセージを含むダイアログを表示する必要があります。

Windows以外の場合、LinuxとmacOSはwinexeと同等のものを必要としません。これは、コンソールウィンドウを作成せずにpwshプロセスを開始できると信じているのに対し、WindowsはコンソールアプリとWindowsアプリを明示的に区別するために必要です。 あなたは確かに今日のタスクスケジューラやcronなどでpwshを使うことができます...すでに。

拡張されたVBScriptシムのさらに別のバージョン:Powershellスクリプトへの引数の受け渡しをサポート

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

たとえば、特定のWindowsイベントをリッスンするPowerShellスクリプトがあり、タスクスケジューラを使用してイベントデータを抽出し、PowerShellスクリプトを呼び出してイベントに関する通知を送信します。 カスタムEventTriggerを使用してカスタムスケジュールタスクを作成しました( 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>

その後、イベントアクション内で変数$(Path) $(ProcessName) $(User)使用できます。 この場合、次のようにスクリプトを呼び出すことができます。 イベントがトリガーにヒットするたびに、Windowsは私のnotifier.ps1を呼び出します。

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

powershell.vbsは完全に再利用可能です。 😏

オリジナル: https

@Cianticが述べたように、この問題を回避する最善の方法は、VBスクリプトを使用することです。

で、 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

次に、それを使用して、たとえばWindowsのスケジュールされたタスクから必要なコマンドを実行します。

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

私はこのようなものを使用して、ウィンドウが点滅することなくタスクを頻繁に実行します。

QB64を使用して、スクリプトを非表示にする小さなEXEを作成できます。 QB64は、QBASICコードを取得してC ++ exeにコンパイルするC ++インタープリターです。 _SHELLHIDEまたはSHELL _HIDEコマンドを使用すると、PowerShellウィンドウをまったく表示せずにEXE内からPowerShellスクリプトを呼び出すことができます。 安全のためにこれを-WindowStyle Hiddenと組み合わせて使用​​しますが、問題が発生したことはありません。 例: SHELL$ = "PowerShell -WindowStyle Hidden -ExecutionPolicy Bypass " + CHR$(34) + "&'" + _STARTDIR$ + "\GetNewDate.ps1';exit $LASTEXITCODE" + CHR$(34): a = _SHELLHIDE(SHELL$)
$SCREENHIDEを使用してコンパイルしたEXE全体を非表示にして、プログラムの一部を表示する必要がないようにすることもできます。
別のコード領域に戻したい終了コードがある場合は、PowerShellスクリプトを呼び出してQB64 EXEに戻すときに、 exit $LASTEXITCODE使用できます。 QB64 EXEからコードを渡したい場合は、コマンドSYSTEMを使用してから、プログラム/スクリプトの残りの部分に戻したいコードを使用できます。 これが誰かを助けることを願っています。

これを使用して、 @ ttimasdfのように各引数が個別のスクリプトであるのではなく、各呼び出しがすべての引数を取得するようにしますが、プレーン配列を使用します。

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

Set-ExecutionPolicyも使用しない限り、サイレントエラーが発生するため、 -ExecutionPolicy Bypassを保持しました。 pwshw.exe待ちきれません。

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

@ロイ・オービソン
そこに行きます。 名前を変更する必要があります😉😅
(Srsly。pwshw.exeという名前を付けて、パスに配置すると、正常に機能するはずです)

pwshチームに何がそんなに長くかかるのか本当にわかりません。
それほど大したことではありません

pwshチームに何がそんなに長くかかるのか本当にわかりません。

財源不足。 より多くのコードレビューアと貢献者が必要です。

Elgato Stream Deckから実行するようにPowerShellスクリプトを構成すると、ウィンドウが開きます。 -Noninteractive-WindowStyle hiddenを使用してみましたが、それでも短時間ポップアップします。

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

次のプレビューでpwshwを取得する予定です。

Elgato Stream Deckから実行するようにPowerShellスクリプトを構成すると、ウィンドウが開きます。 -Noninteractive-WindowStyle hiddenを使用してみましたが、それでも短時間ポップアップします。

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

上に投稿したツールを使用して、そのポップアップを簡単に回避できます。 スチームデッキとスタートアップスクリプトで毎日使用しています

参考:コンソールチームでは、将来のアプリケーション(および既存のアプリケーションの将来のバージョン)がこれに対処する方法を提案しています。 少しオーバーヘッドが発生します[1]が、GUIコンテキストで起動したときにPowerShellに_コンソールウィンドウを割り当てるかどうかを選択する_機能を提供します。

仕様プルリクエスト: https

@DHowettは、PRをマージする前に、これについて

しかし、WindowsターミナルなしでPowerShellを呼び出している場合はどうなりますか? たとえば、Elgato StreamDeckから直接pwsh.exeを呼び出しています。 ターミナルチームから提案されたオプションは、このシナリオ、または他の同様のシナリオを解決しませんか?

@ pcgeek86名前に

@DHowett私は、この機能はWindowsの将来のバージョンでのみ利用可能になると思いますか? それで、まだダウンレベルのWindowsバージョンを使用している人は、本質的に運が悪いのでしょうか? 🤔

consoleAllocationPolicyがinheritOnlyのコンソールサブシステムにあるアプリケーションは、エクスプローラーから

タスクスケジューラの動作は何ですか?

@DHowett for pwshは、コンソールAPIを呼び出すスクリプトが引き続き機能するように、conptyを割り当てることを指定するフラグが必要になります。

PowerShellのようなアプリケーションは、「自動」コンソール割り当てを保持したい場合があり、inheritOnlyはそれらには不適切です。

したがって、ポリシーはすべてのPowerShellシナリオを解決するわけではなく、PowerShellは回避策を再度使用する必要がありますか?

これは、AllocConsoleを直接使用しようとしたPRを思い出させます。

ダウンレベル(@ vexx32)

残念ながら、これは、コンソールサブシステムの一部であり、ターミナルの一部として出荷できない、私のチームが作成するものに対する制限です。 私たちはそれに取り組んでいます😉

タスクスケジューラ(@iSazonov)の動作は何ですか

「Explorer」と言うことは、「コンソールをまだ持っていないコンテキスト」をより少ない言葉で言うのに便利な方法でした。 _コンソールなしでinheritOnlyアプリケーションを起動するものは、コンソールの割り当てを引き起こしませんので、ご安心ください。_

指定するフラグが必要になります(@ SteveL-MSFT)

幸い、PowerShellにはすでにWindowStyleの形式でこれがあります。 ユーザーが非表示の起動を要求しない限り、デフォルトのモードは「_iはAllocConsole() _を呼び出す必要があります」(これはすべてのコンソールAPIのニーズに対応します!)にすることができます。 仕様では、コンソールを(pwsh)に割り当てる責任を移動するだけなので、コンホストが存在するかどうかを最終的に制御できます。 PowerShellはこのケースを処理するように既に設定されているため、「非表示」チェックの前後の数行のデルタです。

すべてのPowerShellシナリオを解決するわけではありません(@iSazonov)

仕様では、PowerShellがこれをどのように処理するかについてさらに説明しています(上記のSteveへの返信を参照)。 私が理解している限り、これは_この問題で呼び出されたすべてのシナリオとリンクされた問題を解決します。_

PRで行ったようにAllocConsole() / AttachConsole()を呼び出すことと、アプリケーションが別のコンソール割り当てポリシーでマニフェストされているときにAllocConsole()を呼び出すことの主な違いは、サブシステムビットが次のことを示していることです。スポーンシェル(cmd、pwsh、bash、ish)は、スポーンされたシェル( pwshw )が終了するのを_待機_する必要があります。これにより、コンソールI / Oハンドルへの干渉が減少します。

AttachConsole()を呼び出してホスティングコンソールに戻るWindowsサブシステムアプリケーションがある場合、スポーンシェルと新しいアプリケーションは、誰が入力/書き込み出力を読み取るかを争います。 そのため、生成したシェルを完全に制御できない限り、WindowsサブシステムアプリケーションからAttachを呼び出すことはできません(できません)。

@DHowettありがとう! PowerShellの提案を明確にするために、SUBSYSTEM_GUIとinheritOnlyを使用しますか?

私の考えでは、PowerShellではSUBSYSTEM_CUIinheritOnlyが正しいと思います。 それはあなたに次の振る舞いを与えます:

  1. cmd( $SHELL )は、pwshが終了するのを待ってから( SUBSYSTEM_CUI )を返します。
  2. エクスプローラー/ taskschedから実行すると、pwshは新しいコンソールウィンドウの作成を決定できます( inheritOnly )。
  3. cmd / pwsh /(コンソールシェル)から実行すると、pwshは自動的にコンソールウィンドウを受け取ります

エクスプローラー/ taskschedから実行すると、pwshは新しいコンソールウィンドウの作成を決定できます(inheritOnly)

うーん、PowerShellは、それがプロセスの所有者(エクスプローラーまたはタスクスケジュール)であることをどのように知ることができますか?

私はそれが知る必要があるとは思わない。

理由は次のとおりです(C ++):

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

PowerShellは、ユーザーがウィンドウを生成しないように要求したかどうかに基づいて、ウィンドウを生成するかどうかを既に認識しています。 この機能はすでに存在しているため、これはこのバグを修正するコードへの最小限の増分変更であり、他のすべてのユースケースの元の動作を維持します。

これは、さらに新しい動作を構築するための優れたプラットフォームを提供します。

@ vexx32はWin10&サーバー2019 OSは、これが今後の素晴らしい思わバリアントのために、私はPowerShell用我々は方法を考える必要があるだろうと思いながら、Server 2012の/ R2&野生そうで2016うちの多くがまだあるに述べたように@DHowettこれについては、現在提案されているソリューション@ SteveL-MSFTよりもエレガントです。

セキュリティパッチの一部としてその変更をダウンレベルOSに移植することもできない限り、機能の更新を行っていないためです(これは非常に疑わしいです)。

サブシステムビットは、スポーンシェル(cmd、pwsh、bash、ish)がスポーンシェル(pwshw)の終了を待機する必要があることを示します。これにより、コンソールI / Oハンドルへの干渉が減少します。

PowerShellでも機能するはずです。 つまり、PowerShellが外部コンソールアプリを呼び出す場合は、新しいポリシーにも従う必要があります。 PowerShellはこれを自動的に取得しますか、それともPowerShellに何かを追加する必要がありますか?

PowerShellは、仕様に記載されているようにオプトインする必要があります。 しかし、あなたは素晴らしい点を提起しました。「継承のみ」のアプリケーションによって生成されたアプリケーションは、コンソールウィンドウをポップアップするので、それは「ひどい」と思います。 私はこれに対処する方法を知っていると信じているので、仕様でこれを再検討します。

その変更をダウンレベルのOSに移植することもできない限り

バックポートを評価する前に機能を完成させる必要があります😉しかし、これがその有用性を制限することに100%同意します。

別のプログラムからPowerShellを起動している場合は、子プロセスの非表示をサポートしている可能性があります。 たとえば、Autohotkeyには実行コマンドの「非表示」フラグがあります。

このページは役に立ちましたか?
0 / 5 - 0 評価