Hapus file yang lebih lama dari 15 hari menggunakan PowerShell

186

Saya ingin menghapus hanya file yang dibuat lebih dari 15 hari yang lalu di folder tertentu. Bagaimana saya bisa melakukan ini menggunakan PowerShell?

pengguna2470170
sumber
5
Sebagian besar jawaban menggunakan CreationTime namun akan direset ketika file disalin sehingga Anda mungkin tidak mendapatkan hasil yang Anda inginkan. LastWriteTime adalah yang berhubungan dengan "Tanggal Dimodifikasi" di Windows Explorer.
Roland Schaer

Jawaban:

308

Jawaban yang diberikan hanya akan menghapus file (yang memang merupakan apa yang ada dalam judul posting ini), tetapi di sini ada beberapa kode yang pertama-tama akan menghapus semua file yang lebih lama dari 15 hari, dan kemudian secara rekursif menghapus direktori kosong yang mungkin tersisa. dibelakang. Kode saya juga menggunakan -Forceopsi untuk menghapus file yang tersembunyi dan hanya-baca juga. Juga, saya memilih untuk tidak menggunakan alias sebagai OP baru untuk PowerShell dan mungkin tidak mengerti apa gci, ?, %, dll.

$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

Dan tentu saja jika Anda ingin melihat file / folder apa yang akan dihapus sebelum benar-benar menghapusnya, Anda bisa menambahkan -WhatIfsakelar ke Remove-Itempanggilan cmdlet di akhir kedua baris.

Kode yang ditampilkan di sini kompatibel dengan PowerShell v2.0, tetapi saya juga menunjukkan kode ini dan kode PowerShell v3.0 yang lebih cepat sebagai fungsi berguna yang dapat digunakan kembali di blog saya .

deadlydog
sumber
22
Terima kasih karena tidak menggunakan alias. Untuk seseorang yang baru mengenal PowerShell dan menemukan posting ini melalui pencarian Google, saya menganggap jawaban Anda sebagai yang terbaik.
Geoff Dawdy
1
Saya mencoba saran @ deadlydog dan tidak masalah jika saya menentukan -15 atau -35 dengan tanggal pembuatan file yang bervariasi selama beberapa bulan (atau baru-baru ini), itu menghapus seluruh isi direktori.
Michele
6
Jika file-file mungkin sedang digunakan, ada baiknya menambahkan "-ErrorAction SilentlyContinue" ke perintah RemoveItem.
Kevin Owen
17
Terima kasih! Saya menggunakan $ _. LastwriteTime, bukan $ _. CreationTime
Lauri Lubi
2
Perintah kedua dalam skrip itu selalu mendapat kesalahan yang Get-ChildItem tidak dapat menemukan bagian dari jalan. Itu mendapat direktori tidak ditemukan pengecualian. Namun menghapus folder kosong tanpa masalah. Tidak yakin mengapa ini mendapatkan kesalahan meskipun berfungsi.
Nathan McKaskle
51

cukup sederhananya (PowerShell V5)

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

Cara lain adalah dengan mengurangi 15 hari dari tanggal saat ini dan membandingkannya CreationTimedengan nilai itu:

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

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

Pada dasarnya, Anda beralih pada file di bawah jalur yang diberikan, kurangi CreationTimesetiap file yang ditemukan dari waktu saat ini, dan bandingkan dengan Daysproperti hasil. The -WhatIfswitch akan memberitahu Anda apa yang akan terjadi tanpa benar-benar menghapus file (file mana yang akan dihapus), menghapus saklar untuk benar-benar menghapus file:

$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
sumber
8

Coba ini:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force
Roland Jansen
sumber
Saya percaya yang terakhir -recurseterlalu banyak, bukan? Daftar dir adalah secara rekursif, penghapusan item tidak boleh termasuk anak-anak, kan?
Joost
Jika direktori yang sedang Anda kerjakan adalah dua direktori yang dalam, rekursi kedua diperlukan.
Bryan S.
5

Skrip Esperento57 tidak berfungsi di versi PowerShell yang lebih lama. Contoh ini tidak:

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
sumber
1
Saya telah memperbarui jawaban saya untuk mengecualikan direktori sekarang, terima kasih.
KERR
3

Alternatif lain (15. diketik ke [rentang waktu] secara otomatis):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose
js2010
sumber
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

Ini akan menghapus folder lama dan isinya.

Aigar
sumber
0

Jika Anda mengalami masalah dengan contoh di atas pada kotak Windows 10, coba ganti .CreationTimedengan .LastwriteTime. Ini berhasil untuk saya.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force
Jeff Blumenthal
sumber
LastwriteTimetidak sama dengan CreationTime, LastwriteTimediperbarui setiap kali file diubah.
MisterSmith
-1
#----- 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
sumber
Juga, itu tidak akan pernah mencapai yang lain pernyataan, karena jika $Filesini kosong itu tidak akan masuk foreach pernyataan. Anda harus menempatkan foreach dalam pernyataan if .
Dieter
@mati sebenarnya bisa mencapai pernyataan lain. Kami memiliki loop yang mirip berdasarkan pada daftar file dan itu secara teratur memasuki loop untuk dengan variabel $ File sebagai null
BeowulfNode42
Saya kira begitu-baru saja menemukan skrip yang sama di sini; networknet.nl/apps/wp/published/…
Shawson