Skrypt programu PowerShell do rekursywnego usuwania
Sep 21 2020
Zacząłem nową pracę i prawie natychmiast zostałem wpuszczony, aby zrobić trochę Powershell, jednak kiedykolwiek korzystałem z Powershell tylko w Exchange i bardzo prostym.
W ciągu następnych kilku miesięcy będę się więcej uczył, ale na razie potrzebuję skryptu, który przejdzie do dowolnego folderu, będzie sprawdzał rekurencyjnie każdy folder i podfolder, usuwając wszystkie pliki starsze niż 2 dni.
Czy ktoś może w tym pomóc nowicjuszowi?
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
Odpowiedzi
SimonS Sep 21 2020 at 18:51
Myślę, że nie byłeś daleko, ale oto trzy rzeczy, które zrobiłbym inaczej:
- Pobierz wszystkie pliki za pomocą jednego polecenia, używając
-RecurseprzełącznikaGet-ChildItem, zamiast przeskakiwać z folderu do folderu tylko po to, aby pobrać pliki do środka - Zamiast tworzyć flagi dla wiadomości e-mail, zbierz informacje, które chcesz wysłać podczas procesu usuwania, zapisz je w tablicy, a następnie wyślij e-mail raz
- Zamiast sprawdzać, czy plik, który chcesz usunąć, nie jest folderem, użyj
-FileparametruGet-ChildItem
Użyłbym go również jako skryptu, a nie a Function, ale to twoja wezwanie:
$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
}