Code for automating incremented ZIP compression? - powershell

I'm trying to ZIP a folder of 800 pictures, with each ZIP file containing only 10 or less pictures, so I should end up with 80 ZIP files. If anyone knows the BAT file code to do this, I would be very appreciative. I also do NOT want to delete the files after they've been zipped.
I know that I'll probably be using 7-Zip, but I just can't seem to find an answer for this anywhere. Thanks!

Try the following PowerShell:
# Setup variables (Change)
$ZipFolder = "T:\YourFolder\WithFiles\ToZip"
$7Zip = "C:\Program Files\7-Zip\7z.exe"
$NewZipsFolder = "T:\FolderToPut\AllOfThe\ZipsIn"
# Script Variables
$pendingFiles = #()
$fileNumber = 1
# Get a list of all the files to be zipped
Get-ChildItem $ZipFolder | sort $_.FullName | ForEach-Object { $pendingFiles += $_.FullName }
# While there are files still to zip
While($pendingFiles){
# Select first 10 files to zip and zip them
$ToZip = $pendingFiles | Select -First 10
& $7Zip "a" "$NewZipsFolder\File-$fileNumber.7z" $ToZip
# Remove first 10 zipped files from pending files array
$pendingFiles = $pendingFiles | Where-Object { $ToZip -notcontains $_ }
$fileNumber++
}
This will create a list of all the file that need to be zipped. Then zip them up in batches of 10 files using 7z.exe (7-zip).
Note: For the variables $ZipFolder & $NewZipsFolder do not put a trailing backslash on the folder paths (\).

You could store an list of files in Powershell using something along the lines of
$fileList = Get-Item -Path "C:\MyPhotosDir\*"
Then set an alias for 7zip
set-alias sz "$env:ProgramFiles\7-Zip\7z.exe"
Then create a loop with a counter along the lines of
$i = 1
foreach $file in $fileList
#Build foder name name
$folderDir = "C:\MyPhotoArchive$($i - ($i % 10) + 1).7z"
sz a -t7z $folderDir $file.filename
end for
I have been writing in VB for a short while and so apologies if the Powershell syntax is a bit off. Essentially that should add 10 files to "C:\MyPhotoArchive1", 10 files to "C:\MyPhotoArchive2". I haven't added files to an archive using 7zip for a long time but I think the call just uses a a and should add files to an archive, creating one when needed.

Related

Compress File per file, same name

