1

Under \\server\logs there's a tree of sub-directories that contain archived log files that don't follow a consistent file-naming convention. I'd like to run a daily scheduled task to zip the non-zipped files from 90 days or earlier into daily zip files. I wish to maintain the directory tree structure and filenames within each zip.

What's the best way to approach this in Powershell?

EDIT: Unless there's a better approach, i think the zip files should be created in \\server\oldlogs and be named for a specific day, eg. \\server\oldlogs\20110630_logs.zip. All files under \\server\logs last modified more than 90 days ago should be added to the appropriate .zip file.

b w
  • 4,553
  • 4
  • 31
  • 36
  • Under \\server\logs there are sub directories. Those sub directories will contain files that do not end in .zip. The process should identify all files that have not been (created/modified/accessed?) in the past 90 days and put them into a .zip in the existing directory structure. After creating the archive file, those same files should then be deleted. Accurate? – billinkc Jan 11 '12 at 18:17
  • @billinkc - Now that you mention it, seems simpler to create the zips in a `\\server\oldlogs` directory. I want to end up with zip files named for a day, that contain files last modified on that date. Then yes, once they're zipped, they should be deleted. I'll update the question. Thanks. – b w Jan 11 '12 at 18:32
  • Why do you use the powershell tag?. Do you need opinions about the problem or the functional script? – mjsr Jan 11 '12 at 19:16
  • @voodoomsr - Because i asked for the best way to approach this in Powershell. – b w Jan 11 '12 at 19:58

2 Answers2

0

From .NET 3, System.IO.Packaging.ZipPackage could do the compression. No subfolders in this example but they can apparently be handled.

The date filter could go something like this:

$ninetyDaysAgo = (get-date).adddays(-90)
$Files | where {$_.lastWriteTime -lt $ninetyDaysAgo}
Community
  • 1
  • 1
noam
  • 1,914
  • 2
  • 20
  • 26
0

Here's a 66% solution (lunch is over). I couldn't get the native zip to work with PowerShell but if you have PowerShell Community Extensions installed, it should be a snap to swap out the zip call How to create a zip archive with PowerShell?

# purloined from http://blogs.inetium.com/blogs/mhodnick/archive/2006/08/07/295.aspx
# I am not smart enough to make it work. Creates an empty .zip file for me
Function ZipIt
{
    param
    (
        [string]$path
    ,   [string]$files
    )

    if (-not $path.EndsWith('.zip')) {$path += '.zip'} 

    if (-not (test-path $path)) { 
      set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
    } 

    $zipFile = (new-object -com shell.application).NameSpace($path) 
    #$files | foreach {$zipfile.CopyHere($_.fullname)} 
    foreach($file in $files)
    {
        $zipfile.CopyHere($file)
    }
}

# this script is reponsible for enumerating subfolders
# for each file it finds, it will test the age on it
# returns an array of all the files meeting criteria
Function Walk-SubFolder
{
    param
    (
        [string]$RootFolder
    )

    $searchPattern = "*.*"
    $maxAge = 90
    $now = Get-Date

    # receiver for the files
    [string[]] $agedOutFileList = @()

    foreach($file in [System.IO.Directory]::GetFiles($RootFolder, $searchPattern, [System.IO.SearchOption]::AllDirectories))
    {
        # test whether the file meets the age criteria
        $age = [System.IO.File]::GetLastWriteTime($file)
        $days = ($now - $age).Days
        if (($now - $age).Days -ge $maxAge)
        {
            # this needs to be archived
            Write-Host("$file is aged $days days")
            $agedOutFileList = $agedOutFileList + $file
        }
    }

    return $agedOutFileList
}

Function PurgeFiles
{
    param
    (
        $fileList
    )
    foreach($file in $fileList)
    {
        # this should be in a try/catch block, etc, etc
        [System.IO.File]::Delete($file)
    }
}

$sourceFolder = "C:\tmp\so"
$zipFile = "C:\tmp\so.zip"


$oldFiles = Walk-SubFolder $sourceFolder
ZipIt $zipFile $oldFiles

#This is commented out as the zip process is not working as expected
#PurgeFiles $oldFiles

I'll see if I can work on it later to get the zip working as expected.

Community
  • 1
  • 1
billinkc
  • 59,250
  • 9
  • 102
  • 159
  • thanks this is interesting. Not exactly right though, in that all files >90 days old get added to the same zip file instead of the zip file corresponding to their last write date. I think i can adapt this though. – b w Jan 11 '12 at 20:03
  • Also, is ZipIt supposed to add with the fully-qualified path included? – b w Jan 11 '12 at 20:10