Need help using Powershell to zip files from YESTERDAY

I’m overwhelmed by all the different coding options for zipping using Powershell. I need help. I need to zip up files in various directories that were made YESTERDAY. I need these new zip files to be put in a different location. I need success or failure written to the log file. It would be nice to get an email, but I’ll work on that later. I’m attaching what I have cobbled together so far, but I could use some help. Am I on the right track? Thanks!

# 09/23/2016 created by Gina Bautista
#Zip up files in directories for YESTERDAY. Put zip files in another directory.
#If unable to the create zip file, then produce an error message in the log file.
# Replace space in hour with zero if it's less than 10
$logpath = "D:\Report-Copy-Move\Logs\Zip_reports_results.txt"

IF "%HOUR:~0,1%" == " " SET HOUR=0%HOUR:~1,1%

# This set the date like this: mm-dd-yr-hrminsecs1/100secs
Set TODAY=%date:~4,2%-%date:~7,2%-%date:~10,4%-%hr%%time:~3,2%%time:~6,2%%time:~9,2%

# Logic to set yesterday
d = date() - 1
wscript.echo year(d) * 10000 + month(d) * 100 + day(d)

SET PATH=%PATH%;C:\Program Files\7-Zip\

# Defining my inputs. These are source files created YESTERDAY.
$Yesterday = Get-Date ((Get-Date).AddDays(-1)) -Format yyyy-MM-dd
$Files_CDC = Get-ChildItem D:\ininbound\CDC\archive\ -Filter "*$Yesterday*"
$Files_FH = Get-ChildItem D:\ininbound\FH\archive\ -Filter "*$Yesterday*"
$Files_SCDC = Get-ChildItem D:\ininbound\SCDC\archive\ -Filter "*$Yesterday*"
$Files_SVH = Get-ChildItem D:\ininbound\SVH\archive\ -Filter "*$Yesterday*"
$Files_Raslo = Get-ChildItem D:\reports\dr_reports\archive\ -Filter "*$Yesterday*"

# Defining my zip output destinatons.
$Destination_CDC = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-French_Arroyo\'
$Destination_FH = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-French_Arroyo\'
$Destination_SCDC = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SCDC\'
$Destination_SVH = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-Sierra\'
$Destination_Raslo = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-Raslo\'

Foreach ($File in $Files)
    $Exe = 'C:\Program Files\7-Zip\7z'
    $Args = $Destination,$File.FullName
    & $Exe $Args
# Success or error? If unable to create zip file to destination, throw error to log file. Loop through this logic for each directory & each zip file created.
            if ($zip.Error -eq $Null)
                #Print results
                Add-content -Path $logpath -value "Zip of {0} succeeded $($zip.FileName)"
                #Zip Failed, throw error
                Add-content -Path $logpath -value "Zip of failed: {1} $($zip.FileName) $($zip.Error.Message)"
       # Clean up
        Add-content -Path $logpath -value "Zip of reports completed"
    exit 0
catch [Exception]
    Add-content -path $logpath -value $_.Exception.Message
    exit 1

Hi Gina,
You appear to be intermixing several different script languages here. Lines 10 - 20 appear to be Batch scripting with the exception of line 18 which appears to be VBScript. The rest of it appears to be Powershell, but you are making references to variables/object that you have not set such as $zip on line 44, 47, and 52, and $session on 58. Additionally your are trying to loop through a collection called $files, but you have not created a collection called $files.


This is the approach i use most often:

Foreach ($file in $files)
    If ($file.CreationTime.DayOfYear -eq $((get-date).DayOfYear -1))
    "Code to add $file to zip here"

Hope this helps somehow :slight_smile:

So, there are a lot of problems with your code as Curtis eluded.

  • In order to de-duplicate the same GCI and Source statements, consider dynamically creating them using a variable. I assume these are sites, so I gave them that moniker in the example code. We can build the source and destination for each site versus defining all of those variables.
  • Get-ChildItem can be a bit painful. The -Filter option is somewhat useless. You need to collect all files and then filter them with Where-Object. You can do something very similar with Get-Date and .AddDays(-1) to look for files created in the last 24 hours
  • Calling command line commands like 7z should be done with Start-Process. First you want to get the exit code, but you have to Wait until the command completes to do so.

This is an example and is NOT tested, but the logic should get you closer to your goal:

$Yesterday = Get-Date ((Get-Date).AddDays(-1)) -Format yyyy-MM-dd
$sites = "CDH", "FH", "SCDC", "SVH", "RASLO"

foreach ($site in $sites) {
    $source = "D:\ininbound\{0}\archive\" -f $site
    $destination = "D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-{0}\Reports-{0}-{1}.zip" -f $site, $yesterday
    $files = Get-ChildItem -Path $source | Where{$_.CreationTime -gt (Get-Date).AddDays(-1)}

    if ($files.Count -gt 0) {
        foreach ($file in $files) {
            $args = @()
            $args += "a" #switch for add
            $args += $file.FullName
            $args += $destination

            $results = (Start-Process -FilePath "C:\Program Files\7-zip\7z.exe" -ArgumentList $args -Wait).ExitCode
            if ($results -ne 0) {
                "Successfully added {0} to {1}" -f $file.FullName, $source
            else {
                "Failed to add {0} to {1}.  Exit Code: {1}" -f $file.FullName, $source, $results
    else {
        "No files to zip in {0}" -f $source

To understand the dynamic path approach, this is basically just building the paths:

$Yesterday = Get-Date ((Get-Date).AddDays(-1)) -Format yyyy-MM-dd
$sites = "CDH", "FH", "SCDC", "SVH", "RASLO"

foreach ($site in $sites) {
    $source = "D:\ininbound\{0}\archive\" -f $site
    $destination = "D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-{0}\Reports-{0}-{1}.zip" -f $site, $yesterday

    "Get files in {0} and zip them in {1}" -f $source, $destination
Get files in D:\ininbound\CDH\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-CDH\
Get files in D:\ininbound\FH\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-FH\
Get files in D:\ininbound\SCDC\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SCDC\
Get files in D:\ininbound\SVH\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SVH\
Get files in D:\ininbound\RASLO\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-RASLO\

Thanks Curtis for the “point-outs”. I will work on those. I appreciate your time in reading the post.

Thanks Kristoffer. I appreciate the tips. I will work on that.

Rob, thank you. I’m going to print all this out and start hand writing it all out. Thank you for the direction. I do appreciate it. These are my first attempts and scripting this out. I do it all manually. So this will help!

I’ve been tinkering over the weekend with my code. Thank you all for your suggestions. I realized that not all my sites (sources) are in the same path. One of the source directories is in a different location:
D:\reports\dr_reports and D:\reports\dr_reports\archive
So I think I need to add a foreach section to handle this one source directory. Is there any easier way to do that?
The zip files are being created with the dynamic file name! I love it! However, they aren’t writing to my destination directories. They are writing to an archive directory in my source paths. What am I missing?


I believe that is because the 7zip parameter for destination is the same as the one for filename, so instead og doing


and then $destination you need to write

and remove the final $destination variable from $args.

Im typing on my phone right now, sorry for the bad formatting. If this doesn’t work i will post my own 7zip function that i use for work tomorrow.

Kind Regards