mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
42 lines
1.4 KiB
PowerShell
42 lines
1.4 KiB
PowerShell
# Prints one free TCP port per preferred port given as an argument.
|
|
#
|
|
# For each element of -Preferred, emits that port if it's free; otherwise
|
|
# emits a random free port in 20000-49999. Uses Get-NetTCPConnection to read
|
|
# the OS socket table directly — more reliable than TcpListener binding on
|
|
# Windows where SO_REUSEADDR can cause false "free" results. Tracks picks
|
|
# within this run so outputs are guaranteed distinct from each other.
|
|
param([Parameter(ValueFromRemainingArguments = $true)][int[]]$Preferred)
|
|
|
|
$script:picked = @()
|
|
|
|
# Build a set of ports currently in LISTEN or ESTABLISHED state once upfront.
|
|
$usedPorts = [System.Collections.Generic.HashSet[int]]::new()
|
|
Get-NetTCPConnection -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.State -in 'Listen', 'Established' } |
|
|
ForEach-Object { $null = $usedPorts.Add($_.LocalPort) }
|
|
|
|
function Test-PortFree {
|
|
param([int]$Port)
|
|
if ($script:picked -contains $Port) { return $false }
|
|
return -not $usedPorts.Contains($Port)
|
|
}
|
|
|
|
function Get-RandomFreePort {
|
|
while ($true) {
|
|
$port = Get-Random -Minimum 20000 -Maximum 50000
|
|
if (Test-PortFree $port) { return $port }
|
|
}
|
|
}
|
|
|
|
foreach ($p in $Preferred) {
|
|
if (Test-PortFree $p) {
|
|
$script:picked += $p
|
|
} else {
|
|
$script:picked += Get-RandomFreePort
|
|
}
|
|
}
|
|
|
|
foreach ($p in $script:picked) {
|
|
[Console]::Out.Write("$p`n")
|
|
}
|