Skip to content

Commit c67ff5b

Browse files
committed
Misc bug fixes and tweaks to functionality
1 parent 3437940 commit c67ff5b

10 files changed

Lines changed: 206 additions & 97 deletions

File tree

Modules/LogHelper/LogHelper.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
ModuleToProcess = 'LogHelper'
55

66
# Version number of this module.
7-
ModuleVersion = '1.0.0.0'
7+
ModuleVersion = '1.0.1.0'
88

99
# ID used to uniquely identify this module
1010
GUID = '{9b13d1af-effb-4827-b880-17e106dac3a1}'

Modules/NetworkScan/NetworkScan.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
ModuleToProcess = 'NetworkScan'
55

66
# Version number of this module.
7-
ModuleVersion = '1.0.1.0'
7+
ModuleVersion = '1.0.2.0'
88

99
# ID used to uniquely identify this module
1010
GUID = '{d4dba74f-b4b6-46e8-b6aa-1ba66775f3ea}'

Modules/NetworkScan/NetworkScan.psm1

Lines changed: 109 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ function Find-IPv4Device {
315315
.PARAMETER ParentProgressId
316316
If the caller is using Write-Progress then all progress information will be written using ParentProgressId as the ParentID
317317
318+
.PARAMETER TimeoutSeconds
319+
Number of seconds to wait for WMI connectivity test to return before timing out.
320+
321+
If not provided then 30 seconds is used as the default.
322+
318323
.EXAMPLE
319324
Find-IPv4Device -DNSServer automatic -DNSDomain automatic -PrivateOnly
320325
@@ -415,6 +420,12 @@ function Find-IPv4Device {
415420
[ValidateNotNull()]
416421
[Int32]
417422
$ParentProgressId = -1
423+
,
424+
[Parameter(Mandatory=$false)]
425+
[ValidateRange(1,32767)]
426+
[alias('Timeout')]
427+
[Int16]
428+
$TimeoutSeconds = 30
418429
)
419430
process {
420431

@@ -796,7 +807,7 @@ function Find-IPv4Device {
796807
Write-NetworkScanLog -Message "PING response from $($Device[$HashKey].IPAddress): $($Device[$HashKey].IsPingAlive)" -MessageLevel Verbose
797808
}
798809
}
799-
}
810+
}
800811
}
801812

802813
# Found that in some cases an ACCESS_VIOLATION error occurs if we don't delay a little bit during each iteration
@@ -920,6 +931,7 @@ function Find-IPv4Device {
920931
PowerShell = $PowerShell
921932
Runspace = $PowerShell.BeginInvoke()
922933
HashKey = $_.Key
934+
StartDate = [DateTime]::Now
923935
}
924936
)) | Out-Null
925937

