You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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批量方案
注意事项
  1. 权限要求:不管用哪种方法,执行账号都需要足够的权限:
    • T-SQL方法:SQL Server的sysadmin角色权限
    • PowerShell方法:目标服务器的Windows管理员权限,以及SQL Server访问权限(如果用Invoke-SqlCmd)
  2. 命名实例处理:T-SQL方案已经自动兼容命名实例,PowerShell注册表方案需要额外处理实例对应的注册表路径
  3. 版本兼容性:sys.server_updates仅适用于SQL Server 2017及以上版本,老版本必须用注册表查询方法

内容的提问来源于stack exchange,提问作者nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:20:59