This Powershell script will allow you to add a couple of ZIP options to the Windows right-click Context Menu for Windows folders.
Overview
Save the following script into a folder of your choice, i.e. C:\Tools\Powershell.
| MKDIR C:\Tools\Powershell
CD C:\Tools\Powershell
|
Save the file something like Context-Menu-Zipper.ps1 in your folder.
| NOTEPAD C:\Tools\Powershell\Context-Menu-Zipper.ps1
|
Here is the entire standalone script...
| <#
███ ██ ██████ ██ ██ ██████ ██ ██ ██ ██ ███████
████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ███████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ████ ██████ ██ ██ ██████ ██ ████ ██ ███████
C O N T E X T M E N U Z I P P E R
───────────────────────────────────────────────────────────────────────
Author : Noxcivis
Website : https://www.noxcivis.com
Version : 1.0
Date : 2025‑07‑29
───────────────────────────────────────────────────────────────────────
.SYNOPSIS
Adds two silent “Zip” actions to the Windows folder context‑menu:
• Zip (Timestamp) – instant, no prompt
• Zip (Timestamp + Suffix…) – prompts for a suffix and remembers it
.DESCRIPTION
Context Menu Zipper installs lightweight VBS helper launchers that call this
PowerShell script in hidden‑console mode, eliminating window flashes. It also
stores the last suffix per user (HKCU) and supports full CLI use.
.PARAMETER Setup
Install or refresh the two context‑menu entries and helper VBS files
(admin‑only).
.PARAMETER Uninstall
Remove the context‑menu entries and helper files (admin‑only).
Aliases: -Remove, -Cleanup
.PARAMETER Folder
Folder path passed by Explorer or supplied manually for CLI zipping.
.PARAMETER Suffix
Optional text to append to the ZIP filename (e.g. “V1”).
Ignored for the plain Zip (Timestamp) action.
.EXAMPLE
PS> .\ContextMenuZipper.ps1 -Setup
Installs / refreshes the context‑menu items (run from an elevated shell).
.EXAMPLE
PS> .\ContextMenuZipper.ps1 -Folder 'C:\Project' -Suffix RC2
Creates C:\Project_20250729_142300_RC2.zip via CLI.
.LINK
https://www.noxcivis.com/ContextMenuZipper
.NOTES
Requires: PowerShell 5.1 or later (STA capable)
Admin rights needed only for -Setup and -Uninstall operations.
LICENSE
This script is released under an MIT‑style “as‑is” license.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction—including use, copy, modify, merge,
publish, and distribute copies of the Software—subject to the following
conditions:
1. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
2. You may not sell the unmodified script as your own product or remove the
original attribution.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
#>
param(
[string] $Folder, # supplied by Explorer or CLI
[switch] $Setup,
[switch] $PromptSuffix, # internal – tells script to prompt
[string] $Suffix,
# uninstall aliases
[Alias('Remove','Cleanup')]
[switch] $Uninstall
)
# ── paths ────────────────────────────────────────────────────────────────────
$Self = $PSCommandPath # full path to this ps1
$ScriptDir = Split-Path -Path $Self -Parent
$PlainVbs = Join-Path $ScriptDir 'ZipPlain.vbs'
$SuffixVbs = Join-Path $ScriptDir 'ZipSuffix.vbs'
# ╔═ Helper: prompt for a suffix (GUI, falls back to console) ════════════════╗
function Read-ZipSuffix {
# registry location
$regPath = 'HKCU:\Software\Context Menu Zipper'
$regName = 'LastSuffix'
try {
Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop
Add-Type -AssemblyName System.Drawing -ErrorAction Stop
# ── fetch previously saved suffix (if any) ────────────────────────────
$last = ''
try {
$last = (Get-ItemProperty -Path $regPath -Name $regName -ErrorAction Stop).$regName
} catch { }
# ── build dialog ──────────────────────────────────────────────────────
$form = New-Object Windows.Forms.Form
$form.Text = 'Zip suffix'
$form.Width = 420
$form.Height = 150
$form.FormBorderStyle = 'FixedDialog'
$form.MaximizeBox = $false
$form.StartPosition = 'CenterScreen'
$form.TopMost = $true
try { $form.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("$env:SystemRoot\System32\zipfldr.dll") } catch { }
$label = New-Object Windows.Forms.Label
$label.Text = 'Optional suffix (e.g., V1). Leave blank for none:'
$label.AutoSize = $true
$label.Left = 10
$label.Top = 15
$form.Controls.Add($label)
$box = New-Object Windows.Forms.TextBox
$box.Left = 10
$box.Top = 40
$box.Width = 380
$box.Text = $last # ← pre‑populate
$form.Controls.Add($box)
$link = New-Object Windows.Forms.LinkLabel
$link.Text = 'Noxcivs'
$link.Left = 10
$link.Top = 72
$link.AutoSize = $true
$null = $link.Add_LinkClicked({
Start-Process 'https://www.noxcivis.com/ContextMenuZipper'
})
$form.Controls.Add($link)
$okBtn = New-Object Windows.Forms.Button
$okBtn.Text = 'OK'
$okBtn.DialogResult = 'OK'
$okBtn.Left = 220
$okBtn.Top = 70
$form.AcceptButton = $okBtn
$form.Controls.Add($okBtn)
$cancelBtn = New-Object Windows.Forms.Button
$cancelBtn.Text = 'Cancel'
$cancelBtn.DialogResult = 'Cancel'
$cancelBtn.Left = 300
$cancelBtn.Top = 70
$form.CancelButton = $cancelBtn
$form.Controls.Add($cancelBtn)
# ── show dialog ───────────────────────────────────────────────────────
if ($form.ShowDialog() -ne 'OK') { return $null }
$newSuffix = $box.Text
# ── persist the new/cleared suffix ───────────────────────────────────
try {
if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null }
if ($newSuffix) {
New-ItemProperty -Path $regPath -Name $regName -Value $newSuffix -PropertyType String -Force | Out-Null
} else {
# user left it blank → remove the value if it exists
if (Get-ItemProperty -Path $regPath -Name $regName -ErrorAction SilentlyContinue) {
Remove-ItemProperty -Path $regPath -Name $regName -Force
}
}
} catch { } # silently ignore registry write errors
return $newSuffix
}
catch {
try {
$input = Read-Host "Suffix [$last] (Enter to keep, Ctrl+C to cancel)"
if ($input -eq '') { $input = $last }
# update registry from console path as well
if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null }
if ($input) {
New-ItemProperty -Path $regPath -Name $regName -Value $input -PropertyType String -Force | Out-Null
}
return $input
} catch { return $null }
}
}
# ╔═ Helper: write two silent VBS wrappers ════════════════════════════════════╗
function Write-HelperScripts {
param([string]$Dir,[string]$PsPath)
$psEsc = $PsPath -replace '"','""' # escape quotes for VB string literal
$plainVbs = @"
' ZipPlain.vbs — silent PowerShell wrapper (no suffix prompt)
Dim sh, folder
Set sh = CreateObject("WScript.Shell")
folder = WScript.Arguments(0)
sh.Run "powershell -NoLogo -NoProfile -Sta -WindowStyle Hidden -ExecutionPolicy Bypass -File ""$psEsc"" -Folder """ & folder & """", 0, False
"@
$suffixVbs = @"
' ZipSuffix.vbs — silent PowerShell wrapper with suffix prompt
Dim sh, folder
Set sh = CreateObject("WScript.Shell")
folder = WScript.Arguments(0)
sh.Run "powershell -NoLogo -NoProfile -Sta -WindowStyle Hidden -ExecutionPolicy Bypass -File ""$psEsc"" -Folder """ & folder & """ -PromptSuffix", 0, False
"@
Set-Content -Path (Join-Path $Dir 'ZipPlain.vbs') -Value $plainVbs -Encoding ASCII
Set-Content -Path (Join-Path $Dir 'ZipSuffix.vbs') -Value $suffixVbs -Encoding ASCII
}
# ╔═ Core: zip folder with timestamp (+ optional suffix) ══════════════════════╗
function Invoke-Zip-Folder {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidateScript({ Test-Path $_ -PathType Container })]
[string] $FolderPath,
[string] $Suffix
)
$parent = Split-Path $FolderPath -Parent
$name = Split-Path $FolderPath -Leaf
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$clean = if ($Suffix) {
$bad = [IO.Path]::GetInvalidFileNameChars() -join ''
($Suffix -replace "[{0}]" -f ([Regex]::Escape($bad)), '_').Trim()
}
$tag = if ($clean) { "_$clean" } else { "" }
$zipPath = Join-Path $parent "$name`_$timestamp$tag.zip"
Compress-Archive -Path (Join-Path $FolderPath '*') -DestinationPath $zipPath -Force
}
# ╔═ Setup: create helper VBS files + registry entries ════════════════════════╗
function Setup-Context-Menus-For-Zip {
$isAdmin = (New-Object Security.Principal.WindowsPrincipal `
([Security.Principal.WindowsIdentity]::GetCurrent())
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) { throw 'Run -Setup in an *elevated* PowerShell window.' }
# 1. create helpers
Write-HelperScripts -Dir $ScriptDir -PsPath $Self
# 2. add / refresh registry entries
$root = 'Registry::HKEY_CLASSES_ROOT\Directory\shell'
$plainKey = Join-Path $root 'ZipWithTimestamp'
$suffixKey = Join-Path $root 'ZipWithTimestampSuffix'
foreach ($k in @($plainKey,$suffixKey)) { if (Test-Path $k) { Remove-Item $k -Recurse -Force } }
# ▸ Zip (Timestamp)
New-Item $plainKey -Force | Out-Null
New-ItemProperty $plainKey -Name MUIVerb -Value 'Zip (Timestamp)' -Force | Out-Null
New-ItemProperty $plainKey -Name Icon -Value 'zipfldr.dll,0' -Force | Out-Null
$cmdPlain = 'wscript.exe "' + $PlainVbs.Replace('"','""') + '" "%V"'
New-Item (Join-Path $plainKey 'command') -Force |
Set-ItemProperty -Name '(default)' -Value $cmdPlain -Force
# ▸ Zip (Timestamp + Suffix…)
New-Item $suffixKey -Force | Out-Null
New-ItemProperty $suffixKey -Name MUIVerb -Value 'Zip (Timestamp + Suffix…)' -Force | Out-Null
New-ItemProperty $suffixKey -Name Icon -Value 'zipfldr.dll,0' -Force | Out-Null
$cmdSuffix = 'wscript.exe "' + $SuffixVbs.Replace('"','""') + '" "%V"'
New-Item (Join-Path $suffixKey 'command') -Force |
Set-ItemProperty -Name '(default)' -Value $cmdSuffix -Force
Write-Host '✔ Context menus installed / refreshed.'
}
# ╔═ Uninstall: remove registry entries + helper files ════════════════════════╗
function Remove-ContextMenus {
$isAdmin = (New-Object Security.Principal.WindowsPrincipal `
([Security.Principal.WindowsIdentity]::GetCurrent())
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) { throw 'Run -Uninstall in an *elevated* PowerShell window.' }
$root = 'Registry::HKEY_CLASSES_ROOT\Directory\shell'
$plainKey = Join-Path $root 'ZipWithTimestamp'
$suffixKey = Join-Path $root 'ZipWithTimestampSuffix'
foreach ($k in @($plainKey,$suffixKey)) {
if (Test-Path $k) {
Remove-Item $k -Recurse -Force
Write-Host "Removed registry key: $k"
}
}
foreach ($file in @($PlainVbs,$SuffixVbs)) {
if (Test-Path $file) {
Remove-Item $file -Force
Write-Host "Deleted helper file : $file"
}
}
Write-Host '✔ Context menus and helper files removed.'
}
# ╔═ Entry point ══════════════════════════════════════════════════════════════╗
try {
switch ($true) {
{ $Uninstall } {
Remove-ContextMenus
break
}
{ $Setup } {
Setup-Context-Menus-For-Zip
break
}
{ $Folder } {
if ($PromptSuffix) {
$tag = Read-ZipSuffix
if ($null -eq $tag) { break } # cancel → nothing
Invoke-Zip-Folder -FolderPath $Folder -Suffix $tag
} else {
Invoke-Zip-Folder -FolderPath $Folder -Suffix $Suffix
}
break
}
default {
Write-Host @"
USAGE
Install (admin) : & '$Self' -Setup
Uninstall (admin) : & '$Self' -Uninstall # or -Remove / -Cleanup
CLI zipping : & '$Self' -Folder 'C:\Path\Project' [-Suffix RC1]
Explorer (after setup):
▸ Zip (Timestamp)
▸ Zip (Timestamp + Suffix…)
"@
}
}
}
catch { Write-Error $_.Exception.Message }
|
Setup
With administrator rights...
Run
| [Your-Folder]\[Script-Name.ps1] -Setup
|
i.e.
| C:\Tools\Powershell\Context-Menu-Zipper.ps1 -Setup
|
Right click on a folder in Windows Explorer and select one of the items shown below.

Command Line Use
From a Powershell command prompt, run the following command...
| C:\Tools\Powershell\ContextMenuZipper.ps1 -Folder "C:\TEMP\Demo"
|
Suffix
If you want to add a predefined suffix to the output filename, i.e.
Uninstall
If you want to remove the Context Menus, just run the following, via an administrator Powershell command window.
| C:\Tools\Powershell\Context-Menu-Zipper.ps1 -Uninstall
|
Technical Notes
When you run the script as an administrator using the -Setup switch, two addional VBS files will be created. This is normal and is required to setup the Context Menus.