This answer works fine - it's using COM rather than pure .NET methods:
https://serverfault.com/a/456496/204875
Although, to be honest, I highly recommend downloading the portable version of 7zip and using that. No installation required, a lot more efficient and faster. If you can distribute a script, you can usually distribute an exe with it (although, yes, some environments are highly regulated).
Example:
$srcdir = "C:\tmp\in"
$zipFilepath = "C:\tmp\out"
$files = Get-ChildItem -Path $srcdir | where{! $_.PSIsContainer}
foreach($file in $files) {
$zipFilename = $file.name -replace '\.\w+$','.zip'
$zipFile = "$zipFilepath\$zipFilename"
#Prepare zip file
if(-not (test-path($zipFile))) {
set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipFile).IsReadOnly = $false
}
else {
# exit loop if zipfile with same name exists
write-warning "$zipfile exists"
Continue
}
# create new COM object
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipFile)
$zipPackage.CopyHere($file.FullName)
#using this method, sometimes files can be 'skipped'
#this 'while' loop checks each file is added before moving to the next
while($zipPackage.Items().Item($file.name) -eq $null){
Start-sleep -milliseconds 250
}
}
write-host "zipfiles created"
Result:
> dir -Recurse
Directory: C:\tmp\in
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 30/12/2021 4:12 pm 5157 txt1.txt
-a---- 30/12/2021 4:12 pm 5157 txt2.txt
-a---- 30/12/2021 4:12 pm 5157 txt3.txt
-a---- 30/12/2021 4:12 pm 5157 txt4.txt
Directory: C:\tmp\out
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 30/12/2021 4:13 pm 1997 txt1.zip
-a---- 30/12/2021 4:14 pm 1997 txt2.zip
-a---- 30/12/2021 4:14 pm 1997 txt3.zip
-a---- 30/12/2021 4:14 pm 1997 txt4.zip