Summary: Use Windows PowerShell to create a .zip archive of multiple folders.
Hey, Scripting Guy! I need to compress multiple folders before I attempt to archive them. I would like to do this without having to install additional software. Can you help?
—DR
Hello DR,
Microsoft Scripting Guy, Ed Wilson, is here. This afternoon I am sipping a red berry tea and munching on a chocolate biscotti. Maybe it is not too exciting, but it is relaxing. I am looking over my email sent to scripter@microsoft.com on my Surface 3 Pro, and things are good.
One of the cool things about the free update to Windows 8.1 from Windows 8 is that in addition to including Windows PowerShell 4.0, it includes .NET Framework 4.5, which is way cool. The thing I love the best is the improved compression classes. It makes working with .zip files a piece of cake.
I have a folder on my laptop that I use for backing up files, creating archives, and stuff like that. So, I do not need to check to see if a folder exists or worry about overwriting such a folder. Here is the path assignment in my script:
$path = "C:\backup"
I use the Get-ChildItem cmdlet to find all of the folders I want to archive. In this example, I want to archive all of my FSO* types of folders. I test my command before I add it to my script. This is the command and its output:
PS C:\> Get-ChildItem -Path c:\ -Filter "fso?" -Directory
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/4/2015 9:47 AM fso
d---- 3/9/2015 3:28 PM fso1
d---- 3/9/2015 3:28 PM fso2
d---- 3/9/2015 3:28 PM fso3
The cool thing is that in the Windows PowerShell ISE, I can highlight only the portion of the command I want to use, and that is what runs. So my actual command will be:
$source = Get-ChildItem -Path c:\ -Filter "fso?" -Directory
I know that this returns a DirectoryInfo object, and that I need to access specific properties to get to the individual folder paths—but I will do that later.
I need to add the assembly that contains the compress classes, so I do this here:
Add-Type -assembly "system.io.compression.filesystem"
I now need to create the destination path for each archive I will create. I do this inside a loop that walks through my collection of DirectoryInfo objects. This script is shown here:
Foreach ($s in $source)
{
$destination = Join-path -path $path -ChildPath "$($s.name).zip"
I keep only one archive of a folder in my Backup folder at a time, so if the archive exists, I want to delete it. Here is the script that accomplishes that task:
If(Test-path $destination) {Remove-item $destination}
Now it is the simple task of creating the archive. Here is the command:
[io.compression.zipfile]::CreateFromDirectory($s.fullname, $destination)
The complete script is shown here:
$path = "C:\backup"
$source = Get-ChildItem -Path c:\ -Filter "fso?" -Directory
Add-Type -assembly "system.io.compression.filesystem"
Foreach ($s in $source)
{
$destination = Join-path -path $path -ChildPath "$($s.name).zip"
If(Test-path $destination) {Remove-item $destination}
[io.compression.zipfile]::CreateFromDirectory($s.fullname, $destination)}
I check to see if the archives exist. As shown in the following image, they do:
DR, that is all there is to using Windows PowerShell to create a .zip archive of multiple folders. Zip Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy