iPERF2GO.psm1
<#
.SYNOPSIS IPERF2GO: A PowerShell module for staging, launching, and cleaning up iperf resources. .DESCRIPTION This module downloads and stages iperf from a GitHub-hosted ZIP file into a temporary folder. It appends the staging folder to your session's PATH and auto-detects the iperf executable. Subsequent commands call the iperf executable by name without specifying its full path. #> #region Module Variables $script:StagedIperfPath = $null $script:StagedIperfExe = $null #endregion #region Module Functions function Initialize-Iperf { [CmdletBinding()] Param( [Parameter()] [string]$GitHubUrl = "https://github.com/Kalichuza/ninjaAdminScripts/raw/refs/heads/main/MISC/iperf3.18_64.zip", [Parameter(Mandatory = $false)] [string]$Destination = "$env:TEMP\IPERF2GO_$([guid]::NewGuid())" ) Write-Verbose "Starting initialization of iperf resources." Write-Verbose "Destination folder: $Destination" Write-Verbose "GitHub URL: $GitHubUrl" # Create the destination folder if it doesn't exist. if (-not (Test-Path -Path $Destination)) { Write-Verbose "Creating destination folder..." try { New-Item -Path $Destination -ItemType Directory -Force | Out-Null Write-Verbose "Folder created." } catch { Write-Error "Failed to create destination folder: $_" return } } else { Write-Verbose "Destination folder already exists." } # Download the ZIP file. $zipFile = Join-Path -Path $Destination -ChildPath "iperf.zip" Write-Verbose "Downloading zip file from '$GitHubUrl' to '$zipFile'" try { Invoke-WebRequest -Uri $GitHubUrl -OutFile $zipFile -UseBasicParsing -ErrorAction Stop Write-Verbose "Download completed successfully." } catch { Write-Error "Download failed: $_" return } # Extract the ZIP file. Write-Verbose "Extracting zip file '$zipFile' to '$Destination'" try { Expand-Archive -Path $zipFile -DestinationPath $Destination -Force -ErrorAction Stop Write-Verbose "Extraction completed successfully." } catch { Write-Error "Extraction failed: $_" return } # Remove the zip file. try { Remove-Item -Path $zipFile -Force Write-Verbose "Removed zip file '$zipFile'" } catch { Write-Warning "Failed to remove zip file: $_" } # Determine the staging path. Write-Verbose "Determining the correct staging path..." $subDirs = Get-ChildItem -Path $Destination -Directory -ErrorAction SilentlyContinue if ($subDirs.Count -eq 1) { $candidate = $subDirs[0].FullName Write-Verbose "Single subdirectory found: '$candidate'" $filesInCandidate = Get-ChildItem -Path $candidate -Recurse -ErrorAction SilentlyContinue if ($filesInCandidate.Count -gt 0) { Write-Verbose "Candidate folder contains $($filesInCandidate.Count) files. Using candidate as staging path." $stagingPath = $candidate } else { Write-Verbose "Candidate folder is empty. Using destination folder as staging path." $stagingPath = $Destination } } else { Write-Verbose "Multiple or no subdirectories found. Using destination folder as staging path." $stagingPath = $Destination } # Append the staging path to the session's PATH. Write-Verbose "Appending staging path to session PATH: '$stagingPath'" $env:Path += ";" + $stagingPath # Detect the iperf executable in the staging path. $exeFiles = Get-ChildItem -Path $stagingPath -Recurse -Filter *.exe | Where-Object { $_.Name -like "*iperf*.exe" } if ($exeFiles -and $exeFiles.Count -ge 1) { $script:StagedIperfExe = $exeFiles[0].Name Write-Output "iperf resources have been initialized at: $stagingPath" Write-Output "Detected iperf executable: $script:StagedIperfExe (staged folder added to PATH)" } else { Write-Error "No iperf executable found in staged path: $stagingPath" } $script:StagedIperfPath = $stagingPath } function Start-IperfListener { [CmdletBinding()] Param( [Parameter(Mandatory = $false)] [int]$Port = 5201, [Parameter(Mandatory = $false)] [switch]$Background ) if (-not $script:StagedIperfExe) { Write-Error "No iperf executable detected. Please run Initialize-Iperf first." return } $iperfExe = $script:StagedIperfExe if (-not (Get-Command $iperfExe -ErrorAction SilentlyContinue)) { Write-Error "iperf executable '$iperfExe' not found in PATH. Ensure initialization succeeded." return } Write-Verbose "Starting iperf listener on port $Port..." $arguments = @("-s", "-p", $Port) if ($Background) { Write-Output "Starting iperf listener in background..." try { Start-Process -FilePath $iperfExe -ArgumentList $arguments -WindowStyle Hidden -ErrorAction Stop } catch { Write-Error "Failed to start iperf listener in background. Error: $_" } } else { Write-Output "Starting iperf listener in current session..." try { & $iperfExe @arguments } catch { Write-Error "Failed to run iperf listener. Error: $_" } } } function Start-IperfCaller { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string]$Server, [Parameter(Mandatory = $false)] [int]$Port = 5201, [Parameter(Mandatory = $false)] [string]$AdditionalArguments ) if (-not $script:StagedIperfExe) { Write-Error "No iperf executable detected. Please run Initialize-Iperf first." return } $iperfExe = $script:StagedIperfExe if (-not (Get-Command $iperfExe -ErrorAction SilentlyContinue)) { Write-Error "iperf executable '$iperfExe' not found in PATH. Ensure initialization succeeded." return } Write-Verbose "Starting iperf client to connect to server $Server on port $Port..." $arguments = @("-c", $Server, "-p", $Port) if ($AdditionalArguments) { $arguments += $AdditionalArguments.Split(" ") } Write-Output "Running iperf client..." try { & $iperfExe @arguments } catch { Write-Error "Failed to run iperf caller. Error: $_" } } function Remove-IperfSession { [CmdletBinding()] Param( [Parameter(Mandatory = $false)] [string]$ResourcePath ) if (-not $ResourcePath) { if ($script:StagedIperfPath) { $ResourcePath = $script:StagedIperfPath } else { Write-Error "No resource path provided and module has not been initialized." return } } Write-Verbose "Cleaning up iperf resources from $ResourcePath..." if (Test-Path -Path $ResourcePath) { try { Remove-Item -Path $ResourcePath -Recurse -Force -ErrorAction Stop Write-Output "Successfully cleaned up iperf resources from $ResourcePath." $script:StagedIperfPath = $null $script:StagedIperfExe = $null } catch { Write-Error "Failed to clean up iperf resources. Error: $_" } } else { Write-Output "Resource path $ResourcePath does not exist." } } function Enable-IperfFirewallRule { [CmdletBinding()] Param( [Parameter(Mandatory = $false)] [int]$Port = 5201 ) Write-Verbose "Enabling firewall rule for iperf on port $Port..." $ruleName = "IPERF2GO_Rule_$Port" try { New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -LocalPort $Port -Protocol TCP -Action Allow -Profile Any -ErrorAction Stop Write-Output "Firewall rule '$ruleName' has been enabled." } catch { Write-Error "Failed to enable firewall rule. Error: $_" } } function Disable-IperfFirewallRule { [CmdletBinding()] Param( [Parameter(Mandatory = $false)] [int]$Port = 5201 ) Write-Verbose "Disabling firewall rule for iperf on port $Port..." $ruleName = "IPERF2GO_Rule_$Port" try { Remove-NetFirewallRule -DisplayName $ruleName -ErrorAction Stop Write-Output "Firewall rule '$ruleName' has been removed." } catch { Write-Error "Failed to disable firewall rule. Error: $_" } } #endregion Export-ModuleMember -Function * |