Azure’s PowerShell Nightmare: Why Outdated Runtimes Are a Security Risk (And How to Fix It) + Video

Listen to this Post

Featured Image

Introduction

Azure Automation accounts and Function apps currently lock users into PowerShell 7.4, despite version 7.5 being available for 18 months and 7.6 for several months. This runtime stagnation not only frustrates developers but also creates a hidden attack surface—unpatched vulnerabilities in older PowerShell versions can be exploited by adversaries to compromise automation workflows and serverless functions.

Learning Objectives

  • Identify the security risks of using deprecated or outdated PowerShell runtimes in Azure cloud services.
  • Apply Azure CLI, PowerShell, and ARM templates to audit, remediate, and work around runtime version limitations.
  • Implement proactive hardening measures including hybrid workers, custom containers, and Azure Policy to prevent runtime‑driven vulnerabilities.

You Should Know

1. The PowerShell Version Gap: Security Implications

PowerShell 7.4 stopped receiving security updates after the release of 7.5 (and later 7.6). Unpatched CVEs—such as remote code execution flaws in `Invoke-Expression` handling or JEA constraint bypasses—remain exploitable in any Azure Automation runbook or Function app stuck on 7.4. Attackers who compromise a low‑privileged runbook could pivot to lateral movement or data exfiltration.

Step‑by‑step: Check your Azure Automation runtime version

 Log into Azure
Connect-AzAccount

List all Automation accounts with their PowerShell runtime
Get-AzAutomationAccount | ForEach-Object {
$account = $_
Get-AzAutomationRunbook -ResourceGroupName $account.ResourceGroupName -AutomationAccountName $account.AutomationAccountName |
Select-Object Name, @{N='RuntimeVersion';E={$_.Properties.RuntimeEnvironment?.Runtime?.Version}}
}

Alternatively, use Azure CLI:

az automation account list --query "[].{name:name, rg:resourceGroup, runtime:runtimeEnvironment}"

2. Auditing Your Entire Environment for Outdated Runtimes

A full inventory prevents blind spots. Use Azure Resource Graph to scan all subscriptions at once.

Step‑by‑step: Run a cross‑subscription audit

// Azure Resource Graph query
resources
| where type =~ 'microsoft.automation/automationaccounts'
| extend runtimes = properties.runtimeEnvironments
| mv-expand runtimes
| where runtimes.properties.runtime.version == '7.4'
| project subscriptionId, resourceGroup, name, currentVersion = runtimes.properties.runtime.version

Export results to CSV for compliance tracking:

Search-AzGraph -Query "<query above>" | Export-Csv -Path "PS74_Accounts.csv" -NoTypeInformation

3. Workaround: Hybrid Runbook Workers with Custom PowerShell

When Azure refuses to update, run your workflows on infrastructure you control. Hybrid Runbook Workers can run any PowerShell version installed on the host VM.

Step‑by‑step: Deploy a Hybrid Worker with PowerShell 7.6

  1. Provision a Windows Server 2022 VM in Azure.

2. Install PowerShell 7.6 (download from GitHub releases):

 Run as Administrator
$url = "https://github.com/PowerShell/PowerShell/releases/download/v7.6.0/PowerShell-7.6.0-win-x64.msi"
$msi = "$env:TEMP\pwsh.msi"
Invoke-WebRequest -Uri $url -OutFile $msi
msiexec /i $msi /quiet ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1

3. Install and register the Hybrid Worker extension:

az extension add --name automation
az automation hybrid-worker create --resource-group MyRG --automation-account MyAA --name MyWorker --vm-name MyVM --resource-group-vm MyRG-VM

4. Target the hybrid worker in your runbook:

 Inside runbook
$hybridWorkerGroup = "MyWorker"
 All commands will execute on that worker using its local PowerShell 7.6
  1. Handling VM SKU Unavailability – Cloud Capacity Crisis
    Jonathan Hope’s complaint about SKU shortages is real: Azure regions run out of popular VM series (e.g., Dv5, Ev5) during peak demand. This breaks deployment pipelines and disaster recovery plans.

Step‑by‑step: Programmatically find available SKUs and failover

 List available SKUs in a region
az vm list-skus --location eastus --size Standard_D --all --output table

Try alternative series with similar specs (e.g., Ddsv5 instead of Dsv5)
az vm create --name MyVM --resource-group MyRG --image Ubuntu2204 --size Standard_D2ds_v5

For ARM/Bicep templates, add logic to retry with fallback SKUs:

var vmSku = contains(listAvailableSkus(), 'Standard_D2s_v5') ? 'Standard_D2s_v5' : 'Standard_D2ds_v5'
resource vm 'Microsoft.Compute/virtualMachines@2023-03-01' = {
name: 'myVM'
location: resourceGroup().location
properties: {
hardwareProfile: { vmSize: vmSku }
// ... rest of config
}
}