@@ -947,9 +959,11 @@ function Find-IPv4Device {
947959
# Double check that we've got a DNS Hostname. If not, get it from DNS
948960
# If we do have a DNS Hostname that doesn't begin with the WMI Machine Name and $ResolveAliases is true, get the machine name from DNS
949961
if (
950-
( !$Device[$HashKey].DnsRecordName) `
951-
-or `
952-
( ( $ResolveAliases -eq $true) -and ($Device[$HashKey].DnsRecordName.StartsWith($HostName, 'CurrentCultureIgnoreCase') -ne $true))
962+
!$Device[$HashKey].DnsRecordName -or
963+
(
964+
$ResolveAliases -eq $true -and
965+
$Device[$HashKey].DnsRecordName.StartsWith($HostName, 'CurrentCultureIgnoreCase') -ne $true
966+
)
953967
) {
954968
try {
955969
[System.Net.Dns]::GetHostByName($HostName) | ForEach-Object {
@@ -977,6 +991,25 @@ function Find-IPv4Device {
977991
}
978992
}
979993
}
994+
elseif ($([DateTime]::Now).Subtract($_.StartDate).TotalSeconds -gt $TimeoutSeconds) {
995+
996+
$HashKey = $_.HashKey
997+
$_.PowerShell.Stop()
998+
$_.PowerShell.dispose()
999+
$_.Runspace = $null
1000+
$_.PowerShell = $null
1001+
1002+
if ($Device[$HashKey].DnsRecordName) {
1003+
Write-NetworkScanLog -Message "Timeout waiting for WMI response from $($Device[$HashKey].DnsRecordName) ($($Device[$HashKey].IPAddress))" -MessageLevel Warning
1004+
Write-NetworkScanLog -Message "WMI response from $($Device[$HashKey].DnsRecordName) ($($Device[$HashKey].IPAddress)): $($Device[$HashKey].IsWmiAlive)" -MessageLevel Verbose
1005+
} elseif ($Device[$HashKey].WmiMachineName) {
1006+
Write-NetworkScanLog -Message "Timeout waiting for WMI response from $($Device[$HashKey].WmiMachineName) ($($Device[$HashKey].IPAddress))" -MessageLevel Warning
1007+
Write-NetworkScanLog -Message "WMI response from $($Device[$HashKey].WmiMachineName) ($($Device[$HashKey].IPAddress)): $($Device[$HashKey].IsWmiAlive)" -MessageLevel Verbose
1008+
} else {
1009+
Write-NetworkScanLog -Message "Timeout waiting for WMI response from $($Device[$HashKey].IPAddress): $($Device[$HashKey].IsWmiAlive)" -MessageLevel Warning
1010+
Write-NetworkScanLog -Message "WMI response from $($Device[$HashKey].IPAddress): $($Device[$HashKey].IsWmiAlive)" -MessageLevel Verbose
1011+
}
1012+
}
9801013
}
9811014

9821015
# Found that in some cases an ACCESS_VIOLATION error occurs if we don't delay a little bit during each iteration
@@ -1247,7 +1280,7 @@ function Find-SqlServerService {
12471280
$RunspacePool.Open()
12481281

12491282
# Create an empty collection to hold the Runspace jobs
1250-
$Runspaces = New-Object System.Collections.ArrayList
1283+
$Runspaces = New-Object System.Collections.ArrayList
12511284

12521285

12531286
$ScanCount = 0
@@ -1277,10 +1310,8 @@ function Find-SqlServerService {
12771310
$DomainName = $null
12781311
$ServiceTypeName = $null
12791312
$ServiceName = $null
1280-
$Server = $null
12811313
$Port = $null
12821314
$IsDynamicPort = $false
1283-
$ServiceInstallDate = $null
12841315
$ServiceStartDate = $null
12851316

12861317
$StdRegProv = $null
@@ -1361,31 +1392,72 @@ function Find-SqlServerService {
13611392
# Get the port number for SQL Server Services
13621393
#if ($_.Type -eq $ManagedServiceTypeEnum::SqlServer) {
13631394
if ($ServiceTypeName -ieq 'SQL Server') {
1364-
$ServiceName = $_.Name
1395+
1396+
$ServiceIpAddress = $null
1397+
$Port = $null
1398+
$IsDynamicPort = $null
1399+
$ServiceName = if ($IsNamedInstance -eq $true) { $InstanceName } else { $_.Name }
13651400
$ManagedComputer.ServerInstances | Where-Object { $_.Name -ieq $ServiceName } | ForEach-Object {
13661401

1367-
$_.ServerProtocols | Where-Object { $_.Name -ieq 'tcp' } | ForEach-Object {
1402+
$_.ServerProtocols | Where-Object {
1403+
$_.Name -ieq 'tcp' -and
1404+
$_.IsEnabled -eq $true
1405+
} | ForEach-Object {
13681406

1369-
# First get the port for all IP Addresses
1370-
$_.IPAddresses | Where-Object { $_.Name -ieq 'ipall' } | ForEach-Object {
1371-
$Port = $_.IPAddressProperties['TcpPort'].Value
1372-
if (-not $Port) {
1373-
$Port = $_.IPAddressProperties['TcpDynamicPorts'].Value
1374-
$IsDynamicPort = $true
1375-
} else {
1376-
$IsDynamicPort = $false
1407+
# If listening on all IPs then get the "IPAll" port info
1408+
# Otherwise get port info for an IP that's enabled and active
1409+
1410+
if ($_.ProtocolProperties['ListenOnAllIPs'].Value -eq $true) {
1411+
1412+
$_.IPAddresses | Where-Object { $_.Name -ieq 'ipall' } | ForEach-Object {
1413+
$Port = $_.IPAddressProperties['TcpPort'].Value
1414+
if (-not $Port) {
1415+
$Port = $_.IPAddressProperties['TcpDynamicPorts'].Value
1416+
$IsDynamicPort = $true
1417+
} else {
1418+
$IsDynamicPort = $false
1419+
}
13771420
}
1378-
}
13791421

1380-
# Then check to see if the port is overridden for the specific IP Address provided
1381-
$_.IPAddresses | Where-Object { ($_.IPAddress -ieq $ServiceIpAddress) -and ($_.IPAddressProperties['Active'].Value -eq $true) -and ($_.IPAddressProperties['Enabled'].Value -eq $true) } | ForEach-Object {
1382-
$Port = $_.IPAddressProperties['TcpPort'].Value
1383-
if (-not $Port) {
1384-
$Port = $_.IPAddressProperties['TcpDynamicPorts'].Value
1385-
$IsDynamicPort = $true
1386-
} else {
1387-
$IsDynamicPort = $false
1422+
} else {
1423+
1424+
# Start with 127.0.0.1 first in case that's the only IP that's enabled
1425+
$_.IPAddresses | Where-Object {
1426+
$_.IPAddressProperties['Active'].Value -eq $true -and
1427+
$_.IPAddressProperties['Enabled'].Value -eq $true -and
1428+
$_.IPAddress.AddressFamily -ieq 'InterNetwork' -and
1429+
$_.IPAddress -ieq '127.0.0.1'
1430+
} | Select-Object -First 1 | ForEach-Object {
1431+
1432+
$ServiceIpAddress = $_.IPAddress.ToString()
1433+
$Port = $_.IPAddressProperties['TcpPort'].Value
1434+
1435+
if (-not $Port) {
1436+
$Port = $_.IPAddressProperties['TcpDynamicPorts'].Value
1437+
$IsDynamicPort = $true
1438+
} else {
1439+
$IsDynamicPort = $false
1440+
}
13881441
}
1442+
1443+
# Now try and see if there's a non-loopback IP enabled
1444+
$_.IPAddresses | Where-Object {
1445+
$_.IPAddressProperties['Active'].Value -eq $true -and
1446+
$_.IPAddressProperties['Enabled'].Value -eq $true -and
1447+
$_.IPAddress.AddressFamily -ieq 'InterNetwork' -and
1448+
$_.IPAddress -ine '127.0.0.1'
1449+
} | Select-Object -First 1 | ForEach-Object {
1450+
1451+
$ServiceIpAddress = $_.IPAddress.ToString()
1452+
$Port = $_.IPAddressProperties['TcpPort'].Value
1453+
1454+
if (-not $Port) {
1455+
$Port = $_.IPAddressProperties['TcpDynamicPorts'].Value
1456+
$IsDynamicPort = $true
1457+
} else {
1458+
$IsDynamicPort = $false
1459+
}
1460+
}
13891461
}
13901462
}
13911463

@@ -1410,12 +1482,6 @@ function Find-SqlServerService {
14101482
$ServiceStartDate = $null
14111483
}
14121484

1413-
# # Get the Service Install Date
1414-
# Get-WmiObject -Namespace root\CIMV2 -Class Win32_Service -Filter "DisplayName = '$($_.DisplayName)'" -Property CreationDate -ComputerName $IpAddress | ForEach-Object {
1415-
# $ServiceStartDate = $_.CreationDate
1416-
# }
1417-
1418-
14191485
Write-Output (
14201486
New-Object -TypeName psobject -Property @{
14211487
ComputerName = $ComputerName
@@ -1486,7 +1552,17 @@ function Find-SqlServerService {
14861552
# Determine if instance is clustered
14871553
$IsClusteredInstance = $null
14881554
$ClusterName = [String]::Empty
1489-
$ServiceIpAddress = $IpAddress
1555+
1556+
# If $ComputerName is the local host then use the loopback IP, otherwise use $IpAddress
1557+
if (
1558+
$ComputerName -ieq $env:COMPUTERNAME -or
1559+
$ComputerName.StartsWith([String]::Concat($env:COMPUTERNAME, '.'), [System.StringComparison]::InvariantCultureIgnoreCase)
1560+
) {
1561+
$ServiceIpAddress = '127.0.0.1'
1562+
} else {
1563+
$ServiceIpAddress = $IpAddress
1564+
}
1565+
14901566

14911567
# Get the TCP port number for SQL Server Services
14921568
$Port = ($StdRegProv.GetStringValue($HKEY_LOCAL_MACHINE,"$RegistryKeyRootPath\MSSQLServer\SuperSocketNetLib\Tcp",'TcpDynamicPorts')).sValue
Binary file not shown.

Modules/SqlServerDatabaseEngineInformation/SqlServerDatabaseEngineInformation.psm1

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3754,6 +3754,10 @@ function Get-SqlConnection {
37543754
$Instance = '(local)'
37553755
,
37563756
[Parameter(Mandatory=$false)]
3757+
[System.Net.IPAddress]
3758+
$IpAddress = $null
3759+
,
3760+
[Parameter(Mandatory=$false)]
37573761
[Int]
37583762
$Port = $null
37593763
,
@@ -3788,7 +3792,11 @@ function Get-SqlConnection {
37883792
$SQLConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection
37893793
$SQLConnectionBuilder = New-Object -TypeName system.Data.SqlClient.SqlConnectionStringBuilder
37903794

3791-
$SQLConnectionBuilder.psBase.DataSource = if ($Port) { "$Instance,$Port" } else { $Instance }
3795+
$SQLConnectionBuilder.psBase.DataSource = if ($IpAddress) {
3796+
if ($Port) { "$($IpAddress.ToString()),$Port" } else { $IpAddress.ToString() }
3797+
} else {
3798+
if ($Port) { "$Instance,$Port" } else { $Instance }
3799+
}
37923800
$SQLConnectionBuilder.psBase.InitialCatalog = $Database
37933801

37943802
if ($PSCmdlet.ParameterSetName -eq 'SQLAuthentication') {
@@ -11126,6 +11134,11 @@ function Get-SqlServerDatabaseEngineInformation {
1112611134
.PARAMETER InstanceName
1112711135
The database engine instance to connect to.
1112811136

11137+
.PARAMETER IpAddress
11138+
The IP Address to use when connecting to the database engine.
11139+
11140+
If not provided, the value provided for InstanceName will be used to connect instead.
11141+
1112911142
.PARAMETER Port
1113011143
The port to use when connecting to the database engine.
1113111144

@@ -11267,6 +11280,10 @@ function Get-SqlServerDatabaseEngineInformation {
1126711280
$InstanceName = '(local)'
1126811281
,
1126911282
[Parameter(Mandatory=$false)]
11283+
[System.Net.IPAddress]
11284+
$IpAddress = $null
11285+
,
11286+
[Parameter(Mandatory=$false)]
1127011287
[int]
1127111288
$Port = $null
1127211289
,
@@ -11341,9 +11358,9 @@ function Get-SqlServerDatabaseEngineInformation {
1134111358

1134211359

1134311360
if ($PSCmdlet.ParameterSetName -eq 'SQLAuthentication') {
11344-
$Connection = Get-SqlConnection -Instance $InstanceName -Port $Port -Username $Username -Password $Password
11361+
$Connection = Get-SqlConnection -Instance $InstanceName -IpAddress $IpAddress -Port $Port -Username $Username -Password $Password
1134511362
} else {
11346-
$Connection = Get-SqlConnection -Instance $InstanceName -Port $Port
11363+
$Connection = Get-SqlConnection -Instance $InstanceName -IpAddress $IpAddress -Port $Port
1134711364
}
1134811365

1134911366

@@ -11726,4 +11743,12 @@ function Get-SqlServerDatabaseEngineInformation {
1172611743
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMOExtended') | Out-Null
1172711744
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SQLWMIManagement') | Out-Null
1172811745
}
11746+
}
11747+
11748+
# Now check which SMO assemblies are loaded and set $SmoMajorVersion to the lowest version
11749+
[System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.FullName -ilike 'Microsoft.SqlServer.SMO, Version=*' } | ForEach-Object {
11750+
if ($_.GetName().Version.Major -lt $SmoMajorVersion) {
11751+
$SmoMajorVersion = $_.GetName().Version.Major
11752+
Write-SqlServerDatabaseEngineInformationLog -Message "Multiple versions of Microsoft.SqlServer.SMO are loaded; reverting to the lowest version to avoid problems" -MessageLevel Warning
11753+
}
1172911754
}
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)