PowerShell script för radering av filer

Permalänk
Medlem

PowerShell script för radering av filer

Hej!

Jag har en Windows dator som server till mina övervakningskameror hemma. Jag vill skapa ett script som automatiskt raderar filer när disken är till 80% full. Den ska då radera filer som är mer än 5 dagar gamla.

Då min kunskap inom script är nära noll så tog jag hjälp av ChatGPT, men jag får inte det att fungera.

Scriptet ser ut såhär

# Konfigurera variabler $drive = "C" # Enhet att övervaka (t.ex. C:, D:) $threshold = 80 # Procentsats som aktiverar filradering $path = "C:\ContaCam\2024" # Mappen att rensa $filter = "*.*" # Filtyp att ta bort (t.ex. *.tmp eller *.* för alla filer) $daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort # Kontrollera enhetens fyllnadsgrad $driveInfo = Get-PSDrive -Name $drive $currentUsage = ($driveInfo.Used / $driveInfo.Maximum) * 100 # Om fyllnadsgraden överskrider tröskelvärdet if ($currentUsage -ge $threshold) { Write-Output "Hårddisken är $([math]::Round($currentUsage, 2))% full. Rensning startar." # Hämta och ta bort filer äldre än $daysOld dagar Get-ChildItem -Path $path -Filter $filter -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } | Remove-Item -Force -Recurse Write-Output "Rensning klar." } else { Write-Output "Hårddisken är $([math]::Round($currentUsage, 2))% full. Ingen åtgärd krävs." }

Felet ligger i $driveInfo.Maximum, som verkar ge ett värde på 0, Får error att jag försöker dela med noll.

Några tips?

Permalänk
Medlem

Om man bara kör "Get-PSDrive -Name C" för att testa så verkar bara Used och Free finnas med, så kanske kan du anpassa scriptet för att använda Free-propertyn istället?

Permalänk
Medlem
Skrivet av Kega:

Hej!

Jag har en Windows dator som server till mina övervakningskameror hemma. Jag vill skapa ett script som automatiskt raderar filer när disken är till 80% full. Den ska då radera filer som är mer än 5 dagar gamla.

Då min kunskap inom script är nära noll så tog jag hjälp av ChatGPT, men jag får inte det att fungera.

Scriptet ser ut såhär

# Konfigurera variabler $drive = "C" # Enhet att övervaka (t.ex. C:, D:) $threshold = 80 # Procentsats som aktiverar filradering $path = "C:\ContaCam\2024" # Mappen att rensa $filter = "*.*" # Filtyp att ta bort (t.ex. *.tmp eller *.* för alla filer) $daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort # Kontrollera enhetens fyllnadsgrad $driveInfo = Get-PSDrive -Name $drive $currentUsage = ($driveInfo.Used / $driveInfo.Maximum) * 100 # Om fyllnadsgraden överskrider tröskelvärdet if ($currentUsage -ge $threshold) { Write-Output "Hårddisken är $([math]::Round($currentUsage, 2))% full. Rensning startar." # Hämta och ta bort filer äldre än $daysOld dagar Get-ChildItem -Path $path -Filter $filter -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } | Remove-Item -Force -Recurse Write-Output "Rensning klar." } else { Write-Output "Hårddisken är $([math]::Round($currentUsage, 2))% full. Ingen åtgärd krävs." }

Felet ligger i $driveInfo.Maximum, som verkar ge ett värde på 0, Får error att jag försöker dela med noll.

Några tips?

Ser väl inte ut som att providern rapporterar maxsize, därav division med noll.

https://learn.microsoft.com/en-us/dotnet/api/system.managemen...

When supported by provider this specifies a maximum drive size.

quick n dirty.

$drive = "C" $driveInfo = Get-PSDrive -Name $drive $diskMaxSize = ($driveInfo.Used + $driveInfo.Free) # Beräkna maximal storlek på disk $currentUsage = ($driveInfo.Used / $diskMaxSize) * 100 # Procent som används

