Use PowerShell to Create ZIP Archive of Folder


Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to create a .zip archive of a folder.

Hey, Scripting Guy! Question Hey, Scripting Guy! I need a way to create a .zip archive of a folder. I would like to do this on my laptop running Windows 8.1, and I do not want to install any other software. Can I do this?

—TR

Hey, Scripting Guy! Answer Hello TR,

Microsoft Scripting Guy, Ed Wilson, is here. The weed eater dude is outside. The guy is really dedicated to his job. I mean, the snow has barely cleared, and he is out there chopping away with his weed eater. I really enjoy hearing him, because it fills me with hope that summer is on its way, and that soon we will have warm weather and we can get outside without having to bundle up.

Certainly I can put on a coat and hop on my bicycle, but I learned (the hard way) a long time ago that trying to ride a bicycle when there is ice on the road is not the smartest thing to do (at least not for me). So I prefer to wait until the snow melts, the ice thaws, and the sun is out before taking to the open road.

TR, luckily, you do not need to wait for anything before you can use Windows PowerShell to create a .zip archive. You have everything you need—and that is .NET Framework 4.5.

The ZipFile .NET Framework class was introduced with .NET Framework 4.5, and Windows 8.1 ships with .NET Framework 4.5 installed. This is really cool because this class is extremely easy to use.

The ZipFile class is not available by default in Windows PowerShell because the System.IO.Compression.FileSystem assembly is not loaded by default. Therefore, I want to load the assembly. The best way to do this is to use the Add-Type cmdlet and specify the name of the assembly as an argument to the –Assembly parameter. This is the command:

Add-Type -assembly "system.io.compression.filesystem"

The ZipFile .NET Framework class has a static method named CreateFromDirectory. This method accepts two arguments: a source directory and a destination file. The source directory and the destination file cannot reside in the same directory. This is due to file locking, and it will generate the following  error message:

Image of error message

When you are using this method, if the file archive file already exists, the following error message appears:

Image of error message

To fix this issue, I add a Test-Path command to delete the archive file if it already exists. This is shown here:

If(Test-path $destination) {Remove-item $destination}

The CreateFromDirectory method is easy to use. It is a static method, so I can access it directly from the ZipFile class. Also it takes two arguments, Source and Destination, so the method call makes sense. Here is the command I use:

[io.compression.zipfile]::CreateFromDirectory($Source, $destination)

For the complete script, I add Source and Destination as variables at the beginning of the script. Remember, Source is a directory and Destination is a file that will hold my .zip archive. Here is the complete script:

$source = "C:\fso"

$destination = "C:\fso1\FSO_Backup.zip"

 If(Test-path $destination) {Remove-item $destination}

Add-Type -assembly "system.io.compression.filesystem"

[io.compression.zipfile]::CreateFromDirectory($Source, $destination) 

Now when I run the script, an archive appears in my destination folder. The archive contains all of the files from the source. This is shown here:

Image of folder

TR, that is all there is to using Windows PowerShell to create a .zip archive of a folder. 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 

