Compressing a file in Powershell & Waiting for it
Windows doesn’t have a standard command line tool for zipping a file. If you are writing a powershell script for portability you can’t depend on a third party tool. The energized tech has a post how to compress a file without a 3rd party tool. It’s very clever. His SEND-ZIP script uses a COM proxy object to the shell.application object to create an empty compressed folder. Then the script copies the target file into the compressed folder and the shell.application is smart of enough to compress the file and then move it into the folder. However, the compression and copying is done asynchronously. This can be problematic if you want to, say, delete the file you put into the archive. You want to make sure the copy succeeded before you delete it. To address that I wrote two additional functions that blocks until a certain number of items are in the archive.
Here’s how I use it:
"compressing datafile to $zipname" send-zip $zipname $datafh wait-zipcount $zipname 1
Here’s the code for wait-zipcount:
function wait-zipcount([string] $zipname, [int] $num) {
$ExplorerShell=NEW-OBJECT -comobject 'Shell.Application'
$count = count-zipfiles -zipname $zipname -ExplorerShell $ExplorerShell
"waiting on zip [$count/$num]..."
while (($count -eq $NULL) -or ($count -lt $num) ) {
"waiting on zip [$count/$num]..."
Start-Sleep -milliseconds 100
$count = count-zipfiles -zipname $zipname -ExplorerShell $ExplorerShell
}
}
and you'll need count-zipfiles:
function count-zipfiles([string] $zipname, [object] $ExplorerShell=$NULL) {
if ((test-path $zipname) -eq $NULL) {
return $NULL
}
if ($ExplorerShell -eq $NULL) {
$ExplorerShell = NEW-OBJECT -comobject 'Shell.Application'
}
$zipdirfh = $ExplorerShell.Namespace($zipname)
$count = $zipdirfh.Items().Count
return $count
}