Skip to content

Unable to compress hidden files with Compress-Archive #66

@LanceUMatthews

Description

@LanceUMatthews

The following code demonstrates two issues:

  1. When passing a directory to the -Path parameter of Compress-Archive, any hidden files are silently ignored; they are neither present in the output file nor mentioned in the -Verbose output. (This behavior is also not mentioned in the documentation.)
  2. When passing hidden files to the -Path parameter of Compress-Archive...
    • ...in PowerShell the first hidden file encountered causes errors to be thrown and output file creation to fail.
    • ...in PowerShell Core output file creation succeeds but each hidden file encountered causes an error to be thrown and the corresponding compressed file entry has its modification timestamp set to 1980-01-01.

Code to reproduce:

$directoryToCompress = New-Item -ItemType Directory -Path 'Input';
$filesToCompress = @();

foreach ($id in 1..5)
{
    $file = New-Item -ItemType File -Path $directoryToCompress -Name "$id.txt" -Value "Hello, World!  This is file #$id.";
    if ($id % 2 -eq 0)
    {
        $file.Attributes = $file.Attributes -bor [System.IO.FileAttributes]::Hidden;
    }

    $filesToCompress += $file;
}

$PSVersionTable;

Compress-Archive -Path $directoryToCompress -DestinationPath 'FromDirectory.zip' -Verbose;
Compress-Archive -Path $filesToCompress     -DestinationPath 'FromFiles.zip'     -Verbose;

PowerShell console output:

Name                           Value
----                           -----
PSVersion                      5.1.17763.134
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.134
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
VERBOSE: Preparing to compress...
VERBOSE: Performing the operation "Compress-Archive" on target "C:\Compress-Archive test\Input".
VERBOSE: Adding 'C:\Compress-Archive test\Input\1.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\3.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\5.txt'.
VERBOSE: Preparing to compress...
VERBOSE: Performing the operation "Compress-Archive" on target "
C:\Compress-Archive test\Input\1.txt
C:\Compress-Archive test\Input\2.txt
C:\Compress-Archive test\Input\3.txt
C:\Compress-Archive test\Input\4.txt
C:\Compress-Archive test\Input\5.txt".
VERBOSE: Adding 'C:\Compress-Archive test\Input\1.txt'.
Get-Item : Could not find item C:\Compress-Archive test\Input\2.txt.
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: (C:\Compress-Archive test\Input\2.txt:String) [Get-Item], IOException
	+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand

VERBOSE: The partially created archive file 'C:\Compress-Archive test\FromFiles.zip' is deleted as it is not usable.
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

PowerShell Core console output:

Name                           Value
----                           -----
PSVersion                      6.1.1
PSEdition                      Core
GitCommitId                    6.1.1
OS                             Microsoft Windows 10.0.17763
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
VERBOSE: Preparing to compress...
VERBOSE: Performing the operation "Compress-Archive" on target "C:\Compress-Archive test\Input".
VERBOSE: Adding 'C:\Compress-Archive test\Input\1.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\3.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\5.txt'.
VERBOSE: Preparing to compress...
VERBOSE: Performing the operation "Compress-Archive" on target "
C:\Compress-Archive test\Input\1.txt
C:\Compress-Archive test\Input\2.txt
C:\Compress-Archive test\Input\3.txt
C:\Compress-Archive test\Input\4.txt
C:\Compress-Archive test\Input\5.txt".
VERBOSE: Adding 'C:\Compress-Archive test\Input\1.txt'.
Get-Item : Could not find item C:\Compress-Archive test\Input\2.txt.
At C:\program files\powershell\6\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:831 char:43
+ ...      $lastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWr ...
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:\Compress-Archive test\Input\2.txt:String) [Get-Item], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand

WARNING: 'C:\Compress-Archive test\Input\2.txt' has LastWriteTime earlier than 1980. Compress-Archive will store any files with LastWriteTime values earlier than 1980 as 1/1/1980 00:00.
VERBOSE: Adding 'C:\Compress-Archive test\Input\2.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\3.txt'.
Get-Item : Could not find item C:\Compress-Archive test\Input\4.txt.
At C:\program files\powershell\6\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:831 char:43
+ ...      $lastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWr ...
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:\Compress-Archive test\Input\4.txt:String) [Get-Item], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetItemCommand

WARNING: 'C:\Compress-Archive test\Input\4.txt' has LastWriteTime earlier than 1980. Compress-Archive will store any files with LastWriteTime values earlier than 1980 as 1/1/1980 00:00.
VERBOSE: Adding 'C:\Compress-Archive test\Input\4.txt'.
VERBOSE: Adding 'C:\Compress-Archive test\Input\5.txt'.

The Get-Item errors reference the following lines in the ZipArchiveHelper function:

# 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.
$lastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions