Find Files older than 6 months and zip them

Kelly Garcia
Kelly Garcia used Ask the Experts™
on
Hi All,

I need to find files older than 6 months and zip them, is there a script some has I can use?

Thank you in advance,
Kay
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Chris DentPowerShell Developer
Top Expert 2010

Commented:
This depends a bit on your PowerShell versions. Compress-Archive is new(ish).
$files = Get-ChildItem Path -File | Where-Object LastWriteTime -lt (Get-Date).AddMonths(-6) | Select-Object -ExpandProperty FullName
Compress-Archive $files -DestinationPath something.zip

Open in new window

Kelly GarciaSenior Systems Administrator

Author

Commented:
should use the -recurse, Get-ChildItem Path -File  -Recurse

Also should I utilise the lastaccesstime instead of lastwritetime?
Chris DentPowerShell Developer
Top Expert 2010

Commented:
Up to you really. I don't much care when files were opened, when they were last written to is often the best metric from my point of view. It's all subjective though, you might key off CreationTime instead.
Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

Kelly GarciaSenior Systems Administrator

Author

Commented:
I have this script:


$pathname = Read-Host "Please Enter Path Name: "
GCI $pathname -Recurse | 
	?{$_.LastAccessTime -le (Get-date).AddMonths(-1)} | 
  Select FullName,CreationTime,LastAccessTime,LastWriteTime |
Export-Csv "c:\$(($pathname -split "\\")[-1]).csv" -NTI 

Open in new window


what is the best way to add the compress-archive command to this script? also any suggestions for improvement?
PowerShell Developer
Top Expert 2010
Commented:
It's essentially the same as the first example. Added the File parameter because zipping directories as well will confusing it. Replaced aliases with full command names (I never use aliases in examples / production code).
$files = Get-ChildItem $pathname -Recurse -File | 
	Where-Object LastAccessTime -le (Get-date).AddMonths(-1) |
        Select-Object -ExpandProperty FullName
Compress-Archive $files -DestinationPath something.zip

Open in new window

Kelly GarciaSenior Systems Administrator

Author

Commented:
I am getting this error:

Exception calling "Write" with "3" argument(s): "Stream was too long."
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:819 char:29
+ ...                     $destStream.Write($buffer, 0, $numberOfBytesRead)
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IOException

also LastAccessTime -le (Get-date).AddMonths(-1)  - does this means files accessed less than a month ago?
Chris DentPowerShell Developer
Top Expert 2010

Commented:
You're likely hitting the 2GB limit on the zip file. How much do you have in $files?

No, it means accessed a month or more ago. When comparing date, a date is considered less if it comes before the value on the right hand side of the expression. For example, yesterday is less than today.
(Get-Date).AddDays(-1) -lt (Get-Date)

Open in new window

Kelly GarciaSenior Systems Administrator

Author

Commented:
also I need the zip files saved in the same path along with the same files name after that I need the non zipped file deleted. should I create a new entry on experts exchange?
Kelly GarciaSenior Systems Administrator

Author

Commented:
also files that are 1gb or more
Chris DentPowerShell Developer
Top Expert 2010

Commented:
That 2GB stream error needs figuring out first. Chances are it'll be best to move the files to a staging area so the entire directory can be zipped.

Let's start with that:
$path = 'C:\Source'
$stagingPath = 'D:\Destination'

Push-Location $path
Get-ChildItem $path -Recurse -File | 
	Where-Object LastAccessTime -le (Get-date).AddMonths(-1) |
    ForEach-Object {
        $relative = Resolve-Path $_.Directory -Relative
        $destination = Join-Path $stagingPath $relative.TrimStart('.')
        if (-not (Test-Path $destination)) {
            $null = New-Item $destination -ItemType Directory
        }

        Copy-Item $_.FullName -Destination $destination
    }
Pop-Location

Open in new window

Start with that and check the size of everything. If it works, Copy-Item can be change to Move-Item (possibly). Alternatively, we can do one pass to generate the list, archive things, and if that works, delete the items on the list.
Chris DentPowerShell Developer
Top Expert 2010

Commented:
> also files that are 1gb or more

It needs to be 7-zip then. The .NET components don't stand a chance. Not a big deal though, start with collecting the files together. Obviously for files that large the size of the staging area is kind of important.
Kelly GarciaSenior Systems Administrator

Author

Commented:
I have written the code below:

$pathname = "C:\Users\kabir.uddin"
$files = Get-ChildItem $pathname -Recurse -File | 
	Where-Object LastAccessTime -le (Get-date).AddMonths(-1)
  
		foreach ($f in $files)
		{
			$Name = $f.fullname
			#Compress-Archive $f -DestinationPath $path\$Name.zip
		}

Open in new window

Kelly GarciaSenior Systems Administrator

Author

Commented:
I will create a new entry on experts exchange
Kelly GarciaSenior Systems Administrator

Author

Commented:
apologies on the code its $f.name not $f.fullname

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial