Auditing Azure Services for TLS 1.2

PivotPoint July 17, 2025

Audit Azure Resources for TLS 1.2 Compliance with PowerShell

Image uploaded by pivotpoint

Microsoft is ending support for TLS versions below 1.2 across Azure services by August 31, 2025. If you're managing cloud infrastructure in Azure, it's important to identify and remediate any services that are still using TLS 1.0 or TLS 1.1.

At PivotPoint, we created a PowerShell script to automate this process by scanning all subscriptions you have access to and reporting which Azure resources may need attention.

Read Microsoft’s official announcement


Why TLS 1.2 Matters

TLS (Transport Layer Security) is the protocol used to secure communication between clients and services. Microsoft is retiring older versions (1.0 and 1.1) due to security vulnerabilities.

Failing to update your resources could result in:

  • Disrupted service connectivity
  • Broken integrations with APIs or applications
  • Security compliance violations

Proactively auditing your Azure environment ensures you're ready for the upcoming changes.


What the Script Does

This PowerShell script performs an audit across all Azure subscriptions available to your account. It checks a variety of resource types known to support TLS configurations, including:

  • Storage Accounts
  • App Services
  • SQL Servers
  • Application Gateways
  • Key Vaults
  • API Management Services
  • Front Door (classic)

Any resource found to be using a TLS version below 1.2 (or with insecure configurations) is logged to a CSV report for easy analysis and follow-up.


How to Use the Script

1. Install the Azure PowerShell Module (if not already installed)

Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force

2. Log in to Azure

Connect-AzAccount

3. Run the Script

Before running, update the $exportPath value to a valid location on your machine where you'd like the CSV report to be saved.

# Login to Azure
Connect-AzAccount
$subscriptions = Get-AzSubscription

# Collect insecure findings
$results = @()

foreach ($sub in $subscriptions) {
    Set-AzContext -SubscriptionId $sub.Id
    $subName = $sub.Name
    Write-Host "Scanning subscription: $subName" -ForegroundColor Cyan

    # 1. Storage Accounts
    Get-AzStorageAccount | Where-Object {
        $_.MinimumTlsVersion -ne "TLS1_2"
    } | ForEach-Object {
        $results += [PSCustomObject]@{
            ResourceType   = "Storage Account"
            Name           = $_.StorageAccountName
            ResourceGroup  = $_.ResourceGroupName
            TLSVersion     = $_.MinimumTlsVersion
            Subscription   = $subName
            Notes          = "Min TLS version is less than 1.2"
        }
    }

    # 2. App Services
    Get-AzWebApp | ForEach-Object {
        $config = Get-AzWebApp -ResourceGroupName $_.ResourceGroup -Name $_.Name
        if ($config.SiteConfig.MinTlsVersion -ne "1.2") {
            $results += [PSCustomObject]@{
                ResourceType   = "App Service"
                Name           = $_.Name
                ResourceGroup  = $_.ResourceGroup
                TLSVersion     = $config.SiteConfig.MinTlsVersion
                Subscription   = $subName
                Notes          = "Min TLS version is less than 1.2"
            }
        }
    }

    # 3. SQL Servers
    Get-AzSqlServer | Where-Object {
        $_.MinimalTlsVersion -ne "1.2"
    } | ForEach-Object {
        $results += [PSCustomObject]@{
            ResourceType   = "SQL Server"
            Name           = $_.ServerName
            ResourceGroup  = $_.ResourceGroupName
            TLSVersion     = $_.MinimalTlsVersion
            Subscription   = $subName
            Notes          = "Min TLS version is less than 1.2"
        }
    }

    # 4. Application Gateways
    Get-AzApplicationGateway | ForEach-Object {
        $gw = $_
        $sslPolicy = $gw.SslPolicy
        $minTls = $sslPolicy.MinProtocolVersion
        $policyType = $sslPolicy.PolicyType
        $policyName = $sslPolicy.PolicyName

        $isInsecure =
            (-not $sslPolicy) -or
            ($policyType -eq "Custom" -and $minTls -ne "TLSv1_2") -or
            ($policyType -eq "Predefined" -and $policyName -notin @(
                "AppGwSslPolicy20170401S", 
                "AppGwSslPolicy20170401", 
                "AppGwSslPolicy20220101"))

        if ($isInsecure) {
            $results += [PSCustomObject]@{
                ResourceType   = "Application Gateway"
                Name           = $gw.Name
                ResourceGroup  = $gw.ResourceGroupName
                TLSVersion     = $minTls
                Subscription   = $subName
                Notes          = if (-not $sslPolicy) { 
                                    "No SSL policy set (potentially insecure)" 
                                 } elseif ($policyType -eq "Custom") { 
                                    "Custom policy with TLS <$($minTls)" 
                                 } else {
                                    "Predefined policy: $policyName (known not secure)"
                                 }
            }
        }
    }

    # 5. Key Vaults
    Get-AzKeyVault | Where-Object {
        $_.EnablePurgeProtection -ne $true -or $_.EnableSoftDelete -ne $true
    } | ForEach-Object {
        $results += [PSCustomObject]@{
            ResourceType   = "Key Vault"
            Name           = $_.VaultName
            ResourceGroup  = $_.ResourceGroupName
            TLSVersion     = "N/A"
            Subscription   = $subName
            Notes          = "Old or insecure: missing purge protection or soft delete"
        }
    }

    # 6. API Management
    Get-AzApiManagement | ForEach-Object {
        if ($_.TlsVersion -ne "1.2") {
            $results += [PSCustomObject]@{
                ResourceType   = "API Management"
                Name           = $_.Name
                ResourceGroup  = $_.ResourceGroupName
                TLSVersion     = $_.TlsVersion
                Subscription   = $subName
                Notes          = "TLS version is less than 1.2"
            }
        }
    }

    # 7. Front Doors
    Get-AzFrontDoor | ForEach-Object {
        if ($_.FrontendEndpoints) {
            foreach ($fe in $_.FrontendEndpoints) {
                if ($fe.CustomHttpsConfiguration.MinimumTlsVersion -ne "1.2") {
                    $results += [PSCustomObject]@{
                        ResourceType   = "Front Door"
                        Name           = $_.Name + " / " + $fe.Name
                        ResourceGroup  = $_.ResourceGroupName
                        TLSVersion     = $fe.CustomHttpsConfiguration.MinimumTlsVersion
                        Subscription   = $subName
                        Notes          = "Minimum TLS version for frontend is less than 1.2"
                    }
                }
            }
        }
    }
}

# Export results (update path below before running)
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
$exportPath = "C:\Users\YourUsername\Azure_TLS_Report_$timestamp.csv"  # <- Update this path
$results | Sort-Object ResourceType, Subscription, Name | Export-Csv -NoTypeInformation -Path $exportPath

Write-Host "TLS audit complete. CSV saved to: $exportPath" -ForegroundColor Green

Review the Output

Once complete, you'll have a CSV file with all non-compliant resources grouped by:

  • Resource Type
  • Resource Name
  • Resource Group
  • Subscription
  • TLS Version
  • Notes

Next Steps

After identifying affected resources, plan your updates:

  • Update TLS settings to 1.2 or higher
  • Apply secure SSL policies to gateways
  • Enable purge protection and soft delete for Key Vaults
  • Monitor new deployments for secure defaults

For help implementing these changes or scaling compliance across large environments, get in touch with us.

Other recent posts