Powershell firewall

Discussion in 'Scripting' started by Sungjin.x64, Oct 1, 2026.

Tags:
  1. Sungjin.x64

    Sungjin.x64 MDL Novice

    Dec 14, 2018
    10
    9
    0
    system beep
    when application try to go internet

    allow or block pop up dialog

    to unblock use replace name by block app
    Remove-NetFirewallRule -DisplayName "name*" -ErrorAction SilentlyContinue"

    ***issue*** in dialogbox allow / block
    if you choose x close dialogue in block firewall rules

    Code:
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    
    $WhiteList = @(
        'svchost', 'System', 'Idle', 'explorer', 'dwm', 'services',
        'lsass', 'csrss', 'spoolsv', 'SearchHost', 'SearchApp',
        'StartMenuExperienceHost', 'ShellExperienceHost', 'Widgets',
        'chrome', 'msedge', 'firefox', 'brave'
    )
    
    $SessionDecisions = @{}
    $ActionLog = [System.Collections.Generic.List[string]]::new()
    
    function Show-AlertPopup ($procName, $procPath, $remoteHost) {
        $form = New-Object System.Windows.Forms.Form
        $form.Text = 'Network Access Alert'
        $form.Size = New-Object System.Drawing.Size(460, 240)
        $form.StartPosition = 'CenterScreen'
        $form.TopMost = $true
        $form.FormBorderStyle = 'FixedDialog'
        $form.MaximizeBox = $false
        $form.MinimizeBox = $false
    
        $label = New-Object System.Windows.Forms.Label
        $label.Location = New-Object System.Drawing.Point(20, 20)
        $label.Size = New-Object System.Drawing.Size(400, 110)
        $label.Text = "An application is attempting outbound traffic:`n`nApp:  $procName.exe`nPath: $procPath`nDest: $remoteHost`n`nAllow this application to access the internet?"
        $form.Controls.Add($label)
    
        $btnAllow = New-Object System.Windows.Forms.Button
        $btnAllow.Location = New-Object System.Drawing.Point(50, 145)
        $btnAllow.Size = New-Object System.Drawing.Size(130, 35)
        $btnAllow.Text = 'ALLOW (Yes)'
        $btnAllow.DialogResult = [System.Windows.Forms.DialogResult]::Yes
        $form.Controls.Add($btnAllow)
    
        $btnBlock = New-Object System.Windows.Forms.Button
        $btnBlock.Location = New-Object System.Drawing.Point(260, 145)
        $btnBlock.Size = New-Object System.Drawing.Size(130, 35)
        $btnBlock.Text = 'BLOCK (No)'
        $btnBlock.DialogResult = [System.Windows.Forms.DialogResult]::No
        $form.Controls.Add($btnBlock)
    
        $form.AcceptButton = $btnAllow
        $form.CancelButton = $btnBlock
    
        [System.Console]::Beep(850, 150)
        $res = $form.ShowDialog()
        $form.Dispose()
    
        if ($res -eq [System.Windows.Forms.DialogResult]::No) { return 'Block' }
        if ($res -eq [System.Windows.Forms.DialogResult]::Yes) { return 'Allow' }
        return 'Skip'
    }
    
    Clear-Host
    Write-Host 'Starting Network Sentry...' -ForegroundColor Cyan
    
    try {
        while ($true) {
            $rawConns = Get-NetTCPConnection -ErrorAction SilentlyContinue | Where-Object {
                $_.State -in @('Established', 'SynSent') -and
                $_.RemoteAddress -notmatch '^(127\.|::1|0\.0\.0\.0|fe80)' -and
                $_.RemoteAddress -notmatch '^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1]))'
            }
    
            $activeDisplayList = @()
            $pendingPrompts = @()
    
            foreach ($conn in $rawConns) {
                $proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
                if (-not $proc -or [string]::IsNullOrWhiteSpace($proc.Path)) { continue }
    
                $pName = $proc.Name
                $pPath = $proc.Path
    
                if ($pName -notmatch 'chrome|msedge|firefox|brave|explorer') {
                    $activeDisplayList += [PSCustomObject]@{
                        ProcessName   = $pName
                        PID           = $proc.Id
                        RemoteAddress = $conn.RemoteAddress
                        Port          = $conn.RemotePort
                        Status        = if ($SessionDecisions.ContainsKey($pPath)) { $SessionDecisions[$pPath] } else { 'Active' }
                    }
                }
    
                if (-not ($WhiteList -contains $pName) -and -not ($SessionDecisions.ContainsKey($pPath))) {
                    $existingRule = Get-NetFirewallRule -DisplayName "BlockApp_$pName*" -ErrorAction SilentlyContinue
                    if ($existingRule) {
                        $SessionDecisions[$pPath] = 'Blocked'
                        continue
                    }
    
                    $pendingPrompts += [PSCustomObject]@{
                        Process = $proc
                        Name    = $pName
                        Path    = $pPath
                        Dest    = "$($conn.RemoteAddress):$($conn.RemotePort)"
                    }
                }
            }
    
            Clear-Host
            Write-Host '=== LIVE NETWORK MONITOR & SENTRY (Ctrl+C to Stop) ===' -ForegroundColor Cyan
            Write-Host "Last Check: $(Get-Date -Format 'HH:mm:ss') | Blocked Rules Active: $( ($SessionDecisions.Values | Where-Object {$_ -eq 'Blocked'}).Count )`n" -ForegroundColor DarkGray
    
            $uniqueDisplay =$activeDisplayList | Sort-Object ProcessName -Unique
            if ($uniqueDisplay) {$uniqueDisplay | Format-Table -AutoSize | Out-String | Write-Host
            } else {
                Write-Host "No third-party outbound connections active.`n" -ForegroundColor DarkYellow
            }
    
            # Display history log of blocks with unblock commands
            if ($ActionLog.Count -gt 0) {
                Write-Host "--- RECENT ACTIONS & UNBLOCK COMMANDS ---" -ForegroundColor Magenta
                foreach ($logEntry in $ActionLog) {
                    Write-Host $logEntry
                }
                Write-Host ""
            }
    
            foreach ($target in $pendingPrompts) {
                if ($SessionDecisions.ContainsKey($target.Path)) { continue }
    
                $choice = Show-AlertPopup -procName $target.Name -procPath $target.Path -remoteHost $target.Dest
    
                if ($choice -eq 'Block') {
                    Stop-Process -Id $target.Process.Id -Force -ErrorAction SilentlyContinue
    
                    $ruleDisplayName = "BlockApp_$($target.Name)"
                    New-NetFirewallRule -DisplayName "$ruleDisplayName (Outbound)" -Direction Outbound -Program $target.Path -Action Block -Profile Any | Out-Null
                    New-NetFirewallRule -DisplayName "$ruleDisplayName (Inbound)" -Direction Inbound -Program $target.Path -Action Block -Profile Any | Out-Null
    
                    $SessionDecisions[$target.Path] = 'Blocked'
    
                    # Formulate the unblock command string
                    $unblockCmd = "Remove-NetFirewallRule -DisplayName 'BlockApp_$($target.Name)*'"
                   
                    # Append to persistent on-screen action log
                    $logMsg = "[BLOCKED] $($target.Name) ($($target.Path))`n  --> To unblock run: $unblockCmd"
                    $ActionLog.Add($logMsg)
    
                    Write-Host "`n[BLOCKED] $($target.Name)" -ForegroundColor Red
                    Write-Host "Unblock Command: $unblockCmd" -ForegroundColor Yellow
                    Start-Sleep -Seconds 2
                }
                elseif ($choice -eq 'Allow') {
                    $SessionDecisions[$target.Path] = 'Allowed'
                    $ActionLog.Add("[ALLOWED] $($target.Name)")
                    Write-Host "`n[ALLOWED] $($target.Name)" -ForegroundColor Green
                    Start-Sleep -Seconds 1
                }
            }
    
            Start-Sleep -Seconds 1
        }
    }
    catch {
        Write-Error "Script crashed with error: $_"
    }