# ShowMessage.ps1 # Wymaga uruchomienia z uprawnieniami Administratora #Requires -RunAsAdministrator param ( [Parameter(Mandatory=$true, Position=0, HelpMessage="Treść wiadomości")] [string]$Message, [Parameter(Mandatory=$true, Position=1, HelpMessage="Typ komunikatu: 1 (Info), 2 (Ostrzeżenie), 3 (Błąd)")] [ValidateSet("1", "2", "3")] [string]$Type ) # Znajdujemy ID sesji aktywnego użytkownika fizycznego (konsoli) $sessionId = (Get-Process explorer -ErrorAction SilentlyContinue | Select-Object -First 1).SessionId if ($null -eq $sessionId) { Write-Host "[BŁĄD] Nie wykryto zalogowanego użytkownika z interfejsem graficznym." -ForegroundColor Red Exit } # Dobór tytułu okna oraz ikonki w zależności od wybranego typu switch ($Type) { "1" { $title = "Komunikat informacyjny" # msg.exe nie obsługuje bezpośrednio ikonek, ale możemy użyć VBScript/PowerShell Windows Forms, # jednak klasyczny msg.exe jest najprostszy. Zróbmy to przez okno Forms dla pełnej kontroli typów! } "2" { $title = "Ostrzeżenie" } "3" { $title = "Błąd" } } # Użycie .NET Windows Forms pozwala na wyświetlenie prawdziwego okna z odpowiednią ikoną w sesji użytkownika $scriptBlock = { param($msg, $t, $sessionIdToUse) # Ładujemy wymagane biblioteki GUI Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName System.Windows.Forms switch ($t) { "1" { [System.Windows.Forms.MessageBox]::Show($msg, "Informacja", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information) } "2" { [System.Windows.Forms.MessageBox]::Show($msg, "Ostrzeżenie", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning) } "3" { [System.Windows.Forms.MessageBox]::Show($msg, "Błąd", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) } } } # Uruchomienie skryptu w kontekście sesji aktywnego użytkownika za pomocą harmonogramu zadań lub joba sesyjnego # Najprostsza metoda "zdalna do lokalnej sesji" w PowerShell to użycie Invoke-Command na sesję lokalną lub msg.exe # Zastosujmy niezawodny natywny mechanizm msg.exe, który automatycznie trafia na ekran aktualnego użytkownika: # Mapowanie naszego typu na parametry przełączników msg (choć msg ma ograniczone opcje, lepiej użyć wywołania msg) # Tytuł dla msg jest domyślnie nagłówkiem, a ikona zależy od systemu. # Zróbmy to elegancko przez msg.exe: switch ($Type) { "1" { $prefix = "[INFORMACJA]" } "2" { $prefix = "[OSTRZEŻENIE]" } "3" { $prefix = "[BŁĄD]" } } # Polecenie msg wysyła okno dialogowe bezpośrednio do aktywnej sesji graficznej konsoli (*) msg * /TIME:0 "$prefix $Message"