Audit Azure Resources for TLS 1.2 Compliance with PowerShell
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.