ลบไฟล์ที่เก่ากว่า 15 วันโดยใช้ PowerShell


186

ฉันต้องการลบเฉพาะไฟล์ที่สร้างขึ้นกว่า 15 วันที่ผ่านมาในโฟลเดอร์เฉพาะ ฉันจะทำสิ่งนี้โดยใช้ PowerShell ได้อย่างไร


5
คำตอบส่วนใหญ่ใช้ CreationTime อย่างไรก็ตามจะได้รับการรีเซ็ตเมื่อไฟล์ถูกคัดลอกดังนั้นคุณอาจไม่ได้รับผลลัพธ์ที่คุณต้องการ LastWriteTime เป็นสิ่งที่สอดคล้องกับ "วันที่แก้ไข" ใน Windows Explorer
Roland Schaer

คำตอบ:


308

คำตอบที่ได้รับจะลบไฟล์เท่านั้น (ซึ่งเป็นที่ยอมรับกันว่าเป็นชื่อของโพสต์นี้) แต่นี่คือรหัสบางส่วนที่จะลบไฟล์ทั้งหมดที่เก่ากว่า 15 วันก่อนจากนั้นจึงลบไดเรกทอรีที่ว่างเปล่าซ้ำ ๆ หลัง รหัสของฉันยังใช้-Forceตัวเลือกในการลบไฟล์ที่ซ่อนและอ่านอย่างเดียวด้วย นอกจากนี้ผมเลือกที่จะไม่ใช้นามแฝงเป็น OP เป็นของใหม่ที่จะ PowerShell และอาจจะไม่เข้าใจสิ่งที่gci, ?, %ฯลฯ

$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

และแน่นอนถ้าคุณต้องการดูว่าไฟล์ / โฟลเดอร์ใดที่จะถูกลบก่อนที่จะทำการลบจริงๆคุณสามารถเพิ่ม-WhatIfสวิตช์ไปยังการRemove-Itemเรียก cmdlet ที่ท้ายบรรทัดทั้งสอง

รหัสที่แสดงในที่นี้คือ PowerShell v2.0 ที่ใช้งานร่วมกันได้ แต่ฉันยังแสดงรหัสนี้และรหัส PowerShell v3.0 ที่เร็วขึ้นเป็นฟังก์ชั่นที่ใช้ซ้ำได้สะดวกบนบล็อกของฉันฟังก์ชั่นที่มีประโยชน์นำมาใช้ใหม่บนบล็อกของฉัน


22
ขอบคุณที่ไม่ใช้นามแฝง สำหรับคนที่ยังใหม่กับ powershell และพบโพสต์นี้ผ่านการค้นหาโดย Google ฉันถือว่าคำตอบของคุณดีที่สุด
Geoff Dawdy

1
ฉันลองคำแนะนำของ @ deadlydog และไม่ว่าฉันจะระบุ -15 หรือ -35 ด้วยวันที่สร้างไฟล์ที่แตกต่างกันจะย้อนกลับไปหลายเดือน (หรือล่าสุด) มันเป็นการลบเนื้อหาทั้งหมดของไดเรกทอรี
มิเคเล่

6
หากไฟล์อาจถูกใช้งานก็ควรเพิ่ม "-ErrorAction SilentlyContinue" ในคำสั่ง RemoveItem
Kevin Owen

17
ขอบคุณ! ฉันใช้ $ _ LastwriteTime แทนที่จะเป็น $ _ CreationTime
Lauri Lubi

2
คำสั่งที่สองในสคริปต์นั้นมักจะได้รับข้อผิดพลาดที่ Get-ChildItem ไม่สามารถหาส่วนของเส้นทางได้ ได้รับไดเรกทอรีไม่พบข้อยกเว้น แต่มันจะลบโฟลเดอร์ว่างโดยไม่มีปัญหา ไม่แน่ใจว่าทำไมมันถึงได้รับข้อผิดพลาดแม้จะทำงานอยู่
Nathan McKaskle


16

อีกวิธีหนึ่งคือการลบ 15 วันนับจากวันที่ปัจจุบันและเปรียบเทียบCreationTimeกับค่านั้น:

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

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

13

โดยทั่วไปคุณวนซ้ำไฟล์ภายใต้เส้นทางที่กำหนดลบCreationTimeของแต่ละไฟล์ที่พบจากเวลาปัจจุบันและเปรียบเทียบกับDaysคุณสมบัติของผลลัพธ์ -WhatIfสวิทช์จะบอกคุณว่าจะเกิดขึ้นจริงโดยไม่ลบไฟล์ (ไฟล์จะถูกลบ) ลบสลับไปจริงลบไฟล์:

$old = 15
$now = Get-Date

Get-ChildItem $path -Recurse |
Where-Object {-not $_.PSIsContainer -and $now.Subtract($_.CreationTime).Days -gt $old } |
Remove-Item -WhatIf

8

ลองสิ่งนี้:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force

ฉันเชื่อว่าสิ่งสุดท้าย-recurseคือสิ่งที่มากเกินไปใช่ไหม? รายชื่อ dir ซ้ำแล้วซ้ำอีกการลบรายการไม่ควรรวมกับเด็กด้วยใช่ไหม
Joost

หากไดเรกทอรีที่คุณใช้งานอยู่นั้นมีสองไดเรกทอรีลึกจำเป็นต้องใช้ค่าที่สอง
ไบรอันเอส

5

สคริปต์ของ Esperento57 ไม่ทำงานใน PowerShell เวอร์ชันเก่ากว่า ตัวอย่างนี้:

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

1
ฉันได้อัปเดตคำตอบเพื่อยกเว้นไดเรกทอรีแล้วขอบคุณ
KERR

3

ทางเลือกอื่น (15. ถูกพิมพ์ไปที่ [timespan] โดยอัตโนมัติ):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose

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

จะเป็นการลบโฟลเดอร์เก่าและเนื้อหา


0

หากคุณกำลังมีปัญหากับตัวอย่างข้างต้นใน Windows 10 กล่องลองเปลี่ยนด้วย.CreationTime .LastwriteTimeสิ่งนี้ใช้ได้สำหรับฉัน

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force

LastwriteTimeจะไม่เหมือนกันCreationTime, LastwriteTimeเป็นอัปเดตในแต่ละครั้งไฟล์ที่มีการแก้ไข
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"
    }
}

นอกจากนี้มันจะไม่เข้าถึงคำสั่งelseเพราะถ้า$Filesว่างเปล่ามันจะไม่ป้อนคำสั่งforeach คุณควรวาง foreach ในคำสั่งif
Dieter

@ati จริง ๆ แล้วมันสามารถเข้าถึงคำสั่งอื่น เรามีลูปที่คล้ายกันโดยยึดตามรายชื่อไฟล์และมันเข้าสู่ for loop ด้วยตัวแปร $ File เป็นโมฆะ
BeowulfNode42

ฉันเดาว่างั้นก็เจอสคริปต์ตัวเดียวกันนี่สิ networknet.nl/apps/wp/published/…
Shawson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.