Uso de SQL Assessment API para SQL Server en Linux

Se aplica a:SQL Server en Linux

La API de Evaluación SQL proporciona un mecanismo para evaluar la configuración de SQL Server en busca de mejores prácticas. La API se entrega con un conjunto de reglas que contiene los procedimientos recomendados por el equipo de SQL Server. Este conjunto de reglas se ha mejorado con el lanzamiento de nuevas versiones. Es útil para asegurarse de que la configuración de SQL Server esté en consonancia con los procedimientos recomendados.

El conjunto de reglas lanzado por Microsoft está disponible en GitHub. Puede ver todo el conjunto de reglas en el repositorio de ejemplos.

En este artículo, utiliza PowerShell para ejecutar la API de Evaluación SQL para SQL Server en Linux y contenedores.

Requisitos previos

  1. Asegúrese de que instala PowerShell en Linux.

  2. Instale el módulo de PowerShell SqlServer desde Galería de PowerShell, ejecutando como el usuario mssql.

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

Configuración de la valoración

La API de Evaluación SQL proporciona salida en formato JSON. Para configurar la API de Evaluación SQL, complete los siguientes pasos:

  1. Crea un inicio de sesión para las evaluaciones de SQL Server usando autenticación SQL en la instancia que quieres evaluar. Utiliza el siguiente script Transact-SQL para crear un inicio de sesión y una contraseña fuerte. La contraseña debe seguir la directiva de contraseña predeterminada de SQL Server. De forma predeterminada, la contraseña debe tener al menos ocho caracteres y contener caracteres de tres de los siguientes cuatro conjuntos: mayúsculas, minúsculas, dígitos en base 10 y símbolos. Las contraseñas pueden tener hasta 128 caracteres. Use contraseñas lo más largas y complejas posible.

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

    El permiso CONTROL SERVER sirve para la mayoría de las evaluaciones. Sin embargo, algunas evaluaciones pueden requerir privilegios de administrador de sistemas . Si no estás ejecutando esas evaluaciones, utiliza los permisos de CONTROL SERVER.

  2. Guarda las credenciales para conectarte a la instancia. Sustituye <password> por la contraseña que usaste en el paso anterior.

    echo "assessmentLogin" > /var/opt/mssql/secrets/assessment
    echo "<password>" >> /var/opt/mssql/secrets/assessment
    
  3. Para proteger las nuevas credenciales de valoración, asegúrese de que solo el usuario mssql pueda acceder a las credenciales.

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

Descarga del script de valoración

El siguiente script de ejemplo llama a la API de Evaluación SQL usando las credenciales que creaste en los pasos anteriores. El script genera salida JSON en el /var/opt/mssql/log/assessments directorio.

Nota:

SQL Assessment API también puede generar resultados en formatos CSV y XML.

El script está disponible para su descarga desde GitHub.

Puede guardar este archivo como /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
    }
}

Nota:

Cuando ejecutes este script en entornos de confianza y se produzca un error de handshake previo al inicio de sesión, añade el indicador -TrustServerCertificate en los comandos de las líneas $serverName, $hostName y Get-SqlInstance del código.

Ejecución de la valoración

  1. Asegúrate de que el mssql usuario sea dueño del script y pueda ejecutarlo.

    chown mssql:mssql /opt/mssql/bin/runassessment.ps1
    chmod 700 /opt/mssql/bin/runassessment.ps1
    
  2. Crea una carpeta de registro y da permisos al mssql usuario para la carpeta.

    mkdir /var/opt/mssql/log/assessments/
    chown mssql:mssql /var/opt/mssql/log/assessments/
    chmod 0700 /var/opt/mssql/log/assessments/
    
  3. Ahora puedes crear tu primera evaluación como mssql usuario. Realizar evaluaciones con este usuario es más seguro, especialmente cuando ejecutas evaluaciones posteriores automáticamente a través de cron o systemd.

    su mssql -c "pwsh -File /opt/mssql/bin/runassessment.ps1"
    
  4. Cuando termina el comando, crea la salida en formato JSON. Puedes usar esta salida con cualquier herramienta que soporte análisis de archivos JSON, incluido Visual Studio Code.