Set up baselines for vulnerability assessments on Azure SQL databases

This PowerShell script sets up baselines based on latest vulnerability assessment scan results for all databases in an Azure SQL Server.

This sample requires Azure PowerShell Az 1.0 or later. Run Get-Module -ListAvailable Az to see which versions are installed. If you need to install, see Install Azure PowerShell module.

Run Connect-AzAccount to sign in to Azure.

If you don't have an Azure subscription, create an Azure free account before you begin.

Sample script

Note

We recommend that you use the Azure Az PowerShell module to interact with Azure. See Install Azure PowerShell to get started. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.

<#
.SYNOPSIS
    This script sets the results of the last successful scan as baseline for each database under the selected Azure SQL Server.

.DESCRIPTION
    This script check if the selected Azure SQL Server uses Vulnerability Assessment Express Configuration, iterates through all user databases under a server and sets the latest scan results as a baseline.

#>


$SubscriptionId     = "<subscriptionid>"                         # The Subscription id that the server belongs to.
$ResourceGroupName  = "<resource group>"                         # The Resource Group that the server belongs to.
$ServerName         = "<server name>"                            # The SQL server name that we want to apply the new SQL Vulnerability Assessment policy to (short name, without suffix).
$APIVersion         = "2022-05-01-preview"




###### New SQL Vulnerability Assessment Commands ######
#######################################################


function GetExpressConfigurationStatus($SubscriptionId, $ResourceGroupName, $ServerName){
    $Uri  = "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Sql/servers/$ServerName/sqlVulnerabilityAssessments/Default?api-version=" + $APIVersion
    SendRestRequest -Method "GET" -Uri $Uri
}


function SetLastScanAsBaselineOnSystemDatabase($SubscriptionId, $ResourceGroupName, $ServerName){
    $Uri  = "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Sql/servers/$ServerName/sqlVulnerabilityAssessments/default/baselines/default?systemDatabaseName=master&api-version=" + $APIVersion
    $Body = "{properties: {latestScan: true,results: {}}}"
    SendRestRequest -Method "PUT" -Uri $Uri -Body $Body
}

function SetLastScanAsBaselineOnUserDatabase($SubscriptionId, $ResourceGroupName, $ServerName, $DatabaseName){
    $Uri  = "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Sql/servers/$ServerName/databases/$DatabaseName/sqlVulnerabilityAssessments/default/baselines/default?api-version=" + $APIVersion
    $Body = "{properties: {latestScan: true,results: {}}}"
    SendRestRequest -Method "PUT" -Uri $Uri -Body $Body
}


function SendRestRequest(
    [Parameter(Mandatory=$True)]
    [string] $Method, 
    [Parameter(Mandatory=$True)]
    [string] $Uri, 
    [parameter( Mandatory=$false )]
    [string] $Body = "DEFAULT")
{  
    $AccessToken = Get-AzAccessToken
    $Token = "Bearer $($AccessToken.Token)"

    $headers = @{
        'Authorization' = $Token
    }

    $Params = @{
         Method = $Method
         Uri = $Uri
         Headers = $headers
         ContentType = "application/json"
    }

    if(!($Body -eq "DEFAULT"))
    {
      $Params = @{
         Method = $Method
         Uri = $Uri
         Body = $Body
         Headers = $headers
         ContentType = "application/json"
         }
    }
   
    Invoke-RestMethod @Params
}

#######################################################



# Connect
Connect-AzAccount
Set-AzContext $SubscriptionId

# Check if Express Configuration is enabled
$ECState = (GetExpressConfigurationStatus -SubscriptionId $SubscriptionId -ResourceGroupName $ResourceGroupName -ServerName $ServerName).properties.State

Write-Host "Express Configuration status: " $ECState

if ($ECState -eq "Enabled")
{
    # Get list of databases
    $databases = Get-AzSqlDatabase -ResourceGroupName $ResourceGroupName -ServerName $ServerName | where {$_.DatabaseName -ne "master"}

    # Set latest scan results as baseline on all user databases
    foreach ($database in $Databases)
    {
        Write-Host "Set baseline on database: '$($database.DatabaseName)'"
        SetLastScanAsBaselineOnUserDatabase -SubscriptionId $SubscriptionId -ResourceGroupName $ResourceGroupName -ServerName $ServerName -DatabaseName $database.DatabaseName    
    }

    Write-Host "Set baseline on 'master' database"
    SetLastScanAsBaselineOnSystemDatabase -SubscriptionId $SubscriptionId -ResourceGroupName $ResourceGroupName -ServerName $ServerName
}
else
{
    Write-Host "The specified server does not have VA Express Configuration enabled therefore bulk baseline operations were not performed."
    return
}

Next steps

For more information on the Azure PowerShell module, see Azure PowerShell documentation.