Comments (19)

  1. Wayne says:

    Is there a built in method to delete from the source after validating that the target zip was created successfully?

  2. nick says:

    we integrated winzip cmd line tools a couple years ago for log file management. if you don’t already have a validation method and want some that are built in to PS I would recommend using get-filehash on the source and destination files, and only if the
    hashes match, remove-item on the source.

  3. sadsa says:

    dsadasda

  4. sadsa says:

    dsadasda

  5. Jakes says:

    Hi SG

    I’m not sure what i’m doing wring here. I have made sure that i’m using Dotnet 4.5 though i’m getting the following error.

    Add-Type : Cannot add type. The assembly ‘system.io.compression.filesystem’ could not
    be found.
    At C:BACKUPSet_Back.ps1:13 char:9
    + Add-Type <<<< -assembly "system.io.compression.filesystem"
    + CategoryInfo : ObjectNotFound: (system.io.compression.filesystem:Stri
    ng) [Add-Type], Exception
    + FullyQualifiedErrorId : ASSEMBLY_NOT_FOUND,Microsoft.PowerShell.Commands.AddTy
    peCommand

    Add-Type : Cannot add type. One or more required assemblies are missing.
    At C:BACKUPSet_Back.ps1:13 char:9
    + Add-Type <<<< -assembly "system.io.compression.filesystem"
    + CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationException
    + FullyQualifiedErrorId : ASSEMBLY_LOAD_ERRORS,Microsoft.PowerShell.Commands.Add
    TypeCommand

    Unable to find type [io.compression.zipfile]: make sure that the assembly containing

    this type is loaded.
    At C:BACKUPSet_Back.ps1:15 char:25
    + [io.compression.zipfile] <<<< ::CreateFromDirectory($Source, $destination)
    + CategoryInfo : InvalidOperation: (io.compression.zipfile:String) [],
    RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

  6. Sonny says:

    Interesting…getting an access denied error.

    I’m attempting to zip my user directory and put it on a shared drive, but the access denied is on my user folder.

    Exception calling "CreateFromDirectory" with "2" argument(s): "Access to the path ‘C:UsersschildsApplication Data’ is denied."
    At line:9 char:1
    + [io.compression.zipfile]::CreateFromDirectory($source, $destination)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : UnauthorizedAccessException

  7. Jennifer says:

    I am getting an error trying to load the assembly. Add-Type : Cannot add type. The assembly ‘system.io.compression.filesystem’ could not
    be found.

    I have .Net 4.5. any thoughts?

  8. Gary says:

    I am able to create zip file no problem.
    In explore if I single click on the zip file I can see and even navigate the directory structure of the zip file in the preview pane.

    However if I click on the zip file to open, it shows empty. If I right click on it and say extract I get an error that it is not a valid compressed folder.

    Then just to really confuse things, If I use winzip, it will uncompress fine.

    Anyone else seen this?

    Welcome to my world!

  9. Ken says:

    I’m stumped on this error:

    Exception calling "CreateFromDirectory" with "2" argument(s): "The process cannot access the file ‘C:exampleexample.log’ because it is being used by another process."

    How can I close the handle on the file? dispose is not working.

  10. Dennis says:

    Could Anti-Virus be getting in the way during the zip file creation?

  11. Joachim says:

    How can I validate that the zip was created successfully (with all files in the zip)?

    "$test=[io.compression.zipfile]::CreateFromDirectory($Source, $destination) "
    does not give me any info in $test.

  12. Joachim says:

    How can I validate that the zip was created successfully (with all files in the zip)?

    "$test=[io.compression.zipfile]::CreateFromDirectory($Source, $destination) "
    does not give me any info in $test.

  13. Paul M says:

    Hi, Can I use this method to password protect the zip file and if so how?

  14. Dusan says:

    Dear Joachim,
    my humble opinion … why you call "$test=[io.compression.zipfile]::CreateFromDirectory($Source, $destination) " if this CREATE ZIP FILE FROM DIRECTORY while you can use Test-Path $test … ?

  15. AK says:

    Hello Ed, could you shed some light on how to password protect these archives? Thank you!

  16. jessie says:

    I noticed when creating a zip file with this method, The compression method is Deflated, yet when compressing with the GUI it is Deflated 64. The end result being a more compressed file with the GUI than the script. Is there a way to invoke Deflated 64
    into the script?

  17. Matt says:

    It appears io.compression has a bug – [io.compression.file]::ExtractToDirectory fails to decompress for zip files bigger than about 4GB.

  18. David says:

    >> You have everything you need

    Really?

    People manually generate zip headers (http://blogs.msdn.com/b/jerrydixon/archive/2014/08/08/zipping-a-single-file-with-powershell.aspx) or use com objects just because *current* api (https://msdn.microsoft.com/en-us/library/system.io.compression.zipfile.aspx) does not include [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile

  19. Justin says:

    Why is everything in Windows always such a PITA? This should be so simple to do, yet of course in Windows it isn’t.

    All I want to do it make a zip file or cab using the command line and without using %TEMP%. In other words, do something that UNIX has been able to do for over thirty years.

Skip to main content