SQL Server 是企业级关系型数据库的常青树,广泛应用于金融、制造、零售等行业。作为 DBA 或运维工程师,日常需要频繁执行实例巡检、数据库备份、性能监控、空间分析等操作。传统做法是通过 SQL Server Management Studio(SSMS)手工完成,但面对多实例、多数据库的环境,图形界面操作效率低下且容易遗漏。PowerShell 凭借其强大的自动化能力和丰富的 SQL Server 模块生态,让这些任务变得可编程、可复用、可调度。
微软提供的 SqlServer 模块封装了 SQL Server Management Objects(SMO)库,几乎覆盖了 SSMS 能做的所有事情。从查询实例信息、管理数据库文件,到执行 T-SQL、配置安全策略,都可以通过 PowerShell 脚本完成。结合 Windows 任务计划或 SQL Agent Job,还能实现定时自动巡检和告警推送,大幅减轻 DBA 的重复劳动负担。
# 简单查询 $results = Invoke-Sqlcmd-ServerInstance$serverInstance-Database$database-Query@" SELECT TOP 10 name AS 表名, rows AS 行数, CAST(reserved AS FLOAT) / 1024 AS 已用MB FROM sys.tables t INNER JOIN sys.partitions p ON t.object_id = p.object_id ORDER BY rows DESC "@
$results | Format-Table-AutoSize
# 带参数的查询(防止 SQL 注入) $params = @{ ServerInstance = $serverInstance Database = $database Query = "SELECT * FROM Users WHERE Department = @dept AND IsActive = 1" Variable = @( (New-Object Microsoft.Data.SqlClient.SqlParameter('@dept', 'Engineering')) ) }
Write-Host"========== SQL Server 性能报告 =========="-ForegroundColor Cyan
# 1. 缓冲池使用率 $bufferPool = Invoke-Sqlcmd-ServerInstance$ServerInstance-Query@" SELECT CAST(COUNT(*) * 8 / 1024.0 AS DECIMAL(10,2)) AS 总缓存MB, CAST(SUM(CASE WHEN is_modified = 1 THEN 8 ELSE 0 END) / 1024.0 AS DECIMAL(10,2)) AS 脏页MB, CAST(SUM(CASE WHEN is_modified = 0 THEN 8 ELSE 0 END) / 1024.0 AS DECIMAL(10,2)) AS 干净页MB FROM sys.dm_os_buffer_descriptors "@ Write-Host"`n缓冲池:总 $($bufferPool.总缓存MB) MB, 脏页 $($bufferPool.脏页MB) MB"
# 2. Top 10 慢查询 $slowQueries = Invoke-Sqlcmd-ServerInstance$ServerInstance-Query@" SELECT TOP 10 SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS 查询语句, qs.execution_count AS 执行次数, CAST(qs.total_elapsed_time / 1000000.0 AS DECIMAL(10,2)) AS 总耗时秒, CAST(qs.total_elapsed_time / 1000000.0 / qs.execution_count AS DECIMAL(10,4)) AS 平均耗时秒, qs.total_logical_reads AS 逻辑读取次数 FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY qs.total_elapsed_time DESC "@