I hope you are all safe in this time of COVID-19.
I'm trying to generate a script that goes to the directory and compresses each file to .zip with the same name as the file, for example:
sample.txt -> sample.zip
sample2.txt -> sample2.zip
but I'm having difficulties, I'm not that used to powershell, I'm learning and improving this script. In the end it will be a script that deletes files older than X days, compresses files and makes them upload in ftp .. the part of excluding with more than X I've already managed it for days, now I grabbed a little bit on this one.
Last try at moment.
param
(
#Future accept input
[string] $InputFolder,
[string] $OutputFolder
)
#test folder
$InputFolder= "C:\Temp\teste"
$OutputFolder="C:\Temp\teste"
$Name2 = Get-ChildItem $InputFolder -Filter '*.csv'| select Name
Set-Variable SET_SIZE -option Constant -value 1
$i = 0
$zipSet = 0
Get-ChildItem $InputFolder | ForEach-Object {
$zipSetName = ($Name2[1]) + ".zip "
Compress-Archive -Path $_.FullName -DestinationPath "$OutputFolder\$zipSetName"
$i++;
$Name2++
if ($i -eq $SET_SIZE) {
$i = 0;
$zipSet++;
}
}
You can simplify things a bit, and it looks like most of the issues are because in your script example $Name2 will contain a different set of items than the Get-ChildItem $InputFolder will return in the loop (i.e. may have other objects other than .csv files).
The best way to deal with things is to use variables with the full file object (i.e. you don't need to use |select name). So I get all the CSV file objects right away and store in the variable $CsvFiles.
We can additionally use the special variable $_ inside the ForEach-Object which represents the current object. We also can use $_.BaseName to give us the name without the extension (assuming that's what you want, otherwise use $_Name to get a zip with the name like xyz.csv).
So a simplified version of the code can be:
$InputFolder= "C:\Temp\teste"
$OutputFolder="C:\Temp\teste"
#Get files to process
$CsvFiles = Get-ChildItem $InputFolder -Filter '*.csv'
#loop through all files to zip
$CsvFiles | ForEach-Object {
$zipSetName = $_.BaseName + ".zip"
Compress-Archive -Path $_.FullName -DestinationPath "$OutputFolder\$zipSetName"
}

PowerShell: How to copy only ".exe" file from ZIP folder to another folder

I have a "ZIP" file and when we extract this, we have 1 "EXE" file within 4-5 sub folder depth level.
I would like to grab that "EXE" file and copy into another folder. How to do it using PowerShell?
I tried below, but it will copy all the ZIP content,
$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("Source Path")
foreach ($item in $zip.items()) {
$shell.Namespace("Destination Path").CopyHere($item)
}
Simple snippet should get your job done
#Sets the variable to the Source folder, recurse drills down to folders within
$Source = get-childitem "C:\Users" -recurse #"C:\Users" an example
#Filters by extension .exe
$List = $Source | where {$_.extension -eq ".exe"}
#Copies all the items to the specified destination
$List | Copy-Item -Destination "C:\Scripts" #"C:\Scripts" an example
The module above scans for every single .EXE files within C:\Users* and copies them to C:\Scripts
As it stands, Clint's answer did not work for me, but something based on Extract Specific Files from ZIP Archive does, with a variation to target a specifically named file. Will need a further tweak to handle multiple files sharing the same name.
Code:
# Set source zip path, target output directory and file name filter
$ZipPath = 'C:\temp\Test.zip'
$OutDir = 'C:\temp'
$Filter = 'MyExe.exe'
# Load compression methods
Add-Type -AssemblyName System.IO.Compression.FileSystem
# Open zip file for reading
$Zip = [System.IO.Compression.ZipFile]::OpenRead($Path)
# Copy selected items to the target directory
$Zip.Entries |
Where-Object { $_.FullName -eq $Filter } |
ForEach-Object {
# Extract the selected items from the zip archive
# and copy them to the out folder
$FileName = $_.Name
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$OutDir\$FileName", $true)
}
# Close zip file
$Zip.Dispose()

Extract zip file and concatenate the extracted content

I have multiple zip files which I want to unzip and concatenate its content to a single file. I do not need each of these unzipped files thus prefer that they never get created if possible.
I need to do this in powershell and only have access to version 2.0.
Currently using 7zip to perform the unzipping. If I do the unzip without attempting to concatenate the output, I end up with all the extracted files using following command.
# all the zip files (10000 of them)
$logs = Get-ChildItem $folders[$i] -filter "*$stake).zip"
foreach ($log in $logs) {
Write-Host $log
& '7z' e $log
}
Attempting to concatenate all the files via following command but I still end up with all the extracted files and the combined.txt file contains repetition of following text. Please advice. Thanks.
# all the zip files (10000 of them)
$logs = Get-ChildItem $folders[$i] -filter "*$stake).zip"
foreach ($log in $logs) {
Write-Host $log
& '7z' e $log >> combined.txt
}
Text being repeated
7-Zip [64] 16.04 : Copyright (c) 1999-2016 Igor Pavlov : 2016-10-04
Scanning the drive for archives: 1 file, 7796 bytes (8 KiB)
Extracting archive: 0000_0000_0000 Game Log (name at 86% staking
25).zip
-- Path = 0000_0000_0000 Game Log (name at 86% staking 25).zip Type = zip Physical Size = 7796
Further clarifications:
I have 10000 zip files.
Upon extraction, each file content = "Hello".
I want to concatenate all these file contents into 1 single file.
Thus single file content will be -
"Hello"
"Hello"
"Hello"
... 10000 times
All I want is this single file which has the concatenated data.
AFAIK ZIP files need to be extracted before they can be read. Even in the case of ZIP browsers, when you "open" a file in it the file is extracted to a temporary location first.
So that's basically what you need to be doing:
$logs = Get-ChildItem $folders[$i] -filter "*$stake).zip"
New-Item -Name "Temp" -ItemType Directory
$output = #()
foreach ($log in $logs) {
Write-Host $log
& '7z' e $log -o"Temp" | Out-Null
Get-ChildItem "Temp" | Foreach-Object {
$output += Get-Content $_.FullName
Remove-Item $_
}
}
Remove-Item "Temp"
$output | Out-File "FullLog.txt"
This goes through each file, extracts it (ignores output of 7zip as it's informational only), reads the content of the extracted file then deletes it. Afterwards it cleans up and writes the total output to a file.

7zip - powershell exclude files/folders with variable

I'm trying to zip a folder but exclude multiple directories using powershell.
I got the following:
if (-not (test-path "$env:ProgramFiles\7-Zip\7z.exe")) {throw "$env:ProgramFiles\7-Zip\7z.exe needed"}
set-alias sz "$env:ProgramFiles\7-Zip\7z.exe"
$Source = "D:\Zip\*"
$Target = "D:\backup.7z"
$exclude = 'Customer\Images\*'
sz a -xr!'$Customer\Images\*' $Target $Source
This works fine.. But when I want the change the -xr! to -xr!'$exclude' or -xr!$exclude it stops working for some reason. Does the variable assigned above not get parsed?
Try this...
if (-not (Test-Path "$env:ProgramFiles\7-Zip\7z.exe")) {throw "$env:ProgramFiles\7-Zip\7z.exe needed"}
$7ZipPath = "$env:ProgramFiles\7-Zip\7z.exe"
$Source = "D:\Zip\*"
$Target = "D:\backup.7z"
$foldersToExclude = 'folder1', 'folder2'
$7zipParams = #('a',$Target)
#($foldersToExclude) | ForEach-Object { $7zipParams += "`"-xr!$_`"" }
$7zipParams += $Source
Write-Host ($7ZipPath+' '+$7zipParams -join ' ') # debug - show the command line
&$7ZipPath $7zipParams
We create an array of params to pass into 7zip, including the excluded folders. As we're appending the excluded folders, we prepend the folder names with the -xr! flags and wrap these in double qoutes.
The #debug line outputs the resultant command line to the console
I call 7zip slightly differently to you, by creating a string with the 7zip executable, then prepending the call to that string path with an ampersand.
This method can exclude multiple folders from the final archive, including folder\subfolder structure.
Two things:
Use the variable inside double quotes if you want it to be expanded:sz a "-xr!$exclude" $Target $Source
Using the pattern Customer\Images\* excludes all files in the directory Images, but includes an empty directory in the resulting file. Use Customer\Images if you don't want to include the directory (or any of its files).

Powershell script to extract Cab file contents and move files to new locations

I've been given 14K CAB files each containing 200 files which need to be unzipped into their original locations.
Unfortunately it's not as easy as all of them being extracted to the same location :-(
I've decided to use PowerShell and have generated a list of individual file locations for each file using SQL and can extract the CABs, unfortunately they all extract to the current location.
I am trying to move them to their respective locations, but am struggling.
Here's the code, I've got so far
$shell_app=new-object -com shell.application
$CABfilename= Import-CSV "CABFileList.csv" -Header CABfilename | Foreach-object {
$zip_file = $shell_app.namespace((Get-Location).Path + "\$CABfilename")
$destination = $shell_app.namespace((Get-Location).Path)
$destination.Copyhere($zip_file.items())
$dvs = Import-csv "CABFileList.csv" -Header Path, DVSFilename |
Foreach-object{
Move-item $_.DVSFilename* $_.Path
}
This is an old question, but someone might find the answer useful anyway. I have adapted one I made today to download all WSPs from a farm and extract their contents.
$CABfilename = Import-CSV "CABFileList.csv" -Header CABfilename | Foreach-object {
# Grab the Solution
$Path = $SaveLocation + $CABfilename
# Check the path is ok
$Path
# Make a copy with extension '.cab' for extraction
$DotCab = $CABfilename + ".cab"
$SolutionDir = $Dotcab -replace '.wsp.cab'
mkdir $SolutionDir
copy-item $CABfilename $DotCab
# Now extract it, assuming you have expand.exe in the filsystem (should be in everything post Server 2008 / Vista)
if(C:\Windows\System32\expand.exe) {
try { cmd.exe /c "C:\Windows\System32\expand.exe -F:* $Dotcab $SolutionDir"}
catch { Write-host "Nope, don't have that, soz."}
}}