5. Hardening Against Runtime Drift with Azure Policy

Prevent engineers from accidentally creating new Automation accounts or Function apps that default to outdated runtimes. Enforce a minimum supported version (or require custom containers).

Step‑by‑step: Create a custom Azure Policy

1. Policy definition (JSON snippet):

{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Automation/automationAccounts" },
{ "field": "Microsoft.Automation/automationAccounts/runtimeEnvironments[].runtime.version", "in": [ "7.4", "7.5" ] }
]
},
"then": { "effect": "deny" }
}
}

2. Assign the policy to a management group or subscription:

New-AzPolicyDefinition -Name "DenyOldPSRuntimes" -Policy ".\denyOldPS.json"
New-AzPolicyAssignment -Name "BlockPS74" -PolicyDefinition $policyDef -Scope "/subscriptions/yourSubId"
  1. Custom Docker Images for Azure Functions – Bypassing Runtime Limitations
    Azure Functions on Linux allow custom containers. Build a container with PowerShell 7.6 and deploy as your Function app, completely bypassing the platform’s built‑in runtime.

Step‑by‑step: Build and deploy custom PowerShell 7.6 function

1. Create `Dockerfile`:

FROM mcr.microsoft.com/azure-functions/powershell:7.4-preview
 Replace base runtime – not officially supported, but works for custom images
RUN pwsh -c "Install-Module -Name Az -Force -AllowClobber"
USER root
RUN apt-get update && apt-get install -y wget
RUN wget https://github.com/PowerShell/PowerShell/releases/download/v7.6.0/powershell-7.6.0-linux-x64.tar.gz -O /tmp/pwsh.tar.gz && \
tar -xzf /tmp/pwsh.tar.gz -C /usr/local/microsoft/powershell/7 && \
ln -sf /usr/local/microsoft/powershell/7/pwsh /usr/bin/pwsh

2. Build and push to Azure Container Registry:

az acr build --registry myregistry --image ps76-function:latest --file Dockerfile .

3. Deploy Function app using that container:

az functionapp create --resource-group MyRG --name MyPS76Function --storage-account mystorage --consumption-plan-location eastus --docker-registry-server-url https://myregistry.azurecr.io --docker-custom-image-name ps76-function:latest --runtime custom

7. Proactive Monitoring for Runtime Deprecation Warnings

Azure sometimes sends health alerts before deprecating a runtime. Set up automated detection to alert your security team the moment Microsoft announces end‑of‑life for 7.4.

Step‑by‑step: Create a Log Analytics alert

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.AUTOMATION"
| where OperationName == "JobLog"
| where ResultDescription contains "runtime version" and ResultDescription contains "deprecated"
| project TimeGenerated, Resource, SubscriptionId, ResultDescription
| summarize count() by Resource, bin(TimeGenerated, 1h)

Create an action group to send alerts to email, Teams, or PagerDuty when count > 0.

What Undercode Say

  • Key Takeaway 1: Cloud provider runtimes are a shared responsibility blind spot – always validate that your serverless and automation components run a patched, current version, even if you must bring your own runtime via hybrid workers or custom containers.
  • Key Takeaway 2: SKU shortages are not just a capacity annoyance; they expose a single point of failure in cloud architecture. Design multi‑region, multi‑SKU fallbacks into your infrastructure-as-code to maintain availability during regional constraints.
  • Analysis: The complaints from Microsoft MVPs highlight a systemic issue: major cloud platforms prioritise stability over security when it comes to built‑in runtimes. Azure’s delay in updating PowerShell (18+ months behind) would never be tolerated for Linux kernels or Windows Server – yet serverless functions and automation accounts are treated as second‑class citizens. Attackers increasingly target automation workflows because they often hold over‑privileged service principals and connection strings. Until Azure provides weekly runtime patching, defenders must assume the platform is compromised and build compensating controls: network isolation for hybrid workers, short‑lived credentials, and frequent key rotation. The PowerShell team releases security fixes monthly – ignoring them for 1.5 years is indefensible.

Prediction

Within 12 months, a major cloud provider will experience a high‑profile breach traced directly to an outdated PowerShell runtime in an automation account – likely a runbook that rotated secrets using a vulnerable version of `Invoke-WebRequest` or suffered from a JEA bypass. This will force Microsoft (and AWS, GCP) to rethink their “managed runtime” model, moving toward weekly automatic patching or allowing customers to bring their own pre‑hardened container images by default. In the interim, security architects will increasingly forbid native Function apps and Automation accounts in favour of self‑managed Kubernetes runners or CI/CD agents – ironically reversing the serverless promise in the name of security.

▶️ Related Video (78% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Nathanmcnulty I – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky