2026/06/16(火)WSL2の中からPowershellでOSへ通知トーストを投げる
PowerShellはWSL2の中から叩けるため、WSL2の中から通知を出したいときに使える。
PowerShellなのでホスト側のWindowsからも使える。
確認環境
PowerShell 7では動かないので注意。
| Env | Ver |
|---|---|
| OS | Windows 11 Pro 25H2 (OSビルド 26200.8655) |
| PowerShell | 5.1.26100.8655 |
やり方
この内容を
toast.ps1など適当な名前で保存する。文字コードはUTF-8 BOM, 改行コードはLFにしておくparam ( [String]$subject = "WSL Notice", [String]$title = "たいとるですー", [String]$message = "お知らせでーす", [String]$icon = "C:/env/1e1b9fdf82a6a544.png", [switch]$keep ) [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText04) $xml = New-Object Windows.Data.Xml.Dom.XmlDocument $xml.LoadXml($template.GetXml()) $toastTextElements = $xml.GetElementsByTagName("text") $toastTextElements.Item(0).AppendChild($xml.CreateTextNode($title)) > $null $toastTextElements.Item(1).AppendChild($xml.CreateTextNode($message)) > $null $toastImageElements = $xml.GetElementsByTagName("image") $toastImageElements.Item(0).SetAttribute("src", $icon) > $null if ($keep) { $xml.DocumentElement.SetAttribute("scenario", "reminder") > $null $actions = $xml.CreateElement("actions") $action = $xml.CreateElement("action") $action.SetAttribute("content", "閉じる") > $null $action.SetAttribute("arguments", "dismiss") > $null $action.SetAttribute("activationType", "background") > $null $actions.AppendChild($action) > $null $xml.DocumentElement.AppendChild($actions) > $null } $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) $appId = $subject $notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appId) $notifier.Show($toast)- 次の書式で叩くと通知トーストが出る
powershell.exe -File 'C:/path/to/toast.ps1' -subject hoge -title fuga -message piyo -icon C:/path/to/icon.png -keep
このスクリプトのオプション
| オプション | 役割 |
|---|---|
-subject |
通知の表題。ここを変えると別の通知として扱われる |
-title |
通知のタイトル |
-message |
メッセージ本文。一行のみ |
-icon |
アイコン。Windowsホストの絶対パスで指定 |
-keep |
このフラグを立てると通知が消えなくなる |
-subjectを変えると別の通知扱いになるため、通知を別々に貯めることができるようになる。
Windows側から叩く方法
powershell 'C:/path/to/toast.ps1' -subject hoge -title fuga -message piyo -icon C:/path/to/icon.png -keep
Windows側から叩く場合、-Fileは省略できる。
参考情報
- ToastTemplateType 列挙型 (Windows.UI.Notifications) - Windows apps | Microsoft Learn
- ここの内容とググった情報からXMLの構造をエスパーして実装している
あとがき
Claude Codeの確認と終了のイベントで通知が出ると便利かなと思って作ってみたが、まだ試せていない。
取りあえずWSL2の中と、Windowsホスト側から叩いたときに通知が出ることは確認している。
PowerShell 7で動かそうと思ったらエラーまみれで動かず、PowerShell 7の場合、NuGetパッケージを取得するか、DLLのパスを直に指定するか、サードパーティの通知ライブラリを使うかということで、諦めた。
2026/06/05(金)Windows 11のEdgeでTLS証明書のキャッシュをクリアする方法
2026/06/04(木)Windows 11でコマンドを使って標準のブラウザを変更する
どこぞのやつはライセンスが面倒なのと、無料利用だと課金誘導のポップアップが出て面倒そうなので完全無償のPS-SFTAを使って解決する。
確認環境
- Windows 11 Pro 25H2 (OSビルド 26200.8457)
- SFTA.ps1 22a3229
やり方
- PS-SFTAにある
SFTA.ps1を拾ってきてどっかに置く - 標準ブラウザ変更保護プログラムであるUCPDとかいうのを殺す
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UCPD" -Name "Start" -Value 4 -PropertyType DWORD -Force schtasks /change /disable /tn "\Microsoft\Windows\AppxDeploymentClient\UCPD velocity" - 管理者権限のPowerShellでこれを流す
powershell -ExecutionPolicy Bypass -command "& { . C:/path/to/SFTA.ps1; Set-PTA MSEdgeHTM http; Set-PTA MSEdgeHTM https; Set-FTA MSEdgeHTM .htm; Set-FTA MSEdgeHTM .html }"
あとがき
Windows 11には標準のブラウザを変更するコマンドは用意されておらず、レジストリの操作も単純ではないようなので、やるとしたらWindowsの設定を開き、アプリ→既定のアプリ→Edge→標準ブラウザにするという手間のかかる作業が必要だが、今回の方式ならコマンドを一発叩くだけなので非常に楽である。
しかもWindowsの設定にあるアプリ→既定のアプリはレイアウトシフトが酷く、少し待たないと操作できないのも面倒なので、そういったフラストレーションから解放されるのも大きい。
2026/05/15(金)Windows 11でPowerShellを使って画面をオフにする方法
Win32APIをPowerShellから叩くことで実現できる。
確認環境
- Windows 11 25H2 (OSビルド 26200.8457)
コード
(Add-Type -MemberDefinition @"
[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);
"@ -Name "Win32API" -PassThru)::SendMessage(0xFFFF, 0x0112, 0xF170, 2)
パラメーターを解説すると0xFFFFはHWND_BROADCAST、0x0112はWM_SYSCOMMAND、0xF170はSC_MONITORPOWERに相当し、2はモニタ電源を落とす固定値である。
つまり内容としては第一引数のパラメーターがHWND_BROADCASTである場合、最上位のウィンドウにWM_SYSCOMMAND指令が出され、そのパラメーターはSC_MONITORPOWERと2であるということで、つまりモニタ電源をオフにするシステムコマンドを最上位のウィンドウに送っている内容になっている。
-Name "Win32API" -PassThruを外したくなるが、外すとエラーで動かなくなるので付ける必要がある。
-PassThruがあることで戻り値が生まれ、-Name "Win32API"をつけることでクラスが生まれるらしい。
参考情報
- SendMessage function (winuser.h) - Win32 apps | Microsoft Learn
- > HWND_BROADCAST ((HWND)0xffff)
LRESULT SendMessage(
[in] HWND hWnd,
[in] UINT Msg,
[in] WPARAM wParam,
[in] LPARAM lParam
);
- WM_SYSCOMMAND message (Winuser.h) - Win32 apps | Microsoft Learn
- > #define WM_SYSCOMMAND 0x0112
- > SC_MONITORPOWER 0xF170
- GET MONITOR STATE POWER ON OR OFF | Microsoft Learn
•-1 (the display is powering on) • 2 (the display is being shut off)
- Add-Type (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn
-Name作成するクラスの名前を指定します。 このパラメーターは、メンバー定義から型を生成するときに必要です。
型名と名前空間は、セッション内で一意である必要があります。 型をアンロードしたり、変更したりすることはできません。 型のコードを変更するには、名前を変更するか、新しい PowerShell セッションを開始する必要があります。 それ以外の場合、コマンドは失敗します。
-PassThru追加された型を表す System.Runtime オブジェクトを返します。 既定では、このコマンドレットは出力を生成しません。 OUTPUTAssembly 使用して DLL ファイルを作成し、新しく作成したアセンブリから型を返す場合は、このパラメーターを使用します。
あとがき
これは私物PCと業務PCでモニタを共有しており、排他制御で利用してる時に便利な技だ。
例えばリモートワークで昼休みに私物PCにスイッチする時で、業務PCをスリープや休止にするとWSLの中身が死んだりして面倒だが、画面オフならそういうことが起きないので便利に切り替えできるという訳。
2026/05/08(金)Windows 11で1603エラーが出てJavaをインストールできなかった時にやったこと
確認環境
- Windows 11 Pro 25H2 (OSビルド 26200.8246)
- jre-8u491-windows-i586.exe
起きていたこと
全オペレーティング・システム用のJavaのダウンロードからWindows用のインストーラーをダウンロードし、インストールしようとしたところ1603エラーが出てインストールできなかった。
オンライン・オフラインどちらのインストーラーでもインストールに失敗した。
OSを再起動してもインストールできなかった。
既存のJavaインストールはない環境だった。
解決のためにやったこと
- イベントビューアを開きWindowsログ>Applicationでインストールログを探した
- MsiInstallerを見つけたので中身を見たところ、インストーラ本体(jre-8u491-windows-i586.exe)ではなく、jre1.8.0_491.msiが出ていた
Windows インストーラー トランザクションを開始しています: C:\Users\hoge\AppData\LocalLow\Oracle\Java\jre1.8.0_491\jre1.8.0_491.msi。クライアント プロセス ID: 3160。 - インストーラーを蹴った時にウィンドウが消え再び出てくる挙動を見ていたので、恐らく別のインストーラーに切り替えるときに管理者特権などが正しく継承されていないのではないかと疑った
C:\Users\hoge\AppData\LocalLow\Oracle\Java\jre1.8.0_491にアクセスしMSIを拾い上げ、直に実行することでインストールできた- この後、動いてなかったVSCodeのPlantUML拡張が動作することを確認したため、問題なくインストールできたと考えている



