- 示例工程
- 数据库
- 教程
- 后端
【免费下载链接】sql-server-samples
Azure Data SQL Samples - Official Microsoft GitHub Repository containing code samples for SQL Server, Azure SQL, Azure Synapse, and Azure SQL Edge
SQL Server 进入生命周期终点(End of Support)后,扩展安全更新(Extended Security Updates,ESU)是继续获得关键安全补丁的重要途径。本文基于 sql-server-samples 仓库的 sql-server-extended-security-updates 模块,完整讲解如何用官方示例脚本(T-SQL 与 PowerShell)自动生成 ESU 注册所需的实例信息清单,并深入解析脚本底层的数据采集逻辑,帮助你为单实例、单机多实例乃至大规模实例清单的批量注册做好准备。
一、ESU 注册信息:为什么需要"生成器"脚本
当 SQL Server 版本结束支持后,需要将其注册到 Azure 门户的 ESU 管理体系中,才能持续接收扩展安全更新。注册时,Azure 门户要求提供每个 SQL Server 实例的实例名(name)、SQL 版本(version)、版本类型(edition)、核心数(cores)和主机类型(hostType),这些字段会用于 ESU 权益的核算与合规审计。
手动为成百上千台服务器逐一填写这些信息既不现实也容易出错。为此,仓库在 scripts 目录 提供了三类官方示例脚本,分别面向不同的采集场景:
| 脚本文件 | 适用场景 | 输出 |
|---|---|---|
| EOS_DataGenerator_SingleInstance.sql | 单个实例,在 SSMS / sqlcmd 中直接执行 | 结果集 |
| EOS_DataGenerator_LocalDiscovery.ps1 | 本机所有 SQL Server 实例(Azure VM、本地物理机或本地虚拟机) | CSV 文件 |
| EOS_DataGenerator_InputList.ps1 | 文本文件中列出的远程实例清单 | CSV 文件 |
PowerShell 脚本生成的 CSV 文件可直接用于 Azure 门户的批量注册(Bulk Register),一次上传完成多台服务器的 ESU 注册。
二、T-SQL 方案:单实例注册信息采集
当只需要采集某一个实例的注册信息时,直接在 SSMS 或 sqlcmd 中执行 EOS_DataGenerator_SingleInstance.sql 即可。
DECLARE @SystemManufacturer NVARCHAR(128), @Edition NVARCHAR(20), @HostType NVARCHAR(30), @Cores int, @SQLVersion NVARCHAR(50) DECLARE @machineinfo TABLE ([Value] NVARCHAR(256), [Data] NVARCHAR(256)) INSERT INTO @machineinfo EXEC xp_instance_regread 'HKEY_LOCAL_MACHINE','HARDWARE\DESCRIPTION\System\BIOS','SystemManufacturer'; SELECT @SystemManufacturer = [Data] FROM @machineinfo WHERE [Value] = 'SystemManufacturer'; SET @HostType = 'Physical Server' IF LOWER(@SystemManufacturer) = 'microsoft' OR LOWER(@SystemManufacturer) = 'vmware' SET @HostType = 'Virtual Machine' SELECT @Cores = hyperthread_ratio FROM sys.dm_os_sys_info; SELECT @Edition = CONVERT(NVARCHAR(20), SERVERPROPERTY('Edition')) SELECT @SQLVersion = CONVERT(NVARCHAR(50), SERVERPROPERTY('ProductVersion')) SELECT SERVERPROPERTY('ServerName') AS [name], CASE LEFT(@SQLVersion,4) WHEN '10.0' THEN '2008' WHEN '10.5' THEN '2008R2' WHEN '11.0' THEN '2012' WHEN '12.0' THEN '2014' WHEN '13.0' THEN '2016' WHEN '14.0' THEN '2017' WHEN '15.0' THEN '2019' ELSE 'Other' END AS [version], LEFT(@Edition,CHARINDEX(' ', @Edition,0)-1) AS edition, @Cores AS cores, @HostType AS hostType;脚本逐段原理
主机类型判定(hostType)脚本通过
xp_instance_regread读取注册表键HARDWARE\DESCRIPTION\System\BIOS下的SystemManufacturer值,用于判断运行环境:- 制造商为
microsoft或vmware→Virtual Machine; - 其他情况 →
Physical Server。
注意
xp_instance_regread是 SQL Server 的未文档化系统扩展存储过程,它读取的是当前实例所在机器的注册表(与xp_regread的"本机"语义在实例上下文中等价),在生产环境使用前应确认你所在组织的安全策略是否允许。- 制造商为
核心数采集(cores)通过
sys.dm_os_sys_info动态管理视图获取hyperthread_ratio字段。从源码结构看,该字段反映的是操作系统可见的逻辑处理器与物理核心的比率折算结果,脚本将其直接作为核心数上报;在启用超线程且 BIOS 配置不同的机器上,建议核对该值与实际物理核心数是否一致。版本与版本类型映射
SERVERPROPERTY('ProductVersion')返回完整产品版本号(如15.0.2000.5),脚本用LEFT(...,4)截取主版本号,映射为业务版本号:10.0→2008、10.5→2008R2、11.0→2012、12.0→2014、13.0→2016、14.0→2017、15.0→2019,其余归为Other;SERVERPROPERTY('Edition')返回版本类型(如Enterprise Edition (64-bit)),脚本通过CHARINDEX(' ', ...)截取第一个空格前的单词作为 edition 值。
实例名(name)使用
SERVERPROPERTY('ServerName'),返回的格式为机器名\实例名(默认实例则为纯机器名),与 Azure 门户注册页展示的实例标识一致。
注意:执行后请务必核对Host Type是否正确,尤其当注册表制造商信息被虚拟机模板自定义过时,手动判断可能比脚本更可靠。
三、PowerShell 方案一:本机全实例自动发现(LocalDiscovery)
当一台机器上安装了多个 SQL Server 实例(或默认实例 + 命名实例混布)时,可使用 EOS_DataGenerator_LocalDiscovery.ps1 一键发现并采集本机全部实例的信息,适用于 Azure VM、本地物理服务器和本地虚拟机三种场景。
运行方式与交互流程
在 PowerShell 中直接执行:
.\EOS_DataGenerator_LocalDiscovery.ps1脚本运行时会依次交互询问:
- CSV 输出文件名:输入文件名(自动补
.csv后缀),文件保存在脚本所在目录;留空则抛出Parameter missing: Output file; - 是否为 Azure 虚拟机(Y/N):
- 回答
Y时,脚本会继续询问Azure 订阅名称,随后自动执行Install-Module -Name Az -AllowClobber -Scope CurrentUser安装/更新 Azure PowerShell 模块、Connect-AzAccount登录,并通过Get-AzVM -Name $env:computername获取 VM 信息(订阅 ID、资源组、VM 名称、操作系统版本),以便在 CSV 中额外输出subscriptionId、resourceGroup、azureVmName、azureVmOS四个 Azure 专属字段; - 回答
N时,走本地(物理机/本地 VM)采集逻辑,CSV 只包含前 5 个核心字段。
- 回答
底层采集逻辑
- 实例发现:通过
Get-Service -DisplayName "SQL Server (*)"枚举所有 SQL Server 相关 Windows 服务,服务名中的MSSQL$前缀被移除后拼接为机器名\实例名(默认实例MSSQLSERVER退化为纯机器名)。 - 实例信息:以
Trusted_Connection=true建立System.Data.SqlClient.SqlConnection,执行SELECT SERVERPROPERTY('Edition'), SERVERPROPERTY('ProductVersion')获取版本与版本类型;CommandTimeout = 0表示不限制查询超时。 - 核心数:通过 WMI 类
Win32_Processor遍历所有物理处理器,累加NumberOfCores(注意:这里统计的是物理核心总数,与 T-SQL 方案的hyperthread_ratio口径不同,两套脚本对同一机器的 cores 值可能略有差异)。 - 主机类型判定:优先级依次为——存在
subscriptionId→Azure Virtual Machine;制造商以Microsoft或VMWare开头 →Virtual Machine;否则 →Physical Server。
输出格式
非 Azure 场景输出列:
name,version,edition,cores,hostTypeAzure 场景输出列(参考仓库示例 MyAzureVMs.csv):
name,version,edition,cores,hostType,subscriptionId,resourceGroup,azureVmName,azureVmOS脚本使用ConvertTo-Csv -NoTypeInformation生成 CSV,并通过% { $_ -Replace '"', ""}去除引号包裹,得到可直接上传的纯文本 CSV。
注意:上传 CSV 到 Azure 门户之前,务必逐行核对Host Type是否正确。
四、PowerShell 方案二:按文本清单批量采集(InputList)
当实例分散在多台机器上时,可先把实例清单写入文本文件,再用 EOS_DataGenerator_InputList.ps1 批量采集。
输入文件格式
参考 ServerInstances.txt,每行一个实例,命名实例写机器名\实例名,默认实例直接写机器名:
Server1\SQL2008 Server1\SQL2008R2 Server2\SQL2008R2 Server3\SQL2008 Server4\SQL2008 Server4运行方式
.\EOS_DataGenerator_InputList.ps1交互流程与 LocalDiscovery 类似:先输入清单文件名(文件需位于脚本同目录,脚本会用Split-Path -Parent $MyInvocation.MyCommand.Path定位脚本目录并拼接路径),再输入CSV 输出文件名。
与 LocalDiscovery 的差异
- 实例来源是
Get-Content $SQLServerList逐行读取的文本清单,而非本机服务枚举,因此可以采集远程机器上的实例; - WMI 查询(
Win32_Processor、Win32_ComputerSystem)也改为针对清单中的机器名$MachineName执行(注意:此处$MachineName取自查询结果第三列,而从脚本的 SQL 查询看该列未在 SELECT 中显式返回,实际采集时以运行环境为准); - 主机类型判定不包含Azure VM 分支(无
subscriptionId概念),仅区分Virtual Machine(Microsoft*/VMWare*制造商)与Physical Server; - 输出固定为 5 列:
name,version,edition,cores,hostType(参考 MyPhysicalServers.csv 示例)。
注意:CSV 上传前同样需要核对Host Type。
五、从 CSV 到注册:批量上传与结果核对
生成 CSV 后,在 Azure 门户的 ESU 注册页面选择"批量注册(Bulk Register)",上传 CSV 即可一次性注册清单内全部实例。注册完成后,可在 ESU 实例清单(Estate)页面核对每条记录的 name、version、edition、cores、hostType 是否正确,确认无误后即可进入安全更新下载环节。
常见排查要点
- 连接失败:InputList 脚本对无法连接的实例会抛出
Could not connect to <ServerName>;确认远程实例已开启 TCP/IP、Windows 防火墙放行 1433 端口,且当前账号具备该实例的登录权限; - cores 口径差异:T-SQL 脚本(
hyperthread_ratio)与 PowerShell 脚本(Win32_Processor.NumberOfCores)统计口径不同,同一实例两个脚本输出可能不同,建议以实际物理核心数为准核对; - Host Type 误判:虚拟化平台未被脚本识别(如 KVM、Hyper-V 的制造商值不在
Microsoft/VMWare之列)时会被归为Physical Server,需人工修正后再上传。
六、适用范围与脚本声明
本模块的脚本以 ESU 注册信息生成器(Data Generator)形式提供,官方说明见 scripts.md,其注册信息字段约定与 Azure 门户的 ESU 批量注册入口一一对应。所有脚本均为示例性质:不隶属任何微软标准支持计划,按"AS IS"提供,不含任何明示或默示担保(包括适销性与特定用途适用性担保),使用风险由使用者自行承担;实际生产使用前,请结合你所在环境的网络、权限与合规要求进行适配与验证。
本模块页面正文内容已迁移至 SQL Docs 的 SQL Server 扩展安全更新文档,本文所介绍的 ESU 注册信息生成示例脚本仍可通过本仓库的 scripts 目录 获取并使用。
- 示例工程
- 数据库
- 教程
- 后端
【免费下载链接】sql-server-samples
Azure Data SQL Samples - Official Microsoft GitHub Repository containing code samples for SQL Server, Azure SQL, Azure Synapse, and Azure SQL Edge
相关推荐
SQL Server 扩展安全更新(ESU)注册信息采集脚本实战指南:T-SQL 单实例查询与 PowerShell 批量发现
SQL Server 扩展安全更新(ESU)注册信息采集脚本实战指南:T SQL 单实例查询与 PowerShell 批量发现 本文围绕 sql server
示例工程数据库教程后端SQL Server 内存数据库 T-SQL 脚本实战指南:在 SQL Server 与 Azure SQL Database 中启用 In-Memory OLTP 与内存分析
SQL Server 内存数据库 T SQL 脚本实战指南:在 SQL Server 与 Azure SQL Database 中启用 In Memory OL
示例工程数据库教程后端WideWorldImporters 行级安全性(Row-Level Security)实战指南:基于 SQL Server 2016+ 与 Azure SQL Database 的 T-SQL 演示
WideWorldImporters 行级安全性(Row Level Security)实战指南:基于 SQL Server 2016+ 与 Azure SQL
示例工程数据库教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考