PowerShell: Einschränkungen von ScriptBlock in Register-ObjectEvent - Windows-10, PowerShell, Automatisierung

Ich versuche, ein PowerShell-Skript zum Schreiben zu erstellenin eine Textdatei, wenn nach einer bestimmten Zeit keine neue Datei in einem Windows-Ordner erstellt wurde (C: Test). Als Grundlage verwende ich das gezeigte Skript Hier. Unten ist mein modifiziertes Skript.

Wie Sie sehen, habe ich eine IF-ELSE-Anweisung hinzugefügt, die überprüft, ob die letzte Dateierstellung länger als 10 Sekunden zurückliegt. Ich habe auch modifiziert $action um den aktuellen Zeitstempel zuzuweisen $lasttimefilecreated und zurücksetzen $logflag. Es scheint jedoch, dass $ action keines dieser beiden Dinge ausführt. Das Add-content "C:FileCreated.txt" Zeile wird erfolgreich ausgeführt und eine Datei wird erstellt, aber die Werte von $lasttimefilecreated und $logflag bleiben unverändert und werden nicht auf die Konsole gedruckt. Gibt es eine andere Möglichkeit, dies zu erreichen? Ich habe den Microsoft - Artikel im Internet gelesen Register-ObjectEvent-Objekt, konnte aber nicht herausfinden, warum der Skriptblock, den ich $ action zuordnete, nicht vollständig funktioniert. Schätze deine Hilfe!

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:Test"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true

### INITIALIZE VARIABLES
$lasttimefilecreated = $(Get-Date)
$logflag = 0
$action = { $lasttimefilecreated = $(Get-Date)
"$lasttimefilecreated"
$logflag = 0
"$logflag"
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
Add-content "C:FileCreated.txt" -value $logline
}

### DECIDE WHICH EVENTS SHOULD BE WATCHED + LOOP INDEFINITELY THROUGH IF-ELSE LOGIC
$created = Register-ObjectEvent $watcher "Created" -Action $action
while ($true) {
if ((New-TimeSpan -Start $lasttimefilecreated –End $(Get-Date)).Seconds -gt 10 -and $logflag -eq 0) {
$logflag = 1
Add-content "C:Log.txt" -value "$(Get-Date)"
"Log.txt file created/modified at $(Get-Date)"
}
else {sleep 5}}

Antworten:

2 fĂĽr Antwort â„– 1

Sie stoĂźen auf zwei verschiedene PowerShell-Ăśberraschungen.

Erstens: Scoping. Wenn Sie eine Variable in Ihrem Ereignishandler ändern, legen Sie nur eine neue Variable fest, die nur in diesem Block vorhanden ist. Wenn Sie dies als einfachen Testfall an der Konsole eingeben, erhalten Sie 1:

$a = 1; {$a = 2}.Invoke(); $a

Um anzugeben, dass Sie dem globalen Bereich zuweisen, mĂĽssen Sie voranstellen global: auf den Variablennamen. Dies wird gedruckt 2:

$a = 1; {$global:a = 2}.Invoke(); $a

Zweitens: Umleitung der Ereignisausgabe. Wenn Sie Ergebnisse von einem Ereignishandler erstellen, werden diese tatsächlich in einem Jobobjekt gespeichert. Verwenden Sie, um auf der Konsole zu drucken Write-Host statt (implizit) Write-Output. Beispielsweise:

Write-Host $lasttimefilecreated

Sie könnten in Betracht ziehen, einen Timer anstelle einer Schleife zu verwenden:

$timer = New-Object System.Timers.Timer
$timer.Interval = 5000
$timer.Enabled = $true
Register-ObjectEvent $timer "Elapsed" -Action {
If ($global:logflag -eq 0) {
$global:logflag = 1
Add-content "C:Log.txt" -value "$(Get-Date)"
Write-Host "Log.txt file created/modified at $(Get-Date)"
}
}
$timer.AutoReset = $true
$timer.Start()
while ($true) {Start-Sleep -Seconds 5}

Die letzte Schleife verhindert lediglich, dass das Skript beendet wird. Die Timer würden weiter laufen, wenn es aufhören würde, aber es sieht ein bisschen komisch aus.


0 fĂĽr Antwort â„– 2

Wenn Sie von ISE ausführen, bevor Sie den ersten speichernMal wird der Code ausgeführt, den Sie in das Skriptfenster eingegeben haben, als ob Sie ihn in die Befehlszeile eingegeben hätten und Sie können den Gültigkeitsbereich "$ script:" nicht verwenden, aber nach dem Speichern wird stattdessen die .ps1-Datei ausgeführt. und der Gültigkeitsbereich "$ script:" gilt innerhalb des Skripts (er ändert die Variablen in Ihrer ise-Sitzung nicht, ändert sie jedoch während der Ausführung des Skripts und aus der Sicht des Skripts, wenn man bedenkt, dass der globale Gültigkeitsbereich Der Gültigkeitsbereich, in dem das Skript gestartet wurde. Wenn Sie den Gültigkeitsbereich "$ global:" verwenden, wirkt sich dies auf das Skript und auch auf die Variablen in Ihrer ise-Sitzung aus (der globale Gültigkeitsbereich, von dem aus das Skript aufgerufen wurde) Für ein Skript spielt es also keine Rolle, welchen dieser Bereiche Sie verwenden, sondern für die Konsole, von der aus ein Skript aufgerufen wird.


Lies jetzt