none
script which delete all folders/files older than x days BUT from x level...first level subfolders (not files) must be excluded RRS feed

  • Question

  • hello

    I surf for hours and cant find what script for this...I have one public folder in which each user have own folder.

    I need to delete all third level subfolders which is older than 5 days BUT need to PRESERVE first level subfolders bellow public. So, all bold need to retain.

    Example:

    d:\public\user 1\some folder\some file.txt
                     user 2\some folder\some file.txt
                     user 3\some folder\some file.txt

    how to do this?

    thanks

    Sunday, November 23, 2014 1:25 AM

Answers

  • Try it

    $deleteDate = (Get-Date).AddDays(-5)
     
    $folders = Get-ChildItem C:\public
     
    foreach($folder in $folders)
    {    
        $userFolders = Get-ChildItem -Path $folder.FullName
        
        foreach($userFolder in $userFolders)
        {
           if (($userFolder.LastWriteTime -eq $deleteDate) -or ($userFolder.LastWriteTime -lt $deleteDate)) 
           {
              Write-Host starije od 5 dana
              $filePath = $userFolder.FullName
              Remove-Item $filePath -Confirm:$false -Recurse
              [System.IO.Directory]::Delete($filePath)
           }
        }    
    } 
     
    

    • Marked as answer by foler Friday, December 5, 2014 1:42 PM
    Friday, December 5, 2014 12:29 PM

All replies

  • This will get the right level

    function Recurse-Folders([string]$path,[int]$level) 
    {
    
      Set-Location -Path $Path
      IF ($Level -GT 1)
      {
         "Location=$(Get-Location) Level=$Level Do Something"
      }
      Else
      {
         "Location=$(Get-Location) Level=$Level"
      }
      $Level++
      
      [String[]]$Folders  = Get-ChildItem "." -Directory
        ForEach ($F in $Folders)
      {
        Recurse-Folders $F $Level
        Set-Location -Path ".." 
      }
      $Level--
    }
    
    
    Recurse-Folders C:\test 0

    Gives this output

    Location=C:\test Level=0
    Location=C:\test\Folder1 Level=1
    Location=C:\test\Folder1\SubFolder1 Level=2 Do Something
    Location=C:\test\Folder1\SubFolder1\SubSubFolder1 Level=3 Do Something
    Location=C:\test\Folder2 Level=1
    Location=C:\test\Folder2\SubFolder1 Level=2 Do Something
    Location=C:\test\Folder2\SubFolder1\SubSubFolder1 Level=3 Do Something
    Location=C:\test\Folder2\SubFolder2 Level=2 Do Something
    Location=C:\test\Folder2\SubFolder2\SubSubFolder1 Level=3 Do Something
    Location=C:\test\Folder3 Level=1
    Location=C:\test\Folder3\SubFolder1 Level=2 Do Something
    Location=C:\test\Folder3\SubFolder1\SubSubFolder1 Level=3 Do Something
    

    Sunday, November 23, 2014 2:08 AM
  • Try this:

    Get-ChildItem d:\public -Directory -Recurse | where { ( $_.fullname -match 'd:\\public\\[^\\]+\\[^\\]+$' ) -and ( $_.CreationTime -lt (Get-Date).AddDays(-5) ) } | foreach { Remove-Item $_.fullname -Recurse -WhatIf

    }


    The -match filter should filter out everything except the third-level folders.

    Run it with the -WhatIf, and check the results.  If it looks right, remove the -WhatIf and rerun it to actually delete the files and folders.

    Edit: add foreach to delete by fullname


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "


    • Edited by mjolinorModerator Sunday, November 23, 2014 2:46 AM
    • Proposed as answer by jrv Sunday, November 23, 2014 2:47 AM
    Sunday, November 23, 2014 2:41 AM
    Moderator
  • There is one more elegant solution that is "almost" as good as mjolinor's Regex solution.

    ????


    ¯\_(ツ)_/¯

    Sunday, November 23, 2014 2:51 AM
  • There is one more elegant solution that is "almost" as good as mjolinor's Regex solution.

    ????


    ¯\_(ツ)_/¯

    Not sure if this is what you had in mind, but:

    Get-ChildItem d:\public -Directory -Recurse |
     where { 
             ( $_.parent.parent.fullname -eq 'd:\public' ) -and
             ( $_.CreationTime -lt (Get-Date).AddDays(-5) )
           } |
     Remove-Item -Recurse -WhatIf


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Sunday, November 23, 2014 3:14 AM
    Moderator
  • There is one more elegant solution that is "almost" as good as mjolinor's Regex solution.

    ????


    ¯\_(ツ)_/¯

    Not sure if this is what you had in mind, but:

    Get-ChildItem d:\public -Directory -Recurse |
     where { 
             ( $_.parent.parent.fullname -eq 'd:\public' ) -and
             ( $_.CreationTime -lt (Get-Date).AddDays(-5) )
           } |
     Remove-Item -Recurse -WhatIf


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Well...it is a variation but how about...is it is "n" levels deep?  Refactor.


    ¯\_(ツ)_/¯


    • Edited by jrv Sunday, November 23, 2014 4:08 AM
    Sunday, November 23, 2014 3:23 AM
  • What about this?

    dir D:\public\*\* -Directory | 
        where CreationTime -lt (Get-Date).AddDays(-5) |
        Remove-Item -Recurse -WhatIf
    

    Sunday, November 23, 2014 3:24 AM

  • Well...it is a variation but how abouut is it is "n" levels deep?  Refactor.


    ¯\_(ツ)_/¯

    Get-ChildItem d:\public -Directory -Recurse |
     where { 
             ( ($_.fullname.split('\')).count -eq 4  ) -and
             ( $_.CreationTime -lt (Get-Date).AddDays(-5) )
           } |
     Remove-Item -Recurse -WhatIf



    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Sunday, November 23, 2014 3:32 AM
    Moderator
  • What about this?

    dir D:\public\*\* -Directory | 
        where CreationTime -lt (Get-Date).AddDays(-5) |
        Remove-Item -Recurse -WhatIf


    I don't know. Doesn't that include everything?

    ¯\_(ツ)_/¯

    Sunday, November 23, 2014 4:11 AM

  • Well...it is a variation but how abouut is it is "n" levels deep?  Refactor.


    ¯\_(ツ)_/¯

    Get-ChildItem d:\public -Directory -Recurse |
     where { 
             ( ($_.fullname.split('\')).count -eq 4  ) -and
             ( $_.CreationTime -lt (Get-Date).AddDays(-5) )
           } |
     Remove-Item -Recurse -WhatIf



    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    That is what I had in mind.

    I knew you would see.  I was posting as a thought experiment for others.  I kinda thought it was a good tickler.


    ¯\_(ツ)_/¯

    Sunday, November 23, 2014 4:14 AM
  • What about this?

    dir D:\public\*\* -Directory | 
        where CreationTime -lt (Get-Date).AddDays(-5) |
        Remove-Item -Recurse -WhatIf


    I don't know. Doesn't that include everything?

    ¯\_(ツ)_/¯

    Nope. It doesn't include the files. I re-read what was being asked for and realized the -Directory switch shouldn't be used if you go by the title of the thread. Since that's gone, let's go ahead and remove the PSv3+ Where-Object shortcut and make this work with PSv2:

    dir D:\public\*\* | 
        where { $_.CreationTime -lt (Get-Date).AddDays(-5) } |
        Remove-Item -Recurse -WhatIf
    
    Of course if you really are just looking for third level folders instead of files and folders, you could use the original solution with the -Directory switch (which can easily be modified to work with PSv2 if necessary). mjolinor's solution would work, too.

    • Marked as answer by foler Sunday, November 23, 2014 11:49 AM
    • Unmarked as answer by foler Friday, December 5, 2014 9:10 AM
    Sunday, November 23, 2014 4:34 AM
  • Is there a constraint that it has to fit on 1 line (Like it is being done on a PDP-11 with 64K of RAM and space is a premium?)

    It is more generic when it has parameters and the caller controls what happens.

    It is easier to develop smaller parts and test them, and then combine them into something bigger and more complex.

    It is also a lot easier to do something no matter how complex, at one level of a tree structure than try to do the whole thing in one go especially when working with destructive operations like delete or remove-item.

    Sunday, November 23, 2014 4:48 AM
  • Hello
    I cant get this to work. when i run this scripts nothing happen or wont delete folders and files.

    Maybe is solution forfiles or some combination with robocopy to move files...

    here is picture with folder tree, instead top level folder "public" is "razmjena"

    Sunday, November 23, 2014 10:36 AM
  • Did you substitute "razmjena" instead of "public" in one of the scripts?
    Sunday, November 23, 2014 10:56 AM
  • yes...
    Sunday, November 23, 2014 10:58 AM
  • dir D:\public\*\* | 
        where { $_.CreationTime -lt (Get-Date).AddDays(-5) } |
        Remove-Item -Recurse

     This work...

    thanks


    • Edited by foler Sunday, November 23, 2014 11:50 AM
    • Marked as answer by foler Sunday, November 23, 2014 11:50 AM
    • Unmarked as answer by foler Friday, December 5, 2014 9:08 AM
    Sunday, November 23, 2014 11:49 AM
  • this script wont delete folders. can someone help me:

    dir D:\public\*\* | 
        where { $_.CreationTime -lt (Get-Date).AddDays(-5) } |
        Remove-Item -Recurse -WhatIf

    Tuesday, November 25, 2014 1:07 PM
  • Start here:

    HELP  about_CommonParameters

    Read all of it very carefully.  It is the first thig you need to know about PowerShell to use it.


    ¯\_(ツ)_/¯

    Tuesday, November 25, 2014 1:23 PM
  • Try it

    $deleteDate = (Get-Date).AddDays(-5)
     
    $folders = Get-ChildItem C:\public
     
    foreach($folder in $folders)
    {    
        $userFolders = Get-ChildItem -Path $folder.FullName
        
        foreach($userFolder in $userFolders)
        {
           if (($userFolder.LastWriteTime -eq $deleteDate) -or ($userFolder.LastWriteTime -lt $deleteDate)) 
           {
              Write-Host starije od 5 dana
              $filePath = $userFolder.FullName
              Remove-Item $filePath -Confirm:$false -Recurse
              [System.IO.Directory]::Delete($filePath)
           }
        }    
    } 
     
    

    • Marked as answer by foler Friday, December 5, 2014 1:42 PM
    Friday, December 5, 2014 12:29 PM