mirror of
https://github.com/freedbygrace/PSOPNSenseAPI.git
synced 2026-07-26 11:58:18 +00:00
Add test cmdlet for diagnosing threading issues (v2025.04.15.1714)
This commit is contained in:
@@ -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.
|
||||
@@ -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.1714'
|
||||
|
||||
# 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 = ''
|
||||
}
|
||||
@@ -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.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Tests threading issues in PowerShell cmdlets.</para>
|
||||
/// <para type="description">The Test-OPNSenseThreading cmdlet tests threading issues in PowerShell cmdlets.</para>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsDiagnostic.Test, "OPNSenseThreading")]
|
||||
[OutputType(typeof(string))]
|
||||
public class TestThreadingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The test mode to run.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0)]
|
||||
[ValidateSet("Direct", "ConfigureAwait", "SynchronizationContext", "TaskRun")]
|
||||
public string Mode { get; set; } = "Direct";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The delay in milliseconds.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public int Delay { get; set; } = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecordInternal()
|
||||
{
|
||||
WriteVerbose($"Starting test in mode: {Mode}");
|
||||
WriteVerbose($"Current thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteVerbose($"Current synchronization context: {SynchronizationContext.Current != null}");
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case "Direct":
|
||||
TestDirect();
|
||||
break;
|
||||
case "ConfigureAwait":
|
||||
TestConfigureAwait();
|
||||
break;
|
||||
case "SynchronizationContext":
|
||||
TestSynchronizationContext();
|
||||
break;
|
||||
case "TaskRun":
|
||||
TestTaskRun();
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose("Test completed");
|
||||
}
|
||||
|
||||
private void TestDirect()
|
||||
{
|
||||
WriteVerbose("Testing direct method call");
|
||||
WriteVerbose($"Before delay - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
|
||||
Task.Delay(Delay).Wait();
|
||||
|
||||
WriteVerbose($"After delay - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteObject("Direct test completed");
|
||||
}
|
||||
|
||||
private void TestConfigureAwait()
|
||||
{
|
||||
WriteVerbose("Testing ConfigureAwait(false)");
|
||||
WriteVerbose($"Before async call - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
|
||||
var result = ExecuteAsyncTask(() => Task.Delay(Delay).ContinueWith(t =>
|
||||
{
|
||||
WriteVerbose($"Inside async task - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
return "ConfigureAwait test completed";
|
||||
}));
|
||||
|
||||
WriteVerbose($"After async call - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteObject(result);
|
||||
}
|
||||
|
||||
private void TestSynchronizationContext()
|
||||
{
|
||||
WriteVerbose("Testing SynchronizationContext");
|
||||
WriteVerbose($"Before async call - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteVerbose($"SynchronizationContext: {SynchronizationContext.Current != null}");
|
||||
|
||||
var syncContext = SynchronizationContext.Current;
|
||||
var result = ExecuteAsyncTask(() => Task.Delay(Delay).ContinueWith(t =>
|
||||
{
|
||||
var taskThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
WriteVerbose($"Inside async task - Thread ID: {taskThreadId}");
|
||||
|
||||
if (syncContext != null)
|
||||
{
|
||||
syncContext.Post(_ =>
|
||||
{
|
||||
WriteVerbose($"Inside SynchronizationContext.Post - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
}, null);
|
||||
}
|
||||
|
||||
return "SynchronizationContext test completed";
|
||||
}));
|
||||
|
||||
WriteVerbose($"After async call - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteObject(result);
|
||||
}
|
||||
|
||||
private void TestTaskRun()
|
||||
{
|
||||
WriteVerbose("Testing Task.Run");
|
||||
WriteVerbose($"Before Task.Run - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
WriteVerbose($"Inside Task.Run - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
Thread.Sleep(Delay);
|
||||
WriteVerbose($"After delay in Task.Run - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
return "TaskRun test completed";
|
||||
});
|
||||
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"After Task.Run - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
|
||||
WriteObject(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
RootModule = 'lib\PSOPNSenseAPI.dll'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '2025.04.15.1543'
|
||||
ModuleVersion = '2025.04.15.1714'
|
||||
|
||||
# Supported PSEditions
|
||||
CompatiblePSEditions = @('Desktop', 'Core')
|
||||
|
||||
Reference in New Issue
Block a user