Search code examples
powershellzipoutputcompressionarchive

In Powershell, how to make the zip output name the same as the input name


I'm writing a simple ps1 script to automatically zip up log files to their own individual zip archives (I'll ultimately use Task Scheduler to schedule), and I want the output name to be the same as the input name (e.g. Log_20210309.log > Log_20210309.zip)

I feel like I'm so close. The below example looks for *.log files with yesterday's date in the filename, and where I need help is piping the filename to the zip output filename.

$Input = "C:\Script\Input\"
$Output = "C:\Scripts\Output\"

Get-ChildItem $Input -Filter *$((Get-Date).AddDays(-1).ToString('yyyyMMdd')).log | Compress-Archive -DestinationPath $Output$_.FileName -Force

The Get-ChildItem part seems to work OK (the script works if I replace everything after the pipe with Compress-Archive -DestinationPath $Output -Force, but the output filename will be blank (".zip")). I've tried dozens of variations of the piped section, including:

Compress-Archive -DestinationPath $Output + $_.FileName -Force
Compress-Archive -DestinationPath $Output + "$_.FileName" -Force
ForEach-Object { Compress-Archive -DestinationPath $Output"$_.FileName" -Force }
ForEach-Object { Compress-Archive -DestinationPath $Output + "$_.FileName" -Force }

and so on...


Solution

  • This script uses variables for the source directory, destination directory, and filename extension to compress. When it is compressing the correct files, remove the -WhatIf from the Compress-Archive command.

    $SourceDir = 'C:\Script\Input'
    $OutputDir = 'C:\Script\Output'
    $Extension = '.log'
    
    Get-ChildItem -File -Recurse -Path $SourceDir -Filter $('*' + $Extension) |
        ForEach-Object {
            Compress-Archive `
                -DestinationPath (Join-Path $OutputDir $($_.BaseName + '.zip')) `
                -Path $_.FullName -WhatIf
        }