diemilz
Goto Top

Powershell - Befehlsausgabe in Variable speichern

Hallo zusammen,

ich habe hier ein PowerShell-Skript, welches mir auf unserem Exchange-Server (Windows Server 2012 R2, Exchange 2016 CU9) Log-Dateien mit einer bestimmten Endung löschen soll, wenn diese älter als 7 Tage sind.

Set-Executionpolicy RemoteSigned
$days=7
$IISLogPath="C:\inetpub\logs\LogFiles\"  
$IISLogPathAux="F:\Logs\"  
$ExchangeLoggingPath='C:\Program Files\Microsoft\Exchange Server\V15\Logging\'  
$ETLLoggingPath="C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\ETLTraces\"  
$ETLLoggingPath2="C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\Logs\"  
$IISHTTPErrLoggingPath="C:\Windows\System32\LogFiles\HTTPERR\"  

Function CleanLogfiles($TargetFolder)
{
    if (Test-Path $TargetFolder) {
        $Now = Get-Date
        $LastWrite = $Now.AddDays(-$days)
        $Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}  
        foreach ($File in $Files)
            {
                Write-Host "Deleting file $File" -ForegroundColor "white"  
                Remove-Item $File -ErrorAction SilentlyContinue | out-null
        }
    }
Else {
    Write-Host "The folder $TargetFolder doesn't exist! Check the folder path!" -ForegroundColor "white"  
    }
}
CleanLogfiles($IISLogPath)
CleanLogfiles($IISLogPathAux)
CleanLogfiles($ExchangeLoggingPath)
CleanLogfiles($ETLLoggingPath)
CleanLogfiles($ETLLoggingPath2)
CleanLogfiles($IISHTTPErrLoggingPath)

Knackpunkt ist die Zeile "$Files = Get-ChildItem.......". Ab dieser Stelle produziert das Skript einen Fehler, dass es nicht den Inhalt auslesen kann (Permission denied). Führe ich den Befehl jedoch über die Shell direkt aus, ohne den Inhalt in eine Variable zu speichern, dann klappt alles.

Dieses Skript ging bis letzte Woche noch und wir haben kein Update eingespielt oder sonst irgendeine Anpassung am System vorgenommen.

Wo habe ich hier den Denkfehler? Ich sehe den Wald vor lauter Bäumen nicht.

Vielen Dank schonmal im Vorraus.

Stephan

Content-ID: 383236

Url: https://administrator.de/contentid/383236

Ausgedruckt am: 05.11.2024 um 17:11 Uhr

MarkBeaker
MarkBeaker 13.08.2018 um 15:07:19 Uhr
Goto Top
Hallo Stephan,

ich habe den Code mal schnell etwas zusammengekürzt, was aber an der Funktion nichts ändern sollte.
Soweit ich das sehe, hast du mal keinen Fehler im Code:

Set-Executionpolicy RemoteSigned
$days=7
$IISLogPath="E:\temp\log\"  

Function CleanLogfiles($TargetFolder)
{
    if (Test-Path $TargetFolder) {
        $Now = Get-Date
        $LastWrite = $Now.AddDays(-$days)
        $Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}  
        foreach ($File in $Files)
            {
                Write-Host "Deleting file $File" -ForegroundColor "white"  
                Remove-Item $File -ErrorAction SilentlyContinue | out-null
        }
    }
Else {
    Write-Host "The folder $TargetFolder doesn't exist! Check the folder path!" -ForegroundColor "white"  
    }
}
CleanLogfiles($IISLogPath)

Kann es sein, dass du zwar über die Shell auf einen Pfad zugreifen kannst ,sprich rechte hast (als Admin?) und dann wenn du das Script so startest nicht hast?
Vielleicht versucht du mal Ordner für Ordner durch.
Bei mir macht es am Client mal keinen Unterschied, ob du es über die Shell oder so ausführst.

Grüße
Christian
emeriks
emeriks 13.08.2018 um 19:58:55 Uhr
Goto Top
Hi,
spontan fällt mir auf
$_.LastWriteTime -le "$LastWrite"
Sollte das nicht einfach lauten ..?
$_.LastWriteTime -le $LastWrite

Aber zur Frage:
Du willst uns sagen, wenn Du
$Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}  
kommt ein Fehler, aber wenn Du
Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}  
dann kommt keiner?

Reden wir von Scheduled Task?
Falls ja:
Permission denied
suggeriert mir, dass Du den Task "mit höchsten Privilegien" laufen lassen musst?

E.
diemilz
diemilz 14.08.2018 um 09:42:34 Uhr
Goto Top
Hi,

die Anführungszeichen waren mal zu Testzwecken drin, ich habe vergessen, die rauszunehmen. Es funktioniert aber in beide Richtungen, also mit und ohne.

Richtig, der Fehler kommt nur, wenn ich die Ausgabe des Befehls in eine Variable speichern möchte. Führe ich den Befehl direkt auf der PowerShell aus (privilegiert), kommt der Fehler nicht. Das Skript ist bereits als Scheduled Task mit höchsten Privilegien hinterlegt. Gibt es irgendwo in der Powershell neben den Execution-Policies (RemoteSigned, Skript ist lokal) noch weitere Policies, die ich bislang nicht kenne?

Wenn ich das Skript über eine privilegierte Shell direkt starte, taucht der Fehler auch auf. Der ausführende Benutzer hat volle Lese- und Schreibrechte auf die Ordner.

Grüße

Stephan
emeriks
emeriks 14.08.2018 um 09:50:28 Uhr
Goto Top
Gut, dass ich gefragt habe. Denn Deine Aussage sind immer noch etwas "wirr", sorry.

Ich verstehe immer noch nicht, warum Du schreibst
Führe ich den Befehl direkt auf der PowerShell aus
Wie machst Du das denn anders ("indirekt"?), wenn Du
die Ausgabe des Befehls in eine Variable speichern
?

Wenn ich das Skript über eine privilegierte Shell direkt starte, taucht der Fehler auch auf.
Na dann brauchen wir also nicht mehr über den Scheduled Task zu reden. Das wäre geklärt.

Also mal klare Frage-Antwort:
Was kommt, wenn Du ohne Skript direkt auf der Kommandozeile eingibst: ?
$Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le $LastWrite}
diemilz
diemilz 14.08.2018 um 10:02:56 Uhr
Goto Top
Also, ich versuche es nochmal deutlicher zu erklären:

Wenn ich den Befehl
$Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le $LastWrite}
auf der Kommandozeile ausgebe, dann gibt es die o.g. Fehlermeldung "Permission denied".

Wenn ich den Befehl
Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le $LastWrite}
auf der Kommandozeile eingebe, dann gibt es keine Fehlermeldung und ich erhalte ganz normal die Ausgabe.

Wenn ich das Skript in einer privilegierten PowerShell starte, kommt ebenfalls die Fehlermeldung.
emeriks
Lösung emeriks 14.08.2018 um 10:47:48 Uhr
Goto Top
OK, danke.
Habe jetzt auch keine Idee mehr ...
Klammern?
$Files = (Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse | Where {$_.LastWriteTime -le LastWrite})
Und wenn nur...?
$Files = Get-ChildItem $TargetFolder -Include *.log, *.etl, *.blg, *.txt, *.LOG, *.ETL, *.BLG, *.TXT -Recurse
diemilz
diemilz 14.08.2018 um 10:54:28 Uhr
Goto Top
Ok, das mit den Klammern hat schonmal funktioniert, jetzt läuft das Skript wieder normal durch.

Stellt sich mir jetzt nur noch die Frage, wieso das Skript vorher auch ohne lief. Kein Update installiert, keine Einstellung angepasst.............. Ich verstehs nicht.