如何通过T-SQL或PowerShell查询SQL Server最后一次SP/CU安装时间
绝对有高效的批量解决方案!不用挨个登录服务器翻控制面板或者日志,用T-SQL或者PowerShell就能轻松搞定多台SQL Server的SP/CU安装时间查询。下面给你详细拆解两种方法:
方法一:用T-SQL直接查询单台/多台SQL Server实例
这种方法适合已经能通过SSMS或其他工具连接SQL Server实例的场景,直接执行脚本就能拿到结果。
方案1:兼容所有SQL Server版本(通过注册表查询)
SQL Server的更新信息会存在系统注册表中,我们可以用xp_instance_regread内置函数读取这些信息,不管是老版本(比如2012、2014)还是新版本都适用:
DECLARE @InstanceName NVARCHAR(100) = SERVERPROPERTY('InstanceName'); SET @InstanceName = ISNULL(@InstanceName, N'MSSQLSERVER'); -- 默认实例用MSSQLSERVER,命名实例自动获取 DECLARE @InstanceID NVARCHAR(100); EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL', @InstanceName, @InstanceID OUTPUT; -- 拼接实例对应的注册表路径 DECLARE @RegPath NVARCHAR(200) = N'SOFTWARE\Microsoft\Microsoft SQL Server\' + @InstanceID + N'\Setup'; DECLARE @UpdateLevel NVARCHAR(100); -- 存储CU/SP编号,比如CU23、SP1 DECLARE @UpdateInstallTime DATETIME; -- 存储更新安装时间 EXEC xp_instance_regread @RegPath, N'UpdateLevel', @UpdateLevel OUTPUT; EXEC xp_instance_regread @RegPath, N'UpdateTime', @UpdateInstallTime OUTPUT; -- 输出查询结果 SELECT SERVERPROPERTY('ServerName') AS [服务器名称], SERVERPROPERTY('ProductVersion') AS [产品版本], @UpdateLevel AS [更新级别], @UpdateInstallTime AS [更新安装时间];
说明:
- 这段脚本会自动识别默认实例或命名实例,不用手动修改路径
- 需要执行脚本的账号拥有SQL Server的
sysadmin权限(因为读取注册表需要高权限)
方案2:仅SQL Server 2017及以上版本(用系统视图)
SQL Server 2017及以后新增了sys.server_updates系统视图,直接就能获取所有安装的更新记录,写法更简洁:
SELECT SERVERPROPERTY('ServerName') AS [服务器名称], update_id AS [更新ID], update_type AS [更新类型], description AS [更新描述], install_date AS [安装时间] FROM sys.server_updates;
说明:
- 这个视图会列出所有安装过的SP/CU,不止最后一次,如果你只需要最新的,加个
ORDER BY install_date DESC OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY即可
方法二:用PowerShell批量查询多台服务器
如果需要一次性查询几十上百台服务器,PowerShell是最佳选择,可以批量执行脚本并导出结果到CSV文件,方便后续统计。
方案1:批量执行T-SQL脚本(通用所有版本)
先准备一个包含所有服务器/实例名的文本文件(比如C:\servers.txt,每行一个,格式如SERVER01或SERVER01\INSTANCE01),然后执行以下脚本:
# 读取服务器列表 $serverList = Get-Content "C:\servers.txt" # 结果输出路径 $outputPath = "C:\SQL_Update_Results.csv" # 循环处理每台服务器 foreach ($server in $serverList) { try { # 执行T-SQL查询 $queryResult = Invoke-SqlCmd -ServerInstance $server -Query @" DECLARE @InstanceName NVARCHAR(100) = SERVERPROPERTY('InstanceName'); SET @InstanceName = ISNULL(@InstanceName, N'MSSQLSERVER'); DECLARE @InstanceID NVARCHAR(100); EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL', @InstanceName, @InstanceID OUTPUT; DECLARE @RegPath NVARCHAR(200) = N'SOFTWARE\Microsoft\Microsoft SQL Server\' + @InstanceID + N'\Setup'; DECLARE @UpdateLevel NVARCHAR(100); DECLARE @UpdateInstallTime DATETIME; EXEC xp_instance_regread @RegPath, N'UpdateLevel', @UpdateLevel OUTPUT; EXEC xp_instance_regread @RegPath, N'UpdateTime', @UpdateInstallTime OUTPUT; SELECT SERVERPROPERTY('ServerName') AS [服务器名称], SERVERPROPERTY('ProductVersion') AS [产品版本], @UpdateLevel AS [更新级别], @UpdateInstallTime AS [更新安装时间]; "@ -ErrorAction Stop # 将结果追加到CSV文件 $queryResult | Export-Csv -Path $outputPath -Append -NoTypeInformation Write-Host "✅ 成功查询服务器:$server" } catch { Write-Host "❌ 查询服务器失败:$server,错误信息:$_" } }
说明:
- 确保你的PowerShell环境安装了
SqlServer模块(可以用Install-Module -Name SqlServer安装) - 执行脚本的账号需要有所有目标SQL Server的
sysadmin权限,以及服务器的Windows访问权限
方案2:直接读取远程注册表(无需连接SQL Server)
如果你不想连接SQL Server实例,也可以直接读取远程服务器的注册表,前提是你的账号有远程服务器的管理员权限:
$serverList = Get-Content "C:\servers.txt" $results = @() foreach ($server in $serverList) { try { # 注意:这里的注册表路径需要根据SQL Server版本调整,比如2019是MSSQL15,2017是MSSQL14,2016是MSSQL13 $remoteRegPath = "\\$server\HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\Setup" # 读取更新信息 $regProps = Get-ItemProperty -Path $remoteRegPath -ErrorAction Stop $resultObj = [PSCustomObject]@{ 服务器名称 = $server 更新级别 = $regProps.UpdateLevel 更新安装时间 = $regProps.UpdateTime 产品版本 = $regProps.ProductVersion } $results += $resultObj Write-Host "✅ 成功读取服务器注册表:$server" } catch { Write-Host "❌ 读取服务器注册表失败:$server,错误信息:$_" } } # 导出结果到CSV $results | Export-Csv -Path "C:\SQL_Update_Registry_Results.csv" -NoTypeInformation -Encoding UTF8
说明:
- 这个方法的缺点是需要提前知道目标服务器上SQL Server的版本对应的注册表前缀(比如MSSQL15对应2019),如果有多个版本或命名实例,处理起来会比较麻烦,更推荐用T-SQL批量方案
注意事项
- 权限要求:不管用哪种方法,执行账号都需要足够的权限:
- T-SQL方法:SQL Server的
sysadmin角色权限 - PowerShell方法:目标服务器的Windows管理员权限,以及SQL Server访问权限(如果用Invoke-SqlCmd)
- T-SQL方法:SQL Server的
- 命名实例处理:T-SQL方案已经自动兼容命名实例,PowerShell注册表方案需要额外处理实例对应的注册表路径
- 版本兼容性:
sys.server_updates仅适用于SQL Server 2017及以上版本,老版本必须用注册表查询方法
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

