From e46beb9ef08fb5d28e20e8808a928190c624cbeb Mon Sep 17 00:00:00 2001 From: umamah Date: Thu, 15 Oct 2026 20:49:08 +0500 Subject: [PATCH 1/4] Feature: Option to show all Windows Firewall rules --- .../Resources/Strings.Designer.cs | 9 ++++ .../Resources/Strings.resx | 3 ++ .../Firewall/Firewall.cs | 49 +++++++++++++++++-- .../GlobalStaticConfiguration.cs | 3 +- .../NETworkManager.Settings/SettingsInfo.cs | 13 +++++ .../ViewModels/FirewallViewModel.cs | 19 ++++++- Source/NETworkManager/Views/FirewallView.xaml | 4 ++ 7 files changed, 94 insertions(+), 6 deletions(-) diff --git a/Source/NETworkManager.Localization/Resources/Strings.Designer.cs b/Source/NETworkManager.Localization/Resources/Strings.Designer.cs index de4abb87d1..0a9bc2957f 100644 --- a/Source/NETworkManager.Localization/Resources/Strings.Designer.cs +++ b/Source/NETworkManager.Localization/Resources/Strings.Designer.cs @@ -4996,6 +4996,15 @@ public static string FirewallRules { } } + /// + /// Looks up a localized string similar to Show all rules. + /// + public static string ShowAllRules { + get { + return ResourceManager.GetString("ShowAllRules", resourceCulture); + } + } + /// /// Looks up a localized string similar to First usable IP address. /// diff --git a/Source/NETworkManager.Localization/Resources/Strings.resx b/Source/NETworkManager.Localization/Resources/Strings.resx index b9a01cc5ef..4145f45e94 100644 --- a/Source/NETworkManager.Localization/Resources/Strings.resx +++ b/Source/NETworkManager.Localization/Resources/Strings.resx @@ -4313,6 +4313,9 @@ You can copy your profile files from “{0}” to “{1}” to migrate your exis Firewall rules + + Show all rules + Windows Firewall settings diff --git a/Source/NETworkManager.Models/Firewall/Firewall.cs b/Source/NETworkManager.Models/Firewall/Firewall.cs index 915692d24c..ad67cbd0ec 100644 --- a/Source/NETworkManager.Models/Firewall/Firewall.cs +++ b/Source/NETworkManager.Models/Firewall/Firewall.cs @@ -67,15 +67,19 @@ public class Firewall #region Methods /// - /// Retrieves all Windows Firewall rules whose display name starts with - /// and maps each one to a object. + /// Retrieves Windows Firewall rules and maps each one to a object. + /// When is , only rules whose display name + /// starts with are returned; otherwise all rules on the system are returned. /// PowerShell errors during the query are logged as warnings; errors for individual /// rules are caught so a single malformed rule does not abort the entire load. /// + /// + /// to query only rules managed by NETworkManager; to query all system firewall rules. + /// /// /// A list of objects representing the matching rules. /// - public static async Task> GetRulesAsync() + public static async Task> GetRulesAsync(bool onlyManagedRules = true) { await RunspaceLock.WaitAsync(); try @@ -87,7 +91,9 @@ public static async Task> GetRulesAsync() using var ps = SMA.PowerShell.Create(); ps.Runspace = SharedRunspace; - ps.AddScript($@" + if (onlyManagedRules) + { + ps.AddScript($@" Get-NetFirewallRule -DisplayName '{RuleIdentifier}*' | ForEach-Object {{ $rule = $_ $portFilter = $rule | Get-NetFirewallPortFilter @@ -111,6 +117,41 @@ public static async Task> GetRulesAsync() Program = $appFilter.Program }} }}"); + } + else + { + ps.AddScript($@" +$rules = Get-NetFirewallRule +$pf = @{{}}; Get-NetFirewallPortFilter | ForEach-Object {{ $pf[$_.InstanceID] = $_ }} +$af = @{{}}; Get-NetFirewallAddressFilter | ForEach-Object {{ $af[$_.InstanceID] = $_ }} +$app = @{{}}; Get-NetFirewallApplicationFilter | ForEach-Object {{ $app[$_.InstanceID] = $_ }} +$if = @{{}}; Get-NetFirewallInterfaceTypeFilter | ForEach-Object {{ $if[$_.InstanceID] = $_ }} +$list = [System.Collections.Generic.List[PSCustomObject]]::new($rules.Count) +foreach ($rule in $rules) {{ + $id = $rule.InstanceID + $portFilter = $pf[$id] + $addressFilter = $af[$id] + $appFilter = $app[$id] + $ifTypeFilter = $if[$id] + $list.Add([PSCustomObject]@{{ + Id = $rule.ID + DisplayName = $rule.DisplayName + Enabled = ($rule.Enabled -eq 'True') + Description = $rule.Description + Direction = [string]$rule.Direction + Action = [string]$rule.Action + Protocol = $portFilter.Protocol + LocalPort = ($portFilter.LocalPort -join ',') + RemotePort = ($portFilter.RemotePort -join ',') + LocalAddress = ($addressFilter.LocalAddress -join ',') + RemoteAddress = ($addressFilter.RemoteAddress -join ',') + Profile = [string]$rule.Profile + InterfaceType = [string]$ifTypeFilter.InterfaceType + Program = $appFilter.Program + }}) +}} +$list"); + } var results = ps.Invoke(); diff --git a/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs b/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs index 8b50e98f0a..1d151f8852 100644 --- a/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs +++ b/Source/NETworkManager.Settings/GlobalStaticConfiguration.cs @@ -1,4 +1,4 @@ -using DnsClient; +using DnsClient; using Lextm.SharpSnmpLib.Messaging; using NETworkManager.Models; using NETworkManager.Models.Export; @@ -267,6 +267,7 @@ public static class GlobalStaticConfiguration // Application: Firewall public static ExportFileType Firewall_ExportFileType => ExportFileType.Csv; + public static bool Firewall_ShowAllRules => false; // Application: Discovery Protocol public static DiscoveryProtocol DiscoveryProtocol_Protocol => DiscoveryProtocol.LldpCdp; diff --git a/Source/NETworkManager.Settings/SettingsInfo.cs b/Source/NETworkManager.Settings/SettingsInfo.cs index e5067acfe0..2338dddb2e 100644 --- a/Source/NETworkManager.Settings/SettingsInfo.cs +++ b/Source/NETworkManager.Settings/SettingsInfo.cs @@ -3312,6 +3312,19 @@ public ExportFileType Firewall_ExportFileType } } = GlobalStaticConfiguration.Firewall_ExportFileType; + public bool Firewall_ShowAllRules + { + get; + set + { + if (value == field) + return; + + field = value; + OnPropertyChanged(); + } + } = GlobalStaticConfiguration.Firewall_ShowAllRules; + #endregion #region Discovery Protocol diff --git a/Source/NETworkManager/ViewModels/FirewallViewModel.cs b/Source/NETworkManager/ViewModels/FirewallViewModel.cs index 9e05b03eca..b4d71917d6 100644 --- a/Source/NETworkManager/ViewModels/FirewallViewModel.cs +++ b/Source/NETworkManager/ViewModels/FirewallViewModel.cs @@ -93,6 +93,23 @@ public string RulesSearch } } + /// + /// Gets or sets whether to show all system firewall rules or only rules managed by NETworkManager. + /// + public bool ShowAllRules + { + get => SettingsManager.Current.Firewall_ShowAllRules; + set + { + if (value == SettingsManager.Current.Firewall_ShowAllRules) + return; + + SettingsManager.Current.Firewall_ShowAllRules = value; + OnPropertyChanged(); + _ = Refresh(); + } + } + /// /// Gets or sets whether a refresh is currently running. /// @@ -549,7 +566,7 @@ private async Task Refresh(bool init = false) try { - var rules = await Firewall.GetRulesAsync(); + var rules = await Firewall.GetRulesAsync(onlyManagedRules: !ShowAllRules); Application.Current.Dispatcher.Invoke(() => { diff --git a/Source/NETworkManager/Views/FirewallView.xaml b/Source/NETworkManager/Views/FirewallView.xaml index dd6e198fb2..af5b8fe951 100644 --- a/Source/NETworkManager/Views/FirewallView.xaml +++ b/Source/NETworkManager/Views/FirewallView.xaml @@ -55,6 +55,10 @@ Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right"> +