System.io.compression in PowerShell Class

Recently have been working on a script that extracts the contents of a file and puts that contents on a server unzipped.

I’ve run into an issue where the script will bomb because it cannot find types that are clearly loaded in the script.

Here is the issue and question:

If I run this script in a new session I get the following error everytime:
At C:\temp\copycode.ps1:89 char:13

  • hidden [ZipArchiveEntry]$entry
    
  •         ~~~~~~~~~~~~~~~
    

Unable to find type [ZipArchiveEntry].
At C:\temp\copycode.ps1:91 char:18

  • ArchiveFile([ZipArchiveEntry]$entry) {
    
  •              ~~~~~~~~~~~~~~~
    

Unable to find type [ZipArchiveEntry].
At C:\temp\copycode.ps1:100 char:10

  •     [ZipFileExtensions]::ExtractToFile($this.entry, $file.FullNam ...
    
  •      ~~~~~~~~~~~~~~~~~
    

Unable to find type [ZipFileExtensions].
+ CategoryInfo : ParserError: (:slight_smile: , ParseException
+ FullyQualifiedErrorId : TypeNotFound

However if I add the following in a separate file and then call this script it runs with out issue. Why won’t the using statements and the add-type work in the same script.

This way works:
param(
[Parameter(Mandatory=$true)][string]$sourceZip,
[Parameter(Mandatory=$true)][string]$destPath
)
[void][Reflection.assembly]::LoadWithPartialName(‘System.IO.Compression’)
[void][Reflection.assembly]::LoadWithPartialName(‘System.IO.Compression.FileSystem’)
add-type -assemblyname ‘System.IO.Compression’
add-type -assemblyname ‘System.IO.Compression.FileSystem’
& .\copy-code.ps1 -sourcezip $sourceZip -destpath $destPath

this doesnt
.\copy-code -sourcezip c:\temp\somezipfile.zip -destpath c:\temp\somezip

copy-code.ps1 — Full source is in gist below:

Using, with namespace, is basically like it is in C# - it makes it easier to use referenced namespaces, but it doesn’t actually reference and load them. So it works when you explicitly load them.

Yes it works when I load them in a wrapper before I create the class. That is why I was puzzled. Or was this a question don? So it works when you explicitly load them. Or a statement?

I would expect it to work when the assemblies are explicitly loaded; “using” does not actually attempt to load assemblies - it provides a shortcut was of using already loaded assemblies.

I commented the classes out and changed to the fullname of the class… Yet I’m still faced with the same issue when trying to initially run the script:

#requires -version 5.0
#using namespace System.IO
#using namespace System.IO.Compression
param(
[Parameter(Mandatory=$true)][string]$sourceZip,
[Parameter(Mandatory=$true)][string]$destPath
)
add-type -assemblyname ‘System.IO.Compression’
add-type -assemblyname ‘System.IO.Compression.FileSystem’

These two references keep failing:
System.IO.Compression.ZipFileExtensions
System.IO.Compression.ZipArchiveEntry

If I add the types in a separate script then call the script with the class it works fine.