Powershell-Skript zum rekursiven Löschen
Sep 21 2020
Ich habe einen neuen Job angefangen und bin fast sofort zu Powershell gekommen, aber ich habe Powershell nur in Exchange verwendet und das ist sehr einfach.
Ich werde in den nächsten Monaten mehr lernen, aber im Moment brauche ich ein Skript, das in einen beliebigen Ordner wechselt, jeden Ordner und Unterordner rekursiv überprüft und alle Dateien löscht, die älter als 2 Tage sind.
Kann jemand bitte einem Neuling dabei helfen? '
Function DelFiles($RootFolder,[ref]$blnDeleteErrmsgSent){
$blnDeleteErrmsgSent = $false
$date = Get-Date $Folders = Dir
$FolderPath = "path" $PSEmailServer = "servername"
# Delete Old Files
Cd $RootFolder foreach($folder in $Folders){ Cd $Folder.FullName
$ToDelete = Dir -Attributes !readonly |Where {$_.lastwritetime -lt ((Get-Date).Adddays(-2))}
foreach($File in $ToDelete){
try{
if($file.Attributes -notcontains "Directory"){ Remove-Item -Path $File.FullName -Force -ErrorAction Stop}
}catch{
# Only Send e-mail alert if we haven't already done so i.e. only once
if(!($blnDeleteErrmsgSent.value)){ $errordescription=$_ $errorline=$_.InvocationInfo.Line.ToString() # Capture Error Information # Notify IT that this script has encountered an error Send-MailMessage -From "ScanDeletion@****.co.uk" -To "IT@****.co.uk" -Subject "errored while deleting old scan files" -Body ("The error occured at " + [string]$date +"`n Error:"+ $errordescription +"`n Line:"+ $errorline)
# Set Flag to True so we don't send multiple e-mail alerts for file deletion errors.
$blnDeleteErrmsgSent.value = $true
}
}
}
}
}
# Call Archive Function (auto-recursive) to archive any xml files in Folder, and subfolders
DelFiles $FolderPath ([ref]$blnDeleteErrmsgSent)
Exit
Antworten
SimonS Sep 21 2020 at 18:51
Ich denke, Sie waren nicht wirklich weit weg, aber hier sind die drei Dinge, die ich anders machen würde:
- Holen Sie sich alle Dateien mit nur einem Befehl, indem Sie den
-RecurseSchalter von verwendenGet-ChildItem, anstatt von Ordner zu Ordner zu springen, nur um die Dateien darin abzurufen - Anstatt Flags für die E-Mail zu erstellen, sammeln Sie die Informationen, die Sie während des Löschvorgangs senden möchten, speichern Sie sie in einem Array und senden Sie die E-Mail einmal
- Verwenden Sie den
-FileParameter von, anstatt zu überprüfen, ob die zu löschende Datei kein Ordner istGet-ChildItem
Ich würde es auch als Skript verwenden, nicht als Function, aber das ist Ihr Aufruf:
$RootFolder = "C:\install\su1587308" $DeleteDate = (Get-Date).AddDays("-2")
$Fails = @() # Get all files below the rootfolder that are not ReadOnly: Get-ChildItem $RootFolder -Recurse -Attributes !ReadOnly -File |
Where-Object { $_.LastWriteTime -lt $DeleteDate } | ForEach-Object {
Try {
Remove-Item $_.FullName -Force -ErrorAction Stop } Catch { # if it fails to the delete, the fullname of the file is stored in a variable $Fails += $_.FullName } } # Only send an email if something failed: if ($Fails) {
$Body = "Could not delete the Following Files:<br>" +($Fails -join '<br>')
$Splat = @{ SmtpServer = "???" From = "ScanDeletion@****.co.uk" To = "IT@****.co.uk" Subject = "errored while deleting old scan files" Body = $Body
BodyAsHtml = $true
}
Send-MailMessage @Splat
}