Skip to content

Commit 4987962

Browse files
Added new script ❄️ 🎁
1 parent 55fc0d2 commit 4987962

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
<#
2+
.SYNOPSIS
3+
Expand-ZipOrGzip - Extracts ZIP or GZIP files, including TAR within GZIP.
4+
5+
.DESCRIPTION
6+
This function extracts ZIP or GZIP compressed files. If a GZIP file contains a TAR file, it extracts the TAR file as well. Notifications are shown at various stages of the process.
7+
8+
.PARAMETER FilePath
9+
The path of the ZIP or GZIP file to be extracted.
10+
11+
.PARAMETER DestinationFolderPath
12+
The destination folder path where the extracted files will be placed.
13+
14+
.PARAMETER HideProgressDialog
15+
Optionally, hides the progress dialog during extraction.
16+
17+
.PARAMETER OverwriteExistingFiles
18+
Optionally, overwrites existing files in the destination directory without prompting.
19+
20+
.EXAMPLE
21+
Expand-ZipOrGzip -FilePath "C:\path\to\file.gz" -DestinationFolderPath "C:\extract\here" -OverwriteExistingFiles
22+
Extracts a GZIP file to the specified destination, overwriting any existing files.
23+
24+
.EXAMPLE
25+
Expand-ZipOrGzip -FilePath "C:\*.gz" -DestinationFolderPath "C:\extract\here" -OverwriteExistingFiles
26+
Extracts a GZIP file of wildcard to the specified destination, overwriting any existing files.
27+
28+
.EXAMPLE
29+
Expand-ZipOrGzip -FilePath "C:\path\to\archive.zip" -DestinationFolderPath "C:\extract\zip"
30+
Extracts a ZIP file to the specified destination folder.
31+
32+
.NOTES
33+
Author: Blake Drumm (blakedrumm@microsoft.com)
34+
Created on: December 1st, 2023
35+
Last Modified: December 2nd, 2023
36+
37+
Personal Blog: https://blakedrumm.com
38+
#>
39+
param
40+
(
41+
[ValidateNotNullOrEmpty()]
42+
[string]$FilePath,
43+
[ValidateNotNullOrEmpty()]
44+
[string]$DestinationFolderPath,
45+
[switch]$HideProgressDialog,
46+
[switch]$OverwriteExistingFiles
47+
)
48+
49+
# Function to show toast notification
50+
function Show-ToastNotification
51+
{
52+
param (
53+
[string]$Title,
54+
[string]$Text,
55+
[int]$Duration = 500,
56+
[string]$IconType = 'Info'
57+
)
58+
59+
Add-Type -AssemblyName System.Windows.Forms
60+
$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
61+
62+
$notifyIcon.Icon = [System.Drawing.SystemIcons]::Information
63+
$notifyIcon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::$IconType
64+
$notifyIcon.BalloonTipTitle = $Title
65+
$notifyIcon.BalloonTipText = $Text
66+
$notifyIcon.Visible = $true
67+
$notifyIcon.ShowBalloonTip($Duration)
68+
}
69+
70+
function Expand-ZipOrGzip (
71+
[ValidateNotNullOrEmpty()][string]$FilePath,
72+
[ValidateNotNullOrEmpty()][string]$DestinationFolderPath,
73+
[switch]$HideProgressDialog,
74+
[switch]$OverwriteExistingFiles
75+
)
76+
{
77+
# Resolve file paths with wildcard characters
78+
$resolvedFilePaths = Resolve-Path $FilePath
79+
foreach ($resolvedFilePath in $resolvedFilePaths)
80+
{
81+
Show-ToastNotification -Title "Extraction Started" -Text "Starting extraction of: `n$resolvedFilePath"
82+
83+
if ((Test-Path $resolvedFilePath) -and (Test-Path $DestinationFolderPath) -and ((Get-Item $DestinationFolderPath).PSIsContainer))
84+
{
85+
try
86+
{
87+
$fileExtension = [System.IO.Path]::GetExtension($resolvedFilePath).ToLower()
88+
89+
if ($fileExtension -eq ".gz")
90+
{
91+
$outputFilePath = [System.IO.Path]::Combine($DestinationFolderPath, [System.IO.Path]::GetFileNameWithoutExtension($resolvedFilePath))
92+
$error.Clear()
93+
try
94+
{
95+
$gzipStream = New-Object System.IO.FileStream($resolvedFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) -ErrorAction Stop
96+
$decompressionStream = New-Object System.IO.Compression.GzipStream($gzipStream, [System.IO.Compression.CompressionMode]::Decompress)
97+
$outputFileStream = New-Object System.IO.FileStream($outputFilePath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
98+
99+
$buffer = New-Object byte[](1024 * 10)
100+
$totalBytesRead = 0
101+
$totalLength = $gzipStream.Length
102+
while ($true)
103+
{
104+
$readBytes = $decompressionStream.Read($buffer, 0, $buffer.Length)
105+
if ($readBytes -eq 0) { break }
106+
$outputFileStream.Write($buffer, 0, $readBytes)
107+
$totalBytesRead += $readBytes
108+
$progress = [math]::Min([math]::Round(($totalBytesRead / $totalLength) * 100, 2), 99.99)
109+
$formattedProgress = "{0:F2}" -f $progress # Format as double digit
110+
Write-Progress -Activity "Extracting GZIP ($resolvedFilePath)" -Status "$formattedProgress% Complete." -PercentComplete $progress
111+
}
112+
}
113+
catch
114+
{
115+
Show-ToastNotification -Title "Error occurred" -Text "$error" -IconType Error
116+
break
117+
}
118+
finally
119+
{
120+
# Ensure streams are properly closed and disposed
121+
try
122+
{
123+
$decompressionStream.Dispose()
124+
}
125+
catch
126+
{
127+
Out-Null
128+
}
129+
try
130+
{
131+
$gzipStream.Dispose()
132+
}
133+
catch
134+
{
135+
Out-Null
136+
}
137+
try
138+
{
139+
$outputFileStream.Dispose()
140+
}
141+
catch
142+
{
143+
Out-Null
144+
}
145+
}
146+
$decompressionStream.Close()
147+
$gzipStream.Close()
148+
$outputFileStream.Close()
149+
150+
Write-Progress -Activity "Extracting GZIP ($resolvedFilePath)" -Status "100% Complete." -PercentComplete 100
151+
Show-ToastNotification -Title "GZIP Extraction Complete" -Text "GZIP extraction complete for: `n$resolvedFilePath"
152+
153+
if ([System.IO.Path]::GetExtension($outputFilePath).ToLower() -eq ".tar")
154+
{
155+
Show-ToastNotification -Title "TAR Extraction Starting" -Text "TAR extraction starting for: `n$resolvedFilePath"
156+
Start-Process -FilePath "tar" -ArgumentList "-xvf", "`"$outputFilePath`"", "-C", "`"$DestinationFolderPath`"" -NoNewWindow -Wait
157+
Remove-Item -Path $outputFilePath
158+
Show-ToastNotification -Title "TAR Extraction Complete" -Text "TAR extraction complete for: `n$resolvedFilePath"
159+
}
160+
}
161+
elseif ($fileExtension -eq ".zip")
162+
{
163+
$copyFlags = 0x00
164+
if ($HideProgressDialog)
165+
{
166+
$copyFlags += 0x04
167+
}
168+
if ($OverwriteExistingFiles)
169+
{
170+
$copyFlags += 0x10
171+
}
172+
Show-ToastNotification -Title "ZIP Extraction Starting" -Text "ZIP extraction starting for: `n$resolvedFilePath"
173+
$shell = New-Object -ComObject Shell.Application
174+
$zipFile = $shell.NameSpace($resolvedFilePath)
175+
$destinationFolder = $shell.NameSpace($DestinationFolderPath)
176+
177+
$destinationFolder.CopyHere($zipFile.Items(), $copyFlags)
178+
Show-ToastNotification -Title "ZIP Extraction Complete" -Text "ZIP extracted to: `n$destinationFolder"
179+
}
180+
else
181+
{
182+
throw "Unsupported file format. Only .zip, .gz, and .tar.gz extensions are supported."
183+
}
184+
}
185+
finally
186+
{
187+
if ($zipFile -ne $null)
188+
{
189+
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($zipFile)
190+
}
191+
if ($destinationFolder -ne $null)
192+
{
193+
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($destinationFolder)
194+
}
195+
if ($shell -ne $null)
196+
{
197+
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($shell)
198+
}
199+
}
200+
}
201+
}
202+
Show-ToastNotification -Title "Extraction Complete" -Text "Extraction complete, file located: `n$DestinationFolderPath"
203+
}
204+
if ($FilePath -or $DestinationFolderPath)
205+
{
206+
Expand-ZipOrGzip -FilePath $FilePath -DestinationFolderPath $DestinationFolderPath -HideProgressDialog:$HideProgressDialog -OverwriteExistingFiles:$OverwriteExistingFiles
207+
}
208+
else
209+
{
210+
# Example usage
211+
Expand-ZipOrGzip
212+
}

0 commit comments

Comments
 (0)