Script to delete files and folders older than X days

This topic contains 13 replies, has 4 voices, and was last updated by  js 2 weeks, 5 days ago.

  • Author
    Posts
  • #100161

    Scott
    Participant

    I wish to run a script daily that will delete folders and respective files in it which are older than X days (for my webcam recordings). I have the following script, though when run, files are not deleted.

    # Enter a number to indicate how many days old the identified file needs to be (must have a "-" in front of it).
    $HowOld = -1
    
    #Path to the root folder
    $Path = "E:\CAMMEDIA"
    
    #Deletion task
    get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}

    Powershell screenshot

    I also created a Task Scheduler Task; the following is in the argument section:

    -ExecutionPolicy Bypass c:\scripts\myscript.ps1 -RunType $true -Path E:\CAMMEDIA

    Suggestions?

  • #100164

    Rob Simmers
    Participant

    Your script has a -WhatIf, which will not delete the files, only report what will be done. If you remove the -WhatIf, does the script work manually? If the script works manually, then the next question is what user is running the script in the scheduled task?

    • #100167

      Scott
      Participant

      Thanks @Rob. If I simply remove the whatif statement, nothing happens.

    • #100170

      Scott
      Participant

      I discovered, I need to replace -whatif with -verbose.

    • #100176

      Scott
      Participant

      Here's what I ended up with...

      #Days older than
      $HowOld = -1
      
      #Path to the root folder
      $Path = "E:\CAMMEDIA"
      
      #Deletion files task
      get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -verbose}
      
      #Deletion empty folders task
      do {
        $dirs = gci $Path -directory -recurse | Where { (gci $_.fullName -Force).count -eq 0 } | select -expandproperty FullName
        $dirs | Foreach-Object { Remove-Item $_ }
      } while ($dirs.count -gt 0)
  • #100177

    Rob Simmers
    Participant

    You are over complicating it. Try something like this:

    #Days older than
    $HowOld = -1
    
    #Path to the root folder
    $Path = "E:\CAMMEDIA"
    
    #Get the files to delete
    $filesToDelete = Get-ChildItem -Path $Path -File -Recurse | Where {$_.lastwritetime -lt (Get-Date).AddDays($HowOld)}
    
    #Delete the files
    $filesToDelete | Remove-Item -Force -WhatIf
    

    Most Powershell cmdlets that Accept Pipeline Input, which will automatically loop through each of the objects passed to it. If you run the following...

    Get-Help Remove-Item -Full
    

    you will see the path, which is also required, accepts...

    -Path
    Specifies a path of the items being removed. Wildcard characters are permitted.

    Required? true
    Position? 0
    Default value None
    Accept pipeline input? True (ByPropertyName, ByValue)
    Accept wildcard characters? false

    You can run the first 3 lines to see if you are collecting the files and then use the prompt to validate the files:

    PS C:\Users\Rob> #Days older than
    $HowOld = -1
    
    #Path to the root folder
    $Path = $env:Temp
    
    #Get the files to delete
    $filesToDelete = Get-ChildItem -Path $Path -File -Recurse | Where {$_.lastwritetime -lt (Get-Date).AddDays($HowOld)}
    
    
    PS C:\Users\Rob> $filesToDelete.Count
    2869
    
    PS C:\Users\Rob> $filesToDelete | Select -First 3
    
    
        Directory: C:\Users\Rob\AppData\Local\Temp
    
    
    Mode                LastWriteTime         Length Name                                                                                                                                                                                                
    ----                -------------         ------ ----                                                                                                                                                                                                
    -a----         5/2/2018  12:55 PM              0 aria-debug-15216.log                                                                                                                                                                                
    -a----         5/2/2018  12:47 PM              0 aria-debug-17600.log                                                                                                                                                                                
    -a----         5/2/2018  12:52 PM            470 aria-debug-1844.log                                                                                                                                                                                 
    
    • #100180

      Scott
      Participant

      I get the following message/error:

      Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
      At line:1 char:10
      + $files | Remove-Item -Force
      +          ~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
          + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemC
         ommand
  • #100183

    Ivan
    Participant

    I think line 11 of the original code by Rob should be:

    $filesToDelete | Remove-Item -Force -WhatIf
    • #100188

      Scott
      Participant

      Okay, that seems to work. To go live, should I remove the whatif statement now? Do I need to replace whatif with verbose?

  • #100185

    Rob Simmers
    Participant

    Oops, wrong variable. Ivan is the man!

  • #100191

    js
    Participant

    Another way...

    # Enter a number to indicate how many days old the identified file needs to be 
    $HowOld = '1' 
    #Path to the root folder
    $Path = "E:\CAMMEDIA"
    
    #Deletion task
    get-childitem $Path -recurse -file | where { (get-date) - $_.lastwritetime -gt $HowOld } | 
      remove-item -force -verbose
    
    • #100207

      Scott
      Participant

      @js, I couldn't get this to work.

    • #100210

      js
      Participant

      Weird. Take off the period. I corrected the code. I'm trying to make $HowOld automatically cast to a [timespan] of one day.

      # One day, the first is a floating point:
      [timespan]1.
      [timespan]'1'
      
      # Error:
      [timespan]'1.'
      
      # One tick:
      [timespan]1
      
  • #100194

    Rob Simmers
    Participant

    Remove -WhatIf will delete the files, performing the operation. If you are looking for logging, you can do use the -Verbose switch or just add $filesToDelete to the script to enumerate or something like:

     $filesToDelete | Select FullName
    

You must be logged in to reply to this topic.