Utiliser l’API SQL Assessment pour SQL Server sur Linux

S’applique à :SQL Server sur Linux

L’API d’évaluation SQL fournit un mécanisme pour évaluer la configuration de SQL Server afin d’identifier les meilleures pratiques. L’API est fournie avec un ensemble de règles contenant les bonnes pratiques recommandées par l’équipe SQL Server. Cet ensemble de règles est amélioré à chaque publication d’une nouvelle version. Il est utile pour vérifier si votre configuration SQL Server est conforme aux bonnes pratiques recommandées.

L’ensemble de règles fourni par Microsoft est disponible sur GitHub. Vous pouvez voir l’ensemble de règles complet dans le dépôt d‘exemples.

Dans cet article, utilisez PowerShell pour exécuter l’API d’évaluation SQL pour SQL Server sur Linux et conteneurs.

Prérequis

  1. Vérifiez que vous avez installé PowerShell sur Linux.

  2. Installez le module PowerShell SqlServer depuis la PowerShell Gallery, en l’exécutant en tant qu’utilisateur mssql.

    su mssql -c "/usr/bin/pwsh -Command Install-Module SqlServer"
    

Configurer l’évaluation

L’API d’évaluation SQL fournit des sorties au format JSON. Pour configurer l’API d’évaluation SQL, suivez les étapes suivantes :

  1. Créez un identifiant pour les évaluations SQL Server en utilisant l’authentification SQL dans l’instance que vous souhaitez évaluer. Utilisez le script de Transact-SQL suivant pour créer une connexion et un mot de passe fort. Votre mot de passe doit suivre la politique de mot de passe par défaut de SQL Server. Par défaut, le mot de passe doit avoir au moins huit caractères appartenant à trois des quatre groupes suivants : lettres majuscules, lettres minuscules, chiffres de base 10 et symboles. Les mots de passe peuvent comporter jusqu'à 128 caractères. Utilisez des mots de passe aussi longs et complexes que possible.

    USE [master];
    GO
    
    CREATE LOGIN [assessmentLogin]
        WITH PASSWORD = N'<password>';
    
    GRANT CONTROL SERVER TO [assessmentLogin];
    GO
    

    L’autorisation CONTROL SERVER fonctionne pour la plupart des évaluations. Cependant, quelques évaluations peuvent nécessiter des privilèges d’administrateur système . Si vous n’exécutez pas ces évaluations, utilisez les CONTROL SERVER autorisations.

  2. Stockez les identifiants pour la connexion à l’instance. Remplacez-le <password> par le mot de passe que vous avez utilisé à l’étape précédente.

    echo "assessmentLogin" > /var/opt/mssql/secrets/assessment
    echo "<password>" >> /var/opt/mssql/secrets/assessment
    
  3. Sécurisez les identifiants de la nouvelle évaluation en veillant à ce que seul l’utilisateur mssql puisse y accéder.

    chmod 600 /var/opt/mssql/secrets/assessment
    chown mssql:mssql /var/opt/mssql/secrets/assessment
    

Télécharger le script d’évaluation

Le script d’exemple suivant appelle l’API d’évaluation SQL en utilisant les identifiants que vous avez créés dans les étapes précédentes. Le script génère une sortie JSON dans le /var/opt/mssql/log/assessments répertoire.

Remarque

L’API SQL Assessment peut également générer une sortie aux formats CSV et XML.

Ce script peut être téléchargé à partir de GitHub.

Vous pouvez enregistrer ce fichier en tant que /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
    }
}

Remarque

Lorsque vous exécutez ce script dans des environnements de confiance et que vous obtenez une erreur de négociation préalable à la connexion, ajoutez l’option -TrustServerCertificate aux commandes des lignes $serverName, $hostName et Get-SqlInstance dans le code.

Exécuter l’évaluation

  1. Assurez-vous que l’utilisateur mssql possède le script et peut l’exécuter.

    chown mssql:mssql /opt/mssql/bin/runassessment.ps1
    chmod 700 /opt/mssql/bin/runassessment.ps1
    
  2. Créez un dossier journal et donnez les permissions à l’utilisateur mssql pour ce dossier.

    mkdir /var/opt/mssql/log/assessments/
    chown mssql:mssql /var/opt/mssql/log/assessments/
    chmod 0700 /var/opt/mssql/log/assessments/
    
  3. Vous pouvez désormais créer votre première évaluation en tant qu’utilisateur mssql . Effectuer des évaluations en tant qu’utilisateur est plus sécurisé, surtout lorsque vous effectuez automatiquement des évaluations ultérieures via cron ou systemd.

    su mssql -c "pwsh -File /opt/mssql/bin/runassessment.ps1"
    
  4. Lorsque la commande se termine, elle crée la sortie au format JSON. Vous pouvez utiliser cette sortie avec n’importe quel outil qui supporte l’analyse des fichiers JSON, y compris Visual Studio Code.