Supprimer les fichiers de plus de 15 jours à l'aide de PowerShell

189

Je souhaite supprimer uniquement les fichiers créés il y a plus de 15 jours dans un dossier particulier. Comment pourrais-je faire cela en utilisant PowerShell?

user2470170
la source
6
La plupart des réponses utilisent CreationTime, mais il est réinitialisé lorsqu'un fichier est copié afin que vous n'obteniez pas les résultats souhaités. LastWriteTime correspond à la "Date de modification" dans l'Explorateur Windows.
Roland Schaer

Réponses:

313

Les réponses données ne supprimeront que les fichiers (ce qui est certes ce qui est dans le titre de cet article), mais voici un code qui supprimera d'abord tous les fichiers datant de plus de 15 jours, puis supprimera récursivement tous les répertoires vides qui pourraient avoir été laissés derrière. Mon code utilise également l' -Forceoption de supprimer les fichiers cachés et en lecture seule. , J'ai choisi aussi de ne pas utiliser les alias que l'OP est nouveau pour PowerShell et peut ne pas comprendre ce que gci, ?, %, etc. sont.

$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

Et bien sûr, si vous voulez voir quels fichiers / dossiers seront supprimés avant de les supprimer, vous pouvez simplement ajouter le -WhatIfcommutateur à l' Remove-Itemappel de l' applet de commande à la fin des deux lignes.

Le code présenté ici est compatible avec PowerShell v2.0, mais je montre également ce code et le code PowerShell v3.0 plus rapide en tant que fonctions réutilisables pratiques sur mon blog .

chien mortel
la source
23
Merci de ne pas utiliser d'alias. Pour quelqu'un qui est nouveau sur PowerShell et qui a trouvé ce message via une recherche Google, je considère que votre réponse est la meilleure.
Geoff Dawdy
1
J'ai essayé la suggestion de @ deadlydog et peu importe si je spécifie -15 ou -35 avec des dates de création de fichier variables remontant à des mois (ou récents), cela supprime tout le contenu du répertoire.
Michele
6
Si des fichiers sont en cours d'utilisation, il vaut également la peine d'ajouter "-ErrorAction SilentlyContinue" à la commande RemoveItem.
Kevin Owen
17
Merci! J'utilise $ _. LastwriteTime au lieu de $ _. CreationTime
Lauri Lubi
2
La deuxième commande de ce script obtient toujours une erreur indiquant que Get-ChildItem ne peut pas trouver une partie du chemin. Il obtient une exception de répertoire introuvable. Pourtant, il supprime les dossiers vides sans problème. Je ne sais pas pourquoi il obtient une erreur malgré le travail.
Nathan McKaskle
57

tout simplement (PowerShell V5)

Get-ChildItem "C:\temp" -Recurse -File | Where CreationTime -lt  (Get-Date).AddDays(-15)  | Remove-Item -Force
Esperento57
la source
16

Une autre méthode consiste à soustraire 15 jours de la date actuelle et à comparer CreationTimeavec cette valeur:

$root  = 'C:\root\folder'
$limit = (Get-Date).AddDays(-15)

Get-ChildItem $root -Recurse | ? {
  -not $_.PSIsContainer -and $_.CreationTime -lt $limit
} | Remove-Item
Ansgar Wiechers
la source
14

Fondamentalement, vous parcourez les fichiers sous le chemin donné, soustrayez la valeur CreationTimede chaque fichier trouvé de l'heure actuelle et comparez avec la Dayspropriété du résultat. Le -WhatIfcommutateur vous dira ce qui se passera sans supprimer réellement les fichiers (quels fichiers seront supprimés), supprimez le commutateur pour supprimer réellement les fichiers:

$old = 15
$now = Get-Date

Get-ChildItem $path -Recurse |
Where-Object {-not $_.PSIsContainer -and $now.Subtract($_.CreationTime).Days -gt $old } |
Remove-Item -WhatIf
Shay Levy
la source
Merci pour cela, en particulier avec le commutateur «WhatIf» pour les tests.
JoelAZ
8

Essaye ça:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force
Roland Jansen
la source
Je crois que le dernier en -recurseest un de trop, non? La liste des répertoires est récursive, la suppression de l'élément ne doit pas être incluse avec les enfants, non?
Joost
Si le répertoire avec lequel vous travaillez est composé de deux répertoires, une seconde -recurse est nécessaire.
Bryan S.
7

Le script d'Esperento57 ne fonctionne pas dans les anciennes versions de PowerShell. Cet exemple fait:

Get-ChildItem -Path "C:\temp" -Recurse -force -ErrorAction SilentlyContinue | where {($_.LastwriteTime -lt  (Get-Date).AddDays(-15) ) -and (! $_.PSIsContainer)} | select name| Remove-Item -Verbose -Force -Recurse -ErrorAction SilentlyContinue
KERR
la source
1
J'ai mis à jour ma réponse pour exclure les répertoires maintenant, merci.
KERR
3

Une autre alternative (15. est automatiquement tapé sur [timepan]):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose
js2010
la source
1
$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Recurse

Cela supprimera les anciens dossiers et son contenu.

Aigar
la source
0
#----- Define parameters -----#
#----- Get current date ----#
$Now = Get-Date
$Days = "15" #----- define amount of days ----#
$Targetfolder = "C:\Logs" #----- define folder where files are located ----#
$Extension = "*.log" #----- define extension ----#
$Lastwrite = $Now.AddDays(-$Days)

#----- Get files based on lastwrite filter and specified folder ---#
$Files = Get-Children $Targetfolder -include $Extension -Recurse | where {$_.LastwriteTime -le "$Lastwrite"}

foreach ($File in $Files)
{
    if ($File -ne $Null)
    {
        write-host "Deleting File $File" backgroundcolor "DarkRed"
        Remove-item $File.Fullname | out-null
    }
    else
        write-host "No more files to delete" -forgroundcolor "Green"
    }
}
Ikruzzz
la source
De plus, il n'atteindra jamais l' instruction else , car si elle $Filesest vide, elle n'entrera pas dans l' instruction foreach . Vous devez placer le foreach dans l' instruction if .
Dieter
@mati en fait, il peut atteindre l'instruction else. Nous avons une boucle for similaire basée sur une liste de fichiers et elle entre régulièrement dans la boucle for avec la variable $ File comme null
BeowulfNode42
Je suppose que si - je suis tombé sur le même script ici; networknet.nl/apps/wp/published/…
Shawson
0

Si vous rencontrez des problèmes avec les exemples ci-dessus sur une boîte Windows 10, essayez de remplacer .CreationTimepar .LastwriteTime. Cela a fonctionné pour moi.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force
Jeff Blumenthal
la source
LastwriteTimen'est pas la même chose que CreationTime, LastwriteTimeest mise à jour chaque fois que le fichier est modifié.
MisterSmith