PowerShell7でもトーストを出したい
...何で、PowerShell5ではトースト出せてPowerShell7ではトースト出せないじゃヽ(`Д´)ノ
ってわけでどうにかした。どー見ても手口はマルウェアだが後悔はしていない。
いや、大丈夫、小細工でencOdeDCommAndとかにはしてないし?
もっと簡単な方法を見つけてしまった...orz
本題
20250117cmd.exe要らんやんけ
20250206文字列化なんぞ要らんやんけ
function ShowToast {
param (
[Parameter(Mandatory = $true)] [string] $Title,
[Parameter(Mandatory = $true)] [string] $Message,
[Parameter(Mandatory = $true)] [string] $Detail
)
begin {}
process {
$null = powershell {
param ($Title, $Message, $Detail)
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
$app_id = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe"
$content = ""
$content += "<?xml version='1.0' encoding='utf-8'?>"
$content += "<toast>"
$content += " <visual>"
$content += " <binding template='ToastGeneric'>"
$content += " <text>$Title</text>"
$content += " <text>$Message</text>"
$content += " <text>$Detail</text>"
$content += " </binding>"
$content += " </visual>"
$content += "</toast>"
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($content)
$toast = New-Object Windows.UI.Notifications.ToastNotification $xml
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($app_id).Show($toast)
} -args $Title, $Message, $Detail
}
end {}
}
説明
えー当初想像もしなかったんでスクリプトブロックを文字列化した挙げ句
Base64Encodeしてpowershellに実行させてたんですが、そんな苦労は不要でした
...pwshでpowershellにスクリプトブロックが渡せるだなんて思わないじゃんorz
つーわけでトーストどころかWinRT関連も割とコレでどーにかなりやがります
嘘だろ、オイ
ちなみにトースト表示自体の元ネタはココ
蛇足
ここまで書いてなんだけど自分への通知はIP Messengerでいい気もする
割と多用するであろうUNCリンクとかも自動生成してくれるし必要ならリモートにも飛ばせる
電文はただのUDPらしいから直接送信したろーかと思ったけどパケットIDとやらで挫折中
function SendIPMsg {
param (
[Parameter(Mandatory = $false)] [string] $ExePath = "$ENV:USERPROFILE\AppData\Local\IPMsg\IPMsg.exe",
[Parameter(Mandatory = $false)] [string] $TargerIP = "127.0.0.1",
[Parameter(Mandatory = $true)] [string] $Message
)
begin {}
process {
$Message = $Message.Replace("`r`n","\n")
$Message = $Message.Replace("`n","\n")
Start-Process -FilePath $ExePath -ArgumentList "/MSGEX", $TargerIP, $Message -NoNewWindow -Wait
}
end {}
}
因みにIP MessengerにはWinGetなDSCまである
流石多分日本製で一番有名なソフト(いやそれFastCopy)
properties:
configurationVersion: 0.2.0
resources:
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: installIPMsg
directives:
description: Install IP Messenger
settings:
id: FastCopy.IPMsg
source: winget
このほかにも権限設定さえできりゃmsgコマンドなんつー手段もあるにはある
※自分への送信だけなら権限不要だったよーな気がする
蛇足の蛇足
おっさん的にはカーニハン版C言語とか思い出すんでParam構文が読みやすいとかいう能書きがキチガイにしか思えないんDeathが最近の若者的にはこんなクソダルい構文がナウでヤングな竹の子族なわけDeathか?
20250206
世の中にはCsWinRTなんつー素敵な物体があるらしい
コイツでpwsh7からWinRTを弄れるらしいんだぜーって聞いて調べてみたら以下のスレを発見
powershell {get-host}
で結果を受け取れる...だと!?というお話だったのでした
Discussion