none
Recursive, filtered Deleting

    Question

  • looking to recursively look through the backup sql folders and if the folder contains a file like *_MASTER* , and if it's the newest file in the directory, then delete all of the other files in the directory...i know you'd prob just sort by the create date grab the top one and see if that one has MASTER in it, if so, delete everything except the one that has MASTER in it. 

    Just new to ps and can't figure out how to do this.

    Thanks

    Thursday, November 21, 2013 10:51 PM

Answers

  • Something like this should do the trick:

    #requires -Version 3.0
    
    $rootFolder = 'D:\SQLBackups'
    
    Get-ChildItem -Path $rootFolder -Directory -Recurse |
    ForEach-Object {
        $subdir = $_
    
        $newestFile = Get-ChildItem -Path $subdir.FullName -File |
                      Sort-Object -Property LastWriteTime -Descending |
                      Select-Object -First 1
    
        if ($newestFile.Name -like '*_MASTER*')
        {
            Get-ChildItem -Path $subdir.FullName -File |
            Where-Object { $_.Name -ne $newestFile.Name } |
            Remove-Item -Force
        }
    }
    

    PowerShell 3.0 is required for the -File and -Directory switches to Get-ChildItem, but it can be revised slightly for PowerShell 2.0 compatibility if you prefer.
    • Proposed as answer by Mike Laughlin Friday, November 22, 2013 1:29 AM
    • Marked as answer by o_dave Monday, November 25, 2013 8:04 PM
    Friday, November 22, 2013 1:19 AM
  • thanks for helping Mike.  When i run this, nothing seems to happen.  I've checked my version and i have version 4.0.  Is there a way to see which file it's viewing? I tried to add -WhatIf after Remove-Item -Force, but when i run this it doesn't err out, it runs, but nothing happening.

    #requires -Version 3.0
    
    $rootFolder = 'D:\SQLBackups'
    
    Get-ChildItem -Path $rootFolder -Directory -Recurse |
    ForEach-Object {
        $subdir = $_
    
        $newestFile = Get-ChildItem -Path $subdir.FullName -File |
                      Sort-Object -Property LastWriteTime -Descending |
                      Select-Object -First 1
    
        if ($newestFile)
        {
            Write-Host "Newest file in '$($subdir.FullName)': '$($newestFile.Name)'"
    
            if ($newestFile.Name -like '*_MASTER*')
            {
                Write-Host "Deleting other files in '$($subdir.FullName)'"
    
                Get-ChildItem -Path $subdir.FullName -File |
                Where-Object { $_.Name -ne $newestFile.Name } |
                Remove-Item -Force -WhatIf
            }
        }
    }

    • Marked as answer by o_dave Monday, November 25, 2013 8:04 PM
    Friday, November 22, 2013 8:44 PM

