使用PowerShell获取本地SQL Server详情时多实例MajorVersion获取失败
解决多SQL实例场景下的PowerShell详情获取问题
问题根源
你的代码存在两个关键问题:
- 使用
Invoke-SqlCmd时未指定目标实例,默认只会连接默认实例,导致多命名实例场景下所有实例的MajorVersion都取的是默认实例的值。 - 用
Substring(10,16)硬截取版本字符串的方式不可靠,不同版本的@@version输出格式可能有差异,容易导致截取错误。
修正后的代码
以下代码解决了上述问题,同时改用注册表直接获取版本对应关系(无需连接数据库,更高效稳定):
function ListSQLInstances { $listinstances = [System.Collections.ArrayList]@() # 注册表路径定义 $sqlRootReg = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQLServer' $instanceNamesReg = "$sqlRootReg\Instance Names\SQL" # 获取所有已安装实例 $installedInstances = (Get-ItemProperty $sqlRootReg).InstalledInstances foreach ($instanceName in $installedInstances) { # 获取实例的完整注册表路径名称 $instanceFullName = (Get-ItemProperty $instanceNamesReg).$instanceName $setupRegPath = "$sqlRootReg\$instanceFullName\Setup" $setupProps = Get-ItemProperty $setupRegPath # 从注册表直接获取MajorVersion对应的版本名称(无需连接数据库) $majorVersionMap = @{ 11 = 'SQL Server 2012' 12 = 'SQL Server 2014' 13 = 'SQL Server 2016' 14 = 'SQL Server 2017' 15 = 'SQL Server 2019' 16 = 'SQL Server 2022' } $majorVersionNumber = [int]$setupProps.Version.Split('.')[0] $majorVersion = $majorVersionMap[$majorVersionNumber] ?? "SQL Server Unknown Version ($majorVersionNumber)" # 构建实例对象 $instance = [PSCustomObject]@{ Instance = $instanceName InstanceNameFullName = $instanceFullName Edition = $setupProps.Edition Version = $setupProps.Version MajorVersion = $majorVersion } [void]$listinstances.Add($instance) } # 输出结果(匹配你要的格式) $listinstances | Format-Table -AutoSize } # 调用函数 ListSQLInstances
关键改进点
- 多实例适配:不再依赖数据库连接,直接从注册表读取所有实例的信息,避免了实例未启动或连接失败的问题。
- 版本映射可靠:通过版本号的主版本号(如11对应2012)做映射,比截取字符串更稳定。
- 代码简洁性:合并重复的注册表读取操作,提升效率。
如果一定要通过数据库连接获取版本(比如需要实时运行状态的版本),可以修改连接部分为:
# 构建实例连接字符串 $serverInstance = if ($instanceName -eq 'MSSQLServer') { 'localhost' } else { "localhost\$instanceName" } try { $versionResult = Invoke-SqlCmd -ServerInstance $serverInstance -Query "SELECT @@VERSION" -ErrorAction Stop # 用正则提取版本名称 if ($versionResult.Column1 -match 'SQL Server (\d{4})') { $majorVersion = "SQL Server $($matches[1])" } else { $majorVersion = 'SQL Server Unknown Version' } } catch { $majorVersion = "Connection Failed: $_" }
内容的提问来源于stack exchange,提问作者scode123
相关产品推荐
相关产品推荐

