derwowusste

Skriptausführung via Taskplaner hin und wieder erfolglos

Moin PS-Experten!

Der Windows-Taskplaner führt hier alle paar Stunden ein Skript aus um den Defender upzudaten:
$v1 = [version](gci \\server\share\Defenderupdates\mpam-fe.exe).VersionInfo.FileVersion
$v2 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updates').AVSignatureVersion  
if ($v1 -gt $v2) {\\server\share\Defenderupdates\mpam-fe.exe}
if ($v1 -gt $v2) {msg * Kontrollmeldung!}

Wer hat eine Erklärung dafür, dass die Kontrollmeldung IMMER kommt, wenn die Versionen nicht übereinstimmen, wohingegen das Update (der Start von mpam-fe.exe) nicht immer ausgeführt wird? Es ist mir ein Rätsel. Da das Skript auf dem selben Share liegt, kann ausgeschlossen werden, dass das Share temporär nicht verfügbar ist.

Mit "nicht immer" meine ich unregelmäßig, völlig regellos. Mal kann ich sehen, dass es 2x in 24 Stunden läuft, wie erwartet, mal läuft es seltsamerweise 3 volle Tage gar nicht (während wie gesagt die Kontrollmeldung IMMER gezeigt wird, wenn die Versionen nicht übereinstimmen).
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 673294

Url: https://administrator.de/forum/windows-taskplaner-defender-update-673294.html

Ausgedruckt am: 14.06.2025 um 22:06 Uhr

Crusher79
Crusher79 10.06.2025 aktualisiert um 17:45:24 Uhr
Goto Top
Moin

was wenn es auf eine Exception läuft?

$v2 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updatesx').AVSignatureVersion  
Get-ChildItem c:\temp

Hab einfach mal hinter Update ein X gehängt. Also nicht lesbar. Get-Childitem macht es trotzdem.

Bin kein PS Guru. Ggf. Error Handlling anpassen, was bei Fehler Stop erzwingt.

# Change the ErrorActionPreference to 'Stop' 
$ErrorActionPreference = 'Stop'  
# Error message is generated and script stops processing
Write-Error -Message 'Test Error' ; Write-Host 'Hello World'  

# Show the ActionPreferenceStopException and the error generated
$Error[0]
$Error[1]

GCI oben läuft durch. Ka wie es sich es sich nun verhält, wenn die Version-Variable $null oder was auch immer ist. Typ [version] kann es ja ggf. nicht sein, wenn Registry unlesbar ist.

Das wäre so mein erster Gedanke.

Get-ItemProperty ist ja relativ simpel. Wenn man es mal 100x Mal nacheinander macht. Ich erinnre mich dunkel dass ich sowas auch mal erzwingen konnte - also den Fehler.

Ist nur geraten und ich weiß auch nicht wie der Vergleich oben mit $null ausgehen würde.

Edit: Konnte es gerade erzwingen, hatte aber die Var vorher nicht entfernt. Da wurde dann weiterausgeführt - trotz Fehler. Wenn die Var nicht initialisiert worden sind dürfte nix ausgeführt werden.

An sinnvollsten wäre es, wenn du es mal mit loggen würdest und die Ergebnisse der Version in die Logdatei schreibst. Ggf. wird es dann klarer was zur der Zeit gelesen wurde.
Crusher79
Crusher79 10.06.2025 aktualisiert um 17:53:03 Uhr
Goto Top
clipboard-image

$v1 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updates').AVSignatureVersion    
$v2 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updatesx').AVSignatureVersion    
if ($v1 -gt $v2) {Write-Host 'A'}  


Hatte es eben schon wieder gelöscht - dachte Irrweg. Hatte vorher aber Error Handling in der ISE aktiv.

Wenn ich das in ISE kopiere kommt sofort "A".

Gehe immer noch stark davon aus dass z.B. Registry Abfrage fehschlägt.

Error-Handling sollte den Fehler eliminieren.

