Public/Network/Connect-WebServerOpenPort.ps1

FUNCTION Connect-WebServerOpenPort {

    [CmdletBinding()]
    PARAM (
        [Parameter(Mandatory=$true)]
        [string]$Address
    )

FUNCTION Test-TCPPorts {
    <#
    .SYNOPSIS
    Tests TCP connectivity to a specified host on multiple ports asynchronously.
 
    .DESCRIPTION
    Tests TCP connectivity to a specified hostname or IP address on ports 1-1024, 4443, 4444, 8000, 8080, 8443, and 10443.
    Runs tests asynchronously with a maximum of 100 concurrent tests and displays a progress bar.
 
    .PARAMETER ComputerName
    The hostname or IP address to test connectivity against.
 
    .PARAMETER Timeout
    The timeout in milliseconds for each TCP connection attempt. Default is 2000ms.
 
    .EXAMPLE
    Test-TCPPorts -ComputerName "example.com"
    Tests TCP connectivity to example.com on specified ports.
 
    .EXAMPLE
    Test-TCPPorts -ComputerName "192.168.1.1" -Timeout 1000
    Tests TCP connectivity to 192.168.1.1 with a 1000ms timeout.
 
    .OUTPUTS
    PSCustomObject with properties: ComputerName, Port, IsOpen, Error (if any).
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$ComputerName,

        [Parameter()]
        [int]$Timeout = 1000
    )

    # Define the ports to test
    $ports = @()
    $ports += 1..1024
    $ports += 4433, 4443, 4444, 8000, 8080, 8443, 10443
    $ports = $ports | Sort-Object -Unique

    $totalPorts = $ports.Count
    $results = [System.Collections.ArrayList]::new()
    $completed = 0

    # Create a runspace pool
    $runspacePool = [RunspaceFactory]::CreateRunspacePool(1, 100)
    $runspacePool.Open()

    $tasks = [System.Collections.ArrayList]::new()

    # ScriptBlock for testing a single port
    $scriptBlock = {
        param ($ComputerName, $Port, $Timeout)
        $result = [PSCustomObject]@{
            ComputerName = $ComputerName
            Port         = $Port
            IsOpen       = $false
        }

        try {
            $tcpClient = New-Object System.Net.Sockets.TcpClient
            $connection = $tcpClient.BeginConnect($ComputerName, $Port, $null, $null)
            $success = $connection.AsyncWaitHandle.WaitOne($Timeout, $false)

            if ($success) {
                $tcpClient.EndConnect($connection)
                $result.IsOpen = $true
            }
            $tcpClient.Close()
        }
        catch {
            $result.Error = $_.Exception.Message
        }
        finally {
            if ($null -ne $tcpClient) {
                $tcpClient.Dispose()
            }
        }

        return $result | Where-Object { $_.IsOpen -eq $True }
    }

    # Create async tasks for each port
    foreach ($port in $ports) {
        $powershell = [PowerShell]::Create()
        $powershell.RunspacePool = $runspacePool
        [void]$powershell.AddScript($scriptBlock).AddArgument($ComputerName).AddArgument($port).AddArgument($Timeout)
        $handle = $powershell.BeginInvoke()
        $tasks.Add([PSCustomObject]@{
            PowerShell = $powershell
            Handle     = $handle
            Port       = $port
        }) | Out-Null
    }

    # Process tasks and update progress
    while ($tasks.Count -gt 0) {
        $completedTasks = $tasks | Where-Object { $_.Handle.IsCompleted }
        foreach ($task in $completedTasks) {
            $result = $task.PowerShell.EndInvoke($task.Handle)
            if ($result.IsOpen) {
                [void]$results.Add($result)
            }
            $task.PowerShell.Dispose()
            $tasks.Remove($task)
            $completed++

            # Update progress bar
            $percentComplete = [math]::Round(($completed / $totalPorts) * 100, 2)
            Write-Progress -Activity "Testing TCP Ports on $ComputerName" `
                          -Status "Tested $completed of $totalPorts ports" `
                          -PercentComplete $percentComplete
        }

        # Small sleep to prevent excessive CPU usage
        Start-Sleep -Milliseconds 100
    }

    # Clean up
    $runspacePool.Close()
    $runspacePool.Dispose()

    # Complete the progress bar
    Write-Progress -Activity "Testing TCP Ports on $ComputerName" -Completed

    # Return results sorted by port
    return $results | Sort-Object Port
}
FUNCTION Open-Website {
    <#
    .SYNOPSIS
        Launches a specified website in the default web browser.
     
    .DESCRIPTION
        This function opens a provided URL in the system's default web browser using the Start-Process cmdlet.
     
    .PARAMETER Url
        The URL of the website to launch (e.g., https://www.example.com).
     
    .EXAMPLE
        Launch-Website -Url "https://www.example.com"
        Opens the specified website in the default browser.
     
    .NOTES
        Ensure the URL includes the protocol (http:// or https://).
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true, Position=0)]
        [ValidateNotNullOrEmpty()]
        [string]$Url
    )
    
    try {
        # Validate URL format
        if ($Url -notmatch '^https?://') {
            throw "Invalid URL format. Please include http:// or https://"
        }
        
        # Launch the website in the default browser
        Start-Process $Url
        Write-Verbose "Successfully launched $Url"
    }
    catch {
        Write-Error "Failed to launch website: $_"
    }
}

$OpenPorts = (Test-TCPPorts $Address).Port
    FOREACH ($Port in $OpenPorts) {
        Open-Website "http://$Address`:$Port/"
        Start-Sleep 2
        Open-Website "https://$Address`:$Port/"
        Start-Sleep 2
    }
}