適用於: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 預設 密碼原則。 依預設,密碼長度必須至少有 8 個字元,並包含下列四種字元組合中其中三種組合的字元:大寫字母、小寫字母、以 10 為底數的數字以及符號。 密碼長度最多可達 128 個字元。 盡可能使用長且複雜的密碼。
USE [master]; GO CREATE LOGIN [assessmentLogin] WITH PASSWORD = N'<password>'; GRANT CONTROL SERVER TO [assessmentLogin]; GOCONTROL 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
}
}
注意
當您在受信任的環境中執行此指令碼時,如果遇到 prelogin 握手錯誤,請在程式碼中 $hostName、Get-SqlInstance 和 $serverName 這幾行的命令加入 -TrustServerCertificate 旗標。
執行評定
確保
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。