适用于:Linux 上的 SQL Server
SQL 评估 API 提供了评估 SQL Server 配置的最佳实践机制。 该 API 附带一个规则集,其中包含 SQL Server 团队建议的最佳做法。 随着新版本的发布,此规则集得到增强。 对于确保 SQL Server 配置符合建议的最佳做法,它非常有用。
Microsoft发布的规则集可在GitHub上获取。 可以在示例存储库中查看完整规则集。
在本文中,使用PowerShell运行Linux 上的 SQL Server及容器的SQL评估API。
先决条件
安装 PowerShell 库中的
SqlServerPowerShell 模块,并以mssql用户身份运行。su mssql -c "/usr/bin/pwsh -Command Install-Module SqlServer"
设置评估
SQL 评估 API 提供 JSON 格式的输出。 要配置SQL评估API,请完成以下步骤:
在你想评估的实例中,创建一个使用 SQL 认证的 SQL Server 评估登录名。 请使用以下 Transact-SQL 脚本创建一个登录名和强密码。 密码应遵循 SQL Server 默认密码策略。 默认情况下,密码必须为至少八个字符且包含以下四种字符中的三种:大写字母、小写字母、十进制数字、符号。 密码可最长为 128 个字符。 使用的密码应尽可能长,尽可能复杂。
USE [master]; GO CREATE LOGIN [assessmentLogin] WITH PASSWORD = N'<password>'; GRANT CONTROL SERVER TO [assessmentLogin]; GO这个
CONTROL SERVER权限适用于大多数评估。 不过,有些评估可能需要系统 管理员 权限。 如果你不执行这些评估,请使用CONTROL SERVER权限。存储连接实例的凭据。 用你之前用过的密码替换
<password>。echo "assessmentLogin" > /var/opt/mssql/secrets/assessment echo "<password>" >> /var/opt/mssql/secrets/assessment通过确保只有
mssql用户可以访问这些凭据,来保护新的评估凭据。chmod 600 /var/opt/mssql/secrets/assessment chown mssql:mssql /var/opt/mssql/secrets/assessment
下载评估脚本
以下示例脚本将调用你在前述步骤中创建的凭证调用 SQL 评估 API。 脚本在 /var/opt/mssql/log/assessments 目录中生成 JSON 输出。
注意
SQL 评估 API 还可以生成 CSV 和 XML 格式的输出。
可从 GitHub 下载该脚本。
可以将此文件另存为 /opt/mssql/bin/runassessment.ps1。
[CmdletBinding()] param ()
$Error.Clear()
# Create output directory if not exists
$outDir = '/var/opt/mssql/log/assessments'
if (-not ( Test-Path $outDir )) { mkdir $outDir }
$outPath = Join-Path $outDir 'assessment-latest'
$errorPath = Join-Path $outDir 'assessment-latest-errors'
if ( Test-Path $errorPath ) { remove-item $errorPath }
function ConvertTo-LogOutput {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true)]
$input
)
process {
switch ($input) {
{ $_ -is [System.Management.Automation.WarningRecord] } {
$result = @{
'TimeStamp' = $(Get-Date).ToString("O");
'Warning' = $_.Message
}
}
default {
$result = @{
'TimeStamp' = $input.TimeStamp;
'Severity' = $input.Severity;
'TargetType' = $input.TargetType;
'ServerName' = $serverName;
'HostName' = $hostName;
'TargetName' = $input.TargetObject.Name;
'TargetPath' = $input.TargetPath;
'CheckId' = $input.Check.Id;
'CheckName' = $input.Check.DisplayName;
'Message' = $input.Message;
'RulesetName' = $input.Check.OriginName;
'RulesetVersion' = $input.Check.OriginVersion.ToString();
'HelpLink' = $input.HelpLink
}
if ( $input.TargetType -eq 'Database') {
$result['AvailabilityGroup'] = $input.TargetObject.AvailabilityGroupName
}
}
}
$result
}
}
function Get-TargetsRecursive {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline = $true)]
[Microsoft.SqlServer.Management.Smo.Server] $server
)
$server
$server.Databases
}
function Get-ConfSetting {
[CmdletBinding()]
param (
$confFile,
$section,
$name,
$defaultValue = $null
)
$inSection = $false
switch -regex -file $confFile {
"^\s*\[\s*(.+?)\s*\]" {
$inSection = $matches[1] -eq $section
}
"^\s*$($name)\s*=\s*(.+?)\s*$" {
if ($inSection) {
return $matches[1]
}
}
}
return $defaultValue
}
try {
Write-Verbose "Acquiring credentials"
$login, $pwd = Get-Content '/var/opt/mssql/secrets/assessment' -Encoding UTF8NoBOM -TotalCount 2
$securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($login, $securePassword)
$securePassword.MakeReadOnly()
Write-Verbose "Acquired credentials"
$serverInstance = '.'
if (Test-Path /var/opt/mssql/mssql.conf) {
$port = Get-ConfSetting /var/opt/mssql/mssql.conf network tcpport
if (-not [string]::IsNullOrWhiteSpace($port)) {
Write-Verbose "Using port $($port)"
$serverInstance = "$($serverInstance),$($port)"
}
}
# IMPORTANT: If the script is run in trusted environments and there is a prelogin handshake error,
# add -TrustServerCertificate flag in the commands for $serverName, $hostName and Get-SqlInstance lines below.
$serverName = (Invoke-SqlCmd -ServerInstance $serverInstance -Credential $credential -Query "SELECT @@SERVERNAME")[0]
$hostName = (Invoke-SqlCmd -ServerInstance $serverInstance -Credential $credential -Query "SELECT HOST_NAME()")[0]
# Invoke assessment and store results.
# Replace 'ConvertTo-Json' with 'ConvertTo-Csv' to change output format.
# Available output formats: JSON, CSV, XML.
# Encoding parameter is optional.
Get-SqlInstance -ServerInstance $serverInstance -Credential $credential -ErrorAction Stop
| Get-TargetsRecursive
| ForEach-Object { Write-Verbose "Invoke assessment on $($_.Urn)"; $_ }
| Invoke-SqlAssessment 3>&1
| ConvertTo-LogOutput
| ConvertTo-Json -AsArray
| Set-Content $outPath -Encoding UTF8NoBOM
}
finally {
Write-Verbose "Error count: $($Error.Count)"
if ($Error) {
$Error
| ForEach-Object { @{ 'TimeStamp' = $(Get-Date).ToString("O"); 'Message' = $_.ToString() } }
| ConvertTo-Json -AsArray
| Set-Content $errorPath -Encoding UTF8NoBOM
}
}
注意
当你在可信环境中运行此脚本时,如果遇到预登录握手错误,请在代码中 -TrustServerCertificate、$hostName 和 Get-SqlInstance 行的命令中添加 $serverName 标志。
执行评估
确保
mssql用户拥有脚本并能执行。chown mssql:mssql /opt/mssql/bin/runassessment.ps1 chmod 700 /opt/mssql/bin/runassessment.ps1创建一个日志文件夹,并赋予
mssql用户该文件夹的权限。mkdir /var/opt/mssql/log/assessments/ chown mssql:mssql /var/opt/mssql/log/assessments/ chmod 0700 /var/opt/mssql/log/assessments/你现在可以以
mssql用户身份创建你的第一个评估。 以该用户身份运行评估会更安全,尤其是在你之后通过cron或systemd自动运行评估时。su mssql -c "pwsh -File /opt/mssql/bin/runassessment.ps1"命令完成后,它会生成 JSON 格式的输出。 你可以将这个输出与任何支持解析JSON文件的工具一起使用,包括Visual Studio Code。