locked
Please help - Delete files based upon names of folders which are in date format RRS feed

  • Question

  • New to PowerShell so please excuse if I am on the wrong track here. I initially created a script to delete files if they are over 3 years old which ran fine. But it seems that the files have an incorrect creation date due to the application that creates these files. The application will creates folders/subfolders based upon the date. For example sub folder one will have the year 2015, 2106, 2107 , inside those folders subfolder 2 will have the months 1,2,3,4...12 and inside those folders subfolder 3 will have folders with the day 1,2,3....31. Within the day folder we have files which get copied and it's these files that we need to delete if they are over 3 years old. I've had a go at listing the folders and trying to concatenate them into date format initially but having problems doing so if that's even what I should be doing. 

    Any help would be greatly appreciated. 

    Adam

    Wednesday, December 13, 2017 1:39 PM

Answers

  • No worries! And this will put the date in the same format that the folder output is giving you, so you can compare directly:

    (Get-Date).AddDays(-1096).tostring('yyyy/MM/dd').Replace('/','\')


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:43 PM
  • So, I think I see what you're trying to do. but try this instead, that way you're not cutting and pasting string objects together to get a folder path:

    (Get-ChildItem "c:\temp\folders\*\*" -Depth 1).fullname

    That should return something like:

    c:\temp\Folders\2016\1\12

    Then you can compare the date above with the date that you want:

    ((Get-Date).AddDays(-1096) | Get-Date -Format 'yyyy/MM/dd').Replace('/','\')
    This date format returns this: 2014\12\13


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 3:40 PM
  • Hi Jeremy, 

    Thanks for your help. When I run (Get-ChildItem "c:\temp\folders\*\*" -Depth 1).fullname I get the output below. I'd just like to see the y/m/d portion of the results and ignore the result of the output. This way I might then be able to use these dates if I'm being clear?

    E.g. 2016/4/22
    2017\4\12 

    C:\temp\folders\2016\1
    C:\temp\folders\2016\2
    C:\temp\folders\2016\3
    C:\temp\folders\2016\4
    C:\temp\folders\2016\4\22
    C:\temp\folders\2016\4\22\New Text Document - Copy (2).txt
    C:\temp\folders\2016\4\22\New Text Document - Copy.txt
    C:\temp\folders\2016\4\22\New Text Document.txt
    C:\temp\folders\2017\1
    C:\temp\folders\2017\2
    C:\temp\folders\2017\3
    C:\temp\folders\2017\4
    C:\temp\folders\2017\4\12
    C:\temp\folders\2017\4\12\New Text Document - Copy (2).txt

    Thanks

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:02 PM
  • Try this instead. - sorry I didn't force it to only take folders in.

    $rootPath = "C:\temp\folders\"
    (Get-ChildItem $rootPath -Recurse | Where-Object {$_.PSIsContainer}).fullname | foreach {$_.replace("$rootPath","")}


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:12 PM

All replies

  • Hi Adam,

    Could you please post the script you've made so far?

    Wednesday, December 13, 2017 2:55 PM
  • Hi

    So here is the first script I created which deletes files based on creation date. 

    $Path = 'c:\temp\folders'
    $Daysback = '-1096'
    $CurrentDate = get-date
    $DatetoDelete = $CurrentDate.AddDays(-1096)
    Get-ChildItem $Path -Recurse | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item -confirm:$false

    My attempt at getting the folder names but stuck at trying to string them together in date order. Apologies if I'm on the wrong track here. 

    $folderyear = (gci "c:\temp\folders\" | where-object {$_.PSIsContainer -eq $True}).Name
    $foldermonth = (gci "c:\temp\folders\*" -Depth 1| where-object {$_.PSIsContainer -eq $True}).Name
    $folderday = (gci "c:\temp\folders\*\*"  -Depth 1| where-object {$_.PSIsContainer -eq $True}).Name

    # Get the folder list
    $dates = New-Object psobject -Property  @{
    folderyear = $folderyear
    foldermonth = $foldermonth
    folderday = $folderday
    }

    So the output of $dates is below. Thought there might be a way to string year, month and day today but can't work out how initially. 

    E.g.
    12/1/2016
    22/1/2016
    12/2/2106
    22/2/2016

    ...

    PS C:\Users\astean> $dates
    folderyear   foldermonth     folderday
    ----------   -----------     ---------
    {2016, 2017} {1, 2, 3, 4...} {22, 12}

    Wednesday, December 13, 2017 3:29 PM
  • So, I think I see what you're trying to do. but try this instead, that way you're not cutting and pasting string objects together to get a folder path:

    (Get-ChildItem "c:\temp\folders\*\*" -Depth 1).fullname

    That should return something like:

    c:\temp\Folders\2016\1\12

    Then you can compare the date above with the date that you want:

    ((Get-Date).AddDays(-1096) | Get-Date -Format 'yyyy/MM/dd').Replace('/','\')
    This date format returns this: 2014\12\13


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 3:40 PM
  • Hi Jeremy, 

    Thanks for your help. When I run (Get-ChildItem "c:\temp\folders\*\*" -Depth 1).fullname I get the output below. I'd just like to see the y/m/d portion of the results and ignore the result of the output. This way I might then be able to use these dates if I'm being clear?

    E.g. 2016/4/22
    2017\4\12 

    C:\temp\folders\2016\1
    C:\temp\folders\2016\2
    C:\temp\folders\2016\3
    C:\temp\folders\2016\4
    C:\temp\folders\2016\4\22
    C:\temp\folders\2016\4\22\New Text Document - Copy (2).txt
    C:\temp\folders\2016\4\22\New Text Document - Copy.txt
    C:\temp\folders\2016\4\22\New Text Document.txt
    C:\temp\folders\2017\1
    C:\temp\folders\2017\2
    C:\temp\folders\2017\3
    C:\temp\folders\2017\4
    C:\temp\folders\2017\4\12
    C:\temp\folders\2017\4\12\New Text Document - Copy (2).txt

    Thanks

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:02 PM
  • I came up with this:

    $daysback = -1096
    Get-ChildItem -LiteralPath "C:\temp\folders" | foreach {
    
        # Full Year
        if([int]$_.Name -lt [int]((Get-Date).AddDays($daysback).ToString("yyyy"))){
    
           # Delete whole year folder
        }
    
        # Year
        elseif([int]$_.Name -eq [int]((Get-Date).AddDays($daysback).ToString("yyyy"))){
    
            # Full Month
            if([int]$_.Name -lt [int](Get-Date).AddDays($daysback).ToString("MM")){
    
               # Delete whole month folder
            }
    
            #  Month
            elseif([int]$_.Name -eq [int](Get-Date).AddDays($daysback).ToString("MM")){
    
               # ... same thing with the day folder
            }
        }
    }

    Pretty much "quick and dirty" and untested...

    Wednesday, December 13, 2017 4:02 PM
  • Try this instead. - sorry I didn't force it to only take folders in.

    $rootPath = "C:\temp\folders\"
    (Get-ChildItem $rootPath -Recurse | Where-Object {$_.PSIsContainer}).fullname | foreach {$_.replace("$rootPath","")}


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:12 PM
  • Hi

    Thanks very much. I'll try and work through this and dissect it. 

    Wednesday, December 13, 2017 4:23 PM
  • Hi Jeremy

    This now just displaying the dates :)

    So from here I'll look to compare with the current date and if older than 3 years delete the files stored within.

    This is really helpful.

    Thanks 

    Wednesday, December 13, 2017 4:26 PM
  • No worries! And this will put the date in the same format that the folder output is giving you, so you can compare directly:

    (Get-Date).AddDays(-1096).tostring('yyyy/MM/dd').Replace('/','\')


    Jeremy Corbello | https://www.jeremycorbello.com

    • Marked as answer by astean Friday, December 15, 2017 2:22 PM
    Wednesday, December 13, 2017 4:43 PM
  • And don't forget to mark the answer for others to learn!

    Jeremy Corbello | https://www.jeremycorbello.com

    Wednesday, December 13, 2017 4:55 PM
  • Thanks Jeremy. I will certainly do. Going to have a go at putting it together today. 
    Thursday, December 14, 2017 10:05 AM
  • Hi,

    I'm checking how the issue is going, was your issue resolved?

    And if the replies as above are helpful, we would appreciate you to mark them as answers, and if you resolve it using your own solution, please share your experience and solution here. It will be greatly helpful to others who have the same question.

    Appreciate for your feedback.

    Best Regards,
    Albert

    Please remember to mark the replies as an answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Friday, December 15, 2017 7:44 AM
  • Hi Albert

    Jeremy was most helpful and I have marked his efforts as answers as they really helped a lot. 

    I have resolved it using the script below. I'm sure it could be coded better but it does what I need it to do and I've added some comments also. 

    # Find today's date and calculate 2 years ago. Set the date in yyyy/mm/dd format and flip the slashes
    $today = (get-date)
    $twoYearsAgo = $today.AddDays(-720).ToString('yyyy/MM/dd').Replace('/','\')
    #Delete the beginning part of path and only show the year, month and date folders
    $rootPath = "C:\temp\folders\"
    $dates = (Get-ChildItem $rootPath -Recurse | Where-Object {$_.PSIsContainer}).fullname  | foreach {$_.replace("$rootPath","")} 
    #Only show the dates if they are 8, 9 or 10 characters  in length
    $results = $dates | Where-Object {$_.length -eq 8 -or $_.length -eq 9 -or $_.length -eq 10}
    #Join the full path up again and loop through the results and if they are less then two years delete the files.
    foreach ($result in $results) {
     If ($result -lt $twoYearsAgo)
     {
           
        
            $lastpath = Join-Path $rootPath -ChildPath $result
            Write-host $lastpath ----- "Delete files within these locations-----"
          # remove-item $lastpath -Recurse -Confirm:$false
          Get-ChildItem $lastpath | remove-item #$lastpath -Recurse -Confirm:$false
           
          }
          }

    Friday, December 15, 2017 2:26 PM