Visa signatur

Gaming: Asus 3080 Ti + 5900X
Proxmox: Ett gäng Intel NUC Gen 8:or
Rojter: UCG-Ultra, WAN 1000/1000

Permalänk
Medlem

Tack för svaren, var det jag misstänkte när jag googlade lite igår, att $driveInfo.Maximum inte ger något värde.

Ska testa vidare när jag kommer hem ikväll.

Permalänk
Medlem

$Driveinfo.maximum rapporteras inte,
Prova att vända på det hela som nedan, leta efter ledigt utrymme istället.
Alltså det får inte vara mindre än 20% ledigt, om det är mindre än 20% ledigt då startar raderingen.
(Tror det fungerar nedan det lilla jag testade.)

FET markerar det jag ändrade i ditt skript.

# Konfigurera variabler
$drive = "C" # Enhet att övervaka (t.ex. C:, D:)
$threshold = 20 # Procentsats som aktiverar filradering
$path = "C:\ContaCam\2024" # Mappen att rensa
$filter = "*.*" # Filtyp att ta bort (t.ex. *.tmp eller *.* för alla filer)
$daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort

# Kontrollera enhetens fyllnadsgrad
$driveInfo = Get-PSDrive -Name $drive
$currentUsage = ($driveInfo.Used / $driveInfo.Free) * 100

# Om fyllnadsgraden överskrider tröskelvärdet
if ($currentUsage -lt $threshold) {
Write-Output "Hårddisken har $([math]::Round($currentUsage, 2))% ledigt. Rensning startar."

# Hämta och ta bort filer äldre än $daysOld dagar
Get-ChildItem -Path $path -Filter $filter -Recurse | Where-Object {
$_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld)
} | Remove-Item -Force -Recurse

Write-Output "Rensning klar."
} else {
Write-Output "Hårddisken har $([math]::Round($currentUsage, 2))% ledigt. Ingen åtgärd krävs."
}

Länken nedan ger en fingervisning och det finns ingen exakt siffra men klart värt att tänka på för maximal stabilitet.

"Solid-state drives
The free space recommendation for an SSD is higher than HDDs. The empty blocks on the solid-state drive used by the computer to write data. When all available space used, it takes longer for the programs to find partially empty blocks. An SSD will become slow and its write performance will decrease as it gets filled up. So, to avoid this issue, it is best to keep at least 25% free space. When the space in your SSD starts exhausting, it becomes difficult for the drive to write the new data to the partially filled blocks because that would delete the existing data. So, to write the data, the drive would need to read the value of the block into its cache. The SSD will then modify the value with the new data to write a file. All this will take a lot of time.

It is noteworthy here that the latest operating systems have the TRIM feature. Once you delete a file, this feature will automatically delete that file’s data from your SSD. The TRIM feature empties the block so that new data can written to the empty block. However, if you use the entire available space before deleting extra files, you may have several partially filled blocks.

The TRIM command doesn’t perform any cleanup and it can’t even consolidate the partially filled blocks into full blocks. So, make sure to avoid filling your SSD before deleting files because that would create partially filled blocks and SSD’s performance will degrade. Some SSD manufacturers reserve about 7% of their total flash storage which is unavailable to the user. The purpose of this “overprovisioning” is to prevent consumers from filling up their SSD. However, whether your SSD has this feature or not, make sure to avoid using more than 75% of your SSD’s capacity.
Read more: https://platinumdatarecovery.com/blog/fill-up-full-capacity © PlatinumDataRecovery.com
"

Tips för maximal stabilitet
Visa signatur

Life is short, make the best of it

Permalänk
Medlem

Tack för hjälpen! Testade ditt script och det fungerade.

Edit: Har uppenbarligen lite knas med %.

PS C:\ContaCam> C:\ContaCam\autodelete2.ps1 Hårddisken har 24.85% ledigt. Ingen åtgärd krävs. PS C:\ContaCam> C:\ContaCam\autodelete2.ps1 Hårddisken har 24.86% ledigt. Rensning startar. Rensning klar.

