As part of an upcoming deployment, I’ve been getting intimate with AWS OpsWorks and Chef. What I mean by Chef is, using the PowerShell resource in Chef. I was recently looking for a way to save some time on a deployment, when I considered removing the unzipping of files downloaded from S3. I wanted to know if there would be a time savings in getting the files to the EC2 Instance in their decompressed format.
This brought me over to my console to compare the newer Expand-Archive cmdlet and .NET. I’ve always considered that dropping down to .NET is a time savings.
In my Chef recipe I’m using .NET for decompression, as I’m deploying to Windows Server 2012 R2 and it includes PowerShell 4.0 by default. The Compress-Archive and Expand-Archive cmdlets were introduced in PowerShell 5.0. This isn’t to say I couldn’t get PowerShell 5.0 in place, but I needed to know if it would even be necessary.
I had a little testing to do. The below command measured the time it took to expand a 133MB zip file using .NET.
Measure-Command -Expression { Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory('C:\Users\tommymaynard\Desktop\HCM-920-UPD-018-WIN_1of10.zip','C:\Users\tommymaynard\Desktop\unzip\') }
When the command was run five separate times, it resulted in following times: 9 seconds 393 milliseconds, 9 seconds 117 milliseconds, 9 seconds 455 milliseconds, 8 seconds 489 milliseconds, and 10 seconds 338 milliseconds. I wasn’t loosing any time by unzipping this file.
The below command does the same thing as the one above; however, it uses the Expand-Archive cmdlet introduced in PowerShell 5.0.
Measure-Command -Expression { Expand-Archive -Path 'C:\Users\tommymaynard\Desktop\HCM-920-UPD-018-WIN_1of10.zip' -OutputPath 'C:\Users\tommymaynard\Desktop\unzip\' }
I executed the above command five times, too. The results were 2 minutes 11 seconds, 2 minutes 9 seconds, 2 minutes 10 seconds, 2 minutes 13 seconds, and 2 minutes 11 seconds.
This is a huge difference in time. Now, I do want to mention that I tested this on Windows 8.1 with PowerShell 5.1 (it’s in preview). The results may be better on different versions of Windows and with different versions of PowerShell. Let me know if you see different results with different configurations, and maybe I’ll do the same. The point is this, however: If you have a reason to speed up your project, you might consider .NET over a PowerShell cmdlet, or function. It seems I’m glad I did. Be sure you test different ways, to do the same thing.