When zipping folders using Compress-Archive it skips all hidden files.
The Documentation page tells us that this cmdlet uses Microsoft .NET Framework API System.IO.Compression.ZipArchive in the background.
Is there some way to force it to archive hidden files? I cannot find this issue documented anywhere. I tried -Force
for the heck of it, didn't help.
My current workaround is to use Set-FileAttribute
to remove the hidden attribute before zipping.
This looks like a bug/oversight in the Compress-Archive
cmdlet. Since the cmdlet provides no "include hidden files" parameter but does accept a collection of source files via the -Path
or -LiteralPath
parameters, I would expect either this...
Compress-Archive -Path (
Get-ChildItem -Path '...' -Force `
| Select-Object -ExpandProperty 'FullName' `
) -DestinationPath '...'
...or this...
Get-ChildItem -Path '...' -Force | Compress-Archive -DestinationPath '...'
...to work as a way of passing hidden files to the cmdlet; the key being specifying the -Force
parameter for Get-ChildItem
. Both of those invocations, however, throw these errors...
Get-Item : Could not find item ....
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:814 char:63
+ ... Entry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (...:String) [Get-Item], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand
Exception setting "LastWriteTime": "Cannot convert null to type "System.DateTimeOffset"."
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:814 char:25
+ ... $currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
...for the first hidden file in the input list. (Note that invoking the first snippet without Select-Object -ExpandProperty 'FullName'
instead throws Compress-Archive : The path '...' either does not exist or is not a valid file system path.
.)
On my system, the referenced lines 812-814 of Microsoft.PowerShell.Archive.psm1
are...
# Updating the File Creation time so that the same timestamp would be retained after expanding the compressed file.
# At this point we are sure that Get-ChildItem would succeed.
$currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime
So, even if we pass -Force
to Get-ChildItem
to get the paths of hidden file objects to pass to Compress-Archive
, internally the cmdlet is fetching those file objects again using Get-Item
...but it's not passing -Force
, which of course will fail (despite what the comment on the previous line claims). Thus, I don't think there's any way to get Compress-Archive
to work with hidden files without either you or Microsoft editing that script.