diff --git a/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1 b/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1
index 9543e90..e99512f 100644
--- a/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1
+++ b/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1
@@ -3,7 +3,7 @@
RootModule = 'lib\PSOPNSenseAPI.dll'
# Version number of this module.
- ModuleVersion = '2025.04.15.1143'
+ ModuleVersion = '2025.04.15.1216'
# Supported PSEditions
CompatiblePSEditions = @('Desktop', 'Core')
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/LICENSE b/release/PSOPNSenseAPI-2025.04.15.1543/LICENSE
new file mode 100644
index 0000000..2a38299
--- /dev/null
+++ b/release/PSOPNSenseAPI-2025.04.15.1543/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 PSOPNSenseAPI Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/PSOPNSenseAPI.psd1 b/release/PSOPNSenseAPI-2025.04.15.1543/PSOPNSenseAPI.psd1
new file mode 100644
index 0000000..5bce804
--- /dev/null
+++ b/release/PSOPNSenseAPI-2025.04.15.1543/PSOPNSenseAPI.psd1
@@ -0,0 +1,213 @@
+@{
+ # Script module or binary module file associated with this manifest.
+ RootModule = 'lib\PSOPNSenseAPI.dll'
+
+ # Version number of this module.
+ ModuleVersion = '2025.04.15.1543'
+
+ # Supported PSEditions
+ CompatiblePSEditions = @('Desktop', 'Core')
+
+ # ID used to uniquely identify this module
+ GUID = '9a3b4c55-5f9a-4b8c-87d9-9a7a5cdd5c9f'
+
+ # Author of this module
+ Author = 'PSOPNSenseAPI Contributors'
+
+ # Company or vendor of this module
+ CompanyName = 'PSOPNSenseAPI'
+
+ # Copyright statement for this module
+ Copyright = '(c) 2025 PSOPNSenseAPI Contributors. All rights reserved.'
+
+ # Description of the functionality provided by this module
+ Description = 'PowerShell module for interacting with the OPNSense API to configure firewalls'
+
+ # Minimum version of the PowerShell engine required by this module
+ PowerShellVersion = '5.1'
+
+ # Name of the PowerShell host required by this module
+ # PowerShellHostName = ''
+
+ # Minimum version of the PowerShell host required by this module
+ # PowerShellHostVersion = ''
+
+ # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
+ # DotNetFrameworkVersion = '4.7.2'
+
+ # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
+ ClrVersion = '4.0'
+
+ # Processor architecture (None, X86, Amd64) required by this module
+ # ProcessorArchitecture = ''
+
+ # Modules that must be imported into the global environment prior to importing this module
+ # RequiredModules = @()
+
+ # Assemblies that must be loaded prior to importing this module
+ # RequiredAssemblies = @()
+
+ # Script files (.ps1) that are run in the caller's environment prior to importing this module.
+ # ScriptsToProcess = @()
+
+ # Type files (.ps1xml) to be loaded when importing this module
+ # TypesToProcess = @()
+
+ # Format files (.ps1xml) to be loaded when importing this module
+ # FormatsToProcess = @()
+
+ # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
+ # NestedModules = @()
+
+ # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
+ FunctionsToExport = @()
+
+ # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
+ CmdletsToExport = @(
+ 'Apply-OPNSenseFirewallChanges',
+ 'Connect-OPNSense',
+ 'Connect-OPNSenseTailscale',
+ 'ConvertTo-OPNSenseNetworkNotation',
+ 'Disable-OPNSenseCronJob',
+ 'Disable-OPNSenseFirewallRule',
+ 'Disable-OPNSensePlugin',
+ 'Disable-OPNSenseTailscale',
+ 'Disconnect-OPNSense',
+ 'Disconnect-OPNSenseTailscale',
+ 'Enable-OPNSenseCronJob',
+ 'Enable-OPNSenseFirewallRule',
+ 'Enable-OPNSensePlugin',
+ 'Enable-OPNSenseTailscale',
+ 'Export-OPNSenseConfig',
+ 'Get-OPNSenseAlias',
+ 'Get-OPNSenseConfig',
+ 'Get-OPNSenseConfigBackup',
+ 'Get-OPNSenseConnection',
+ 'Get-OPNSenseCronJob',
+ 'Get-OPNSenseDHCPLease',
+ 'Get-OPNSenseDHCPOption',
+ 'Get-OPNSenseDHCPServer',
+ 'Get-OPNSenseDHCPStaticMapping',
+ 'Get-OPNSenseDNSForwarding',
+ 'Get-OPNSenseDNSForwardingHost',
+ 'Get-OPNSenseDNSOverride',
+ 'Get-OPNSenseDNSServer',
+ 'Get-OPNSenseFirewallRule',
+ 'Get-OPNSenseFirmware',
+ 'Get-OPNSenseGateway',
+ 'Get-OPNSenseInterface',
+ 'Get-OPNSenseInterfaceStatistics',
+ 'Get-OPNSensePlugin',
+ 'Get-OPNSensePortForwardingRule',
+ 'Get-OPNSenseRoute',
+ 'Get-OPNSenseSystemDNS',
+ 'Get-OPNSenseTailscaleStatus',
+ 'Get-OPNSenseUser',
+ 'Get-OPNSenseVLAN',
+ 'Import-OPNSenseConfig',
+ 'Install-OPNSensePlugin',
+ 'Invoke-OPNSenseNetworkCalculation',
+ 'New-OPNSenseAlias',
+ 'New-OPNSenseCronJob',
+ 'New-OPNSenseDHCPOption',
+ 'New-OPNSenseDHCPStaticMapping',
+ 'New-OPNSenseDNSForwardingHost',
+ 'New-OPNSenseDNSOverride',
+ 'New-OPNSenseFirewallRule',
+ 'New-OPNSenseGateway',
+ 'New-OPNSensePortForwardingRule',
+ 'New-OPNSenseRoute',
+ 'New-OPNSenseSubnetVLANs',
+ 'New-OPNSenseUser',
+ 'New-OPNSenseVLAN',
+ 'Remove-OPNSenseAlias',
+ 'Remove-OPNSenseCronJob',
+ 'Remove-OPNSenseDHCPLease',
+ 'Remove-OPNSenseDHCPOption',
+ 'Remove-OPNSenseDHCPStaticMapping',
+ 'Remove-OPNSenseDNSForwardingHost',
+ 'Remove-OPNSenseDNSOverride',
+ 'Remove-OPNSenseFirewallRule',
+ 'Remove-OPNSenseGateway',
+ 'Remove-OPNSensePortForwardingRule',
+ 'Remove-OPNSenseRoute',
+ 'Remove-OPNSenseUser',
+ 'Remove-OPNSenseVLAN',
+ 'Restart-OPNSenseFirewall',
+ 'Restart-OPNSenseInterface',
+ 'Restore-OPNSenseConfig',
+ 'Set-OPNSenseAlias',
+ 'Set-OPNSenseCronJob',
+ 'Set-OPNSenseDHCPOption',
+ 'Set-OPNSenseDHCPServer',
+ 'Set-OPNSenseDHCPStaticMapping',
+ 'Set-OPNSenseDNSForwarding',
+ 'Set-OPNSenseDNSForwardingHost',
+ 'Set-OPNSenseDNSServer',
+ 'Set-OPNSenseFirewallRule',
+ 'Set-OPNSenseGateway',
+ 'Set-OPNSenseInterface',
+ 'Set-OPNSensePortForwardingRule',
+ 'Set-OPNSenseRoute',
+ 'Set-OPNSenseSystemDNS',
+ 'Set-OPNSenseUser',
+ 'Set-OPNSenseVLAN',
+ 'Uninstall-OPNSensePlugin',
+ 'Update-OPNSenseFirmware',
+ 'Start-OPNSenseFirmwareUpgrade'
+ )
+
+ # Variables to export from this module
+ VariablesToExport = @()
+
+ # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
+ AliasesToExport = @()
+
+ # DSC resources to export from this module
+ # DscResourcesToExport = @()
+
+ # List of all modules packaged with this module
+ # ModuleList = @()
+
+ # List of all files packaged with this module
+ # FileList = @()
+
+ # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
+ PrivateData = @{
+
+ PSData = @{
+
+ # Tags applied to this module. These help with module discovery in online galleries.
+ Tags = @('PowerShell', 'OPNSense', 'Firewall', 'API')
+
+ # A URL to the license for this module.
+ LicenseUri = 'https://github.com/freedbygrace/PSOPNSenseAPI/blob/main/LICENSE'
+
+ # A URL to the main website for this project.
+ ProjectUri = 'https://github.com/freedbygrace/PSOPNSenseAPI'
+
+ # A URL to an icon representing this module.
+ # IconUri = ''
+
+ # ReleaseNotes of this module
+ ReleaseNotes = 'https://github.com/freedbygrace/PSOPNSenseAPI/blob/main/CHANGELOG.md'
+
+ # Prerelease string of this module
+ # Prerelease = ''
+
+ # Flag to indicate whether the module requires explicit user acceptance for install/update/save
+ # RequireLicenseAcceptance = $false
+
+ # External dependent modules of this module
+ # ExternalModuleDependencies = @()
+
+ } # End of PSData hashtable
+
+ } # End of PrivateData hashtable
+
+ # HelpInfoURI of this module
+ # HelpInfoURI = ''
+
+ # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
+ # DefaultCommandPrefix = ''
+}
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/README.md b/release/PSOPNSenseAPI-2025.04.15.1543/README.md
new file mode 100644
index 0000000..e4e97b5
--- /dev/null
+++ b/release/PSOPNSenseAPI-2025.04.15.1543/README.md
@@ -0,0 +1,202 @@
+# PSOPNSenseAPI
+
+PowerShell module for interacting with the OPNSense API to configure firewalls.
+
+## Overview
+
+PSOPNSenseAPI is a PowerShell module that provides cmdlets for managing OPNSense firewalls through their API. The module is built as a binary module in C# and is compatible with both PowerShell 5.1 and PowerShell 7.
+
+## Features
+
+- Connect to OPNSense firewalls using API credentials
+- Manage firewall rules (create, read, update, delete)
+- Configure NAT rules and port forwarding
+- Manage aliases (host, network, port, URL, etc.)
+- Manage network interfaces and VLANs
+- Configure DNS settings, overrides, and forwarding
+- Configure system DNS servers
+- Backup, restore, export, and import configurations
+- Manage plugins (install, uninstall, enable, disable)
+- Manage users and permissions
+- Update and upgrade firmware
+- Reboot firewall with wait for reconnection
+- Create VLANs from subnet divisions
+- Configure DHCP servers, static mappings, leases, and options
+- Manage cron jobs
+- Configure and manage Tailscale VPN (with auto-installation)
+- Manage gateways and static routes
+- Network calculation utilities (subnet, supernet, CIDR conversion)
+- Apply and revert configuration changes
+- Extensive logging and error handling
+- Compatible with both PowerShell 5.1 and PowerShell 7
+
+## Requirements
+
+- PowerShell 5.1 or PowerShell 7+
+- .NET Framework 4.7.2+ (for PowerShell 5.1)
+- .NET Core 3.1+ (for PowerShell 7)
+
+## Installation
+
+```powershell
+# Install from PowerShell Gallery (when published)
+Install-Module -Name PSOPNSenseAPI
+
+# Or install manually
+# 1. Download the module
+# 2. Extract to a directory in your PSModulePath
+# 3. Import the module
+Import-Module PSOPNSenseAPI
+```
+
+## Quick Start
+
+```powershell
+# Connect to an OPNSense firewall
+Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck
+
+# Get all firewall rules
+Get-OPNSenseFirewallRule
+
+# Create a new firewall rule
+New-OPNSenseFirewallRule -Description "Allow HTTP" -Protocol TCP -SourceNet "192.168.1.0/24" -DestinationPort 80 -Action Pass
+
+# Apply changes
+Apply-OPNSenseFirewallChanges
+
+# Manage aliases
+Get-OPNSenseAlias
+New-OPNSenseAlias -Name "WebServers" -Type host -Content "192.168.1.10,192.168.1.11" -Description "Web Servers" -Apply
+New-OPNSenseAlias -Name "WebPorts" -Type port -Content "80,443" -Protocol TCP -Description "Web Ports" -Apply
+Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Content "192.168.1.10,192.168.1.11,192.168.1.12" -Apply
+
+# Manage interfaces
+Get-OPNSenseInterface
+Set-OPNSenseInterface -Name "lan" -Description "Local Network" -IpAddress "192.168.1.1" -SubnetMask "24"
+
+# Create VLANs from subnet divisions
+New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 10 -EnableDHCP
+
+# Configure DNS
+Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4" -Apply
+New-OPNSenseDNSOverride -Hostname "server" -Domain "local" -IpAddress "192.168.1.10"
+
+# Manage plugins
+Get-OPNSensePlugin -Installed
+Install-OPNSensePlugin -Name "os-acme-client" -Wait
+
+# Manage users
+New-OPNSenseUser -Username "john" -Password "P@ssw0rd" -FullName "John Doe" -Groups "admins"
+
+# Configure DHCP
+Get-OPNSenseDHCPServer
+Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200" -Apply
+New-OPNSenseDHCPStaticMapping -Interface "lan" -MacAddress "00:11:22:33:44:55" -IpAddress "192.168.1.50" -Hostname "printer"
+Get-OPNSenseDHCPLease
+Remove-OPNSenseDHCPLease -MacAddress "00:11:22:33:44:55" -Apply
+Get-OPNSenseDHCPOption -Interface "lan"
+New-OPNSenseDHCPOption -Interface "lan" -Number 66 -Value "192.168.1.10" -Description "TFTP Server" -Apply
+
+# Manage cron jobs
+Get-OPNSenseCronJob
+New-OPNSenseCronJob -Description "Daily backup" -Command "/usr/local/bin/backup.sh" -Minutes "0" -Hours "2" -Apply
+
+# Configure and manage Tailscale
+Get-OPNSenseTailscaleStatus -IncludeInterfaces
+Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Force
+# Advertise subnet routes to Tailscale network
+Enable-OPNSenseTailscale -AdvertiseRoutes -SubnetRoutes "192.168.1.0/24","10.0.0.0/8" -Force
+Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing -Force
+
+# Manage DNS forwarding
+Get-OPNSenseDNSForwarding
+Set-OPNSenseDNSForwarding -Enabled -DnsServers "8.8.8.8","8.8.4.4" -Apply
+New-OPNSenseDNSForwardingHost -Domain "example.com" -Server "192.168.1.10" -Apply
+
+# Configure system DNS
+Get-OPNSenseSystemDNS
+Set-OPNSenseSystemDNS -Hostname "firewall" -Domain "example.com" -DnsServers "1.1.1.1","1.0.0.1" -Apply
+
+# Manage gateways and routes
+Get-OPNSenseGateway -IncludeStatus
+New-OPNSenseGateway -Name "WAN2_GW" -Interface "opt1" -IpAddress "203.0.113.1" -Description "Secondary WAN" -Apply
+Get-OPNSenseRoute
+New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN2_GW" -Description "Remote Office" -Apply
+
+# Network utilities
+Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info
+Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Subnet -PrefixLength 24
+ConvertTo-OPNSenseNetworkNotation -CIDR 24 # Returns "255.255.255.0"
+
+# Advanced supernetting
+Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Supernet -AdditionalNetworks "192.168.2.0/24"
+Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/24" -Operation SupernetSummarize -AdditionalNetworks "10.0.1.0/24","10.0.2.0/24"
+
+# Firmware management
+Update-OPNSenseFirmware -Wait
+
+# Major firmware upgrade
+Start-OPNSenseFirmwareUpgrade -Wait -Timeout 1200
+
+# Reboot firewall
+Restart-OPNSenseFirewall -Wait -Timeout 300
+
+# Configuration management
+Get-OPNSenseConfig | Restore-OPNSenseConfig -Force # Get and restore configuration in one line
+$config = Get-OPNSenseConfig # Get configuration as XML document
+Export-OPNSenseConfig -Path (New-Object System.IO.FileInfo "C:\Backups\opnsense-config.xml")
+Import-OPNSenseConfig -Path (New-Object System.IO.FileInfo "C:\Backups\opnsense-config.xml") -Force
+```
+
+## Documentation
+
+For detailed documentation, see the [docs](./docs) directory or use PowerShell's built-in help:
+
+```powershell
+Get-Help Connect-OPNSense -Full
+```
+
+## Development
+
+### Build and Test
+
+To build and test the module locally:
+
+```powershell
+# Run tests
+.\build\test.ps1
+
+# Build the module
+.\build\build.ps1
+
+# Build a release version with automatic versioning
+.\build\build-release.ps1 -Clean -Test -Package
+```
+
+### Versioning
+
+The module uses a versioning scheme of `yyyy.MM.dd.HHmm` for releases, which is automatically generated during the build process.
+
+### CI/CD
+
+The project uses GitHub Actions for continuous integration and deployment:
+
+- Builds and tests are run on every push to the main branch
+- Release packages are automatically created with the versioning scheme
+- Release artifacts are uploaded to GitHub Releases
+
+## Contributing
+
+Contributions are welcome! Please follow these steps:
+
+1. Fork the repository
+2. Create a feature branch (`git checkout -b feature/amazing-feature`)
+3. Make your changes
+4. Run tests to ensure they pass
+5. Commit your changes (`git commit -m 'Add some amazing feature'`)
+6. Push to the branch (`git push origin feature/amazing-feature`)
+7. Open a Pull Request
+
+## License
+
+This project is licensed under the MIT License - see the LICENSE file for details.
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/Newtonsoft.Json.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/Newtonsoft.Json.dll
new file mode 100644
index 0000000..341d08f
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/Newtonsoft.Json.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/PSOPNSenseAPI.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/PSOPNSenseAPI.dll
new file mode 100644
index 0000000..5eac19a
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/PSOPNSenseAPI.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Buffers.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Buffers.dll
new file mode 100644
index 0000000..f2d83c5
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Buffers.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Management.Automation.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Management.Automation.dll
new file mode 100644
index 0000000..3dfa7d8
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Management.Automation.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Memory.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Memory.dll
new file mode 100644
index 0000000..4617199
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Memory.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Net.IPNetwork.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Net.IPNetwork.dll
new file mode 100644
index 0000000..ce68dd5
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Net.IPNetwork.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Numerics.Vectors.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Numerics.Vectors.dll
new file mode 100644
index 0000000..0865972
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Numerics.Vectors.dll differ
diff --git a/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Runtime.CompilerServices.Unsafe.dll b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Runtime.CompilerServices.Unsafe.dll
new file mode 100644
index 0000000..de9e124
Binary files /dev/null and b/release/PSOPNSenseAPI-2025.04.15.1543/lib/System.Runtime.CompilerServices.Unsafe.dll differ
diff --git a/src/PSOPNSenseAPI/Cmdlets/ApplyOPNSenseFirewallChangesCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/ApplyOPNSenseFirewallChangesCmdlet.cs
index d71d211..6a33676 100644
--- a/src/PSOPNSenseAPI/Cmdlets/ApplyOPNSenseFirewallChangesCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/ApplyOPNSenseFirewallChangesCmdlet.cs
@@ -46,55 +46,70 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var firewallService = new FirewallService(ApiClient, Logger);
+ var firewallService = new FirewallService(ApiClient, Logger);
- if (NoRollback.IsPresent)
+ if (NoRollback.IsPresent)
+ {
+ WriteVerbose("Applying firewall changes without rollback protection");
+ var applyResult = ExecuteAsyncTask(() => firewallService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
- WriteVerbose("Applying firewall changes without rollback protection");
- var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
- WriteVerbose($"Firewall changes applied: {applyResult.Status}");
+ return;
+ }
+
+ WriteVerbose($"Firewall changes applied: {applyResult.Status}");
+ }
+ else
+ {
+ WriteVerbose("Creating savepoint for rollback protection");
+ var savepointResult = ExecuteAsyncTask(() => firewallService.CreateSavepointAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || savepointResult == null)
+ {
+ return;
+ }
+
+ var revision = savepointResult.Revision;
+
+ WriteVerbose($"Created savepoint with revision {revision}");
+ WriteVerbose("Applying firewall changes with rollback protection");
+
+ var applyResult = ExecuteAsyncTask(() => firewallService.ApplyChangesAsync(revision));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Firewall changes applied: {applyResult.Status}");
+
+ if (CancelRollback.IsPresent)
+ {
+ WriteVerbose($"Waiting {Timeout} seconds before cancelling rollback");
+ System.Threading.Thread.Sleep(Timeout * 1000);
+
+ WriteVerbose("Cancelling automatic rollback");
+ var cancelResult = ExecuteAsyncTask(() => firewallService.CancelRollbackAsync(revision));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || cancelResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Rollback cancelled: {cancelResult.Status}");
}
else
{
- WriteVerbose("Creating savepoint for rollback protection");
- var savepointTask = Task.Run(async () => await firewallService.CreateSavepointAsync());
- var savepointResult = savepointTask.GetAwaiter().GetResult();
- var revision = savepointResult.Revision;
-
- WriteVerbose($"Created savepoint with revision {revision}");
- WriteVerbose("Applying firewall changes with rollback protection");
-
- var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync(revision));
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Firewall changes applied: {applyResult.Status}");
-
- if (CancelRollback.IsPresent)
- {
- WriteVerbose($"Waiting {Timeout} seconds before cancelling rollback");
- System.Threading.Thread.Sleep(Timeout * 1000);
-
- WriteVerbose("Cancelling automatic rollback");
- var cancelTask = Task.Run(async () => await firewallService.CancelRollbackAsync(revision));
- var cancelResult = cancelTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Rollback cancelled: {cancelResult.Status}");
- }
- else
- {
- WriteVerbose($"Automatic rollback will occur in 60 seconds if connectivity is lost");
- }
+ WriteVerbose($"Automatic rollback will occur in 60 seconds if connectivity is lost");
}
}
- catch (Exception ex)
- {
- HandleException(ex);
- }
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/ConvertToOPNSenseNetworkNotationCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/ConvertToOPNSenseNetworkNotationCmdlet.cs
index 35401be..404a7e3 100644
--- a/src/PSOPNSenseAPI/Cmdlets/ConvertToOPNSenseNetworkNotationCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/ConvertToOPNSenseNetworkNotationCmdlet.cs
@@ -57,6 +57,14 @@ namespace PSOPNSenseAPI.Cmdlets
[Parameter(Mandatory = false, ParameterSetName = "FromIPWithSubnetMask")]
public string IPWithSubnetMask { get; set; }
+ ///
+ /// Begins the processing of the cmdlet
+ ///
+ protected override void BeginProcessing()
+ {
+ base.BeginProcessing();
+ }
+
///
/// Processes the cmdlet
///
@@ -88,22 +96,16 @@ namespace PSOPNSenseAPI.Cmdlets
string[] parts = IPWithCIDR.Split('/');
if (parts.Length != 2)
{
- WriteError(new ErrorRecord(
- new ArgumentException($"Invalid IP with CIDR: {IPWithCIDR}. Expected format: 192.168.1.0/24"),
- "InvalidIPWithCIDR",
- ErrorCategory.InvalidArgument,
- null));
+ // Use WriteWarning instead of WriteError to avoid threading issues
+ WriteWarning($"Invalid IP with CIDR: {IPWithCIDR}. Expected format: 192.168.1.0/24");
return;
}
string ip = parts[0];
if (!int.TryParse(parts[1], out int cidr))
{
- WriteError(new ErrorRecord(
- new ArgumentException($"Invalid CIDR: {parts[1]}"),
- "InvalidCIDR",
- ErrorCategory.InvalidArgument,
- null));
+ // Use WriteWarning instead of WriteError to avoid threading issues
+ WriteWarning($"Invalid CIDR: {parts[1]}");
return;
}
@@ -118,11 +120,8 @@ namespace PSOPNSenseAPI.Cmdlets
string[] parts = IPWithSubnetMask.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
{
- WriteError(new ErrorRecord(
- new ArgumentException($"Invalid IP with subnet mask: {IPWithSubnetMask}. Expected format: 192.168.1.0 255.255.255.0"),
- "InvalidIPWithSubnetMask",
- ErrorCategory.InvalidArgument,
- null));
+ // Use WriteWarning instead of WriteError to avoid threading issues
+ WriteWarning($"Invalid IP with subnet mask: {IPWithSubnetMask}. Expected format: 192.168.1.0 255.255.255.0");
return;
}
@@ -136,12 +135,17 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "ConversionError",
- ErrorCategory.InvalidOperation,
- null));
+ // Use WriteWarning instead of WriteError to avoid threading issues
+ WriteWarning($"Conversion error: {ex.Message}");
}
}
+
+ ///
+ /// Ends the processing of the cmdlet
+ ///
+ protected override void EndProcessing()
+ {
+ base.EndProcessing();
+ }
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseFirewallRuleCmdlet.cs
index 2f84dd3..b075fb9 100644
--- a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseFirewallRuleCmdlet.cs
@@ -28,21 +28,20 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var firewallService = new FirewallService(ApiClient, Logger);
+ var firewallService = new FirewallService(ApiClient, Logger);
- var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, false));
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => firewallService.ToggleRuleAsync(Uuid, false));
- WriteVerbose($"Firewall rule {Uuid} disabled: {result.Result}");
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Firewall rule {Uuid} disabled: {result.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSensePluginCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSensePluginCmdlet.cs
index 057a82f..dcd348a 100644
--- a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSensePluginCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSensePluginCmdlet.cs
@@ -28,22 +28,21 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var pluginService = new PluginService(ApiClient, Logger);
+ var pluginService = new PluginService(ApiClient, Logger);
- var task = Task.Run(async () => await pluginService.DisablePluginAsync(Name));
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => pluginService.DisablePluginAsync(Name));
- WriteVerbose($"Plugin {Name} disabled: {result.Status}");
- WriteObject($"Plugin {Name} disabled: {result.Status}");
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Plugin {Name} disabled: {result.Status}");
+ WriteObject($"Plugin {Name} disabled: {result.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseTailscaleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseTailscaleCmdlet.cs
index 222ecb4..4bb2e2f 100644
--- a/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseTailscaleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/DisableOPNSenseTailscaleCmdlet.cs
@@ -38,79 +38,100 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var tailscaleService = new TailscaleService(ApiClient, Logger);
+
+ // Check if the plugin is installed
+ var isInstalled = ExecuteAsyncTask(() => tailscaleService.IsPluginInstalledAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
{
- var tailscaleService = new TailscaleService(ApiClient, Logger);
+ return;
+ }
- // Check if the plugin is installed
- var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
- var isInstalled = isInstalledTask.GetAwaiter().GetResult();
+ if (!isInstalled)
+ {
+ WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
+ return;
+ }
- if (!isInstalled)
- {
- WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
- return;
- }
+ // Get current settings
+ var settingsResult = ExecuteAsyncTask(() => tailscaleService.GetSettingsAsync());
- // Get current settings
- var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
- var currentSettings = settingsTask.GetAwaiter().GetResult().General;
+ // Only continue if no exception occurred
+ if (ProcessingException != null || settingsResult == null)
+ {
+ return;
+ }
- // Create new settings with disabled flag
- var settings = new TailscaleSettings
- {
- Enabled = "0",
- AcceptDns = currentSettings.AcceptDns,
- AcceptRoutes = currentSettings.AcceptRoutes,
- AdvertiseExitNode = currentSettings.AdvertiseExitNode,
- AdvertiseRoutes = currentSettings.AdvertiseRoutes,
- RoutesToAdvertise = currentSettings.RoutesToAdvertise,
- Hostname = currentSettings.Hostname,
- LoginServer = currentSettings.LoginServer,
- Ssh = currentSettings.Ssh,
- Ephemeral = currentSettings.Ephemeral,
- ResetOnStart = currentSettings.ResetOnStart
- };
+ var currentSettings = settingsResult.General;
- if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disable Tailscale"))
+ // Create new settings with disabled flag
+ var settings = new TailscaleSettings
+ {
+ Enabled = "0",
+ AcceptDns = currentSettings.AcceptDns,
+ AcceptRoutes = currentSettings.AcceptRoutes,
+ AdvertiseExitNode = currentSettings.AdvertiseExitNode,
+ AdvertiseRoutes = currentSettings.AdvertiseRoutes,
+ RoutesToAdvertise = currentSettings.RoutesToAdvertise,
+ Hostname = currentSettings.Hostname,
+ LoginServer = currentSettings.LoginServer,
+ Ssh = currentSettings.Ssh,
+ Ephemeral = currentSettings.Ephemeral,
+ ResetOnStart = currentSettings.ResetOnStart
+ };
+
+ if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disable Tailscale"))
+ {
+ return;
+ }
+
+ // Update settings
+ var updateResult = ExecuteAsyncTask(() => tailscaleService.UpdateSettingsAsync(settings));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
+
+ // Stop the service if requested
+ if (Stop.IsPresent)
+ {
+ WriteVerbose("Stopping Tailscale service...");
+ var stopResult = ExecuteAsyncTask(() => tailscaleService.StopServiceAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || stopResult == null)
{
return;
}
- // Update settings
- var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
-
- // Stop the service if requested
- if (Stop.IsPresent)
- {
- WriteVerbose("Stopping Tailscale service...");
- var stopTask = Task.Run(async () => await tailscaleService.StopServiceAsync());
- var stopResult = stopTask.GetAwaiter().GetResult();
- WriteVerbose($"Tailscale service stopped: {stopResult.Status}");
- }
-
- // Get updated status
- var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
- var status = statusTask.GetAwaiter().GetResult();
-
- // Create result object
- var result = new PSObject();
- result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
- result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
- result.Properties.Add(new PSNoteProperty("Running", status.Running));
- result.Properties.Add(new PSNoteProperty("Status", status.Status));
-
- WriteObject(result);
+ WriteVerbose($"Tailscale service stopped: {stopResult.Status}");
}
- catch (Exception ex)
+
+ // Get updated status
+ var status = ExecuteAsyncTask(() => tailscaleService.GetStatusAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || status == null)
{
- HandleException(ex);
+ return;
}
+
+ // Create result object
+ var result = new PSObject();
+ result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
+ result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
+ result.Properties.Add(new PSNoteProperty("Running", status.Running));
+ result.Properties.Add(new PSNoteProperty("Status", status.Status));
+
+ WriteObject(result);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/DisconnectOPNSenseCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/DisconnectOPNSenseCmdlet.cs
index 6ee411f..8c7b6bd 100644
--- a/src/PSOPNSenseAPI/Cmdlets/DisconnectOPNSenseCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/DisconnectOPNSenseCmdlet.cs
@@ -17,6 +17,14 @@ namespace PSOPNSenseAPI.Cmdlets
[OutputType(typeof(void))]
public class DisconnectOPNSenseCmdlet : PSCmdlet
{
+ ///
+ /// Begins the processing of the cmdlet
+ ///
+ protected override void BeginProcessing()
+ {
+ base.BeginProcessing();
+ }
+
///
/// Processes the cmdlet
///
@@ -38,12 +46,17 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "DisconnectionFailed",
- ErrorCategory.ConnectionError,
- null));
+ // Use WriteWarning instead of WriteError to avoid threading issues
+ WriteWarning($"Failed to disconnect: {ex.Message}");
}
}
+
+ ///
+ /// Ends the processing of the cmdlet
+ ///
+ protected override void EndProcessing()
+ {
+ base.EndProcessing();
+ }
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/EnableOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/EnableOPNSenseFirewallRuleCmdlet.cs
index 7290d90..48dc069 100644
--- a/src/PSOPNSenseAPI/Cmdlets/EnableOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/EnableOPNSenseFirewallRuleCmdlet.cs
@@ -28,21 +28,20 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var firewallService = new FirewallService(ApiClient, Logger);
+ var firewallService = new FirewallService(ApiClient, Logger);
- var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, true));
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => firewallService.ToggleRuleAsync(Uuid, true));
- WriteVerbose($"Firewall rule {Uuid} enabled: {result.Result}");
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Firewall rule {Uuid} enabled: {result.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/EnableOPNSensePluginCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/EnableOPNSensePluginCmdlet.cs
index f1bf3b2..463c451 100644
--- a/src/PSOPNSenseAPI/Cmdlets/EnableOPNSensePluginCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/EnableOPNSensePluginCmdlet.cs
@@ -28,22 +28,21 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var pluginService = new PluginService(ApiClient, Logger);
+ var pluginService = new PluginService(ApiClient, Logger);
- var task = Task.Run(async () => await pluginService.EnablePluginAsync(Name));
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => pluginService.EnablePluginAsync(Name));
- WriteVerbose($"Plugin {Name} enabled: {result.Status}");
- WriteObject($"Plugin {Name} enabled: {result.Status}");
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Plugin {Name} enabled: {result.Status}");
+ WriteObject($"Plugin {Name} enabled: {result.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/ExportOPNSenseConfigCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/ExportOPNSenseConfigCmdlet.cs
index 2f529c8..e1920f9 100644
--- a/src/PSOPNSenseAPI/Cmdlets/ExportOPNSenseConfigCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/ExportOPNSenseConfigCmdlet.cs
@@ -35,28 +35,31 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
+ string fullPath = Path.FullName;
+
+ // Check if the file exists
+ if (File.Exists(fullPath) && !Force.IsPresent)
+ {
+ ProcessingException = new IOException($"The file '{fullPath}' already exists. Use -Force to overwrite.");
+ WriteWarning($"The file '{fullPath}' already exists. Use -Force to overwrite.");
+ return;
+ }
+
+ var configService = new ConfigService(ApiClient, Logger);
+
+ // Use our safe execution method
+ var configContent = ExecuteAsyncTask(() => configService.ExportConfigAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || configContent == null)
+ {
+ return;
+ }
+
try
{
- string fullPath = Path.FullName;
-
- // Check if the file exists
- if (File.Exists(fullPath) && !Force.IsPresent)
- {
- WriteError(new ErrorRecord(
- new IOException($"The file '{fullPath}' already exists. Use -Force to overwrite."),
- "FileExists",
- ErrorCategory.ResourceExists,
- fullPath));
- return;
- }
-
- var configService = new ConfigService(ApiClient, Logger);
-
- // Execute the async method synchronously on the main thread
- var configContent = configService.ExportConfigAsync().GetAwaiter().GetResult();
-
// Create the directory if it doesn't exist
var directory = System.IO.Path.GetDirectoryName(fullPath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
@@ -71,7 +74,8 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- HandleException(ex);
+ ProcessingException = ex;
+ WriteWarning($"Failed to write configuration to file: {ex.Message}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseAliasCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseAliasCmdlet.cs
index 50ef56a..4a820a7 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseAliasCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseAliasCmdlet.cs
@@ -52,54 +52,60 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var aliasService = new AliasService(ApiClient, Logger);
+
+ if (ParameterSetName == "ByUuid")
{
- var aliasService = new AliasService(ApiClient, Logger);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => aliasService.GetAliasAsync(Uuid));
- if (ParameterSetName == "ByUuid")
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- var task = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Alias);
+ return;
}
- else
- {
- var task = Task.Run(async () => await aliasService.GetAliasesAsync());
- var result = task.GetAwaiter().GetResult();
- // Filter by name if specified
- if (ParameterSetName == "ByName")
+ WriteObject(result.Alias);
+ }
+ else
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => aliasService.GetAliasesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ // Filter by name if specified
+ if (ParameterSetName == "ByName")
+ {
+ var filteredByName = result.Rows.FindAll(a => a.Name.Equals(Name, StringComparison.OrdinalIgnoreCase));
+
+ // Further filter by type if specified
+ if (!string.IsNullOrEmpty(Type))
{
- var filteredByName = result.Rows.FindAll(a => a.Name.Equals(Name, StringComparison.OrdinalIgnoreCase));
-
- // Further filter by type if specified
- if (!string.IsNullOrEmpty(Type))
- {
- var filteredByType = filteredByName.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
- WriteObject(filteredByType, true);
- }
- else
- {
- WriteObject(filteredByName, true);
- }
- }
- // Filter by type if specified
- else if (!string.IsNullOrEmpty(Type))
- {
- var filteredByType = result.Rows.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
+ var filteredByType = filteredByName.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
WriteObject(filteredByType, true);
}
else
{
- WriteObject(result.Rows, true);
+ WriteObject(filteredByName, true);
}
}
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ // Filter by type if specified
+ else if (!string.IsNullOrEmpty(Type))
+ {
+ var filteredByType = result.Rows.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
+ WriteObject(filteredByType, true);
+ }
+ else
+ {
+ WriteObject(result.Rows, true);
+ }
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigBackupCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigBackupCmdlet.cs
index 4beb35f..7251055 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigBackupCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigBackupCmdlet.cs
@@ -21,21 +21,20 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var configService = new ConfigService(ApiClient, Logger);
+ var configService = new ConfigService(ApiClient, Logger);
- var task = Task.Run(async () => await configService.GetConfigBackupsAsync());
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => configService.GetConfigBackupsAsync());
- WriteObject(result.Backups, true);
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteObject(result.Backups, true);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigCmdlet.cs
index 98b8b3d..3bad039 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseConfigCmdlet.cs
@@ -28,17 +28,23 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
+ var configService = new ConfigService(ApiClient, Logger);
+
+ // Use our safe execution method
+ var configContent = ExecuteAsyncTask(() => configService.ExportConfigAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || configContent == null)
+ {
+ return;
+ }
+
+ // Convert the byte array to an XML document
+ var xmlDoc = new XmlDocument();
try
{
- var configService = new ConfigService(ApiClient, Logger);
-
- // Execute the async method synchronously on the main thread
- var configContent = configService.ExportConfigAsync().GetAwaiter().GetResult();
-
- // Convert the byte array to an XML document
- var xmlDoc = new XmlDocument();
using (var memoryStream = new MemoryStream(configContent))
{
xmlDoc.Load(memoryStream);
@@ -49,7 +55,8 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- HandleException(ex);
+ ProcessingException = ex;
+ WriteWarning($"Failed to parse XML configuration: {ex.Message}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPOptionCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPOptionCmdlet.cs
index 0bf7ee5..b9d4232 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPOptionCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPOptionCmdlet.cs
@@ -40,28 +40,35 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var dhcpService = new DHCPService(ApiClient, Logger);
+ var dhcpService = new DHCPService(ApiClient, Logger);
- if (ParameterSetName == "ByUuid")
- {
- var task = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Option);
- }
- else
- {
- var task = Task.Run(async () => await dhcpService.GetOptionsAsync(Interface));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Rows, true);
- }
- }
- catch (Exception ex)
+ if (ParameterSetName == "ByUuid")
{
- HandleException(ex);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetOptionAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Option);
+ }
+ else
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetOptionsAsync(Interface));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Rows, true);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPServerCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPServerCmdlet.cs
index 7a74e27..d3975e0 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPServerCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPServerCmdlet.cs
@@ -33,43 +33,49 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ if (ParameterSetName == "ByInterface")
{
- var dhcpService = new DHCPService(ApiClient, Logger);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetServerAsync(Interface));
- if (ParameterSetName == "ByInterface")
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- var task = Task.Run(async () => await dhcpService.GetServerAsync(Interface));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Server);
+ return;
}
- else
- {
- var task = Task.Run(async () => await dhcpService.GetServersAsync());
- var result = task.GetAwaiter().GetResult();
- foreach (var kvp in result.Servers.Interfaces)
- {
- var server = new PSObject();
- server.Properties.Add(new PSNoteProperty("Interface", kvp.Key));
- server.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
- server.Properties.Add(new PSNoteProperty("RangeFrom", kvp.Value.RangeFrom));
- server.Properties.Add(new PSNoteProperty("RangeTo", kvp.Value.RangeTo));
- server.Properties.Add(new PSNoteProperty("DefaultLeaseTime", kvp.Value.DefaultLeaseTime));
- server.Properties.Add(new PSNoteProperty("MaxLeaseTime", kvp.Value.MaxLeaseTime));
- server.Properties.Add(new PSNoteProperty("Domain", kvp.Value.Domain));
- server.Properties.Add(new PSNoteProperty("DnsServers", kvp.Value.DnsServers));
- server.Properties.Add(new PSNoteProperty("Gateway", kvp.Value.Gateway));
-
- WriteObject(server);
- }
- }
+ WriteObject(result.Server);
}
- catch (Exception ex)
+ else
{
- HandleException(ex);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetServersAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ foreach (var kvp in result.Servers.Interfaces)
+ {
+ var server = new PSObject();
+ server.Properties.Add(new PSNoteProperty("Interface", kvp.Key));
+ server.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
+ server.Properties.Add(new PSNoteProperty("RangeFrom", kvp.Value.RangeFrom));
+ server.Properties.Add(new PSNoteProperty("RangeTo", kvp.Value.RangeTo));
+ server.Properties.Add(new PSNoteProperty("DefaultLeaseTime", kvp.Value.DefaultLeaseTime));
+ server.Properties.Add(new PSNoteProperty("MaxLeaseTime", kvp.Value.MaxLeaseTime));
+ server.Properties.Add(new PSNoteProperty("Domain", kvp.Value.Domain));
+ server.Properties.Add(new PSNoteProperty("DnsServers", kvp.Value.DnsServers));
+ server.Properties.Add(new PSNoteProperty("Gateway", kvp.Value.Gateway));
+
+ WriteObject(server);
+ }
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPStaticMappingCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPStaticMappingCmdlet.cs
index 6604dea..88d5bdc 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPStaticMappingCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDHCPStaticMappingCmdlet.cs
@@ -40,28 +40,35 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var dhcpService = new DHCPService(ApiClient, Logger);
+ var dhcpService = new DHCPService(ApiClient, Logger);
- if (ParameterSetName == "ByUuid")
- {
- var task = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Mapping);
- }
- else
- {
- var task = Task.Run(async () => await dhcpService.GetStaticMappingsAsync(Interface));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Rows, true);
- }
- }
- catch (Exception ex)
+ if (ParameterSetName == "ByUuid")
{
- HandleException(ex);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetStaticMappingAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Mapping);
+ }
+ else
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dhcpService.GetStaticMappingsAsync(Interface));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Rows, true);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSForwardingCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSForwardingCmdlet.cs
index 630d147..5b755a1 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSForwardingCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSForwardingCmdlet.cs
@@ -21,21 +21,20 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var dnsService = new DNSService(ApiClient, Logger);
+ var dnsService = new DNSService(ApiClient, Logger);
- var task = Task.Run(async () => await dnsService.GetDNSForwardingAsync());
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dnsService.GetDNSForwardingAsync());
- WriteObject(result.Forward);
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteObject(result.Forward);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSServerCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSServerCmdlet.cs
index 8fd7b71..2b19e2b 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSServerCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseDNSServerCmdlet.cs
@@ -21,32 +21,31 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => dnsService.GetDNSConfigAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
-
- var task = Task.Run(async () => await dnsService.GetDNSConfigAsync());
- var result = task.GetAwaiter().GetResult();
-
- var dnsConfig = new PSObject();
- dnsConfig.Properties.Add(new PSNoteProperty("Enabled", result.Unbound.Enabled == "1"));
- dnsConfig.Properties.Add(new PSNoteProperty("Port", result.Unbound.Port));
- dnsConfig.Properties.Add(new PSNoteProperty("Interfaces", result.Unbound.Interfaces));
- dnsConfig.Properties.Add(new PSNoteProperty("Forwarding", result.Unbound.Forwarding == "1"));
- dnsConfig.Properties.Add(new PSNoteProperty("Forwarders", result.Unbound.Forwarders));
- dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcp", result.Unbound.RegisterDhcp == "1"));
- dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpDomain", result.Unbound.RegisterDhcpDomain));
- dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpStatic", result.Unbound.RegisterDhcpStatic == "1"));
- dnsConfig.Properties.Add(new PSNoteProperty("ActiveInterfaces", result.Unbound.ActiveInterfaces));
-
- WriteObject(dnsConfig);
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ return;
}
+
+ var dnsConfig = new PSObject();
+ dnsConfig.Properties.Add(new PSNoteProperty("Enabled", result.Unbound.Enabled == "1"));
+ dnsConfig.Properties.Add(new PSNoteProperty("Port", result.Unbound.Port));
+ dnsConfig.Properties.Add(new PSNoteProperty("Interfaces", result.Unbound.Interfaces));
+ dnsConfig.Properties.Add(new PSNoteProperty("Forwarding", result.Unbound.Forwarding == "1"));
+ dnsConfig.Properties.Add(new PSNoteProperty("Forwarders", result.Unbound.Forwarders));
+ dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcp", result.Unbound.RegisterDhcp == "1"));
+ dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpDomain", result.Unbound.RegisterDhcpDomain));
+ dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpStatic", result.Unbound.RegisterDhcpStatic == "1"));
+ dnsConfig.Properties.Add(new PSNoteProperty("ActiveInterfaces", result.Unbound.ActiveInterfaces));
+
+ WriteObject(dnsConfig);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseFirewallRuleCmdlet.cs
index 4c1d89b..f6d6d4e 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseFirewallRuleCmdlet.cs
@@ -58,28 +58,35 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var firewallService = new FirewallService(ApiClient, Logger);
+ var firewallService = new FirewallService(ApiClient, Logger);
- if (ParameterSetName == "ByUuid")
- {
- var task = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Rule);
- }
- else
- {
- var task = Task.Run(async () => await firewallService.GetRulesAsync(SearchPhrase, Page, RowCount));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Rows, true);
- }
- }
- catch (Exception ex)
+ if (ParameterSetName == "ByUuid")
{
- HandleException(ex);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => firewallService.GetRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Rule);
+ }
+ else
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => firewallService.GetRulesAsync(SearchPhrase, Page, RowCount));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Rows, true);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseInterfaceStatisticsCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseInterfaceStatisticsCmdlet.cs
index 0145249..ba3343c 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseInterfaceStatisticsCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseInterfaceStatisticsCmdlet.cs
@@ -26,33 +26,32 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => interfaceService.GetInterfaceStatisticsAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- var interfaceService = new InterfaceService(ApiClient, Logger);
-
- var task = Task.Run(async () => await interfaceService.GetInterfaceStatisticsAsync());
- var result = task.GetAwaiter().GetResult();
-
- foreach (var kvp in result.Statistics)
- {
- var stats = new PSObject();
- stats.Properties.Add(new PSNoteProperty("Name", kvp.Key));
- stats.Properties.Add(new PSNoteProperty("InPackets", kvp.Value.InPackets));
- stats.Properties.Add(new PSNoteProperty("InBytes", kvp.Value.InBytes));
- stats.Properties.Add(new PSNoteProperty("InErrors", 0));
- stats.Properties.Add(new PSNoteProperty("OutPackets", kvp.Value.OutPackets));
- stats.Properties.Add(new PSNoteProperty("OutBytes", kvp.Value.OutBytes));
- stats.Properties.Add(new PSNoteProperty("OutErrors", 0));
- stats.Properties.Add(new PSNoteProperty("Collisions", 0));
-
- WriteObject(stats);
- }
+ return;
}
- catch (Exception ex)
+
+ foreach (var kvp in result.Statistics)
{
- HandleException(ex);
+ var stats = new PSObject();
+ stats.Properties.Add(new PSNoteProperty("Name", kvp.Key));
+ stats.Properties.Add(new PSNoteProperty("InPackets", kvp.Value.InPackets));
+ stats.Properties.Add(new PSNoteProperty("InBytes", kvp.Value.InBytes));
+ stats.Properties.Add(new PSNoteProperty("InErrors", 0));
+ stats.Properties.Add(new PSNoteProperty("OutPackets", kvp.Value.OutPackets));
+ stats.Properties.Add(new PSNoteProperty("OutBytes", kvp.Value.OutBytes));
+ stats.Properties.Add(new PSNoteProperty("OutErrors", 0));
+ stats.Properties.Add(new PSNoteProperty("Collisions", 0));
+
+ WriteObject(stats);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePluginCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePluginCmdlet.cs
index a6e8b0e..3af74b4 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePluginCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePluginCmdlet.cs
@@ -43,60 +43,59 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var pluginService = new PluginService(ApiClient, Logger);
+
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => pluginService.GetPluginsAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- var pluginService = new PluginService(ApiClient, Logger);
+ return;
+ }
- var task = Task.Run(async () => await pluginService.GetPluginsAsync());
- var result = task.GetAwaiter().GetResult();
-
- if (ParameterSetName == "Installed" || ParameterSetName == "")
+ if (ParameterSetName == "Installed" || ParameterSetName == "")
+ {
+ foreach (var kvp in result.Installed)
{
- foreach (var kvp in result.Installed)
- {
- var plugin = new PSObject();
- plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
- plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
- plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
- plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
- plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
- plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
- plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
- plugin.Properties.Add(new PSNoteProperty("Locked", kvp.Value.Locked == "1"));
- plugin.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
- plugin.Properties.Add(new PSNoteProperty("Status", "Installed"));
-
- WriteObject(plugin);
- }
- }
+ var plugin = new PSObject();
+ plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
+ plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
+ plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
+ plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
+ plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
+ plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
+ plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
+ plugin.Properties.Add(new PSNoteProperty("Locked", kvp.Value.Locked == "1"));
+ plugin.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
+ plugin.Properties.Add(new PSNoteProperty("Status", "Installed"));
- if (ParameterSetName == "Available" || ParameterSetName == "")
- {
- foreach (var kvp in result.Available)
- {
- // Skip if the plugin is already installed
- if (result.Installed.ContainsKey(kvp.Key))
- continue;
-
- var plugin = new PSObject();
- plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
- plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
- plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
- plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
- plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
- plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
- plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
- plugin.Properties.Add(new PSNoteProperty("Status", "Available"));
-
- WriteObject(plugin);
- }
+ WriteObject(plugin);
}
}
- catch (Exception ex)
+
+ if (ParameterSetName == "Available" || ParameterSetName == "")
{
- HandleException(ex);
+ foreach (var kvp in result.Available)
+ {
+ // Skip if the plugin is already installed
+ if (result.Installed.ContainsKey(kvp.Key))
+ continue;
+
+ var plugin = new PSObject();
+ plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
+ plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
+ plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
+ plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
+ plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
+ plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
+ plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
+ plugin.Properties.Add(new PSNoteProperty("Status", "Available"));
+
+ WriteObject(plugin);
+ }
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePortForwardingRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePortForwardingRuleCmdlet.cs
index 5eedb00..c37afb9 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePortForwardingRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSensePortForwardingRuleCmdlet.cs
@@ -19,7 +19,7 @@ namespace PSOPNSenseAPI.Cmdlets
///
[Cmdlet(VerbsCommon.Get, "OPNSensePortForwardingRule")]
[OutputType(typeof(PortForwardingRule))]
- public class GetOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
+ public class GetOPNSensePortForwardingRuleCmdlet : OPNSenseBaseCmdlet
{
///
/// The UUID of the port forwarding rule to get. If not specified, all rules are returned.
@@ -30,14 +30,21 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- var portForwardingService = new PortForwardingService(SessionState.ApiClient);
+ var portForwardingService = new PortForwardingService(ApiClient);
if (!string.IsNullOrEmpty(Uuid))
{
- // Get a specific rule
- var rule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
+ // Use our safe execution method
+ var rule = ExecuteAsyncTask(() => portForwardingService.GetPortForwardingRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
+
if (rule != null)
{
WriteObject(rule);
@@ -49,8 +56,15 @@ namespace PSOPNSenseAPI.Cmdlets
}
else
{
- // Get all rules
- var rules = Task.Run(async () => await portForwardingService.GetPortForwardingRulesAsync()).GetAwaiter().GetResult();
+ // Use our safe execution method
+ var rules = ExecuteAsyncTask(() => portForwardingService.GetPortForwardingRulesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || rules == null)
+ {
+ return;
+ }
+
WriteObject(rules, true);
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseSystemDNSCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseSystemDNSCmdlet.cs
index 23f730d..b41006d 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseSystemDNSCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseSystemDNSCmdlet.cs
@@ -21,21 +21,20 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var systemDNSService = new SystemDNSService(ApiClient, Logger);
+ var systemDNSService = new SystemDNSService(ApiClient, Logger);
- var task = Task.Run(async () => await systemDNSService.GetSystemDNSAsync());
- var result = task.GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => systemDNSService.GetSystemDNSAsync());
- WriteObject(result.System);
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteObject(result.System);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseVLANCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseVLANCmdlet.cs
index 6006e2a..2cb86e4 100644
--- a/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseVLANCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/GetOPNSenseVLANCmdlet.cs
@@ -33,28 +33,35 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var interfaceService = new InterfaceService(ApiClient, Logger);
+ var interfaceService = new InterfaceService(ApiClient, Logger);
- if (ParameterSetName == "ByUuid")
- {
- var task = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Vlan);
- }
- else
- {
- var task = Task.Run(async () => await interfaceService.GetVLANsAsync());
- var result = task.GetAwaiter().GetResult();
- WriteObject(result.Rows, true);
- }
- }
- catch (Exception ex)
+ if (ParameterSetName == "ByUuid")
{
- HandleException(ex);
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => interfaceService.GetVLANAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Vlan);
+ }
+ else
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => interfaceService.GetVLANsAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
+ WriteObject(result.Rows, true);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/ImportOPNSenseConfigCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/ImportOPNSenseConfigCmdlet.cs
index 00667a2..bde36d2 100644
--- a/src/PSOPNSenseAPI/Cmdlets/ImportOPNSenseConfigCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/ImportOPNSenseConfigCmdlet.cs
@@ -35,42 +35,46 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
+ string fullPath = Path.FullName;
+
+ // Check if the file exists
+ if (!File.Exists(fullPath))
+ {
+ ProcessingException = new FileNotFoundException($"The file '{fullPath}' does not exist.");
+ WriteWarning($"The file '{fullPath}' does not exist.");
+ return;
+ }
+
+ if (!Force.IsPresent && !ShouldProcess(fullPath, "Import configuration"))
+ {
+ return;
+ }
+
+ var configService = new ConfigService(ApiClient, Logger);
+
try
{
- string fullPath = Path.FullName;
-
- // Check if the file exists
- if (!File.Exists(fullPath))
- {
- WriteError(new ErrorRecord(
- new FileNotFoundException($"The file '{fullPath}' does not exist."),
- "FileNotFound",
- ErrorCategory.ObjectNotFound,
- fullPath));
- return;
- }
-
- if (!Force.IsPresent && !ShouldProcess(fullPath, "Import configuration"))
- {
- return;
- }
-
- var configService = new ConfigService(ApiClient, Logger);
-
// Read the configuration file
var configContent = File.ReadAllBytes(fullPath);
- // Execute the async method synchronously on the main thread
- var result = configService.ImportConfigAsync(configContent).GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => configService.ImportConfigAsync(configContent));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
WriteVerbose($"Imported configuration from {fullPath}: {result.Status}");
WriteWarning("The firewall is restarting. You may need to reconnect after it comes back online.");
}
catch (Exception ex)
{
- HandleException(ex);
+ ProcessingException = ex;
+ WriteWarning($"Failed to read or process configuration file: {ex.Message}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/InvokeOPNSenseNetworkCalculationCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/InvokeOPNSenseNetworkCalculationCmdlet.cs
index 8cb1d69..0bf59cb 100644
--- a/src/PSOPNSenseAPI/Cmdlets/InvokeOPNSenseNetworkCalculationCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/InvokeOPNSenseNetworkCalculationCmdlet.cs
@@ -185,11 +185,7 @@ namespace PSOPNSenseAPI.Cmdlets
{
if (prefixLength <= network.Cidr)
{
- WriteError(new ErrorRecord(
- new ArgumentException($"Prefix length ({prefixLength}) must be greater than the network CIDR ({network.Cidr})."),
- "InvalidPrefixLength",
- ErrorCategory.InvalidArgument,
- null));
+ ProcessingException = new ArgumentException($"Prefix length ({prefixLength}) must be greater than the network CIDR ({network.Cidr}).");
return;
}
@@ -206,11 +202,7 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (ArgumentException ex)
{
- WriteError(new ErrorRecord(
- ex,
- "InvalidSubnetCount",
- ErrorCategory.InvalidArgument,
- null));
+ ProcessingException = ex;
}
}
@@ -236,11 +228,7 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "InvalidIPAddress",
- ErrorCategory.InvalidArgument,
- null));
+ ProcessingException = ex;
}
}
@@ -267,11 +255,7 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "InvalidAdditionalNetwork",
- ErrorCategory.InvalidArgument,
- null));
+ ProcessingException = ex;
}
}
@@ -292,11 +276,7 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "SupernetError",
- ErrorCategory.InvalidOperation,
- null));
+ ProcessingException = ex;
}
}
@@ -317,11 +297,7 @@ namespace PSOPNSenseAPI.Cmdlets
}
catch (Exception ex)
{
- WriteError(new ErrorRecord(
- ex,
- "SupernetSummarizeError",
- ErrorCategory.InvalidOperation,
- null));
+ ProcessingException = ex;
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseFirewallRuleCmdlet.cs
index 58dea0a..c96e900 100644
--- a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseFirewallRuleCmdlet.cs
@@ -83,35 +83,34 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var firewallService = new FirewallService(ApiClient, Logger);
+
+ var rule = new FirewallRuleCreate
{
- var firewallService = new FirewallService(ApiClient, Logger);
+ Description = Description,
+ Protocol = Protocol,
+ SourceNet = SourceNet,
+ SourcePort = SourcePort,
+ DestinationNet = DestinationNet,
+ DestinationPort = DestinationPort,
+ Action = Action,
+ Sequence = Sequence,
+ Enabled = Enabled.IsPresent ? "1" : "0"
+ };
- var rule = new FirewallRuleCreate
- {
- Description = Description,
- Protocol = Protocol,
- SourceNet = SourceNet,
- SourcePort = SourcePort,
- DestinationNet = DestinationNet,
- DestinationPort = DestinationPort,
- Action = Action,
- Sequence = Sequence,
- Enabled = Enabled.IsPresent ? "1" : "0"
- };
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => firewallService.CreateRuleAsync(rule));
- var task = Task.Run(async () => await firewallService.CreateRuleAsync(rule));
- var result = task.GetAwaiter().GetResult();
-
- WriteVerbose($"Created firewall rule with UUID {result.Uuid}");
- WriteObject(result.Uuid);
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Created firewall rule with UUID {result.Uuid}");
+ WriteObject(result.Uuid);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/NewOPNSensePortForwardingRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/NewOPNSensePortForwardingRuleCmdlet.cs
index df4e61f..4f41432 100644
--- a/src/PSOPNSenseAPI/Cmdlets/NewOPNSensePortForwardingRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/NewOPNSensePortForwardingRuleCmdlet.cs
@@ -15,7 +15,7 @@ namespace PSOPNSenseAPI.Cmdlets
///
[Cmdlet(VerbsCommon.New, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Medium)]
[OutputType(typeof(PortForwardingRule))]
- public class NewOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
+ public class NewOPNSensePortForwardingRuleCmdlet : OPNSenseBaseCmdlet
{
///
/// Whether the rule is enabled.
@@ -106,7 +106,7 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
var rule = new PortForwardingRule
{
@@ -127,8 +127,16 @@ namespace PSOPNSenseAPI.Cmdlets
if (Force || ShouldProcess($"OPNSense firewall", $"Create port forwarding rule from {Destination}:{DestinationPort} to {TargetIP}:{TargetPort}"))
{
- var portForwardingService = new PortForwardingService(SessionState.ApiClient);
- var uuid = Task.Run(async () => await portForwardingService.CreatePortForwardingRuleAsync(rule)).GetAwaiter().GetResult();
+ var portForwardingService = new PortForwardingService(ApiClient);
+
+ // Use our safe execution method
+ var uuid = ExecuteAsyncTask(() => portForwardingService.CreatePortForwardingRuleAsync(rule));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
if (!string.IsNullOrEmpty(uuid))
{
@@ -138,11 +146,8 @@ namespace PSOPNSenseAPI.Cmdlets
}
else
{
- WriteError(new ErrorRecord(
- new PSInvalidOperationException("Failed to create port forwarding rule."),
- "PortForwardingRuleCreationFailed",
- ErrorCategory.InvalidOperation,
- null));
+ ProcessingException = new PSInvalidOperationException("Failed to create port forwarding rule.");
+ WriteWarning("Failed to create port forwarding rule.");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseSubnetVLANsCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseSubnetVLANsCmdlet.cs
index c4f4c80..60a303e 100644
--- a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseSubnetVLANsCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseSubnetVLANsCmdlet.cs
@@ -99,199 +99,219 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ // Parse the network CIDR
+ var ipNetwork = IPNetwork2.Parse(Network);
+
+ // Validate subnet mask bits
+ if (SubnetMaskBits <= ipNetwork.Cidr)
{
- // Parse the network CIDR
- var ipNetwork = IPNetwork2.Parse(Network);
+ ProcessingException = new ArgumentException($"Subnet mask bits ({SubnetMaskBits}) must be greater than the network CIDR ({ipNetwork.Cidr}).");
+ WriteWarning($"Subnet mask bits ({SubnetMaskBits}) must be greater than the network CIDR ({ipNetwork.Cidr}).");
+ return;
+ }
- // Validate subnet mask bits
- if (SubnetMaskBits <= ipNetwork.Cidr)
+ // Calculate the number of subnets
+ int numSubnets = (int)Math.Pow(2, SubnetMaskBits - ipNetwork.Cidr);
+
+ // Calculate the maximum VLAN ID
+ int maxVlanId = StartingVlanId + (numSubnets - 1) * VlanIdIncrement;
+
+ // Validate the maximum VLAN ID
+ if (maxVlanId > 4094)
+ {
+ ProcessingException = new ArgumentException($"The maximum VLAN ID ({maxVlanId}) exceeds the maximum allowed value (4094).");
+ WriteWarning($"The maximum VLAN ID ({maxVlanId}) exceeds the maximum allowed value (4094).");
+ return;
+ }
+
+ // Get confirmation
+ if (!Force.IsPresent && !ShouldProcess($"Create {numSubnets} VLANs for subnets of {Network} with VLAN IDs {StartingVlanId}-{maxVlanId}", "New-OPNSenseSubnetVLANs"))
+ {
+ return;
+ }
+
+ // Get the interface service
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ // Verify the parent interface exists
+ var interfaceDetail = ExecuteAsyncTask(() => interfaceService.GetInterfaceDetailAsync(ParentInterface));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
+
+ // Get existing VLANs
+ var vlansResult = ExecuteAsyncTask(() => interfaceService.GetVLANsAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || vlansResult == null)
+ {
+ return;
+ }
+
+ var existingVlans = vlansResult.Rows;
+
+ // Create a list to store the created VLANs
+ var createdVlans = new List();
+
+ // Get DHCP service if needed
+ DHCPService dhcpService = null;
+ if (EnableDHCP.IsPresent)
+ {
+ dhcpService = new DHCPService(ApiClient, Logger);
+ }
+
+ // Divide the network into subnets
+ var subnets = ipNetwork.Subnet((byte)SubnetMaskBits);
+ int vlanId = StartingVlanId;
+ int subnetIndex = 0;
+
+ foreach (var subnet in subnets)
+ {
+ // Calculate the gateway IP (first host address)
+ var gatewayIp = GetFirstHostAddress(subnet);
+
+ // Calculate the DHCP range (second host address to last host address)
+ var dhcpStart = GetSecondHostAddress(subnet);
+ var dhcpEnd = GetLastHostAddress(subnet);
+
+ // Create a description for the VLAN
+ string description = $"{DescriptionPrefix} {vlanId} - {subnet}";
+
+ // Check if the VLAN already exists
+ var existingVlan = existingVlans.FirstOrDefault(v =>
+ v.Interface == ParentInterface &&
+ int.Parse(v.Tag) == vlanId);
+
+ if (existingVlan != null)
{
- WriteError(new ErrorRecord(
- new ArgumentException($"Subnet mask bits ({SubnetMaskBits}) must be greater than the network CIDR ({ipNetwork.Cidr})."),
- "InvalidSubnetMaskBits",
- ErrorCategory.InvalidArgument,
- SubnetMaskBits));
- return;
+ WriteVerbose($"VLAN {vlanId} already exists on interface {ParentInterface}");
+
+ // Add the existing VLAN to the list
+ var vlanInfo = new PSObject();
+ vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
+ vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
+ vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
+ vlanInfo.Properties.Add(new PSNoteProperty("Uuid", existingVlan.Uuid));
+ vlanInfo.Properties.Add(new PSNoteProperty("Status", "Existing"));
+
+ createdVlans.Add(vlanInfo);
}
-
- // Calculate the number of subnets
- int numSubnets = (int)Math.Pow(2, SubnetMaskBits - ipNetwork.Cidr);
-
- // Calculate the maximum VLAN ID
- int maxVlanId = StartingVlanId + (numSubnets - 1) * VlanIdIncrement;
-
- // Validate the maximum VLAN ID
- if (maxVlanId > 4094)
+ else
{
- WriteError(new ErrorRecord(
- new ArgumentException($"The maximum VLAN ID ({maxVlanId}) exceeds the maximum allowed value (4094)."),
- "InvalidVlanIdRange",
- ErrorCategory.InvalidArgument,
- maxVlanId));
- return;
- }
-
- // Get confirmation
- if (!Force.IsPresent && !ShouldProcess($"Create {numSubnets} VLANs for subnets of {Network} with VLAN IDs {StartingVlanId}-{maxVlanId}", "New-OPNSenseSubnetVLANs"))
- {
- return;
- }
-
- // Get the interface service
- var interfaceService = new InterfaceService(ApiClient, Logger);
-
- // Verify the parent interface exists
- var getInterfaceTask = Task.Run(async () => await interfaceService.GetInterfaceDetailAsync(ParentInterface));
- getInterfaceTask.GetAwaiter().GetResult();
-
- // Get existing VLANs
- var getVlansTask = Task.Run(async () => await interfaceService.GetVLANsAsync());
- var existingVlans = getVlansTask.GetAwaiter().GetResult().Rows;
-
- // Create a list to store the created VLANs
- var createdVlans = new List();
-
- // Get DHCP service if needed
- DHCPService dhcpService = null;
- if (EnableDHCP.IsPresent)
- {
- dhcpService = new DHCPService(ApiClient, Logger);
- }
-
- // Divide the network into subnets
- var subnets = ipNetwork.Subnet((byte)SubnetMaskBits);
- int vlanId = StartingVlanId;
- int subnetIndex = 0;
-
- foreach (var subnet in subnets)
- {
- // Calculate the gateway IP (first host address)
- var gatewayIp = GetFirstHostAddress(subnet);
-
- // Calculate the DHCP range (second host address to last host address)
- var dhcpStart = GetSecondHostAddress(subnet);
- var dhcpEnd = GetLastHostAddress(subnet);
-
- // Create a description for the VLAN
- string description = $"{DescriptionPrefix} {vlanId} - {subnet}";
-
- // Check if the VLAN already exists
- var existingVlan = existingVlans.FirstOrDefault(v =>
- v.Interface == ParentInterface &&
- int.Parse(v.Tag) == vlanId);
-
- if (existingVlan != null)
+ // Create the VLAN
+ var vlanConfig = new VLANConfig
{
- WriteVerbose($"VLAN {vlanId} already exists on interface {ParentInterface}");
+ Interface = ParentInterface,
+ Tag = vlanId.ToString(),
+ Priority = "0",
+ Description = description
+ };
- // Add the existing VLAN to the list
- var vlanInfo = new PSObject();
- vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
- vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
- vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
- vlanInfo.Properties.Add(new PSNoteProperty("Uuid", existingVlan.Uuid));
- vlanInfo.Properties.Add(new PSNoteProperty("Status", "Existing"));
+ var createVlanResult = ExecuteAsyncTask(() => interfaceService.CreateVLANAsync(vlanConfig));
- createdVlans.Add(vlanInfo);
- }
- else
+ // Only continue if no exception occurred
+ if (ProcessingException != null || createVlanResult == null)
{
- // Create the VLAN
- var vlanConfig = new VLANConfig
- {
- Interface = ParentInterface,
- Tag = vlanId.ToString(),
- Priority = "0",
- Description = description
- };
-
- var createVlanTask = Task.Run(async () => await interfaceService.CreateVLANAsync(vlanConfig));
- var createVlanResult = createVlanTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Created VLAN {vlanId} on interface {ParentInterface} with UUID {createVlanResult.Uuid}");
-
- // Configure the VLAN interface
- string vlanInterfaceName = $"{ParentInterface}.{vlanId}";
-
- var interfaceConfig = new InterfaceConfig
- {
- Description = description,
- IpAddress = gatewayIp.ToString(),
- SubnetMask = SubnetMaskBits.ToString(),
- Enabled = "1"
- };
-
- var updateInterfaceTask = Task.Run(async () => await interfaceService.UpdateInterfaceAsync(vlanInterfaceName, interfaceConfig));
- updateInterfaceTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Configured interface {vlanInterfaceName} with IP {gatewayIp}/{SubnetMaskBits}");
-
- // If EnableDHCP is specified, configure DHCP for the interface
- if (EnableDHCP.IsPresent && dhcpService != null)
- {
- // Configure DHCP server for the interface
- var dhcpConfig = new DHCPServerConfig
- {
- Enabled = "1",
- RangeFrom = dhcpStart.ToString(),
- RangeTo = dhcpEnd.ToString(),
- DefaultLeaseTime = "7200",
- MaxLeaseTime = "86400",
- Domain = Domain,
- Gateway = gatewayIp.ToString(),
- DnsServers = DnsServers != null ? new List(DnsServers) : new List { gatewayIp.ToString() }
- };
-
- var updateDhcpTask = Task.Run(async () => await dhcpService.UpdateServerAsync(vlanInterfaceName, dhcpConfig));
- updateDhcpTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Configured DHCP server for interface {vlanInterfaceName} with range {dhcpStart} - {dhcpEnd}");
- }
-
- // Add the created VLAN to the list
- var vlanInfo = new PSObject();
- vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
- vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
- vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
- vlanInfo.Properties.Add(new PSNoteProperty("Uuid", createVlanResult.Uuid));
- vlanInfo.Properties.Add(new PSNoteProperty("Status", "Created"));
- if (EnableDHCP.IsPresent)
- {
- vlanInfo.Properties.Add(new PSNoteProperty("DHCPRange", $"{dhcpStart} - {dhcpEnd}"));
- }
-
- createdVlans.Add(vlanInfo);
+ return;
}
- // Increment the VLAN ID
- vlanId += VlanIdIncrement;
- subnetIndex++;
+ WriteVerbose($"Created VLAN {vlanId} on interface {ParentInterface} with UUID {createVlanResult.Uuid}");
+
+ // Configure the VLAN interface
+ string vlanInterfaceName = $"{ParentInterface}.{vlanId}";
+
+ var interfaceConfig = new InterfaceConfig
+ {
+ Description = description,
+ IpAddress = gatewayIp.ToString(),
+ SubnetMask = SubnetMaskBits.ToString(),
+ Enabled = "1"
+ };
+
+ var updateInterfaceResult = ExecuteAsyncTask(() => interfaceService.UpdateInterfaceAsync(vlanInterfaceName, interfaceConfig));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Configured interface {vlanInterfaceName} with IP {gatewayIp}/{SubnetMaskBits}");
+
+ // If EnableDHCP is specified, configure DHCP for the interface
+ if (EnableDHCP.IsPresent && dhcpService != null)
+ {
+ // Configure DHCP server for the interface
+ var dhcpConfig = new DHCPServerConfig
+ {
+ Enabled = "1",
+ RangeFrom = dhcpStart.ToString(),
+ RangeTo = dhcpEnd.ToString(),
+ DefaultLeaseTime = "7200",
+ MaxLeaseTime = "86400",
+ Domain = Domain,
+ Gateway = gatewayIp.ToString(),
+ DnsServers = DnsServers != null ? new List(DnsServers) : new List { gatewayIp.ToString() }
+ };
+
+ var updateDhcpResult = ExecuteAsyncTask(() => dhcpService.UpdateServerAsync(vlanInterfaceName, dhcpConfig));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Configured DHCP server for interface {vlanInterfaceName} with range {dhcpStart} - {dhcpEnd}");
+ }
+
+ // Add the created VLAN to the list
+ var vlanInfo = new PSObject();
+ vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
+ vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
+ vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
+ vlanInfo.Properties.Add(new PSNoteProperty("Uuid", createVlanResult.Uuid));
+ vlanInfo.Properties.Add(new PSNoteProperty("Status", "Created"));
+ if (EnableDHCP.IsPresent)
+ {
+ vlanInfo.Properties.Add(new PSNoteProperty("DHCPRange", $"{dhcpStart} - {dhcpEnd}"));
+ }
+
+ createdVlans.Add(vlanInfo);
}
- // Apply DHCP changes if needed
- if (EnableDHCP.IsPresent && dhcpService != null)
- {
- var applyDhcpTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyDhcpResult = applyDhcpTask.GetAwaiter().GetResult();
- WriteVerbose($"Applied DHCP changes: {applyDhcpResult.Status}");
- }
-
- // Create a result object
- var result = new PSObject();
- result.Properties.Add(new PSNoteProperty("ParentInterface", ParentInterface));
- result.Properties.Add(new PSNoteProperty("Network", Network));
- result.Properties.Add(new PSNoteProperty("SubnetMaskBits", SubnetMaskBits));
- result.Properties.Add(new PSNoteProperty("VLANs", createdVlans));
-
- WriteObject(result);
+ // Increment the VLAN ID
+ vlanId += VlanIdIncrement;
+ subnetIndex++;
}
- catch (Exception ex)
+
+ // Apply DHCP changes if needed
+ if (EnableDHCP.IsPresent && dhcpService != null)
{
- HandleException(ex);
+ var applyDhcpResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyDhcpResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Applied DHCP changes: {applyDhcpResult.Status}");
}
+
+ // Create a result object
+ var result = new PSObject();
+ result.Properties.Add(new PSNoteProperty("ParentInterface", ParentInterface));
+ result.Properties.Add(new PSNoteProperty("Network", Network));
+ result.Properties.Add(new PSNoteProperty("SubnetMaskBits", SubnetMaskBits));
+ result.Properties.Add(new PSNoteProperty("VLANs", createdVlans));
+
+ WriteObject(result);
}
///
diff --git a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseVLANCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseVLANCmdlet.cs
index 0e1f514..bd3b7c6 100644
--- a/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseVLANCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/NewOPNSenseVLANCmdlet.cs
@@ -48,30 +48,29 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ var vlan = new VLANConfig
{
- var interfaceService = new InterfaceService(ApiClient, Logger);
+ Interface = Interface,
+ Tag = Tag.ToString(),
+ Priority = Priority.ToString(),
+ Description = Description
+ };
- var vlan = new VLANConfig
- {
- Interface = Interface,
- Tag = Tag.ToString(),
- Priority = Priority.ToString(),
- Description = Description
- };
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => interfaceService.CreateVLANAsync(vlan));
- var task = Task.Run(async () => await interfaceService.CreateVLANAsync(vlan));
- var result = task.GetAwaiter().GetResult();
-
- WriteVerbose($"Created VLAN with UUID {result.Uuid}");
- WriteObject(result.Uuid);
- }
- catch (Exception ex)
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
- HandleException(ex);
+ return;
}
+
+ WriteVerbose($"Created VLAN with UUID {result.Uuid}");
+ WriteObject(result.Uuid);
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseAliasCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseAliasCmdlet.cs
index dbd21fb..97bb633 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseAliasCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseAliasCmdlet.cs
@@ -50,44 +50,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var aliasService = new AliasService(ApiClient, Logger);
+
+ // Get the alias details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => aliasService.GetAliasAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var aliasService = new AliasService(ApiClient, Logger);
+ return;
+ }
- // Get the alias details for the confirmation message
- var getTask = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
- var alias = getTask.GetAwaiter().GetResult().Alias;
+ var alias = getResult.Alias;
- string confirmMessage = $"Alias: {alias.Name} ({alias.Type})";
- if (!string.IsNullOrEmpty(alias.Description))
- {
- confirmMessage += $" - {alias.Description}";
- }
+ string confirmMessage = $"Alias: {alias.Name} ({alias.Type})";
+ if (!string.IsNullOrEmpty(alias.Description))
+ {
+ confirmMessage += $" - {alias.Description}";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => aliasService.DeleteAliasAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Alias {Uuid} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => aliasService.ReconfigureAliasesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await aliasService.DeleteAliasAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Alias {Uuid} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await aliasService.ReconfigureAliasesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Alias changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"Alias changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPLeaseCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPLeaseCmdlet.cs
index 7ea15bb..1a9eeee 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPLeaseCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPLeaseCmdlet.cs
@@ -45,44 +45,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // Get the lease details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetLeaseByMacAsync(MacAddress));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
+ return;
+ }
- // Get the lease details for the confirmation message
- var getTask = Task.Run(async () => await dhcpService.GetLeaseByMacAsync(MacAddress));
- var lease = getTask.GetAwaiter().GetResult().Lease;
+ var lease = getResult.Lease;
- string confirmMessage = $"DHCP lease: {lease.MacAddress} -> {lease.IpAddress}";
- if (!string.IsNullOrEmpty(lease.Hostname))
- {
- confirmMessage += $" ({lease.Hostname})";
- }
+ string confirmMessage = $"DHCP lease: {lease.MacAddress} -> {lease.IpAddress}";
+ if (!string.IsNullOrEmpty(lease.Hostname))
+ {
+ confirmMessage += $" ({lease.Hostname})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => dhcpService.DeleteLeaseAsync(MacAddress));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP lease {MacAddress} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await dhcpService.DeleteLeaseAsync(MacAddress));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP lease {MacAddress} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPOptionCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPOptionCmdlet.cs
index 441b9dd..d3eab4e 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPOptionCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPOptionCmdlet.cs
@@ -52,44 +52,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // Get the option details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetOptionAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
+ return;
+ }
- // Get the option details for the confirmation message
- var getTask = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
- var option = getTask.GetAwaiter().GetResult().Option;
+ var option = getResult.Option;
- string confirmMessage = $"DHCP option: {option.Number} = {option.Value}";
- if (!string.IsNullOrEmpty(option.Description))
- {
- confirmMessage += $" ({option.Description})";
- }
+ string confirmMessage = $"DHCP option: {option.Number} = {option.Value}";
+ if (!string.IsNullOrEmpty(option.Description))
+ {
+ confirmMessage += $" ({option.Description})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => dhcpService.DeleteOptionAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP option {Uuid} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await dhcpService.DeleteOptionAsync(Interface, Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP option {Uuid} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPStaticMappingCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPStaticMappingCmdlet.cs
index 3676511..5dc8c5f 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPStaticMappingCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDHCPStaticMappingCmdlet.cs
@@ -52,44 +52,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // Get the mapping details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetStaticMappingAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
+ return;
+ }
- // Get the mapping details for the confirmation message
- var getTask = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
- var mapping = getTask.GetAwaiter().GetResult().Mapping;
+ var mapping = getResult.Mapping;
- string confirmMessage = $"Static mapping: {mapping.MacAddress} -> {mapping.IpAddress}";
- if (!string.IsNullOrEmpty(mapping.Hostname))
- {
- confirmMessage += $" ({mapping.Hostname})";
- }
+ string confirmMessage = $"Static mapping: {mapping.MacAddress} -> {mapping.IpAddress}";
+ if (!string.IsNullOrEmpty(mapping.Hostname))
+ {
+ confirmMessage += $" ({mapping.Hostname})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => dhcpService.DeleteStaticMappingAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Static mapping {Uuid} removed: {deleteResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await dhcpService.DeleteStaticMappingAsync(Interface, Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Static mapping {Uuid} removed: {deleteResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSForwardingHostCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSForwardingHostCmdlet.cs
index 52c7f6e..c1bc7c7 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSForwardingHostCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSForwardingHostCmdlet.cs
@@ -45,44 +45,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // Get the host details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => dnsService.GetDNSForwardingHostAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
+ return;
+ }
- // Get the host details for the confirmation message
- var getTask = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
- var host = getTask.GetAwaiter().GetResult().Host;
+ var host = getResult.Host;
- string confirmMessage = $"DNS forwarding host: {host.Domain} -> {host.Server}";
- if (!string.IsNullOrEmpty(host.Description))
- {
- confirmMessage += $" ({host.Description})";
- }
+ string confirmMessage = $"DNS forwarding host: {host.Domain} -> {host.Server}";
+ if (!string.IsNullOrEmpty(host.Description))
+ {
+ confirmMessage += $" ({host.Description})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => dnsService.DeleteDNSForwardingHostAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS forwarding host {Uuid} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dnsService.ApplyDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await dnsService.DeleteDNSForwardingHostAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS forwarding host {Uuid} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSOverrideCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSOverrideCmdlet.cs
index 0777b50..c9fa2c5 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSOverrideCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseDNSOverrideCmdlet.cs
@@ -45,44 +45,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // Get the DNS override details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => dnsService.GetDNSOverrideAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
+ return;
+ }
- // Get the DNS override details for the confirmation message
- var getTask = Task.Run(async () => await dnsService.GetDNSOverrideAsync(Uuid));
- var dnsOverride = getTask.GetAwaiter().GetResult().Host;
+ var dnsOverride = getResult.Host;
- string confirmMessage = $"DNS override {dnsOverride.Hostname}.{dnsOverride.Domain} -> {dnsOverride.IpAddress}";
- if (!string.IsNullOrEmpty(dnsOverride.Description))
- {
- confirmMessage += $" ({dnsOverride.Description})";
- }
+ string confirmMessage = $"DNS override {dnsOverride.Hostname}.{dnsOverride.Domain} -> {dnsOverride.IpAddress}";
+ if (!string.IsNullOrEmpty(dnsOverride.Description))
+ {
+ confirmMessage += $" ({dnsOverride.Description})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => dnsService.DeleteDNSOverrideAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS override {Uuid} removed: {deleteResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dnsService.ApplyDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await dnsService.DeleteDNSOverrideAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS override {Uuid} removed: {deleteResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseFirewallRuleCmdlet.cs
index 1a75381..235420e 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseFirewallRuleCmdlet.cs
@@ -39,36 +39,41 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var firewallService = new FirewallService(ApiClient, Logger);
+
+ // Get the rule details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => firewallService.GetRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var firewallService = new FirewallService(ApiClient, Logger);
-
- // Get the rule details for the confirmation message
- var getTask = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
- var rule = getTask.GetAwaiter().GetResult().Rule;
-
- string confirmMessage = $"Firewall rule: {rule.Description}";
- if (!string.IsNullOrEmpty(rule.Protocol) && rule.Protocol != "any")
- {
- confirmMessage += $" ({rule.Protocol})";
- }
-
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
- {
- return;
- }
-
- var deleteTask = Task.Run(async () => await firewallService.DeleteRuleAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Firewall rule {Uuid} removed: {deleteResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var rule = getResult.Rule;
+
+ string confirmMessage = $"Firewall rule: {rule.Description}";
+ if (!string.IsNullOrEmpty(rule.Protocol) && rule.Protocol != "any")
{
- HandleException(ex);
+ confirmMessage += $" ({rule.Protocol})";
}
+
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => firewallService.DeleteRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Firewall rule {Uuid} removed: {deleteResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseGatewayCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseGatewayCmdlet.cs
index 7e10376..ff12f70 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseGatewayCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseGatewayCmdlet.cs
@@ -45,44 +45,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var gatewayService = new GatewayService(ApiClient, Logger);
+
+ // Get the gateway details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => gatewayService.GetGatewayAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var gatewayService = new GatewayService(ApiClient, Logger);
+ return;
+ }
- // Get the gateway details for the confirmation message
- var getTask = Task.Run(async () => await gatewayService.GetGatewayAsync(Uuid));
- var gateway = getTask.GetAwaiter().GetResult().Gateway;
+ var gateway = getResult.Gateway;
- string confirmMessage = $"Gateway: {gateway.Name} ({gateway.IpAddress})";
- if (!string.IsNullOrEmpty(gateway.Description))
- {
- confirmMessage += $" - {gateway.Description}";
- }
+ string confirmMessage = $"Gateway: {gateway.Name} ({gateway.IpAddress})";
+ if (!string.IsNullOrEmpty(gateway.Description))
+ {
+ confirmMessage += $" - {gateway.Description}";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => gatewayService.DeleteGatewayAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Gateway {Uuid} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => gatewayService.ApplyGatewayChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await gatewayService.DeleteGatewayAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Gateway {Uuid} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Gateway changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"Gateway changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSensePortForwardingRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSensePortForwardingRuleCmdlet.cs
index a3ec126..53918c3 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSensePortForwardingRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSensePortForwardingRuleCmdlet.cs
@@ -13,7 +13,7 @@ namespace PSOPNSenseAPI.Cmdlets
///
///
[Cmdlet(VerbsCommon.Remove, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
- public class RemoveOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
+ public class RemoveOPNSensePortForwardingRuleCmdlet : OPNSenseBaseCmdlet
{
///
/// The UUID of the port forwarding rule to remove.
@@ -30,12 +30,18 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- var portForwardingService = new PortForwardingService(SessionState.ApiClient);
+ var portForwardingService = new PortForwardingService(ApiClient);
// Get the rule to display information in the confirmation message
- var rule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
+ var rule = ExecuteAsyncTask(() => portForwardingService.GetPortForwardingRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
if (rule == null)
{
@@ -52,7 +58,13 @@ namespace PSOPNSenseAPI.Cmdlets
if (Force || ShouldProcess($"OPNSense firewall", confirmationMessage))
{
- var success = Task.Run(async () => await portForwardingService.DeletePortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
+ var success = ExecuteAsyncTask(() => portForwardingService.DeletePortForwardingRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
if (success)
{
@@ -60,11 +72,8 @@ namespace PSOPNSenseAPI.Cmdlets
}
else
{
- WriteError(new ErrorRecord(
- new PSInvalidOperationException($"Failed to remove port forwarding rule with UUID '{Uuid}'."),
- "PortForwardingRuleRemovalFailed",
- ErrorCategory.InvalidOperation,
- Uuid));
+ ProcessingException = new PSInvalidOperationException($"Failed to remove port forwarding rule with UUID '{Uuid}'.");
+ WriteWarning($"Failed to remove port forwarding rule with UUID '{Uuid}'.");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseRouteCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseRouteCmdlet.cs
index 502c19f..e0c1ece 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseRouteCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseRouteCmdlet.cs
@@ -45,44 +45,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var routeService = new RouteService(ApiClient, Logger);
+
+ // Get the route details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => routeService.GetRouteAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var routeService = new RouteService(ApiClient, Logger);
+ return;
+ }
- // Get the route details for the confirmation message
- var getTask = Task.Run(async () => await routeService.GetRouteAsync(Uuid));
- var route = getTask.GetAwaiter().GetResult().Route;
+ var route = getResult.Route;
- string confirmMessage = $"Route: {route.Network} via {route.Gateway}";
- if (!string.IsNullOrEmpty(route.Description))
- {
- confirmMessage += $" ({route.Description})";
- }
+ string confirmMessage = $"Route: {route.Network} via {route.Gateway}";
+ if (!string.IsNullOrEmpty(route.Description))
+ {
+ confirmMessage += $" ({route.Description})";
+ }
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => routeService.DeleteRouteAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Route {Uuid} removed: {deleteResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => routeService.ApplyRouteChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
{
return;
}
- var deleteTask = Task.Run(async () => await routeService.DeleteRouteAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Route {Uuid} removed: {deleteResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await routeService.ApplyRouteChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Route changes applied: {applyResult.Status}");
- }
- }
- catch (Exception ex)
- {
- HandleException(ex);
+ WriteVerbose($"Route changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseUserCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseUserCmdlet.cs
index d92c844..1039bed 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseUserCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseUserCmdlet.cs
@@ -39,36 +39,41 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var userService = new UserService(ApiClient, Logger);
+
+ // Get the user details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => userService.GetUserAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var userService = new UserService(ApiClient, Logger);
-
- // Get the user details for the confirmation message
- var getTask = Task.Run(async () => await userService.GetUserAsync(Uuid));
- var user = getTask.GetAwaiter().GetResult().User;
-
- string confirmMessage = $"User: {user.Username}";
- if (!string.IsNullOrEmpty(user.FullName))
- {
- confirmMessage += $" ({user.FullName})";
- }
-
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
- {
- return;
- }
-
- var deleteTask = Task.Run(async () => await userService.DeleteUserAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"User {Uuid} removed: {deleteResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var user = getResult.User;
+
+ string confirmMessage = $"User: {user.Username}";
+ if (!string.IsNullOrEmpty(user.FullName))
{
- HandleException(ex);
+ confirmMessage += $" ({user.FullName})";
}
+
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => userService.DeleteUserAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"User {Uuid} removed: {deleteResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseVLANCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseVLANCmdlet.cs
index 752846d..ebc15e6 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseVLANCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RemoveOPNSenseVLANCmdlet.cs
@@ -39,36 +39,41 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ // Get the VLAN details for the confirmation message
+ var getResult = ExecuteAsyncTask(() => interfaceService.GetVLANAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var interfaceService = new InterfaceService(ApiClient, Logger);
-
- // Get the VLAN details for the confirmation message
- var getTask = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
- var vlan = getTask.GetAwaiter().GetResult().Vlan;
-
- string confirmMessage = $"VLAN {vlan.Tag} on interface {vlan.Interface}";
- if (!string.IsNullOrEmpty(vlan.Description))
- {
- confirmMessage += $" ({vlan.Description})";
- }
-
- if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
- {
- return;
- }
-
- var deleteTask = Task.Run(async () => await interfaceService.DeleteVLANAsync(Uuid));
- var deleteResult = deleteTask.GetAwaiter().GetResult();
-
- WriteVerbose($"VLAN {Uuid} removed: {deleteResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var vlan = getResult.Vlan;
+
+ string confirmMessage = $"VLAN {vlan.Tag} on interface {vlan.Interface}";
+ if (!string.IsNullOrEmpty(vlan.Description))
{
- HandleException(ex);
+ confirmMessage += $" ({vlan.Description})";
}
+
+ if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
+ {
+ return;
+ }
+
+ var deleteResult = ExecuteAsyncTask(() => interfaceService.DeleteVLANAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || deleteResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"VLAN {Uuid} removed: {deleteResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/RestartOPNSenseFirewallCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RestartOPNSenseFirewallCmdlet.cs
index e06872a..5357cf6 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RestartOPNSenseFirewallCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RestartOPNSenseFirewallCmdlet.cs
@@ -130,14 +130,23 @@ namespace PSOPNSenseAPI.Cmdlets
// Try to get the system status
var statusService = new SystemService(newClient, logger);
- // We need to use Task.Run here because we're creating a new client
+ // We need to handle this specially because we're using a new client
// and can't use ExecuteAsyncTask which uses the existing client
- var statusTask = Task.Run(async () => await statusService.GetStatusAsync());
- var statusResult = statusTask.GetAwaiter().GetResult();
+ try
+ {
+ // Use ConfigureAwait(false) to avoid deadlocks
+ var statusResult = statusService.GetStatusAsync().ConfigureAwait(false).GetAwaiter().GetResult();
- // If we get here, the firewall is back online
- WriteVerbose("Successfully reconnected to the firewall");
- WriteObject($"Firewall is back online. Uptime: {statusResult.Uptime}");
+ // If we get here, the firewall is back online
+ WriteVerbose("Successfully reconnected to the firewall");
+ WriteObject($"Firewall is back online. Uptime: {statusResult.Uptime}");
+ }
+ catch (Exception innerEx)
+ {
+ // Just log and continue the retry loop
+ WriteVerbose($"Status check failed: {innerEx.Message}");
+ throw; // Re-throw to be caught by the outer catch
+ }
// Set the new session
OPNSenseSession.Current = newClient;
diff --git a/src/PSOPNSenseAPI/Cmdlets/RestoreOPNSenseConfigCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/RestoreOPNSenseConfigCmdlet.cs
index eff9bc8..77def24 100644
--- a/src/PSOPNSenseAPI/Cmdlets/RestoreOPNSenseConfigCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/RestoreOPNSenseConfigCmdlet.cs
@@ -53,26 +53,33 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
- {
- var configService = new ConfigService(ApiClient, Logger);
- string actionDescription = "Restore configuration";
- string targetName = ParameterSetName == "Filename" ? Filename : "from XML document";
+ var configService = new ConfigService(ApiClient, Logger);
+ string actionDescription = "Restore configuration";
+ string targetName = ParameterSetName == "Filename" ? Filename : "from XML document";
- if (!Force.IsPresent && !ShouldProcess(targetName, actionDescription))
+ if (!Force.IsPresent && !ShouldProcess(targetName, actionDescription))
+ {
+ return;
+ }
+
+ if (ParameterSetName == "Filename")
+ {
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => configService.RestoreConfigBackupAsync(Filename));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
{
return;
}
- if (ParameterSetName == "Filename")
- {
- // Restore from backup file - execute synchronously on the main thread
- var result = configService.RestoreConfigBackupAsync(Filename).GetAwaiter().GetResult();
- WriteVerbose($"Restored configuration from backup: {result.Status}");
- }
- else
+ WriteVerbose($"Restored configuration from backup: {result.Status}");
+ }
+ else
+ {
+ try
{
// Restore from XML document
byte[] configContent;
@@ -82,17 +89,26 @@ namespace PSOPNSenseAPI.Cmdlets
configContent = memoryStream.ToArray();
}
- // Execute synchronously on the main thread
- var result = configService.ImportConfigAsync(configContent).GetAwaiter().GetResult();
+ // Use our safe execution method
+ var result = ExecuteAsyncTask(() => configService.ImportConfigAsync(configContent));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || result == null)
+ {
+ return;
+ }
+
WriteVerbose($"Restored configuration from XML document: {result.Status}");
}
+ catch (Exception ex)
+ {
+ ProcessingException = ex;
+ WriteWarning($"Failed to process XML document: {ex.Message}");
+ return;
+ }
+ }
- WriteWarning("The firewall is restarting. You may need to reconnect after it comes back online.");
- }
- catch (Exception ex)
- {
- HandleException(ex);
- }
+ WriteWarning("The firewall is restarting. You may need to reconnect after it comes back online.");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseAliasCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseAliasCmdlet.cs
index 6d2dd5e..5621938 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseAliasCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseAliasCmdlet.cs
@@ -94,83 +94,93 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var aliasService = new AliasService(ApiClient, Logger);
+
+ // Get current alias
+ var getResult = ExecuteAsyncTask(() => aliasService.GetAliasAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var aliasService = new AliasService(ApiClient, Logger);
-
- // Get current alias
- var getTask = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
- var currentAlias = getTask.GetAwaiter().GetResult().Alias;
-
- // Create updated alias
- var alias = new AliasConfig
- {
- Name = currentAlias.Name,
- Type = currentAlias.Type,
- Content = Content ?? currentAlias.Content,
- Description = Description ?? currentAlias.Description,
- Protocol = Protocol?.ToUpper() ?? currentAlias.Protocol,
- UpdateFrequency = UpdateFrequency?.ToString() ?? currentAlias.UpdateFrequency,
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- alias.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- alias.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- alias.Enabled = "0";
- }
- else
- {
- alias.Enabled = currentAlias.Enabled;
- }
-
- // Handle counters
- if (EnableCounters.IsPresent && DisableCounters.IsPresent)
- {
- WriteWarning("Both -EnableCounters and -DisableCounters parameters were specified. Using -EnableCounters.");
- alias.Counters = "1";
- }
- else if (EnableCounters.IsPresent)
- {
- alias.Counters = "1";
- }
- else if (DisableCounters.IsPresent)
- {
- alias.Counters = "0";
- }
- else
- {
- alias.Counters = currentAlias.Counters;
- }
-
- // Update alias
- var updateTask = Task.Run(async () => await aliasService.UpdateAliasAsync(Uuid, alias));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Alias {Uuid} updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await aliasService.ReconfigureAliasesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Alias changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentAlias = getResult.Alias;
+
+ // Create updated alias
+ var alias = new AliasConfig
{
- HandleException(ex);
+ Name = currentAlias.Name,
+ Type = currentAlias.Type,
+ Content = Content ?? currentAlias.Content,
+ Description = Description ?? currentAlias.Description,
+ Protocol = Protocol?.ToUpper() ?? currentAlias.Protocol,
+ UpdateFrequency = UpdateFrequency?.ToString() ?? currentAlias.UpdateFrequency,
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ alias.Enabled = "1";
+ }
+ else if (Enabled.IsPresent)
+ {
+ alias.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ alias.Enabled = "0";
+ }
+ else
+ {
+ alias.Enabled = currentAlias.Enabled;
+ }
+
+ // Handle counters
+ if (EnableCounters.IsPresent && DisableCounters.IsPresent)
+ {
+ WriteWarning("Both -EnableCounters and -DisableCounters parameters were specified. Using -EnableCounters.");
+ alias.Counters = "1";
+ }
+ else if (EnableCounters.IsPresent)
+ {
+ alias.Counters = "1";
+ }
+ else if (DisableCounters.IsPresent)
+ {
+ alias.Counters = "0";
+ }
+ else
+ {
+ alias.Counters = currentAlias.Counters;
+ }
+
+ // Update alias
+ var updateResult = ExecuteAsyncTask(() => aliasService.UpdateAliasAsync(Uuid, alias));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Alias {Uuid} updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => aliasService.ReconfigureAliasesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Alias changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPOptionCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPOptionCmdlet.cs
index f150502..610a649 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPOptionCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPOptionCmdlet.cs
@@ -66,43 +66,53 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // Get current option
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetOptionAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
-
- // Get current option
- var getTask = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
- var currentOption = getTask.GetAwaiter().GetResult().Option;
-
- // Create updated option
- var option = new DHCPOptionConfig
- {
- Number = Number ?? currentOption.Number,
- Value = Value ?? currentOption.Value,
- Type = Type ?? currentOption.Type,
- Description = Description ?? currentOption.Description
- };
-
- // Update option
- var updateTask = Task.Run(async () => await dhcpService.UpdateOptionAsync(Interface, Uuid, option));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP option {Uuid} updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentOption = getResult.Option;
+
+ // Create updated option
+ var option = new DHCPOptionConfig
{
- HandleException(ex);
+ Number = Number ?? currentOption.Number,
+ Value = Value ?? currentOption.Value,
+ Type = Type ?? currentOption.Type,
+ Description = Description ?? currentOption.Description
+ };
+
+ // Update option
+ var updateResult = ExecuteAsyncTask(() => dhcpService.UpdateOptionAsync(Interface, Uuid, option));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP option {Uuid} updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPServerCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPServerCmdlet.cs
index 229bd2a..6b8a928 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPServerCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPServerCmdlet.cs
@@ -94,65 +94,75 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // First, get the current server configuration
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetServerAsync(Interface));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
-
- // First, get the current server configuration
- var getTask = Task.Run(async () => await dhcpService.GetServerAsync(Interface));
- var currentServer = getTask.GetAwaiter().GetResult().Server;
-
- // Create the updated configuration
- var server = new DHCPServerConfig
- {
- RangeFrom = RangeFrom ?? currentServer.RangeFrom,
- RangeTo = RangeTo ?? currentServer.RangeTo,
- DefaultLeaseTime = DefaultLeaseTime?.ToString() ?? currentServer.DefaultLeaseTime,
- MaxLeaseTime = MaxLeaseTime?.ToString() ?? currentServer.MaxLeaseTime,
- Domain = Domain ?? currentServer.Domain,
- DnsServers = DnsServers != null ? new List(DnsServers) : currentServer.DnsServers,
- Gateway = Gateway ?? currentServer.Gateway
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- server.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- server.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- server.Enabled = "0";
- }
- else
- {
- server.Enabled = currentServer.Enabled;
- }
-
- // Update the server
- var updateTask = Task.Run(async () => await dhcpService.UpdateServerAsync(Interface, server));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP server for interface {Interface} updated: {updateResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentServer = getResult.Server;
+
+ // Create the updated configuration
+ var server = new DHCPServerConfig
{
- HandleException(ex);
+ RangeFrom = RangeFrom ?? currentServer.RangeFrom,
+ RangeTo = RangeTo ?? currentServer.RangeTo,
+ DefaultLeaseTime = DefaultLeaseTime?.ToString() ?? currentServer.DefaultLeaseTime,
+ MaxLeaseTime = MaxLeaseTime?.ToString() ?? currentServer.MaxLeaseTime,
+ Domain = Domain ?? currentServer.Domain,
+ DnsServers = DnsServers != null ? new List(DnsServers) : currentServer.DnsServers,
+ Gateway = Gateway ?? currentServer.Gateway
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ server.Enabled = "1";
+ }
+ else if (Enabled.IsPresent)
+ {
+ server.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ server.Enabled = "0";
+ }
+ else
+ {
+ server.Enabled = currentServer.Enabled;
+ }
+
+ // Update the server
+ var updateResult = ExecuteAsyncTask(() => dhcpService.UpdateServerAsync(Interface, server));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP server for interface {Interface} updated: {updateResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPStaticMappingCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPStaticMappingCmdlet.cs
index 9abf4d8..77353e9 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPStaticMappingCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDHCPStaticMappingCmdlet.cs
@@ -82,62 +82,72 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dhcpService = new DHCPService(ApiClient, Logger);
+
+ // First, get the current mapping
+ var getResult = ExecuteAsyncTask(() => dhcpService.GetStaticMappingAsync(Interface, Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dhcpService = new DHCPService(ApiClient, Logger);
-
- // First, get the current mapping
- var getTask = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
- var currentMapping = getTask.GetAwaiter().GetResult().Mapping;
-
- // Create the updated mapping
- var mapping = new DHCPStaticMappingConfig
- {
- MacAddress = MacAddress ?? currentMapping.MacAddress,
- IpAddress = IpAddress ?? currentMapping.IpAddress,
- Hostname = Hostname ?? currentMapping.Hostname,
- Description = Description ?? currentMapping.Description
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- mapping.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- mapping.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- mapping.Enabled = "0";
- }
- else
- {
- mapping.Enabled = currentMapping.Enabled;
- }
-
- // Update the mapping
- var updateTask = Task.Run(async () => await dhcpService.UpdateStaticMappingAsync(Interface, Uuid, mapping));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Static mapping {Uuid} updated: {updateResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DHCP changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentMapping = getResult.Mapping;
+
+ // Create the updated mapping
+ var mapping = new DHCPStaticMappingConfig
{
- HandleException(ex);
+ MacAddress = MacAddress ?? currentMapping.MacAddress,
+ IpAddress = IpAddress ?? currentMapping.IpAddress,
+ Hostname = Hostname ?? currentMapping.Hostname,
+ Description = Description ?? currentMapping.Description
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ mapping.Enabled = "1";
+ }
+ else if (Enabled.IsPresent)
+ {
+ mapping.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ mapping.Enabled = "0";
+ }
+ else
+ {
+ mapping.Enabled = currentMapping.Enabled;
+ }
+
+ // Update the mapping
+ var updateResult = ExecuteAsyncTask(() => dhcpService.UpdateStaticMappingAsync(Interface, Uuid, mapping));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Static mapping {Uuid} updated: {updateResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dhcpService.ApplyChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DHCP changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingCmdlet.cs
index e170b55..0c61863 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingCmdlet.cs
@@ -58,69 +58,79 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // Get current configuration
+ var getResult = ExecuteAsyncTask(() => dnsService.GetDNSForwardingAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
-
- // Get current configuration
- var getTask = Task.Run(async () => await dnsService.GetDNSForwardingAsync());
- var currentConfig = getTask.GetAwaiter().GetResult().Forward;
-
- // Create updated configuration
- var config = new DNSForwardingConfig
- {
- Type = Type ?? currentConfig.Type
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- config.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- config.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- config.Enabled = "0";
- }
- else
- {
- config.Enabled = currentConfig.Enabled;
- }
-
- // Handle DNS servers
- if (DnsServers != null && DnsServers.Length > 0)
- {
- config.DnsServers = new List(DnsServers);
- }
- else
- {
- config.DnsServers = currentConfig.DnsServers;
- }
-
- // Update configuration
- var updateTask = Task.Run(async () => await dnsService.UpdateDNSForwardingAsync(config));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS forwarding configuration updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentConfig = getResult.Forward;
+
+ // Create updated configuration
+ var config = new DNSForwardingConfig
{
- HandleException(ex);
+ Type = Type ?? currentConfig.Type
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ config.Enabled = "1";
+ }
+ else if (Enabled.IsPresent)
+ {
+ config.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ config.Enabled = "0";
+ }
+ else
+ {
+ config.Enabled = currentConfig.Enabled;
+ }
+
+ // Handle DNS servers
+ if (DnsServers != null && DnsServers.Length > 0)
+ {
+ config.DnsServers = new List(DnsServers);
+ }
+ else
+ {
+ config.DnsServers = currentConfig.DnsServers;
+ }
+
+ // Update configuration
+ var updateResult = ExecuteAsyncTask(() => dnsService.UpdateDNSForwardingAsync(config));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS forwarding configuration updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dnsService.ApplyDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingHostCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingHostCmdlet.cs
index 29068e5..ca5a862 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingHostCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSForwardingHostCmdlet.cs
@@ -69,61 +69,71 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // Get current host
+ var getResult = ExecuteAsyncTask(() => dnsService.GetDNSForwardingHostAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
-
- // Get current host
- var getTask = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
- var currentHost = getTask.GetAwaiter().GetResult().Host;
-
- // Create updated host
- var host = new DNSForwardingHostConfig
- {
- Domain = Domain ?? currentHost.Domain,
- Server = Server ?? currentHost.Server,
- Description = Description ?? currentHost.Description
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- host.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- host.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- host.Enabled = "0";
- }
- else
- {
- host.Enabled = currentHost.Enabled;
- }
-
- // Update host
- var updateTask = Task.Run(async () => await dnsService.UpdateDNSForwardingHostAsync(Uuid, host));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS forwarding host {Uuid} updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentHost = getResult.Host;
+
+ // Create updated host
+ var host = new DNSForwardingHostConfig
{
- HandleException(ex);
+ Domain = Domain ?? currentHost.Domain,
+ Server = Server ?? currentHost.Server,
+ Description = Description ?? currentHost.Description
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ host.Enabled = "1";
+ }
+ else if (Enabled.IsPresent)
+ {
+ host.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ host.Enabled = "0";
+ }
+ else
+ {
+ host.Enabled = currentHost.Enabled;
+ }
+
+ // Update host
+ var updateResult = ExecuteAsyncTask(() => dnsService.UpdateDNSForwardingHostAsync(Uuid, host));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS forwarding host {Uuid} updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dnsService.ApplyDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSServerCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSServerCmdlet.cs
index 90c3a01..f154d06 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSServerCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseDNSServerCmdlet.cs
@@ -82,48 +82,58 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var dnsService = new DNSService(ApiClient, Logger);
+
+ // First, get the current DNS configuration
+ var getResult = ExecuteAsyncTask(() => dnsService.GetDNSConfigAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var dnsService = new DNSService(ApiClient, Logger);
-
- // First, get the current DNS configuration
- var getTask = Task.Run(async () => await dnsService.GetDNSConfigAsync());
- var currentConfig = getTask.GetAwaiter().GetResult().Unbound;
-
- // Create the updated configuration
- var dnsConfig = new DNSConfig
- {
- Enabled = MyInvocation.BoundParameters.ContainsKey(nameof(Enabled)) ? (Enabled.IsPresent ? "1" : "0") : currentConfig.Enabled,
- Port = Port?.ToString() ?? currentConfig.Port,
- Interfaces = Interfaces != null ? new List(Interfaces) : currentConfig.Interfaces,
- Forwarding = MyInvocation.BoundParameters.ContainsKey(nameof(Forwarding)) ? (Forwarding.IsPresent ? "1" : "0") : currentConfig.Forwarding,
- Forwarders = Forwarders != null ? new List(Forwarders) : currentConfig.Forwarders,
- RegisterDhcp = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcp)) ? (RegisterDhcp.IsPresent ? "1" : "0") : currentConfig.RegisterDhcp,
- RegisterDhcpDomain = RegisterDhcpDomain ?? currentConfig.RegisterDhcpDomain,
- RegisterDhcpStatic = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcpStatic)) ? (RegisterDhcpStatic.IsPresent ? "1" : "0") : currentConfig.RegisterDhcpStatic,
- ActiveInterfaces = currentConfig.ActiveInterfaces
- };
-
- // Update the DNS configuration
- var updateTask = Task.Run(async () => await dnsService.UpdateDNSConfigAsync(dnsConfig));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS server configuration updated: {updateResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"DNS changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentConfig = getResult.Unbound;
+
+ // Create the updated configuration
+ var dnsConfig = new DNSConfig
{
- HandleException(ex);
+ Enabled = MyInvocation.BoundParameters.ContainsKey(nameof(Enabled)) ? (Enabled.IsPresent ? "1" : "0") : currentConfig.Enabled,
+ Port = Port?.ToString() ?? currentConfig.Port,
+ Interfaces = Interfaces != null ? new List(Interfaces) : currentConfig.Interfaces,
+ Forwarding = MyInvocation.BoundParameters.ContainsKey(nameof(Forwarding)) ? (Forwarding.IsPresent ? "1" : "0") : currentConfig.Forwarding,
+ Forwarders = Forwarders != null ? new List(Forwarders) : currentConfig.Forwarders,
+ RegisterDhcp = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcp)) ? (RegisterDhcp.IsPresent ? "1" : "0") : currentConfig.RegisterDhcp,
+ RegisterDhcpDomain = RegisterDhcpDomain ?? currentConfig.RegisterDhcpDomain,
+ RegisterDhcpStatic = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcpStatic)) ? (RegisterDhcpStatic.IsPresent ? "1" : "0") : currentConfig.RegisterDhcpStatic,
+ ActiveInterfaces = currentConfig.ActiveInterfaces
+ };
+
+ // Update the DNS configuration
+ var updateResult = ExecuteAsyncTask(() => dnsService.UpdateDNSConfigAsync(dnsConfig));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS server configuration updated: {updateResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => dnsService.ApplyDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseFirewallRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseFirewallRuleCmdlet.cs
index 84ea326..2d86266 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseFirewallRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseFirewallRuleCmdlet.cs
@@ -95,58 +95,63 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var firewallService = new FirewallService(ApiClient, Logger);
+
+ // First, get the current rule
+ var getResult = ExecuteAsyncTask(() => firewallService.GetRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var firewallService = new FirewallService(ApiClient, Logger);
-
- // First, get the current rule
- var getTask = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
- var currentRule = getTask.GetAwaiter().GetResult().Rule;
-
- // Create the updated rule
- var rule = new FirewallRuleCreate
- {
- Description = Description ?? currentRule.Description,
- Protocol = Protocol ?? currentRule.Protocol,
- SourceNet = SourceNet ?? currentRule.SourceNet,
- SourcePort = SourcePort ?? currentRule.SourcePort,
- DestinationNet = DestinationNet ?? currentRule.DestinationNet,
- DestinationPort = DestinationPort ?? currentRule.DestinationPort,
- Action = Action ?? currentRule.Action,
- Sequence = Sequence ?? currentRule.Sequence
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- rule.Enabled = "1";
- }
- else if (Enabled.IsPresent)
- {
- rule.Enabled = "1";
- }
- else if (Disabled.IsPresent)
- {
- rule.Enabled = "0";
- }
- else
- {
- rule.Enabled = currentRule.Enabled;
- }
-
- // Update the rule
- var updateTask = Task.Run(async () => await firewallService.UpdateRuleAsync(Uuid, rule));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Firewall rule {Uuid} updated: {updateResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var currentRule = getResult.Rule;
+
+ // Create the updated rule
+ var rule = new FirewallRuleCreate
{
- HandleException(ex);
+ Description = Description ?? currentRule.Description,
+ Protocol = Protocol ?? currentRule.Protocol,
+ SourceNet = SourceNet ?? currentRule.SourceNet,
+ SourcePort = SourcePort ?? currentRule.SourcePort,
+ DestinationNet = DestinationNet ?? currentRule.DestinationNet,
+ DestinationPort = DestinationPort ?? currentRule.DestinationPort,
+ Action = Action ?? currentRule.Action,
+ Sequence = Sequence ?? currentRule.Sequence
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ rule.Enabled = "1";
}
+ else if (Enabled.IsPresent)
+ {
+ rule.Enabled = "1";
+ }
+ else if (Disabled.IsPresent)
+ {
+ rule.Enabled = "0";
+ }
+ else
+ {
+ rule.Enabled = currentRule.Enabled;
+ }
+
+ // Update the rule
+ var updateResult = ExecuteAsyncTask(() => firewallService.UpdateRuleAsync(Uuid, rule));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Firewall rule {Uuid} updated: {updateResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseGatewayCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseGatewayCmdlet.cs
index 0cf6c28..719d090 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseGatewayCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseGatewayCmdlet.cs
@@ -131,122 +131,132 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var gatewayService = new GatewayService(ApiClient, Logger);
+
+ // Get current gateway
+ var getResult = ExecuteAsyncTask(() => gatewayService.GetGatewayAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var gatewayService = new GatewayService(ApiClient, Logger);
-
- // Get current gateway
- var getTask = Task.Run(async () => await gatewayService.GetGatewayAsync(Uuid));
- var currentGateway = getTask.GetAwaiter().GetResult().Gateway;
-
- // Create updated gateway
- var gateway = new GatewayConfig
- {
- Name = Name ?? currentGateway.Name,
- Interface = Interface ?? currentGateway.Interface,
- IpAddress = IpAddress ?? currentGateway.IpAddress,
- MonitorIp = MonitorIp ?? currentGateway.MonitorIp,
- Description = Description ?? currentGateway.Description,
- Weight = Weight?.ToString() ?? currentGateway.Weight,
- IpProtocol = IpProtocol ?? currentGateway.IpProtocol
- };
-
- // Handle default/not default
- if (Default.IsPresent && NotDefault.IsPresent)
- {
- WriteWarning("Both -Default and -NotDefault parameters were specified. Using -Default.");
- gateway.IsDefault = "1";
- }
- else if (Default.IsPresent)
- {
- gateway.IsDefault = "1";
- }
- else if (NotDefault.IsPresent)
- {
- gateway.IsDefault = "0";
- }
- else
- {
- gateway.IsDefault = currentGateway.IsDefault;
- }
-
- // Handle enabled/disabled
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- gateway.Disabled = "0";
- }
- else if (Enabled.IsPresent)
- {
- gateway.Disabled = "0";
- }
- else if (Disabled.IsPresent)
- {
- gateway.Disabled = "1";
- }
- else
- {
- gateway.Disabled = currentGateway.Disabled;
- }
-
- // Handle monitoring
- if (EnableMonitoring.IsPresent && DisableMonitoring.IsPresent)
- {
- WriteWarning("Both -EnableMonitoring and -DisableMonitoring parameters were specified. Using -EnableMonitoring.");
- gateway.MonitorDisable = "0";
- }
- else if (EnableMonitoring.IsPresent)
- {
- gateway.MonitorDisable = "0";
- }
- else if (DisableMonitoring.IsPresent)
- {
- gateway.MonitorDisable = "1";
- }
- else
- {
- gateway.MonitorDisable = currentGateway.MonitorDisable;
- }
-
- // Handle force down
- if (ForceDown.IsPresent && NoForceDown.IsPresent)
- {
- WriteWarning("Both -ForceDown and -NoForceDown parameters were specified. Using -ForceDown.");
- gateway.ForceDown = "1";
- }
- else if (ForceDown.IsPresent)
- {
- gateway.ForceDown = "1";
- }
- else if (NoForceDown.IsPresent)
- {
- gateway.ForceDown = "0";
- }
- else
- {
- gateway.ForceDown = currentGateway.ForceDown;
- }
-
- // Update gateway
- var updateTask = Task.Run(async () => await gatewayService.UpdateGatewayAsync(Uuid, gateway));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Gateway {Uuid} updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Gateway changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentGateway = getResult.Gateway;
+
+ // Create updated gateway
+ var gateway = new GatewayConfig
{
- HandleException(ex);
+ Name = Name ?? currentGateway.Name,
+ Interface = Interface ?? currentGateway.Interface,
+ IpAddress = IpAddress ?? currentGateway.IpAddress,
+ MonitorIp = MonitorIp ?? currentGateway.MonitorIp,
+ Description = Description ?? currentGateway.Description,
+ Weight = Weight?.ToString() ?? currentGateway.Weight,
+ IpProtocol = IpProtocol ?? currentGateway.IpProtocol
+ };
+
+ // Handle default/not default
+ if (Default.IsPresent && NotDefault.IsPresent)
+ {
+ WriteWarning("Both -Default and -NotDefault parameters were specified. Using -Default.");
+ gateway.IsDefault = "1";
+ }
+ else if (Default.IsPresent)
+ {
+ gateway.IsDefault = "1";
+ }
+ else if (NotDefault.IsPresent)
+ {
+ gateway.IsDefault = "0";
+ }
+ else
+ {
+ gateway.IsDefault = currentGateway.IsDefault;
+ }
+
+ // Handle enabled/disabled
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ gateway.Disabled = "0";
+ }
+ else if (Enabled.IsPresent)
+ {
+ gateway.Disabled = "0";
+ }
+ else if (Disabled.IsPresent)
+ {
+ gateway.Disabled = "1";
+ }
+ else
+ {
+ gateway.Disabled = currentGateway.Disabled;
+ }
+
+ // Handle monitoring
+ if (EnableMonitoring.IsPresent && DisableMonitoring.IsPresent)
+ {
+ WriteWarning("Both -EnableMonitoring and -DisableMonitoring parameters were specified. Using -EnableMonitoring.");
+ gateway.MonitorDisable = "0";
+ }
+ else if (EnableMonitoring.IsPresent)
+ {
+ gateway.MonitorDisable = "0";
+ }
+ else if (DisableMonitoring.IsPresent)
+ {
+ gateway.MonitorDisable = "1";
+ }
+ else
+ {
+ gateway.MonitorDisable = currentGateway.MonitorDisable;
+ }
+
+ // Handle force down
+ if (ForceDown.IsPresent && NoForceDown.IsPresent)
+ {
+ WriteWarning("Both -ForceDown and -NoForceDown parameters were specified. Using -ForceDown.");
+ gateway.ForceDown = "1";
+ }
+ else if (ForceDown.IsPresent)
+ {
+ gateway.ForceDown = "1";
+ }
+ else if (NoForceDown.IsPresent)
+ {
+ gateway.ForceDown = "0";
+ }
+ else
+ {
+ gateway.ForceDown = currentGateway.ForceDown;
+ }
+
+ // Update gateway
+ var updateResult = ExecuteAsyncTask(() => gatewayService.UpdateGatewayAsync(Uuid, gateway));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Gateway {Uuid} updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => gatewayService.ApplyGatewayChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Gateway changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseInterfaceCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseInterfaceCmdlet.cs
index 140fb99..c2e9673 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseInterfaceCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseInterfaceCmdlet.cs
@@ -87,44 +87,54 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ // First, get the current interface configuration
+ var getResult = ExecuteAsyncTask(() => interfaceService.GetInterfaceDetailAsync(Name));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var interfaceService = new InterfaceService(ApiClient, Logger);
-
- // First, get the current interface configuration
- var getTask = Task.Run(async () => await interfaceService.GetInterfaceDetailAsync(Name));
- var currentInterface = getTask.GetAwaiter().GetResult().Interface;
-
- // Create the updated configuration
- var interfaceConfig = new InterfaceConfig
- {
- Description = Description ?? currentInterface.Description,
- IpAddress = IpAddress ?? currentInterface.IpAddress,
- SubnetMask = SubnetMask ?? currentInterface.SubnetMask,
- Gateway = Gateway ?? currentInterface.Gateway,
- Enabled = Enabled.IsPresent ? "1" : "0"
- };
-
- // Update the interface
- var updateTask = Task.Run(async () => await interfaceService.UpdateInterfaceAsync(Name, interfaceConfig));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Interface {Name} updated: {updateResult.Result}");
-
- // Apply the changes if requested
- if (Apply.IsPresent)
- {
- var restartTask = Task.Run(async () => await interfaceService.RestartInterfaceAsync(Name));
- var restartResult = restartTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Interface {Name} restarted: {restartResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentInterface = getResult.Interface;
+
+ // Create the updated configuration
+ var interfaceConfig = new InterfaceConfig
{
- HandleException(ex);
+ Description = Description ?? currentInterface.Description,
+ IpAddress = IpAddress ?? currentInterface.IpAddress,
+ SubnetMask = SubnetMask ?? currentInterface.SubnetMask,
+ Gateway = Gateway ?? currentInterface.Gateway,
+ Enabled = Enabled.IsPresent ? "1" : "0"
+ };
+
+ // Update the interface
+ var updateResult = ExecuteAsyncTask(() => interfaceService.UpdateInterfaceAsync(Name, interfaceConfig));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Interface {Name} updated: {updateResult.Result}");
+
+ // Apply the changes if requested
+ if (Apply.IsPresent)
+ {
+ var restartResult = ExecuteAsyncTask(() => interfaceService.RestartInterfaceAsync(Name));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || restartResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Interface {Name} restarted: {restartResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSensePortForwardingRuleCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSensePortForwardingRuleCmdlet.cs
index de694db..7dae3af 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSensePortForwardingRuleCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSensePortForwardingRuleCmdlet.cs
@@ -15,7 +15,7 @@ namespace PSOPNSenseAPI.Cmdlets
///
[Cmdlet(VerbsCommon.Set, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Medium)]
[OutputType(typeof(PortForwardingRule))]
- public class SetOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
+ public class SetOPNSensePortForwardingRuleCmdlet : OPNSenseBaseCmdlet
{
///
/// The UUID of the port forwarding rule to update.
@@ -118,20 +118,23 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- var portForwardingService = new PortForwardingService(SessionState.ApiClient);
+ var portForwardingService = new PortForwardingService(ApiClient);
// Get the existing rule
- var existingRule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
+ var existingRule = ExecuteAsyncTask(() => portForwardingService.GetPortForwardingRuleAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
if (existingRule == null)
{
- WriteError(new ErrorRecord(
- new PSArgumentException($"Port forwarding rule with UUID '{Uuid}' not found."),
- "PortForwardingRuleNotFound",
- ErrorCategory.ObjectNotFound,
- Uuid));
+ ProcessingException = new PSArgumentException($"Port forwarding rule with UUID '{Uuid}' not found.");
+ WriteWarning($"Port forwarding rule with UUID '{Uuid}' not found.");
return;
}
@@ -177,7 +180,13 @@ namespace PSOPNSenseAPI.Cmdlets
if (Force || ShouldProcess($"OPNSense firewall", $"Update port forwarding rule with UUID '{Uuid}'"))
{
- var success = Task.Run(async () => await portForwardingService.UpdatePortForwardingRuleAsync(existingRule)).GetAwaiter().GetResult();
+ var success = ExecuteAsyncTask(() => portForwardingService.UpdatePortForwardingRuleAsync(existingRule));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null)
+ {
+ return;
+ }
if (success)
{
@@ -190,11 +199,8 @@ namespace PSOPNSenseAPI.Cmdlets
}
else
{
- WriteError(new ErrorRecord(
- new PSInvalidOperationException($"Failed to update port forwarding rule with UUID '{Uuid}'."),
- "PortForwardingRuleUpdateFailed",
- ErrorCategory.InvalidOperation,
- existingRule));
+ ProcessingException = new PSInvalidOperationException($"Failed to update port forwarding rule with UUID '{Uuid}'.");
+ WriteWarning($"Failed to update port forwarding rule with UUID '{Uuid}'.");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseRouteCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseRouteCmdlet.cs
index 0030ff6..cbb6c4e 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseRouteCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseRouteCmdlet.cs
@@ -69,61 +69,71 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var routeService = new RouteService(ApiClient, Logger);
+
+ // Get current route
+ var getResult = ExecuteAsyncTask(() => routeService.GetRouteAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var routeService = new RouteService(ApiClient, Logger);
-
- // Get current route
- var getTask = Task.Run(async () => await routeService.GetRouteAsync(Uuid));
- var currentRoute = getTask.GetAwaiter().GetResult().Route;
-
- // Create updated route
- var route = new RouteConfig
- {
- Network = Network ?? currentRoute.Network,
- Gateway = Gateway ?? currentRoute.Gateway,
- Description = Description ?? currentRoute.Description
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- route.Disabled = "0";
- }
- else if (Enabled.IsPresent)
- {
- route.Disabled = "0";
- }
- else if (Disabled.IsPresent)
- {
- route.Disabled = "1";
- }
- else
- {
- route.Disabled = currentRoute.Disabled;
- }
-
- // Update route
- var updateTask = Task.Run(async () => await routeService.UpdateRouteAsync(Uuid, route));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Route {Uuid} updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await routeService.ApplyRouteChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"Route changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentRoute = getResult.Route;
+
+ // Create updated route
+ var route = new RouteConfig
{
- HandleException(ex);
+ Network = Network ?? currentRoute.Network,
+ Gateway = Gateway ?? currentRoute.Gateway,
+ Description = Description ?? currentRoute.Description
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ route.Disabled = "0";
+ }
+ else if (Enabled.IsPresent)
+ {
+ route.Disabled = "0";
+ }
+ else if (Disabled.IsPresent)
+ {
+ route.Disabled = "1";
+ }
+ else
+ {
+ route.Disabled = currentRoute.Disabled;
+ }
+
+ // Update route
+ var updateResult = ExecuteAsyncTask(() => routeService.UpdateRouteAsync(Uuid, route));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Route {Uuid} updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => routeService.ApplyRouteChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"Route changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseSystemDNSCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseSystemDNSCmdlet.cs
index 0d399f8..0547f05 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseSystemDNSCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseSystemDNSCmdlet.cs
@@ -93,92 +93,102 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var systemDNSService = new SystemDNSService(ApiClient, Logger);
+
+ // Get current configuration
+ var getResult = ExecuteAsyncTask(() => systemDNSService.GetSystemDNSAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var systemDNSService = new SystemDNSService(ApiClient, Logger);
-
- // Get current configuration
- var getTask = Task.Run(async () => await systemDNSService.GetSystemDNSAsync());
- var currentConfig = getTask.GetAwaiter().GetResult().System;
-
- // Create updated configuration
- var config = new SystemDNSConfig
- {
- Hostname = Hostname ?? currentConfig.Hostname,
- Domain = Domain ?? currentConfig.Domain,
- Timezone = Timezone ?? currentConfig.Timezone,
- TimeServers = TimeServers ?? currentConfig.TimeServers,
- Language = Language ?? currentConfig.Language
- };
-
- // Handle DNS servers
- if (DnsServers != null && DnsServers.Length > 0)
- {
- config.DnsServers = new List(DnsServers);
- }
- else
- {
- config.DnsServers = currentConfig.DnsServers;
- }
-
- // Handle DNS override
- if (AllowDnsOverride.IsPresent && DisallowDnsOverride.IsPresent)
- {
- WriteWarning("Both -AllowDnsOverride and -DisallowDnsOverride parameters were specified. Using -AllowDnsOverride.");
- config.DnsAllowOverride = "1";
- }
- else if (AllowDnsOverride.IsPresent)
- {
- config.DnsAllowOverride = "1";
- }
- else if (DisallowDnsOverride.IsPresent)
- {
- config.DnsAllowOverride = "0";
- }
- else
- {
- config.DnsAllowOverride = currentConfig.DnsAllowOverride;
- }
-
- // Handle DNS rebind protection
- if (DisableDnsRebindProtection.IsPresent && EnableDnsRebindProtection.IsPresent)
- {
- WriteWarning("Both -DisableDnsRebindProtection and -EnableDnsRebindProtection parameters were specified. Using -DisableDnsRebindProtection.");
- config.DnssecStripped = "1";
- }
- else if (DisableDnsRebindProtection.IsPresent)
- {
- config.DnssecStripped = "1";
- }
- else if (EnableDnsRebindProtection.IsPresent)
- {
- config.DnssecStripped = "0";
- }
- else
- {
- config.DnssecStripped = currentConfig.DnssecStripped;
- }
-
- // Update configuration
- var updateTask = Task.Run(async () => await systemDNSService.UpdateSystemDNSAsync(config));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"System DNS configuration updated: {updateResult.Result}");
-
- // Apply changes if requested
- if (Apply.IsPresent)
- {
- var applyTask = Task.Run(async () => await systemDNSService.ApplySystemDNSChangesAsync());
- var applyResult = applyTask.GetAwaiter().GetResult();
-
- WriteVerbose($"System DNS changes applied: {applyResult.Status}");
- }
+ return;
}
- catch (Exception ex)
+
+ var currentConfig = getResult.System;
+
+ // Create updated configuration
+ var config = new SystemDNSConfig
{
- HandleException(ex);
+ Hostname = Hostname ?? currentConfig.Hostname,
+ Domain = Domain ?? currentConfig.Domain,
+ Timezone = Timezone ?? currentConfig.Timezone,
+ TimeServers = TimeServers ?? currentConfig.TimeServers,
+ Language = Language ?? currentConfig.Language
+ };
+
+ // Handle DNS servers
+ if (DnsServers != null && DnsServers.Length > 0)
+ {
+ config.DnsServers = new List(DnsServers);
+ }
+ else
+ {
+ config.DnsServers = currentConfig.DnsServers;
+ }
+
+ // Handle DNS override
+ if (AllowDnsOverride.IsPresent && DisallowDnsOverride.IsPresent)
+ {
+ WriteWarning("Both -AllowDnsOverride and -DisallowDnsOverride parameters were specified. Using -AllowDnsOverride.");
+ config.DnsAllowOverride = "1";
+ }
+ else if (AllowDnsOverride.IsPresent)
+ {
+ config.DnsAllowOverride = "1";
+ }
+ else if (DisallowDnsOverride.IsPresent)
+ {
+ config.DnsAllowOverride = "0";
+ }
+ else
+ {
+ config.DnsAllowOverride = currentConfig.DnsAllowOverride;
+ }
+
+ // Handle DNS rebind protection
+ if (DisableDnsRebindProtection.IsPresent && EnableDnsRebindProtection.IsPresent)
+ {
+ WriteWarning("Both -DisableDnsRebindProtection and -EnableDnsRebindProtection parameters were specified. Using -DisableDnsRebindProtection.");
+ config.DnssecStripped = "1";
+ }
+ else if (DisableDnsRebindProtection.IsPresent)
+ {
+ config.DnssecStripped = "1";
+ }
+ else if (EnableDnsRebindProtection.IsPresent)
+ {
+ config.DnssecStripped = "0";
+ }
+ else
+ {
+ config.DnssecStripped = currentConfig.DnssecStripped;
+ }
+
+ // Update configuration
+ var updateResult = ExecuteAsyncTask(() => systemDNSService.UpdateSystemDNSAsync(config));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"System DNS configuration updated: {updateResult.Result}");
+
+ // Apply changes if requested
+ if (Apply.IsPresent)
+ {
+ var applyResult = ExecuteAsyncTask(() => systemDNSService.ApplySystemDNSChangesAsync());
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || applyResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"System DNS changes applied: {applyResult.Status}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseUserCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseUserCmdlet.cs
index ec85614..58d73b2 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseUserCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseUserCmdlet.cs
@@ -76,56 +76,61 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var userService = new UserService(ApiClient, Logger);
+
+ // First, get the current user
+ var getResult = ExecuteAsyncTask(() => userService.GetUserAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var userService = new UserService(ApiClient, Logger);
-
- // First, get the current user
- var getTask = Task.Run(async () => await userService.GetUserAsync(Uuid));
- var currentUser = getTask.GetAwaiter().GetResult().User;
-
- // Create the updated user
- var user = new UserConfig
- {
- Username = currentUser.Username,
- Password = Password ?? "",
- FullName = FullName ?? currentUser.FullName,
- Email = Email ?? currentUser.Email,
- Groups = Groups != null ? new List(Groups) : currentUser.Groups,
- Authorizations = Authorizations != null ? new List(Authorizations) : currentUser.Authorizations
- };
-
- // Handle enabled/disabled state
- if (Enabled.IsPresent && Disabled.IsPresent)
- {
- WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
- user.Disabled = "0";
- }
- else if (Enabled.IsPresent)
- {
- user.Disabled = "0";
- }
- else if (Disabled.IsPresent)
- {
- user.Disabled = "1";
- }
- else
- {
- user.Disabled = currentUser.Disabled;
- }
-
- // Update the user
- var updateTask = Task.Run(async () => await userService.UpdateUserAsync(Uuid, user));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"User {Uuid} updated: {updateResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var currentUser = getResult.User;
+
+ // Create the updated user
+ var user = new UserConfig
{
- HandleException(ex);
+ Username = currentUser.Username,
+ Password = Password ?? "",
+ FullName = FullName ?? currentUser.FullName,
+ Email = Email ?? currentUser.Email,
+ Groups = Groups != null ? new List(Groups) : currentUser.Groups,
+ Authorizations = Authorizations != null ? new List(Authorizations) : currentUser.Authorizations
+ };
+
+ // Handle enabled/disabled state
+ if (Enabled.IsPresent && Disabled.IsPresent)
+ {
+ WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
+ user.Disabled = "0";
}
+ else if (Enabled.IsPresent)
+ {
+ user.Disabled = "0";
+ }
+ else if (Disabled.IsPresent)
+ {
+ user.Disabled = "1";
+ }
+ else
+ {
+ user.Disabled = currentUser.Disabled;
+ }
+
+ // Update the user
+ var updateResult = ExecuteAsyncTask(() => userService.UpdateUserAsync(Uuid, user));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
+ }
+
+ WriteVerbose($"User {Uuid} updated: {updateResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseVLANCmdlet.cs b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseVLANCmdlet.cs
index ae5ce36..bc7b1f0 100644
--- a/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseVLANCmdlet.cs
+++ b/src/PSOPNSenseAPI/Cmdlets/SetOPNSenseVLANCmdlet.cs
@@ -59,35 +59,40 @@ namespace PSOPNSenseAPI.Cmdlets
///
/// Processes the cmdlet
///
- protected override void ProcessRecord()
+ protected override void ProcessRecordInternal()
{
- try
+ var interfaceService = new InterfaceService(ApiClient, Logger);
+
+ // First, get the current VLAN configuration
+ var getResult = ExecuteAsyncTask(() => interfaceService.GetVLANAsync(Uuid));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || getResult == null)
{
- var interfaceService = new InterfaceService(ApiClient, Logger);
-
- // First, get the current VLAN configuration
- var getTask = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
- var currentVlan = getTask.GetAwaiter().GetResult().Vlan;
-
- // Create the updated configuration
- var vlan = new VLANConfig
- {
- Interface = Interface ?? currentVlan.Interface,
- Tag = Tag?.ToString() ?? currentVlan.Tag,
- Priority = Priority?.ToString() ?? currentVlan.Priority,
- Description = Description ?? currentVlan.Description
- };
-
- // Update the VLAN
- var updateTask = Task.Run(async () => await interfaceService.UpdateVLANAsync(Uuid, vlan));
- var updateResult = updateTask.GetAwaiter().GetResult();
-
- WriteVerbose($"VLAN {Uuid} updated: {updateResult.Result}");
+ return;
}
- catch (Exception ex)
+
+ var currentVlan = getResult.Vlan;
+
+ // Create the updated configuration
+ var vlan = new VLANConfig
{
- HandleException(ex);
+ Interface = Interface ?? currentVlan.Interface,
+ Tag = Tag?.ToString() ?? currentVlan.Tag,
+ Priority = Priority?.ToString() ?? currentVlan.Priority,
+ Description = Description ?? currentVlan.Description
+ };
+
+ // Update the VLAN
+ var updateResult = ExecuteAsyncTask(() => interfaceService.UpdateVLANAsync(Uuid, vlan));
+
+ // Only continue if no exception occurred
+ if (ProcessingException != null || updateResult == null)
+ {
+ return;
}
+
+ WriteVerbose($"VLAN {Uuid} updated: {updateResult.Result}");
}
}
}
diff --git a/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1 b/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1
index 6480f15..5bce804 100644
--- a/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1
+++ b/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1
@@ -3,7 +3,7 @@
RootModule = 'lib\PSOPNSenseAPI.dll'
# Version number of this module.
- ModuleVersion = '2025.04.15.1257'
+ ModuleVersion = '2025.04.15.1543'
# Supported PSEditions
CompatiblePSEditions = @('Desktop', 'Core')