# Konfigurera variabler $drive = "C" # Enhet att övervaka (t.ex. C:, D:) $threshold = 30 # Procentsats som aktiverar filradering $path = "C:\ContaCam\Altan\2024" # Mappen att rensa $filter = "*.*" # Filtyp att ta bort (t.ex. *.tmp eller *.* för alla filer) $daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort # Kontrollera enhetens fyllnadsgrad $driveInfo = Get-PSDrive -Name $drive $currentUsage = ($driveInfo.Used / $driveInfo.Free) * 100 # Om fyllnadsgraden överskrider tröskelvärdet if ($currentUsage -lt $threshold) { Write-Output "Hårddisken har $([math]::Round($currentUsage, 2))% ledigt. Rensning startar." # Hämta och ta bort filer äldre än $daysOld dagar Get-ChildItem -Path $path -Filter $filter -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } | Remove-Item -Force -Recurse Write-Output "Rensning klar." } else { Write-Output "Hårddisken har $([math]::Round($currentUsage, 2))% ledigt. Ingen åtgärd krävs." }

Är det nånting jag missat?

En sak till, hur lägger jag till fler mappar att rensa?

Permalänk
Medlem

Just nu har du 30% som threshold?

Det borde vara

$currentFree = ($driveInfo.Free / ($driveInfo.Free+$driveInfo.Used)) * 100

$currentUsage hade krävts att du jämför med 80% istället.

Permalänk
Medlem

Nu verkar fungerar det som tänkt, tack för all input, ChatGPT var inte klockren på detta märkte jag.
Blev en del googlande men såhär ser det ut nu, med loggfil och allt:

Edit: Väntar på att disken ska fyllas upp så jag verkligen ser att det funkar

# Konfigurera variabler $drive = "C" # Enhet att övervaka $threshold = 30 # Procentsats som aktiverar filradering # Lista med mappar att rensa $folders = @( "C:\ContaCam\Altan\2024", "C:\ContaCam\Framsidan\2024", "C:\ContaCam\Baksidan\2024", "C:\ContaCam\Sidan\2024", "C:\ContaCam\Verkstad\2024" ) $filter = "*.*" # Filtyp att ta bort $daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort $logFile = "C:\ContaCam\CleanupLog.txt" # Loggfil # Kontrollera enhetens fyllnadsgrad function Get-FreeSpacePercentage { param([string]$drive) $driveInfo = Get-PSDrive -Name $drive -ErrorAction SilentlyContinue if ($null -eq $driveInfo) { throw "Enheten '$drive' hittades inte. Kontrollera enhetsnamnet." } return ($driveInfo.Free / ($driveInfo.Free + $driveInfo.Used)) * 100 } # Funktion för att logga function Write-Log { param([string]$message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content -Path $logFile -Value "$timestamp - $message" } # Kontrollera om mapp existerar function Validate-Folder { param([string]$folderPath) if (-Not (Test-Path -Path $folderPath)) { Write-Log "Varning: Mappen '$folderPath' existerar inte. Hoppar över." return $false } return $true } # Start av scriptet Write-Log "Diskrensningsscript startat." try { $currentFree = Get-FreeSpacePercentage -drive $drive if ($currentFree -lt $threshold) { Write-Log "Hårddisken har $([math]::Round($currentFree, 2))% ledigt. Rensning startar." foreach ($folder in $folders) { if (-Not (Validate-Folder -folderPath $folder)) { continue } Write-Log "Rensar mapp: $folder" # Hämta filer att ta bort $filesToDelete = Get-ChildItem -Path $folder -Filter $filter -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } if ($filesToDelete.Count -gt 0) { Write-Log "Antal filer att rensa i ${folder}: $($filesToDelete.Count)." foreach ($file in $filesToDelete) { try { Remove-Item -Path $file.FullName -Force -Recurse Write-Log "Raderade fil: $($file.FullName)" } catch { Write-Log "Kunde inte radera fil: $($file.FullName). Fel: $($_.Exception.Message)" } } } else { Write-Log "Inga filer att rensa i $folder." } } Write-Log "Rensning klar." } else { Write-Log "Hårddisken har $([math]::Round($currentFree, 2))% ledigt. Ingen åtgärd krävs." } } catch { Write-Log "Ett fel inträffade: $($_.Exception.Message)" } Write-Log "Diskrensningsscript avslutat."