https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell ...

$ErrorActionPreference = 'Stop'

Liefert Fehler macht aber NICHT weiter. Platziere das mal bitte oben in die erste Zeile. Dann sollte es schon gut sein.

try...catch etc. gibs zwar auch, aber betrifft nur die Zeilen die es umschließt. Denke mit der Preference für dein Script sollte es schon getan sein.
DerWoWusste
DerWoWusste 10.06.2025 um 20:09:02 Uhr
Goto Top
Moin.

Da die Kontrollmeldung kommt, ist $v1>$v2 ja gegeben, sprich: das erste Kommando muss ebenso laufen. Tut es aber nicht, denn dann würde zu den selben Zeiten wie die Kontrollmeldung kommt ja auch ins Eventlog geschrieben, dass ein Defender Update stattfand - dies ist eben nur oft gegeben, aber längt nicht immer.
Crusher79
Crusher79 10.06.2025 um 20:47:51 Uhr
Goto Top
if ($v1 -gt $v2)

Gilt ja für beides. Hab ich mit den Buchstaben "A" simuliert. Ohne Error Handling kann es Amok laufen und macht einfach weiter. Vergleicht die Variablen, obwohl ein Wert Unsinn ist.

$ErrorActionPreference = 'Stop'

Probiere das mal wie gesagt oben aus. Für den Fall das zu einer Zeit mal eben NICHT die Registry z.B. sauber gelesen wird. Dann wird nix weiter ausgeführt und das Log sollte leer sein.

Ob nun "A" kommt oder das was {msg * Kontrollmeldung!} bewirkt ist ja egal. Es rennt aufgrund falscher Meldung weiter durch, da der bool'schle Vergleich true ergibt.

Wenn ich recht habe müsste $ErrorActionPreference alles stoppen, wenn etwas auf einen Hammer läuft.
em-pie
em-pie 10.06.2025 um 21:22:52 Uhr
Goto Top
Moin,

Würde das auch eher anfangen.
Spannend ist ja, was $v1 bzw. $v2 zum Zeitpunkt des Fehlers enthalten.
Vielleicht mal für ein paar Tage die beiden Inhalte (mit Zeitstempel) in eine Text-Datei schreiben lassen.

Wenn die zum Zeitpunkt des Fehlers leer sind, sollte auch ein
if($v1 > $v2 -and $null -ne $v1 -and $null -ne $v2){…}
godlie
godlie 11.06.2025 um 11:24:27 Uhr
Goto Top
Hallo,

ich glaube du hast hier einen kleinen Denkfehler, dein Regestry Wert ist keine Nummer sondern ein String, von daher wird $1 -gr $2 nie wirklich funktioneren.


Ich vermute du musst $1 und $2 casten, damit ein -gt oder -lt Vergleich funktioniert

[System.Version]"2.7.0.19530" -gt [System.Version]"3.0.0.4080"  

grüße
bildschirmfoto 2025-06-11 um 11.22.56
em-pie
em-pie 11.06.2025 aktualisiert um 11:40:25 Uhr
Goto Top
@goodlie
er hast den String doch als Version "konvertiert": $v1 = [version](...)

Habe das mal mit dem null getestet:
$v1 = [version] "1.429.316.0"  
$v2 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updates2').AVSignatureVersion  

Write-Host "V1: $v1"  
Write-Host "V2: $v2"  

if($v1 -gt $v2){
    Write-Host "v1 gt then v2"  
} else {
    Write-Host "v1 not gt then v2"  
}

if($null -ne $v1) {Write-Host "V1: $v1 is not null"}  
if($null -ne $v2) {Write-Host "V2: $v1 is not null"}  

Ergebnis:
Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\Windows Defender\Signature Updates2' because it does not 
exist.
At C:\_scripts\Powershell\test.ps1:2 char:17
+ ... = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows D ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (HKLM:\SOFTWARE\...nature Updates2:String) [Get-ItemProperty], ItemNotFo 
   undException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
 
