Public/Get-HDTUsableAddress.ps1

function Get-HDTUsableAddress {
    <#
        .SYNOPSIS
            The first IPv4 address on this machine that a share could be reached
            from, or nothing.
 
        .DESCRIPTION
            FOUND ON A LIVE MACHINE, FROM ITS OWN LOG. A VM in WinPE printed
            "waiting for an address" seven times while holding 192.168.2.39 the
            whole time, because the payload did this inline:
 
                foreach ($candidate in (([string] $fact['HDTIPAddress']) -split ','))
 
            HDTIPAddress is a [string[]] (Get-HDTMachineFact). Casting an array
            to a string SPACE-joins it, so the comma split produced one element -
            '192.168.2.39 fe80::7796:...' - which matches no IPv4 pattern. The
            machine waited the full timeout for an address it already had.
 
            IT IS A COMMAND BECAUSE IT WAS A BUG. Inline in the payload it was
            reachable only by booting a VM; the payload's own test reads that
            file's SHAPE and cannot execute it. A decision has to be a command
            before a test can find anything wrong with it.
 
            EVERY SHAPE THE FACT CAN ARRIVE IN is read: the array it really is,
            a single string, a comma-joined string, and the space-joined string
            the broken cast produced. A reader that accepted only one of them is
            how this happened.
 
            APIPA IS NOT AN ADDRESS. 169.254.* is precisely the case where a
            machine looks connected and can reach nothing (SPIKES S9.2), and
            0.0.0.0 is the unconfigured adapter saying so.
 
        .PARAMETER Fact
            What Get-HDTMachineFact returned. Null is not an error.
 
        .INPUTS
            None. This command does not accept pipeline input.
 
        .OUTPUTS
            System.String - the address, or empty.
 
        .EXAMPLE
            Get-HDTUsableAddress -Fact $fact
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [AllowNull()]
        [object] $Fact
    )

    Set-StrictMode -Version Latest
    $ErrorActionPreference = 'Stop'

    if ($null -eq $Fact) { return '' }
    if (-not $Fact.Contains('HDTIPAddress')) { return '' }

    $value = $Fact['HDTIPAddress']
    if ($null -eq $value) { return '' }

    # SPLIT ON COMMA AND WHITESPACE, over each element of whatever arrived - so
    # the array, the comma-joined string and the space-joined one all read the
    # same.
    $candidate = @()
    foreach ($item in @($value)) {
        if ($null -eq $item) { continue }
        $candidate += ([string] $item) -split '[,\s]+'
    }

    foreach ($address in $candidate) {

        $trimmed = ([string] $address).Trim()
        if ([string]::IsNullOrWhiteSpace($trimmed)) { continue }

        if ($trimmed -notmatch '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') { continue }

        if ($trimmed.StartsWith('169.254.')) { continue }
        if ($trimmed -eq '0.0.0.0') { continue }

        return $trimmed
    }

    return ''
}