Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- 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()
Advertisement