V1: 1.429.316.0
V2: 
v1 gt then v2
1: 1.429.316.0 is not null


Wenn du also diese Zeile
if ($v1 -gt $v2) {\\server\share\Defenderupdates\mpam-fe.exe}if ($v1 -gt $v2) {\\server\share\Defenderupdates\mpam-fe.exe
so abänderst:
if (($v1 -gt $v2) -and ($null -ne $v1) -and ($null -ne $v2)) {\\server\share\Defenderupdates\mpam-fe.exe}if ($v1 -gt $v2) {\\server\share\Defenderupdates\mpam-fe.exe
Sollte es zu dem Fehlerbild nicht mehr kommen - testen kann ich das hier natürlich nicht hinreichend valide...
DerWoWusste
DerWoWusste 11.06.2025 um 11:54:42 Uhr
Goto Top
Irgendwas sagt mir, dass Ihr das Problem nicht versteht. Vielleicht bin ich es auch.
Wenn ich das Skript interaktiv ausführe, so geht es immer.
Nur über den Taskplaner kommt es manchmal zu diesen unerklärlichen Aussetzern.

Auch wenn ich es so abändere, wird die mpam-fe.exe über den Taskplaner manchmal einfach nicht gestartet:
$v1 = [version](gci \\server\share\Defenderupdates\mpam-fe.exe).VersionInfo.FileVersion
$v2 = [version](Get-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows Defender\Signature Updates').AVSignatureVersion  
echo $v1 > $env:temp\v1.txt
echo $v2 > $env:temp\v2.txt
if ($v1 -gt $v2) {
	ni $env:temp\kannlosgehen.txt
	gci \\server\share\Defenderupdates\mpam-fe.exe >$env:temp\mpam_props.txt
	\\server\share\Defenderupdates\mpam-fe.exe}
Dabei werden brav alle 4 Tempdateien erzeugt und erhalten auch völlig korrekten Inhalt.

Es sieht mir nach einem unerklärlichen Bug im Taskplaner aus, der sich meist nach ein paar Tagen von alleine behebt.
Crusher79
Crusher79 11.06.2025 um 12:30:13 Uhr
Goto Top
Zitat von @godlie:

ich glaube du hast hier einen kleinen Denkfehler, dein Regestry Wert ist keine Nummer sondern ein String, von daher wird $1 -gr $2 nie wirklich funktioneren.

Hier wird ein VERSION Objekt erstellt. Wo die KeysMajor Minor Build Revision gefüllt werden.

IsPublic IsSerial Name                                     BaseType                                                                                                                                                            
-------- -------- ----                                     --------                                                                                                                                                            
True     True     Int32                                    System.ValueType 

Wenn wir das Objekt zerlegen und uns mal "Major" asnchauen so verbergen sich dahinter dann Integer Werte.

Damit ist es vergleichbar. [version] presst die Infos aus dem Filesystem und der Registry in dieses Format mit bis zu 4 Zahlen Werten.


Ich kann es reproduzieren, wen nich die Registry Abfrage manipuliere! Dann wäre $v2 kaputt - NULL. Damit wird dann der Vergleich immer wahr und er schreibt auch das Log immer.

@DerWoWusste ggf. wird auch Registry zeitweise nicht als Laufwerk dargestellt, wenn du das Script ausführst.

(Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates").AVSignatureVersion  

clipboard-image


HKLM ist ja ein "virt." Laufwerk. Schreib von daher mal den Pfad wie oben mit Registry::HKEY_LOCAL_MACHINE... aus.

Wenn du in der PowerShell

cd "HKLM:/"  

eingibst, so wechselt es von C:\ auf HKLM:\ Beachte den Prompt.


@DerWoWusste ggf. ist also die registry zur Laufzeit im Taskplaner ann TEILWEISE nicht sauber gemapped.

Der vollständige Pfade KÖNNTE hier helfen.

Ansonten kann man noch - wie @em-pie schon aufzeigte - Fehlerbehandlung weiter einbauen. Wenn es hier um das Filesytem geht, in das die Registry quasi gemapped ist:

Test-Path -Path "HKLM:/"  

Das könnte ich mir gut vorstellen. Dass zur Laufzeit irgendwann, spontan, weil in China ein Sack Reis umgekippt ist, genu das Laufwerk HLKM eben mal NICHT da ist.

Entweder du machst globale Fehlerbehandlung oder du baust was ein. So wie @em-pie es schrieb oder einen lustigen Test-Path.

Test-Path -Path "HKLM:/"  

Würde also ggf. auch verhindern dass der Wert NULL wird und das Script weiter läfut.

Registry::HKEY_LOCAL_MACHINE\SOFTWARE\ .....

Könnte dafür sorgen dass eben nicht über HKLM gegangen wird und die Werte trotzdem kommen.

Ich vermute sehr stark das zufällig und spontan "HLKM:/" nicht einghängt ist und es darum versagt.
godlie
godlie 11.06.2025 um 12:33:15 Uhr
Goto Top
@em-pie
@Crusher79

Danke für den Hinweis, ich hatte das [version] übersehen im ersten Post
Crusher79
Crusher79 11.06.2025 um 12:39:48 Uhr
Goto Top
Zitat von @DerWoWusste:

Irgendwas sagt mir, dass Ihr das Problem nicht versteht. Vielleicht bin ich es auch.
Wenn ich das Skript interaktiv ausführe, so geht es immer.
Nur über den Taskplaner kommt es manchmal zu diesen unerklärlichen Aussetzern.

Ja nee, ich hab noch mal nachgedacht!

NULL Fehler von oben würde heisse das IMMER die EXE ausgeführt wird. Dachte du meinst sowas. Dann wäre also in deinen Fall immer eine Installation angestoßen worden - auch wenn die Version nicht größer ist.

Was ist mit Get-ChildItem und der EXE. Überlege gerade ob die duch das Kommando noch blockiert ist und nicht ausgeführt wird.

Du könntest ein Start-Sleep davor setzen.
DerWoWusste
DerWoWusste 11.06.2025 um 12:40:05 Uhr
Goto Top
Update: es hat mit Versionsabfragen mal gar nichts zu tun.

Selbst wenn das Skript nur aus einer Zeile besteht:
\\server\share\defenderupdates\mpam-fe.exe

Schlägt es auf Rechnern hin und wieder fehl im Taskplaner, während es interaktiv (mit dem selben Benutzer, der im Task steht, nämlich "system" ausgeführt) IMMER läuft.
Crusher79
Crusher79 11.06.2025 um 12:40:37 Uhr
Goto Top
Zitat von @godlie:

@em-pie
@Crusher79

Danke für den Hinweis, ich hatte das [version] übersehen im ersten Post

Alles gut. Ich hab übersehen dass es scheinbar genau umgekehrt ist ^^

Mit meinen tollen Fehler sollte die EXE ja immer ausgeführt werden - Tut sie aber nicht. Soll sie aber ja scheinbar. Mist.
Crusher79
Crusher79 11.06.2025 um 12:49:20 Uhr
Goto Top
Zitat von @DerWoWusste:

Update: es hat mit Versionsabfragen mal gar nichts zu tun.

Selbst wenn das Skript nur aus einer Zeile besteht:
\\server\share\defenderupdates\mpam-fe.exe

Schlägt es auf Rechnern hin und wieder fehl im Taskplaner, während es interaktiv (mit dem selben Benutzer, der im Task steht, nämlich "system" ausgeführt) IMMER läuft.

Dann dürfte ja $LastExitCode nicht 0 sein - fehlerfrei.

Du könnest Start-Sleep nehemn, wenn der Code nicht 0 ist und es ein paar Sekunden später nochmal ausführen.

Wenn die Binary im Netz liegt ggf. kurzer Wischer und Übertragungsfehler. Holzhammer wäre es nochmal zu wiederholen.

try ... catch ... finally könnte man ggf. auch noch hernehmen. Kniffelig.
DerWoWusste
DerWoWusste 11.06.2025 aktualisiert um 12:54:56 Uhr
Goto Top
Ok, Task geändert von powershell.exe updatedefender.ps1 auf updatedefender.bat - es läuft.
[inhalt wie gesagt mittlerweile zum Test jeweils nur noch
\\server\share\defenderupdates\mpam-fe.exe]
Was macht die Powershell da nur? Ich schätze, die mpam-fe.exe ist da nicht unschuldig dran, da ich hier täglich netzwerkweit soviele Tasks ablaufen lasse und nichts sonst dieses Problem erzeugt.

Ich werde jetzt diesen Versionsvergleich in Batch nachbauen.
Crusher79
Crusher79 11.06.2025 um 13:06:18 Uhr
Goto Top
powershell.exe -noprofile -executionpolicy bypass -file .\script.ps1

Wie hast du denn die Shell und das Script aufgerufen? Ggf. hätte man da noch was rausholen können.
em-pie
em-pie 11.06.2025 um 13:28:18 Uhr
Goto Top
Zitat von @DerWoWusste:

Update: es hat mit Versionsabfragen mal gar nichts zu tun.

Selbst wenn das Skript nur aus einer Zeile besteht:
\\server\share\defenderupdates\mpam-fe.exe

Schlägt es auf Rechnern hin und wieder fehl im Taskplaner, während es interaktiv (mit dem selben Benutzer, der im Task steht, nämlich "system" ausgeführt) IMMER läuft.

Vielleicht kommt die PS (partiell) nicht an den UNC-Pfad dran - oder wird geblockt!?
Hilft es, wenn du ein Start-Process() nutzt, um die mpam-fe.exe zu starten (auch wenn du gerade auf batch schwenkst)?
Und was passiert, wenn du in der Powershell noch ein Push-Location() davor setzt:
...
Push-Location -Path ...
Start-Process -FilePath ...
DerWoWusste
DerWoWusste 11.06.2025, aktualisiert am 12.06.2025 um 13:05:07 Uhr
Goto Top
Ja, man "könnte" sicher vieles.
Wie gesagt, ich fackele mit Tasks sehr viel ab und nie, nie hatte ich so einen Schwachfug zuvor.
Die mpam-fe.exe ist ja schon seit Jahrzehnten bei MS im Einsatz - vielleicht ist das einfach buggy code, der unter PS im Taskplaner mitunter spackt, während er unter cmd im Taskplaner nie spackt.
emeriks
emeriks 13.06.2025 um 17:07:08 Uhr
Goto Top
Ich würde im PS1 den Programmpfad in "" setzen, weil da ein "-" im Namen ist, was sonst auch als Operator zum Einsatz kommt. Zwar würde das nicht erklären, warum es mal geht und mal nicht, aber es wäre ein Ansatz.

Weiterhin würde ich wissen wollen, ob es ggf. daran liegt, dass die EXE zeitweise - warum auch immer - nicht verfügbar ist. Das könnte man mit einem "If(Test-Path "...") {"schreibe ins Log"} abfackeln.

Ebenso könnte man die EXE mittels "Start-Process" starten, was u.U. "bessere" Fehlermeldungen bringt.
DerWoWusste
DerWoWusste 13.06.2025 um 19:51:59 Uhr
Goto Top
Es hat sich bestätigt: ausgeführt in Batch gelingt es immer. Was auch immer mit dieser exe ist, die Kombination von Aufruf aus dem Taskplaner gelingt nur über Batch zuverlässig... Bei Powershell eher "meistens" oft aber auch nicht, manchmal wie "festgefressen" (mehrere erfolglose Starts hintereinander).

Definitiv ein Bug, der mir bislang nur bei dieser einen exe begegnet ist, kein Skriptproblem.