Permalänk
Medlem
Skrivet av Kega:

Nu verkar fungerar det som tänkt, tack för all input, ChatGPT var inte klockren på detta märkte jag.
Blev en del googlande men såhär ser det ut nu, med loggfil och allt:

Edit: Väntar på att disken ska fyllas upp så jag verkligen ser att det funkar

# Konfigurera variabler $drive = "C" # Enhet att övervaka $threshold = 30 # Procentsats som aktiverar filradering # Lista med mappar att rensa $folders = @( "C:\ContaCam\Altan\2024", "C:\ContaCam\Framsidan\2024", "C:\ContaCam\Baksidan\2024", "C:\ContaCam\Sidan\2024", "C:\ContaCam\Verkstad\2024" ) $filter = "*.*" # Filtyp att ta bort $daysOld = 5 # Filer äldre än detta antal dagar kommer att tas bort $logFile = "C:\ContaCam\CleanupLog.txt" # Loggfil # Kontrollera enhetens fyllnadsgrad function Get-FreeSpacePercentage { param([string]$drive) $driveInfo = Get-PSDrive -Name $drive -ErrorAction SilentlyContinue if ($null -eq $driveInfo) { throw "Enheten '$drive' hittades inte. Kontrollera enhetsnamnet." } return ($driveInfo.Free / ($driveInfo.Free + $driveInfo.Used)) * 100 } # Funktion för att logga function Write-Log { param([string]$message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content -Path $logFile -Value "$timestamp - $message" } # Kontrollera om mapp existerar function Validate-Folder { param([string]$folderPath) if (-Not (Test-Path -Path $folderPath)) { Write-Log "Varning: Mappen '$folderPath' existerar inte. Hoppar över." return $false } return $true } # Start av scriptet Write-Log "Diskrensningsscript startat." try { $currentFree = Get-FreeSpacePercentage -drive $drive if ($currentFree -lt $threshold) { Write-Log "Hårddisken har $([math]::Round($currentFree, 2))% ledigt. Rensning startar." foreach ($folder in $folders) { if (-Not (Validate-Folder -folderPath $folder)) { continue } Write-Log "Rensar mapp: $folder" # Hämta filer att ta bort $filesToDelete = Get-ChildItem -Path $folder -Filter $filter -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } if ($filesToDelete.Count -gt 0) { Write-Log "Antal filer att rensa i ${folder}: $($filesToDelete.Count)." foreach ($file in $filesToDelete) { try { Remove-Item -Path $file.FullName -Force -Recurse Write-Log "Raderade fil: $($file.FullName)" } catch { Write-Log "Kunde inte radera fil: $($file.FullName). Fel: $($_.Exception.Message)" } } } else { Write-Log "Inga filer att rensa i $folder." } } Write-Log "Rensning klar." } else { Write-Log "Hårddisken har $([math]::Round($currentFree, 2))% ledigt. Ingen åtgärd krävs." } } catch { Write-Log "Ett fel inträffade: $($_.Exception.Message)" } Write-Log "Diskrensningsscript avslutat."

Snyggt! Det där borde fungera som tänkt.
//freeAppz

Visa signatur

Life is short, make the best of it

Permalänk
Medlem

Ser att det redan var löst men ett tips är att lära sig pipes i PS.

Löses enklast såhär:

$Size = Get-Volume -DriveLetter C | Select Size $Size

Visa signatur

[IT-Dept]
Ryzen 5700x - 32 - 1070