Need help using Powershell to zip files from YESTERDAY

This topic contains 8 replies, has 4 voices, and was last updated by  Kristoffer Berg 11 months, 2 weeks ago.

  • Author
    Posts
  • #54562

    Gina Bautista
    Participant

    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
    #
    try
    {
    $logpath = "D:\Report-Copy-Move\Logs\Zip_reports_results.txt"
    
    SET HOUR=%TIME:~0,2%
    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\Reports-Arroyo-%YESTERDAY%.zip'
    $Destination_FH = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-French_Arroyo\Reports-French-%YESTERDAY%.zip'
    $Destination_SCDC = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SCDC\Reports-SCDC-%YESTERDAY%.zip'
    $Destination_SVH = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-Sierra\Reports-Sierra-%YESTERDAY%.zip'
    $Destination_Raslo = 'D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-Raslo\Reports-Raslo-%YESTERDAY%.zip'
    
    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)"
                }
                else
                {
                    #Zip Failed, throw error
                    Add-content -Path $logpath -value "Zip of failed: {1} $($zip.FileName) $($zip.Error.Message)"
                }
        }
        finally
        {
           # Clean up
            $session.Dispose()
            Add-content -Path $logpath -value "Zip of reports completed"
        }
     
        exit 0
    }
    catch [Exception]
    {
        Add-content -path $logpath -value $_.Exception.Message
        exit 1
    }
    
  • #54565

    Curtis Smith
    Participant

    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.

    • #54699

      Gina Bautista
      Participant

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

  • #54576

    Kristoffer Berg
    Participant

    Hi!

    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 🙂

    • This reply was modified 12 months ago by  Kristoffer Berg. Reason: Missed a closing bracket in example
    • #54700

      Gina Bautista
      Participant

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

  • #54610

    Rob Simmers
    Participant

    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\Reports-CDH-2016-09-25.zip
    Get files in D:\ininbound\FH\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-FH\Reports-FH-2016-09-25.zip
    Get files in D:\ininbound\SCDC\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SCDC\Reports-SCDC-2016-09-25.zip
    Get files in D:\ininbound\SVH\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-SVH\Reports-SVH-2016-09-25.zip
    Get files in D:\ininbound\RASLO\archive\ and zip them in D:\00-ZIPS-TO-SEND-TO-ZOTEC\Reports-RASLO\Reports-RASLO-2016-09-25.zip
    
    • #54701

      Gina Bautista
      Participant

      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!

    • #54851

      Gina Bautista
      Participant

      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?

  • #54937

    Kristoffer Berg
    Participant

    Hi

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

    $file.FullName

    and then $destination you need to write

    "$destination\$($file.Name)"

    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
    Kristoffer

You must be logged in to reply to this topic.