Stannellc

FirewallState

Aug 18th, 2026 (edited)
1,797
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 9.84 KB | Source Code | 0 0
  1. <#
  2. I had a need to be able to turn Windows Defender firewall on/off at will and it was getting to be a pain.
  3. This script will give you a tray icon you can use. Click on, click off.
  4. In case you forget, it includes a timer that will turn it back on after you disable it in case you forget.
  5.  
  6. Options on right click context menu:
  7.  
  8. Disable for 5min, 15min, 1hr and an option to add 5min increments
  9. Sound alert that plays when firewall re-enables. Can be customized.
  10. Tool tip shows a countdown to enable time.
  11.  
  12. SS - NovaWright Studios
  13. #>
  14.  
  15. # =========================================================================
  16. # CONFIGURATION SETTINGS
  17. # =========================================================================
  18. # Set to $true to show the system tray icon
  19. # Set to $false to hide the icon completely (runs silently in background)
  20. $showTrayIcon = $true
  21. # Default disable duration in minutes when left-clicking icon
  22. $defaultDisableMinutes = 10
  23. # Set to $true to play an audio alert when the firewall auto-enables
  24. $enableSoundAlert = $true
  25. # Path to a custom .wav sound file. If left empty "" or file is not found, falls back to Windows system sounds.
  26. $customWavPath = ""
  27. # =========================================================================
  28.  
  29. Add-Type -AssemblyName System.Windows.Forms
  30. Add-Type -AssemblyName System.Drawing
  31.  
  32. # Ensure script runs with Administrator privileges
  33. if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
  34.     Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
  35.     exit
  36. }
  37.  
  38. # Create System Tray Icon
  39. $notifyIcon = New-Object System.Windows.Forms.NotifyIcon
  40.  
  41. # Set Tray Icon Visibility based on configuration above
  42. $notifyIcon.Visible = $showTrayIcon
  43.  
  44. # Global Target Time, Warning State, & 1-Second Timer Initialization
  45. $script:endTime = [DateTime]::MinValue
  46. $script:warnedOneMinute = $false
  47.  
  48. $autoEnableTimer = New-Object System.Windows.Forms.Timer
  49. $autoEnableTimer.Interval = 1000 # Ticks every 1 second to update countdown
  50.  
  51. # Helper function to play custom .wav or fallback system sound
  52. function Play-AlertSound ([string]$systemSoundType = "Asterisk", [bool]$ignoreAlertToggle = $false) {
  53.     if (-not $enableSoundAlert -and -not $ignoreAlertToggle) { return }
  54.  
  55.     if (-not [string]::IsNullOrWhiteSpace($customWavPath) -and (Test-Path $customWavPath)) {
  56.         try {
  57.             $player = New-Object System.Media.SoundPlayer($customWavPath)
  58.             $player.Play() # Asynchronous playback
  59.         } catch {
  60.             [System.Media.SystemSounds]::$systemSoundType.Play()
  61.         }
  62.     } else {
  63.         if ($systemSoundType -eq "Exclamation") {
  64.             [System.Media.SystemSounds]::Exclamation.Play()
  65.         } else {
  66.             [System.Media.SystemSounds]::Asterisk.Play()
  67.         }
  68.     }
  69. }
  70.  
  71. # Helper function to query live state and update Icon + Tooltip
  72. function Update-FirewallState {
  73.     $isEnabled = (Get-NetFirewallProfile -Profile Domain).Enabled
  74.    
  75.     if ($isEnabled) {
  76.         $notifyIcon.Icon = [System.Drawing.SystemIcons]::Shield
  77.         $notifyIcon.Text = "Firewall: ENABLED (Click to disable for ${defaultDisableMinutes}m)"
  78.     } else {
  79.         $notifyIcon.Icon = [System.Drawing.SystemIcons]::Warning
  80.         $remaining = $script:endTime - [DateTime]::Now
  81.        
  82.         if ($remaining.TotalSeconds -gt 0) {
  83.             if ($remaining.TotalHours -ge 1) {
  84.                 $timeLeft = "{0:D2}:{1:D2}:{2:D2}" -f [math]::Floor($remaining.TotalHours), $remaining.Minutes, $remaining.Seconds
  85.             } else {
  86.                 $timeLeft = "{0:D2}:{1:D2}" -f $remaining.Minutes, $remaining.Seconds
  87.             }
  88.             $notifyIcon.Text = "Firewall: DISABLED ($timeLeft left)"
  89.         } else {
  90.             $notifyIcon.Text = "Firewall: DISABLED"
  91.         }
  92.     }
  93. }
  94.  
  95. # Function to turn firewall ON
  96. function Enable-Firewall ([string]$source = "manual") {
  97.     Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
  98.     $autoEnableTimer.Stop()
  99.     $script:warnedOneMinute = $false
  100.    
  101.     Update-FirewallState
  102.  
  103.     if ($source -eq "timer") {
  104.         Play-AlertSound -systemSoundType "Asterisk"
  105.         if ($showTrayIcon) {
  106.             $notifyIcon.ShowBalloonTip(4000, "Windows Firewall Restored", "Disable timer expired. Firewall auto-enabled.", [System.Windows.Forms.ToolTipIcon]::Info)
  107.         }
  108.     } else {
  109.         if ($showTrayIcon) {
  110.             $notifyIcon.ShowBalloonTip(3000, "Windows Firewall Enabled", "Firewall ENABLED. Protection active.", [System.Windows.Forms.ToolTipIcon]::Info)
  111.         }
  112.     }
  113. }
  114.  
  115. # Function to turn firewall OFF and start timer
  116. function Disable-Firewall ([int]$minutes = $defaultDisableMinutes) {
  117.     Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
  118.    
  119.     $script:endTime = [DateTime]::Now.AddMinutes($minutes)
  120.     $script:warnedOneMinute = $false
  121.     $autoEnableTimer.Start()
  122.    
  123.     Update-FirewallState
  124.  
  125.     if ($showTrayIcon) {
  126.         $notifyIcon.ShowBalloonTip(4000, "Windows Firewall Disabled", "Firewall DISABLED. Auto-enables in ${minutes}m.", [System.Windows.Forms.ToolTipIcon]::Warning)
  127.     }
  128. }
  129.  
  130. # Timer Event (Fires every second)
  131. $autoEnableTimer.add_Tick({
  132.     $remaining = $script:endTime - [DateTime]::Now
  133.  
  134.     if ($remaining.TotalSeconds -gt 0) {
  135.         if ($remaining.TotalSeconds -le 60 -and -not $script:warnedOneMinute) {
  136.             $script:warnedOneMinute = $true
  137.             Play-AlertSound -systemSoundType "Exclamation"
  138.             if ($showTrayIcon) {
  139.                 $notifyIcon.ShowBalloonTip(4000, "Firewall Auto-Enable Warning", "1 minute remaining until Firewall re-enables.", [System.Windows.Forms.ToolTipIcon]::Warning)
  140.             }
  141.         }
  142.         Update-FirewallState
  143.     } else {
  144.         Enable-Firewall -source "timer"
  145.     }
  146. })
  147.  
  148. # Dedicated Left-Click Event Handler
  149. $notifyIcon.add_MouseClick({
  150.     param($sender, $e)
  151.     if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Left) {
  152.         $currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
  153.         if ($currentState) {
  154.             Disable-Firewall -minutes $defaultDisableMinutes
  155.         } else {
  156.             Enable-Firewall -source "manual"
  157.         }
  158.     }
  159. })
  160.  
  161. # --- RIGHT-CLICK CONTEXT MENU ---
  162. $contextMenu = New-Object System.Windows.Forms.ContextMenuStrip
  163.  
  164. # "Disable For..." Submenu
  165. $presetMenu = New-Object System.Windows.Forms.ToolStripMenuItem("Disable For...")
  166.  
  167. $item15 = $presetMenu.DropDownItems.Add("15 Minutes")
  168. $item15.add_Click({ Disable-Firewall -minutes 15 })
  169.  
  170. $item30 = $presetMenu.DropDownItems.Add("30 Minutes")
  171. $item30.add_Click({ Disable-Firewall -minutes 30 })
  172.  
  173. $item60 = $presetMenu.DropDownItems.Add("1 Hour")
  174. $item60.add_Click({ Disable-Firewall -minutes 60 })
  175.  
  176. $null = $contextMenu.Items.Add($presetMenu)
  177.  
  178. # "Add 5 Minutes" Option
  179. $extendItem = $contextMenu.Items.Add("Add 5 Minutes")
  180. $extendItem.add_Click({
  181.     $currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
  182.     if (-not $currentState) {
  183.         $script:endTime = $script:endTime.AddMinutes(5)
  184.         if (($script:endTime - [DateTime]::Now).TotalSeconds -gt 60) {
  185.             $script:warnedOneMinute = $false
  186.         }
  187.         Update-FirewallState
  188.         if ($showTrayIcon) {
  189.             $notifyIcon.ShowBalloonTip(3000, "Timer Extended", "Added 5 minutes to the firewall disable timer.", [System.Windows.Forms.ToolTipIcon]::Info)
  190.         }
  191.     }
  192. })
  193.  
  194. $null = $contextMenu.Items.Add("-") # Separator line
  195.  
  196. # --- SOUND ALERTS SUBMENU ---
  197. $soundMenu = New-Object System.Windows.Forms.ToolStripMenuItem("Sound Alerts")
  198.  
  199. # Toggle Enable/Disable Sounds
  200. $toggleSoundItem = $soundMenu.DropDownItems.Add("Enable Audio Chimes")
  201. $toggleSoundItem.CheckOnClick = $true
  202. $toggleSoundItem.Checked = $enableSoundAlert
  203. $toggleSoundItem.add_Click({
  204.     $script:enableSoundAlert = $toggleSoundItem.Checked
  205. })
  206.  
  207. # Test Sound Action
  208. $testSoundItem = $soundMenu.DropDownItems.Add("Test Sound Alert")
  209. $testSoundItem.add_Click({
  210.     # Forces sound playback even if audio chimes are currently muted
  211.     Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
  212. })
  213.  
  214. $null = $soundMenu.DropDownItems.Add("-") # Submenu Separator
  215.  
  216. # Select Custom Sound File
  217. $selectWavItem = $soundMenu.DropDownItems.Add("Select Custom .WAV Sound...")
  218. $selectWavItem.add_Click({
  219.     $dialog = New-Object System.Windows.Forms.OpenFileDialog
  220.     $dialog.Filter = "WAV Audio Files (*.wav)|*.wav"
  221.     $dialog.Title = "Select Audio Alert Sound"
  222.     if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
  223.         $script:customWavPath = $dialog.FileName
  224.         # Auto-play sound test on selection
  225.         Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
  226.     }
  227. })
  228.  
  229. # Reset to Windows Default System Sound
  230. $resetWavItem = $soundMenu.DropDownItems.Add("Use Default System Sound")
  231. $resetWavItem.add_Click({
  232.     $script:customWavPath = ""
  233.     Play-AlertSound -systemSoundType "Asterisk" -ignoreAlertToggle $true
  234. })
  235.  
  236. $null = $contextMenu.Items.Add($soundMenu)
  237.  
  238. $null = $contextMenu.Items.Add("-") # Separator line
  239. $exitItem = $contextMenu.Items.Add("Exit")
  240.  
  241. # Context menu dynamic update handler when opened
  242. $contextMenu.add_Opening({
  243.     $currentState = (Get-NetFirewallProfile -Profile Domain).Enabled
  244.     # Only allow "Add 5 Minutes" when firewall is currently disabled
  245.     $extendItem.Enabled = -not $currentState
  246.    
  247.     # Update sound menu checkmark state
  248.     $toggleSoundItem.Checked = $script:enableSoundAlert
  249. })
  250.  
  251. $exitItem.add_Click({
  252.     $autoEnableTimer.Stop()
  253.     $notifyIcon.Visible = $false
  254.     [System.Windows.Forms.Application]::Exit()
  255. })
  256.  
  257. $notifyIcon.ContextMenuStrip = $contextMenu
  258.  
  259. # Initial state load
  260. Update-FirewallState
  261.  
  262. # Keep script running in background
  263. [System.Windows.Forms.Application]::Run()
Advertisement