Skip to content

Commit ea0aaeb

Browse files
Find-DbaInstance - Fix TcpConnected false for multiple named instances; add verbose messages
The TcpClient in Test-TcpPort was created once (in begin{}) and shared across all port tests. After the first successful Connect()+Close(), the client was disposed, causing all subsequent port tests to throw ObjectDisposedException (caught, returning IsOpen=False). Fix: create a new TcpClient per port test (moved to process{}) with Dispose() in a finally block. Also filter out port 0 from Browser results - DbaBrowserReply.TCPPort defaults to 0 for instances that don't report a TCP port, and testing port 0 can leave the socket in an error state. Added Verbose messages throughout the Browser scan path to aid debugging: Browser results, port test results, per-instance BrowseReply TCPPort lookup and outcome. Co-authored-by: Andreas Jordan <andreasjordan@users.noreply.github.com>
1 parent 295c2b0 commit ea0aaeb

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

public/Find-DbaInstance.ps1

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,22 @@ function Find-DbaInstance {
350350
try {
351351
Write-ProgressHelper -Activity "Processing: $($computer)" -StepNumber ($stepCounter++) -Message "Probing Browser service"
352352
$browseResult = Get-SQLInstanceBrowserUDP -ComputerName $computer -EnableException
353-
$ports = $browseResult.TCPPort | Test-TcpPort -ComputerName $computer
353+
Write-Message -Level Verbose -Message "Browser returned $($browseResult.Count) instance(s): $(($browseResult | ForEach-Object { "$($_.InstanceName):$($_.TCPPort)" }) -join ', ')" -Target $computer -FunctionName Find-DbaInstance
354+
# Filter port 0 - Browser returns 0 for instances that don't report a TCP port (default instances)
355+
$ports = $browseResult.TCPPort | Where-Object { $_ -gt 0 } | Test-TcpPort -ComputerName $computer
356+
Write-Message -Level Verbose -Message "Port test results from Browser: $(($ports | ForEach-Object { "Port $($_.Port)=$($_.IsOpen)" }) -join ', ')" -Target $computer -FunctionName Find-DbaInstance
354357
} catch {
358+
Write-Message -Level Verbose -Message "Browser scan failed: $_" -Target $computer -FunctionName Find-DbaInstance
355359
# here to avoid an empty catch
356360
$null = 1
357361
}
358362
# Fall back to default port testing if Browser returned no port info
359363
# (e.g. SQL Server 2022+ where Browser is deprecated, or default instances
360364
# which don't report a TCP port via Browser UDP)
361365
if (-not $ports) {
366+
Write-Message -Level Verbose -Message "No port info from Browser, falling back to default ports: $($TCPPort -join ', ')" -Target $computer -FunctionName Find-DbaInstance
362367
$ports = $TCPPort | Test-TcpPort -ComputerName $computer
368+
Write-Message -Level Verbose -Message "Fallback port test results: $(($ports | ForEach-Object { "Port $($_.Port)=$($_.IsOpen)" }) -join ', ')" -Target $computer -FunctionName Find-DbaInstance
363369
}
364370
} else {
365371
$ports = $TCPPort | Test-TcpPort -ComputerName $computer
@@ -455,16 +461,20 @@ function Find-DbaInstance {
455461
$object.Confidence = 'Medium'
456462
if ($object.BrowseReply.TCPPort) {
457463
$object.Port = $object.BrowseReply.TCPPort
464+
Write-Message -Level Verbose -Message "Instance $instance: Browser reported TCPPort $($object.Port), checking PortsScanned: $(($object.PortsScanned | ForEach-Object { "Port $($_.Port)=$($_.IsOpen)" }) -join ', ')" -Target $computer -FunctionName Find-DbaInstance
458465

459466
$object.PortsScanned | Where-Object Port -EQ $object.Port | ForEach-Object {
460467
$object.TcpConnected = $_.IsOpen
468+
Write-Message -Level Verbose -Message "Instance $instance: Port $($_.Port) IsOpen=$($_.IsOpen), TcpConnected set to $($object.TcpConnected)" -Target $computer -FunctionName Find-DbaInstance
461469
}
462470
} else {
463471
# Default instance - Browser doesn't report a specific TCP port,
464472
# check if any of the fallback ports we tested is open
473+
Write-Message -Level Verbose -Message "Instance $instance: Browser has no TCPPort (default instance), checking PortsScanned for any open port: $(($object.PortsScanned | ForEach-Object { "Port $($_.Port)=$($_.IsOpen)" }) -join ', ')" -Target $computer -FunctionName Find-DbaInstance
465474
$object.PortsScanned | Where-Object IsOpen | Select-Object -First 1 | ForEach-Object {
466475
$object.Port = $_.Port
467476
$object.TcpConnected = $true
477+
Write-Message -Level Verbose -Message "Instance $instance: Found open port $($_.Port), TcpConnected set to True" -Target $computer -FunctionName Find-DbaInstance
468478
}
469479
}
470480
}
@@ -814,21 +824,20 @@ function Find-DbaInstance {
814824
[Parameter(ValueFromPipeline)][int[]]$Port
815825
)
816826

817-
begin {
818-
$client = New-Object Net.Sockets.TcpClient
819-
}
820827
process {
821828
foreach ($item in $Port) {
829+
$client = New-Object Net.Sockets.TcpClient
822830
try {
823831
$client.Connect($ComputerName.ComputerName, $item)
824832
if ($client.Connected) {
825-
$client.Close()
826833
New-Object -TypeName Dataplat.Dbatools.Discovery.DbaPortReport -ArgumentList $ComputerName.ComputerName, $item, $true
827834
} else {
828835
New-Object -TypeName Dataplat.Dbatools.Discovery.DbaPortReport -ArgumentList $ComputerName.ComputerName, $item, $false
829836
}
830837
} catch {
831838
New-Object -TypeName Dataplat.Dbatools.Discovery.DbaPortReport -ArgumentList $ComputerName.ComputerName, $item, $false
839+
} finally {
840+
$client.Dispose()
832841
}
833842
}
834843
}

0 commit comments

Comments
 (0)