Manchmal ist es notwendig auf einer ganzen Reihe von Computern eine Nachricht anzuzeigen um die Benutzer sofort über etwas zu informieren oder aufzufordern etwas bestimmtes zu tun, wie z. B. ein Programm zu schließen. Mit Hilfe der Powershell, WMIC und entsprechenden Rechten ist dies tatsächlich recht einfach möglich. Da anscheinend einige Leute schon mal nach einer Lösung für diese Anforderung gesucht haben und es einige Threads in Foren dazu gibt, zeige ich in diesem Artikel meine Lösung.
Um den folgenden Code nutzen zu können, muss auf Computern auf denen die Nachricht angezeigt werden soll die Firewall entsprechend konfiguriert sein. Bei Windows 10 habe ich dies bisher nicht hinbekommen.
Für Windows 7 und XP funktioniert es mit folgendem Befehl:
1 2 3 4 5 6 7 8 9 |
$Username = 'user' $Password = 'pass' $pass = ConvertTo-SecureString -AsPlainText $Password -Force $MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$pass $computer = "192.168.1.10" $msg = "Testnachricht" Invoke-WmiMethod -Path Win32_Process -Name Create -ArgumentList "msg * $msg" -ComputerName $computer -Credential $MySecureCreds |
Mit Hilfe des Benutzers und dazugehörigen Passworts erstellt man „PSCredentials“ die dann im Invoke-WmiMethod-Befehl genutzt werden können.
Auf dem Zielcomputer wird dann durch den übergebenen String das Programm „msg“ ausgeführt und zeigt die hinter dem * bzw. in der Variable $msg befindliche Meldung an.
Die ausgegebene Meldung sähe dann z. B. so aus:
Die Meldung verschwindet nur leider so etwa nach einer Minute, auch ohne dass jemand diese bestätigt hat… Vermutlich lässt sich das noch mit irgendeinem Parameter steuern. Für meine Zwecke hat die Minute aber erst einmal ausgereicht.
So könnte man die Meldung auf jeder Maschine innerhalb eines ganzen Class-C-Netzes ausgeben lassen, wenn sich die Ziel-IP-Adressen anpingen lassen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$Username = 'user' $Password = 'pass' $Password = 'pass' $pass = ConvertTo-SecureString -AsPlainText $Password -Force $MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$pass $count = 1 $max = 255 $msg = "Testnachricht" do { $computer = "192.168.1.$count" if (Test-Connection $computerip -Quiet -Count 1) { Invoke-WmiMethod -Path Win32_Process -Name Create -ArgumentList "msg * $msg" -ComputerName $computerip -Credential $MySecureCreds } # Ausgabe, damit man weiß bei welchem Computer man angekommen ist Write-Host 'Host' . $computer . ' wurde verarbeitet.' $count++ } until ($count -gt $max) |
Das einzige Problem ist, dass dieses Skript sehr lange braucht, wenn man gerade jetzt unbedingt auf allen PCs gleichzeitig die Meldung angezeigt haben will. Hier müsste man das Skript noch „parallelisieren“.
Edit: Ich habe dieses Skript bisher nur benötigt um von Windows 10 aus Message-Boxen auf Windows XP und 7-Rechnern anzeigen zu lassen. An Windows 10-Maschinen WMIC-Abfragen per Powershell zu schicken habe ich auch nach Stunden langer Recherche und Rumgefrickel mit DCOM-Sicherheitseinstellungen in zwei jungfräuclichen VMs und trotz deaktivierter Firewall nicht hinbekommen. Warum das nicht geht bleibt mir ein Rätsel. Falls jemand damit Glück hat oder eine Idee woran es noch liegen kann, könnte er sich vielleicht in den Kommentaren dazu äußern.