<#
I had a need to be able to turn Windows Defender firewall on/off at will and it was getting to be a pain.
This script will give you a tray icon you can use. Click on, click off.
In case you forget, it includes a timer that will turn it back on after you disable it in case you forget.
Options on right click context menu:
Disable for 5min, 15min, 1hr and an option to add 5min increments
Sound alert that plays when firewall re-enables. Can be customized.
Tool tip shows a countdown to enable time.
SS - NovaWright Studios
#>
# =========================================================================
# CONFIGURATION SETTINGS
# =========================================================================
# Set to $true to show the system tray icon
# Set to $false to hide the icon completely (runs silently in background)
$showTrayIcon = $true
# Default disable duration in minutes when left-clicking icon
$defaultDisableMinutes = 10
# Set to $true to play an audio alert when the firewall auto-enables
$enableSoundAlert = $true
# Path to a custom .wav sound file. If left empty "" or file is not found, falls back to Windows system sounds.
$customWavPath = ""
# =========================================================================
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Ensure script runs with Administrator privileges
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
exit
}
# Create System Tray Icon
$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
# Set Tray Icon Visibility based on configuration above
$notifyIcon.Visible = $showTrayIcon
# Global Target Time, Warning State, & 1-Second Timer Initialization
$script:endTime = [DateTime]::MinValue
$script:warnedOneMinute = $false
$autoEnableTimer = New-Object System.Windows.Forms.Timer
$autoEnableTimer.Interval = 1000 # Ticks every 1 second to update countdown
# Helper function to play custom .wav or fallback system sound
function Play-AlertSound ([string]$systemSoundType = "Asterisk", [bool]$ignoreAlertToggle = $false) {
if (-not $enableSoundAlert -and -not $ignoreAlertToggle) { return }
if (-not [string]::IsNullOrWhiteSpace($customWavPath) -and (Test-Path $customWavPath)) {
try {
$player = New-Object System.Media.SoundPlayer($customWavPath)
$player.Play() # Asynchronous playback
} catch {
[System.Media.SystemSounds]::$systemSoundType.Play()
}
} else {
if ($systemSoundType -eq "Exclamation") {
[System.Media.SystemSounds]::Exclamation.Play()
} else {
[System.Media.SystemSounds]::Asterisk.Play()
}
}
}
# Helper function to query live state and update Icon + Tooltip
function Update-FirewallState {
$isEnabled = (Get-NetFirewallProfile -Profile Domain).Enabled
if ($isEnabled) {
$notifyIcon.Icon = [System.Drawing.SystemIcons]::Shield
$notifyIcon.Text = "Firewall: ENABLED (Click to disable for ${defaultDisableMinutes}m)"
} else {
$notifyIcon.Icon = [System.Drawing.SystemIcons]::Warning
$remaining = $script:endTime - [DateTime]::Now
if ($remaining.TotalSeconds -gt 0) {
if ($remaining.TotalHours -ge 1) {
$timeLeft = "{0:D2}:{1:D2}:{2:D2}" -f [math]::Floor($remaining.TotalHours), $remaining.Minutes, $remaining.Seconds
} else {
$timeLeft = "{0:D2}:{1:D2}" -f $remaining.Minutes, $remaining.Seconds
}
$notifyIcon.Text = "Firewall: DISABLED ($timeLeft left)"
} else {
$notifyIcon.Text = "Firewall: DISABLED"
}
}
}
# Function to turn firewall ON
function Enable-Firewall ([string]$source = "manual") {
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
$autoEnableTimer.Stop()
$script:warnedOneMinute = $false
Update-FirewallState
if ($source -eq "timer") {
Play-AlertSound -systemSoundType "Asterisk"
if ($showTrayIcon) {
$notifyIcon.ShowBalloonTip(4000, "Windows Firewall Restored", "Disable timer expired. Firewall auto-enabled.", [System.Windows.Forms.ToolTipIcon]::Info)
}
} else {
if ($showTrayIcon) {
$notifyIcon.ShowBalloonTip(3000, "Windows Firewall Enabled", "Firewall ENABLED. Protection active.", [System.Windows.Forms.ToolTipIcon]::Info)
}
}
}
# Function to turn firewall OFF and start timer
function Disable-Firewall ([int]$minutes = $defaultDisableMinutes) {
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
$script:endTime = [DateTime]::Now.AddMinutes($minutes)
$script:warnedOneMinute = $false
$autoEnableTimer.Start()
Update-FirewallState
if ($showTrayIcon) {
$notifyIcon.ShowBalloonTip(4000, "Windows Firewall Disabled", "Firewall DISABLED. Auto-enables in ${minutes}m.", [System.Windows.Forms.ToolTipIcon]::Warning)
}
}
# Timer Event (Fires every second)
$autoEnableTimer.add_Tick({
$remaining = $script:endTime - [DateTime]::Now
if ($remaining.TotalSeconds -gt 0) {
if ($remaining.TotalSeconds -le 60 -and -not $script:warnedOneMinute) {
$script:warnedOneMinute = $true
Play-AlertSound -systemSoundType "Exclamation"
if ($showTrayIcon) {
$notifyIcon.ShowBalloonTip(4000, "Firewall Auto-Enable Warning", "1 minute remaining until Firewall re-enables.", [System.Windows.Forms.ToolTipIcon]::Warning)
}
}
Update-FirewallState
} else {
Enable-Firewall -source "timer"
}
})
# Dedicated Left-Click Event Handler
$notifyIcon.add_MouseClick({
param($sender, $e)
if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Left) {
$currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
if ($currentState) {
Disable-Firewall -minutes $defaultDisableMinutes
} else {
Enable-Firewall -source "manual"
}
}
})
# --- RIGHT-CLICK CONTEXT MENU ---
$contextMenu = New-Object System.Windows.Forms.ContextMenuStrip
# "Disable For..." Submenu
$presetMenu = New-Object System.Windows.Forms.ToolStripMenuItem("Disable For...")
$item15 = $presetMenu.DropDownItems.Add("15 Minutes")
$item15.add_Click({ Disable-Firewall -minutes 15 })
$item30 = $presetMenu.DropDownItems.Add("30 Minutes")
$item30.add_Click({ Disable-Firewall -minutes 30 })
$item60 = $presetMenu.DropDownItems.Add("1 Hour")
$item60.add_Click({ Disable-Firewall -minutes 60 })
$null = $contextMenu.Items.Add($presetMenu)
# "Add 5 Minutes" Option
$extendItem = $contextMenu.Items.Add("Add 5 Minutes")
$extendItem.add_Click({
$currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
if (-not $currentState) {
$script:endTime = $script:endTime.AddMinutes(5)
if (($script:endTime - [DateTime]::Now).TotalSeconds -gt 60) {
$script:warnedOneMinute = $false
}
Update-FirewallState
if ($showTrayIcon) {
$notifyIcon.ShowBalloonTip(3000, "Timer Extended", "Added 5 minutes to the firewall disable timer.", [System.Windows.Forms.ToolTipIcon]::Info)
}
}
})
$null = $contextMenu.Items.Add("-") # Separator line
# --- SOUND ALERTS SUBMENU ---
$soundMenu = New-Object System.Windows.Forms.ToolStripMenuItem("Sound Alerts")
# Toggle Enable/Disable Sounds
$toggleSoundItem = $soundMenu.DropDownItems.Add("Enable Audio Chimes")
$toggleSoundItem.CheckOnClick = $true
$toggleSoundItem.Checked = $enableSoundAlert
$toggleSoundItem.add_Click({
$script:enableSoundAlert = $toggleSoundItem.Checked
})
# Test Sound Action
$testSoundItem = $soundMenu.DropDownItems.Add("Test Sound Alert")
$testSoundItem.add_Click({
# Forces sound playback even if audio chimes are currently muted
Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
})
$null = $soundMenu.DropDownItems.Add("-") # Submenu Separator
# Select Custom Sound File
$selectWavItem = $soundMenu.DropDownItems.Add("Select Custom .WAV Sound...")
$selectWavItem.add_Click({
$dialog = New-Object System.Windows.Forms.OpenFileDialog
$dialog.Filter = "WAV Audio Files (*.wav)|*.wav"
$dialog.Title = "Select Audio Alert Sound"
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$script:customWavPath = $dialog.FileName
# Auto-play sound test on selection
Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
}
})
# Reset to Windows Default System Sound
$resetWavItem = $soundMenu.DropDownItems.Add("Use Default System Sound")
$resetWavItem.add_Click({
$script:customWavPath = ""
Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
})
$null = $contextMenu.Items.Add($soundMenu)
$null = $contextMenu.Items.Add("-") # Separator line
$exitItem = $contextMenu.Items.Add("Exit")
# Context menu dynamic update handler when opened
$contextMenu.add_Opening({
$currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
# Only allow "Add 5 Minutes" when firewall is currently disabled
$extendItem.Enabled = -not $currentState
# Update sound menu checkmark state
$toggleSoundItem.Checked = $script:enableSoundAlert
})
$exitItem.add_Click({
$autoEnableTimer.Stop()
$notifyIcon.Visible = $false
[System.Windows.Forms.Application]::Exit()
})
$notifyIcon.ContextMenuStrip = $contextMenu
# Initial state load
Update-FirewallState
# Keep script running in background
[System.Windows.Forms.Application]::Run()
Comments
0 B
|👍
/👎