All replies

  • Something like this should do the trick:

    #requires -Version 3.0
    
    $rootFolder = 'D:\SQLBackups'
    
    Get-ChildItem -Path $rootFolder -Directory -Recurse |
    ForEach-Object {
        $subdir = $_
    
        $newestFile = Get-ChildItem -Path $subdir.FullName -File |
                      Sort-Object -Property LastWriteTime -Descending |
                      Select-Object -First 1
    
        if ($newestFile.Name -like '*_MASTER*')
        {
            Get-ChildItem -Path $subdir.FullName -File |
            Where-Object { $_.Name -ne $newestFile.Name } |
            Remove-Item -Force
        }
    }
    

    PowerShell 3.0 is required for the -File and -Directory switches to Get-ChildItem, but it can be revised slightly for PowerShell 2.0 compatibility if you prefer.
    • Proposed as answer by Mike Laughlin Friday, November 22, 2013 1:29 AM
    • Marked as answer by o_dave Monday, November 25, 2013 8:04 PM
    Friday, November 22, 2013 1:19 AM
  • thanks for helping Mike.  When i run this, nothing seems to happen.  I've checked my version and i have version 4.0.  Is there a way to see which file it's viewing? I tried to add -WhatIf after Remove-Item -Force, but when i run this it doesn't err out, it runs, but nothing happening.
    Friday, November 22, 2013 8:16 PM
  • oops looks like i was logged in with the wrong account above...
    Friday, November 22, 2013 8:20 PM
  • thanks for helping Mike.  When i run this, nothing seems to happen.  I've checked my version and i have version 4.0.  Is there a way to see which file it's viewing? I tried to add -WhatIf after Remove-Item -Force, but when i run this it doesn't err out, it runs, but nothing happening.

    #requires -Version 3.0
    
    $rootFolder = 'D:\SQLBackups'
    
    Get-ChildItem -Path $rootFolder -Directory -Recurse |
    ForEach-Object {
        $subdir = $_
    
        $newestFile = Get-ChildItem -Path $subdir.FullName -File |
                      Sort-Object -Property LastWriteTime -Descending |
                      Select-Object -First 1
    
        if ($newestFile)
        {
            Write-Host "Newest file in '$($subdir.FullName)': '$($newestFile.Name)'"
    
            if ($newestFile.Name -like '*_MASTER*')
            {
                Write-Host "Deleting other files in '$($subdir.FullName)'"
    
                Get-ChildItem -Path $subdir.FullName -File |
                Where-Object { $_.Name -ne $newestFile.Name } |
                Remove-Item -Force -WhatIf
            }
        }
    }

    • Marked as answer by o_dave Monday, November 25, 2013 8:04 PM
    Friday, November 22, 2013 8:44 PM
  • Sorry guys.  This looks perfect.  The location is a network location, but i've tested locally with some dummy files with diff create dates, changed the '*_MASTER*' to other words found in the filenames and i still get nothing. It's not printing the name of the top 1 sorted file or anything.  any other ideas what i could be doing wrong?  The test directory has files like:

    Name Extension Size Attributes Modified
    this is the latest_MASTER.txt txt 0 ---A----- 11/22/2013 1:05:34 PM
    this is the next file.txt txt 8 ---A----- 11/22/2013 9:53:02 AM
    this is the next file_MASTER.txt txt 6 ---A----- 11/22/2013 9:52:52 AM
    This is the oldest file.txt txt 0 - --A----- 11/22/2013 9:43:35 AM

    Friday, November 22, 2013 9:49 PM
  • The code works fine for me.  You did change the $rootFolder variable's value, right?  D:\SQLBackups was a path I just made up.
    Friday, November 22, 2013 11:07 PM
  • correct. It runs, but it appears it doesn't find anything...not sure why. does it matter i'm using version 4 instead of 3?
    Monday, November 25, 2013 3:09 PM
  • That shouldn't matter; in fact, I was running PowerShell 4.0 when I tested it myself.

    At this point, I would recommend just saving this as a script file and stepping through it in the ISE to see why it's not working for you

    Monday, November 25, 2013 3:41 PM
  • ok. Thanks for all of your help everyone.
    Monday, November 25, 2013 4:55 PM
  • Sorry guys.  This looks perfect.  The location is a network location, but i've tested locally with some dummy files with diff create dates, changed the '*_MASTER*' to other words found in the filenames and i still get nothing. It's not printing the name of the top 1 sorted file or anything.  any other ideas what i could be doing wrong?  The test directory has files like:

    Name Extension Size Attributes Modified
    this is the latest_MASTER.txt txt 0 ---A----- 11/22/2013 1:05:34 PM
    this is the next file.txt txt 8 ---A----- 11/22/2013 9:53:02 AM
    this is the next file_MASTER.txt txt 6 ---A----- 11/22/2013 9:52:52 AM
    This is the oldest file.txt txt 0 - --A----- 11/22/2013 9:43:35 AM

    Just reading through this and thought of possibilities, why this is not working for you. Assuming this above is the content of your test directory located at c:\mytest\test you will need set the $rootDirectory variable to c:\mytest if you run David's script only against c:\mytest\test it will not do anything because it is looking for subfolders of $rootDirectory, since this is what you actually wanted.
    Monday, November 25, 2013 5:51 PM
  • Dirk, you are exactly right.  My actual location where i want to run this is a set of sub directories.  In my test i was just working on a single root directory.  Thanks All for your help with this and Dirk for pointing out my ignorance.

    Cheers!

    Monday, November 25, 2013 8:03 PM