Azure PowerShell: Automation Scripts, Modules, and Common Errors Fixed

Microsoft Fix Intermediate 14 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

Picture this: you've written a clean Azure PowerShell script to automate your VM deployments, it's worked perfectly for months, and then one Monday morning it stops dead with a cryptic Connect-AzAccount : The term 'Connect-AzAccount' is not recognized error , or worse, a silent authentication failure right in the middle of a production pipeline. I've seen this exact scenario on dozens of machines. And the error message rarely tells you what's actually broken.

Azure PowerShell is Microsoft's official collection of PowerShell modules for managing Azure resources. The current module , Az PowerShell, replaced the older AzureRM module and runs on Windows, Linux, and macOS. It talks directly to the Azure Resource Manager API, giving you control over virtually every Azure service through thousands of cmdlets. The problem is that "Azure PowerShell" is actually several different things, and mixing them up is where most trouble starts.

Here are the most common root causes I see:

  • Module name confusion. The old AzureRM module is deprecated and no longer maintained. Scripts written against *-AzureRM* cmdlets simply don't work with the current Az module. Many online examples still reference AzureRM, which catches people out constantly.
  • Multiple conflicting module versions. Running AzureRM side-by-side with Az causes namespace collisions that produce deeply unhelpful errors. PowerShell loads whichever module it finds first in the module path, and the result is unpredictable.
  • PowerShell version mismatch. The Az module recommends PowerShell 7 or higher. Scripts running under Windows PowerShell 5.1 may hit compatibility issues, and some cmdlets behave differently between the two.
  • MFA enforcement breaking automation. Starting September 2025, Microsoft requires multifactor authentication when signing in with a Microsoft Entra ID user identity. Any automation pipeline that relied on a plain username and password Connect-AzAccount call now fails at the authentication step.
  • Confused identity of related-but-separate modules. Tools like AzureAD, Microsoft.Graph, MSOnline, and Azure Stack PowerShell are not part of Azure PowerShell, but they look like they should be. Errors from those modules often get incorrectly blamed on the Az module, sending you down the wrong troubleshooting path entirely.

Microsoft's error messages for these problems are notoriously sparse. You get a red line in the terminal and a vague "not recognized" or "authentication failed", nothing that tells you whether the issue is a missing module, a wrong module version, an expired token, or a service principal that lost its role assignment overnight.

I know this is frustrating, especially when it blocks a deployment pipeline your whole team depends on. The good news is that once you understand the Az module's actual architecture, the fixes are very systematic. Browse all Microsoft fix guides →

The Quick Fix, Try This First

If your Azure PowerShell scripts have suddenly stopped working and you're not sure why, this single sequence resolves about 70% of the cases I encounter. Open a PowerShell 7 terminal as Administrator and run these three commands in order:

# 1. Check your current Az module version
Get-InstalledModule -Name Az

# 2. Update to the latest Az module
Update-Module -Name Az -Force

# 3. Re-authenticate
Connect-AzAccount

If Get-InstalledModule returns nothing, you don't have the Az module installed at all, skip ahead to Step 1 in the step-by-step section below.

If it returns a version older than Az 12.0.0, you're running something that's had significant breaking changes addressed since then. The Update-Module -Force flag forces the update even if you have a "newer" pre-release version cached locally.

After updating, Connect-AzAccount opens your default browser for authentication. On Windows, it defaults to Web Account Manager (WAM), which handles MFA automatically, this is the right behavior since September 2025. If you're in Azure China 21Vianet or another sovereign cloud, you need:

Connect-AzAccount -Environment AzureChinaCloud

Once authenticated, verify your subscription context loaded correctly:

Get-AzContext

You should see your subscription name, tenant ID, and account. If you see the wrong subscription, switch it with:

Set-AzContext -SubscriptionId "your-subscription-id-here"

If you're running in an automation scenario (pipelines, scheduled tasks, runbooks), plain interactive auth won't help you. Jump straight to Step 4, service principal authentication, because that's the correct path post-MFA-enforcement.

Pro Tip
Before you spend an hour diagnosing a broken Azure PowerShell script, always run $PSVersionTable.PSVersion first. If it says 5.1, you're on Windows PowerShell, not PowerShell 7. Most modern Az module features work on 5.1, but edge cases absolutely don't, and the error messages give you zero indication that the PowerShell version is the culprit. Install PowerShell 7 first, then retest.
1
Install the Az PowerShell Module (Clean Slate)

Before installing, check whether the old AzureRM module is present on your machine. Running Az and AzureRM together causes serious conflicts, they share cmdlet verb-noun pairs and fight over which one gets loaded. Run this first:

Get-InstalledModule -Name AzureRM -ErrorAction SilentlyContinue

If anything comes back, uninstall AzureRM completely before going further:

Uninstall-AzureRm

That cmdlet removes the entire AzureRM family of modules in one shot. Then install the current Az module from the PowerShell Gallery:

Install-Module -Name Az -Repository PSGallery -Force -AllowClobber

The -AllowClobber flag lets the installer overwrite any cmdlet aliases that conflict with existing commands. Without it, the install can fail silently on machines with other Azure-adjacent modules already present.

On Linux, the process is identical, just make sure you're running PowerShell 7, not the system bash shell. Install PowerShell 7 via your package manager first if needed. On macOS, use Homebrew to install PowerShell 7, then the same Install-Module command works exactly the same way.

If you're in an enterprise environment without direct internet access, you'll need to use the offline installation path or a private NuGet feed. That's covered in the Advanced section below.

How to know it worked: Run Get-Module -Name Az -ListAvailable. You should see the Az module listed with a version number of 12.0.0 or higher. If you see multiple versions listed, that's fine, PowerShell will use the highest version by default.

2
Verify Your PowerShell Version and Execution Policy

Azure PowerShell works on both Windows PowerShell 5.1 and PowerShell 7+, but the recommended version is PowerShell 7 or higher. The difference matters more than most people expect. Check your version right now:

$PSVersionTable.PSVersion

If you see Major: 5, you're on the older Windows PowerShell. That's not necessarily broken, but if you're hitting weird behavior with the Az module, upgrading to PowerShell 7 should be your first move, not your last resort.

Next, check your execution policy. This is the most common reason why a freshly installed Az module refuses to load:

Get-ExecutionPolicy -List

You'll see policies for different scopes: MachinePolicy, UserPolicy, Process, CurrentUser, LocalMachine. If LocalMachine shows Restricted or AllSigned, PowerShell won't load unsigned modules. Set it to allow local scripts and remote signed scripts:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Using CurrentUser scope avoids needing to run as Administrator and doesn't affect other users on the same machine. In corporate environments, the MachinePolicy or UserPolicy entries may be set by Group Policy and override this, see the Advanced section if you're hitting that wall.

After setting the execution policy, try importing the module manually to confirm it loads:

Import-Module Az

How to know it worked: No red errors after the Import-Module call. Then run Get-Command -Module Az.Accounts, you should see a list of cmdlets including Connect-AzAccount, Get-AzContext, and Disconnect-AzAccount.

3
Authenticate with Connect-AzAccount

Interactive authentication is straightforward, but there are several ways it can fail depending on your environment. The basic command:

Connect-AzAccount

On Windows, this defaults to Web Account Manager (WAM), which opens a Windows account picker. WAM handles MFA natively, you won't need to do anything special for the September 2025 MFA requirement if you're using interactive sign-in. On Linux and macOS, it opens a browser-based login instead.

If the browser doesn't open, common in headless servers or SSH sessions, use the device code flow:

Connect-AzAccount -UseDeviceAuthentication

This gives you a URL (https://microsoft.com/devicelogin) and a code. You enter that code in a browser on any device. Clean and reliable for server environments.

If you operate in a sovereign cloud environment, you must specify the environment explicitly or authentication will fail against the wrong endpoint:

# Azure China 21Vianet
Connect-AzAccount -Environment AzureChinaCloud

# Azure US Government
Connect-AzAccount -Environment AzureUSGovernment

After a successful sign-in, always validate your context immediately:

Get-AzContext

Check that the Account, Subscription, and Tenant fields show what you expect. A surprisingly common issue is accidentally authenticating against the right account but loading the wrong subscription, especially if your account has access to multiple subscriptions.

How to know it worked: Get-AzContext returns your account UPN, subscription name, and tenant ID without throwing an error. If you see Account: with nothing after it, the authentication didn't actually stick, try again with -UseDeviceAuthentication.

4
Set Up a Service Principal for Automation

If you're running Azure PowerShell in a pipeline, scheduled task, Azure Automation runbook, or any other non-interactive context, stop using user credentials entirely. The MFA enforcement that took effect in September 2025 makes username/password automation impossible for user identities. Service principals are the right answer.

First, create a service principal using the Az module itself. Make sure you're already authenticated interactively for this step:

# Create a new service principal and assign it the Contributor role
$sp = New-AzADServicePrincipal -DisplayName "MyAutomationSP"

# Get the client secret (only shown once, save it now)
$clientSecret = $sp.PasswordCredentials.SecretText
$clientId = $sp.AppId
$tenantId = (Get-AzContext).Tenant.Id

Write-Host "Client ID: $clientId"
Write-Host "Tenant ID: $tenantId"
Write-Host "Client Secret: $clientSecret"

Save those three values in a secrets vault (Azure Key Vault, GitHub Actions secrets, or your CI/CD platform's secret store). Never hardcode them in a script file.

To authenticate as the service principal in your automation scripts:

$credential = New-Object System.Management.Automation.PSCredential(
    $clientId,
    (ConvertTo-SecureString $clientSecret -AsPlainText -Force)
)

Connect-AzAccount -ServicePrincipal `
    -Credential $credential `
    -Tenant $tenantId

For even more secure automation in Azure-native environments, use a managed identity instead, no credentials to store or rotate at all. In that case, authentication is simply:

Connect-AzAccount -Identity

How to know it worked: Get-AzContext should show the service principal's application ID in the Account field rather than a user UPN. You can now run this script without any human interaction.

5
Fix Module-Specific Errors and Broken Cmdlets

The Az PowerShell module is a wrapper module, it contains sub-modules for individual Azure services. Az.Network handles networking, Az.Aks handles Azure Kubernetes Service, and so on. When a specific cmdlet throws an error like The term 'Get-AzVirtualNetwork' is not recognized, the problem is often that one particular sub-module failed to install or got corrupted, not that the whole Az module is broken.

Identify which sub-module owns the cmdlet you need:

# Find which module a cmdlet belongs to
Get-Command Get-AzVirtualNetwork | Select-Object Module

If that returns nothing, the sub-module isn't loaded. Force reinstall it:

Install-Module -Name Az.Network -Force -AllowClobber

For errors that look like Method not found or Could not load file or assembly, those typically signal a .NET version mismatch or a partially updated module state. The cleanest fix is a full module refresh:

# Remove all Az modules from the current session
Get-Module Az* | Remove-Module -Force

# Remove installed modules entirely
Get-InstalledModule Az* | Uninstall-Module -Force

# Reinstall fresh
Install-Module -Name Az -Repository PSGallery -Force

Also check whether you're accidentally using the AzPreview module. The AzPreview module bundles all GA modules from Az plus preview modules. Microsoft explicitly states it's not meant for production environments because preview modules don't follow the same breaking change policies. If you installed AzPreview thinking it was a superset upgrade, that may be the source of inconsistent behavior. Uninstall it and use the standard Az module for production work.

How to know it worked: Running Get-Command -Module Az.Network (or whichever sub-module you reinstalled) returns a full list of cmdlets without errors. Your original script command executes without the "not recognized" error.

Advanced Troubleshooting

Enterprise Proxy and Network Issues

In corporate environments, the Az module's calls to the Azure Resource Manager API often get blocked by a proxy, firewall, or SSL inspection appliance. The error typically looks like No such host is known or The SSL connection could not be established, neither of which says "proxy" anywhere.

Configure proxy settings for your PowerShell session before connecting:

[System.Net.WebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy("http://your-proxy:port")
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
Connect-AzAccount

For persistent proxy configuration, the Az module supports a global settings approach. You can also set the HTTP_PROXY and HTTPS_PROXY environment variables before launching PowerShell, the module picks those up automatically on non-Windows platforms.

Group Policy Blocking Module Loads

In domain-joined environments, Group Policy can enforce execution policies that override anything you set at the user or machine scope. When Set-ExecutionPolicy appears to succeed but modules still won't load, run:

Get-ExecutionPolicy -List

If MachinePolicy or UserPolicy shows Restricted or AllSigned, those are GPO-enforced and you cannot override them from PowerShell. You need to work with your AD admin to adjust the relevant GPO, typically found under Computer Configuration > Windows Settings > Security Settings > Software Restriction Policies or the equivalent PowerShell Script Execution setting in Administrative Templates > Windows Components > Windows PowerShell.

Managing Multiple Subscriptions and Tenants

One of the most common scripting bugs I see is code that assumes the "current" subscription is the right one. Azure PowerShell uses a context system, each authenticated session has an active context that determines which subscription and tenant your cmdlets target. When you have access to multiple subscriptions, you must be explicit:

# List all available contexts
Get-AzContext -ListAvailable

# Switch to a specific subscription
Set-AzContext -SubscriptionId "00000000-0000-0000-0000-000000000000"

# Or use the subscription name
Set-AzContext -SubscriptionName "Production-East"

For scripts that need to loop across multiple subscriptions, use Get-AzSubscription to enumerate them and call Set-AzContext inside your loop. This is cleaner than trying to pass subscription parameters to every individual cmdlet.

Debugging with Invoke-AzRestMethod

When a high-level Az cmdlet is behaving unexpectedly and you're not sure if the bug is in the module or in your Azure configuration, drop down to the raw REST layer. The Invoke-AzRestMethod cmdlet lets you make direct calls to the Azure Resource Manager API using your existing authenticated session:

Invoke-AzRestMethod -Path "/subscriptions/{sub-id}/resourceGroups?api-version=2021-04-01" -Method GET

This cuts out the Az module abstraction entirely and shows you exactly what the API returns. If the REST call succeeds but the cmdlet doesn't, the issue is in the module. If the REST call also fails, the issue is with your Azure permissions or configuration.

MFA Impact on Existing Automation

Since September 2025, any automation relying on Connect-AzAccount -Credential with a user account UPN will fail with an MFA-required error. The fix is not to disable MFA, it's to migrate to service principals or managed identities as covered in Step 4. If you're in an organization with dozens of old automation scripts, use this query to find all the affected ones:

# Search for scripts using user-credential-based auth
Get-ChildItem -Recurse -Filter "*.ps1" | Select-String "Connect-AzAccount.*Credential"

Each hit needs to be audited and migrated to service principal or managed identity auth.

When to Call Microsoft Support
If you've worked through everything above and you're still seeing authentication failures with a valid service principal, check first whether your service principal's role assignment is still intact, role assignments can be accidentally removed during subscription transfers or policy enforcement. Run Get-AzRoleAssignment -ServicePrincipalName $clientId to confirm. If role assignments look correct and you're still blocked, especially in sovereign clouds or with conditional access policies configured by your IT department, that's the point to open a ticket with Microsoft Support. Bring your correlation IDs from failed requests, you can pull these from the Azure Activity Log under Monitor > Activity log in the Azure portal.

Prevention & Best Practices

Most Azure PowerShell headaches are preventable with a few deliberate habits. I've watched teams burn hours on the same recurring problems that a handful of simple practices would have avoided entirely.

Pin your module versions in production scripts. The Az module gets updated frequently, Microsoft releases breaking changes up to twice a year. If your scripts run with whatever the latest installed version is, a routine Update-Module by a colleague can silently break your automation. At the top of production scripts, specify a minimum version:

#Requires -Modules @{ ModuleName = 'Az'; ModuleVersion = '12.0.0' }

This causes the script to fail immediately with a clear error if the wrong version is loaded, instead of failing mysteriously halfway through execution.

Never mix Az and AzureRM. I know I've said this before, but it bears repeating, I still find environments years into the Az era where someone installed AzureRM "just to run one old script" and never cleaned it up. The conflict is insidious. Remove AzureRM entirely and migrate those old scripts to Az cmdlets. The verb-noun pattern changes (Get-AzureRmVM becomes Get-AzVM), but Microsoft provides an automatic migration tool for this.

Use credential contexts, not hardcoded credentials. The Az module's context management system (Save-AzContext, Import-AzContext) lets you export and reuse authentication tokens across sessions without embedding secrets in scripts. Combined with Azure Key Vault for service principal secrets, you get a clean credential chain that's auditable and rotatable without script changes.

Filter output early, not late. The Az module returns full .NET objects for everything, a Get-AzVM call on a large subscription can return enormous objects. Pipe results to Where-Object or use the -ResourceGroupName parameter to scope your queries at the cmdlet level. Don't pull everything and filter in memory, it's slow and burns unnecessary API quota.

Understand the control plane vs. data plane split. The Az module handles both control plane operations (managing what resources exist) and data plane operations (controlling what those resources do). Some data plane operations require different permissions than control plane operations. If you get a permission error on a data plane cmdlet even with Contributor role, you probably need an additional data-specific role like Storage Blob Data Contributor rather than just Contributor.

Quick Wins
  • Run $PSVersionTable.PSVersion at the top of any new debugging session, rule out PowerShell version issues in 5 seconds
  • Add Set-StrictMode -Version Latest to your Azure PowerShell scripts to catch variable typos and undefined references before they reach production
  • Use Get-AzContext as the first command in every automation script to verify the correct subscription is loaded before running any destructive operations
  • Review the official Upcoming breaking changes page in the Azure PowerShell docs before every major Az module update, bookmark it and check it quarterly

Frequently Asked Questions

What is the difference between Az, AzureRM, and the Azure PowerShell module?

These are three different generations of Microsoft's Azure management tooling for PowerShell. The Az PowerShell module is the current, recommended one, it's cross-platform, actively maintained, and uses *-Az* cmdlet names like Get-AzVM. AzureRM is the previous generation, now deprecated and no longer receiving updates or security fixes, its cmdlets use *-AzureRM* names. The older Azure PowerShell module (sometimes just called "Azure") targets legacy Azure Service Manager APIs that are scheduled for retirement. For anything new, use Az exclusively and remove AzureRM from your systems entirely to avoid module conflicts.

Why does Connect-AzAccount fail with an MFA error in my automated script?

Starting September 2025, Microsoft enforces multifactor authentication for Microsoft Entra ID user identities signing in to Azure. That enforcement breaks any automation that was using Connect-AzAccount -Credential with a regular user account username and password. The fix is to stop using user credentials for automation entirely. Create a service principal with New-AzADServicePrincipal, assign it the appropriate role, and authenticate using Connect-AzAccount -ServicePrincipal. If you're running inside Azure (VMs, Functions, Automation Runbooks), use a managed identity with Connect-AzAccount -Identity instead, no credentials needed at all.

Can I run Azure PowerShell without installing anything on my local machine?

Yes, Azure Cloud Shell is a browser-based environment that gives you a fully configured Azure PowerShell session without installing anything. You access it directly from the Azure portal by clicking the Cloud Shell button (the >_ icon in the top navigation bar), or by going to shell.azure.com. Cloud Shell runs PowerShell on a Linux container, so Windows-specific PowerShell features aren't available there, but all Az module cmdlets work fine. There's also a Docker container option if you want a reproducible, isolated environment locally, Microsoft publishes an official Azure PowerShell container image you can pull and run.

Is the AzPreview module safe to use in production?

Microsoft explicitly recommends against using AzPreview in production environments. The AzPreview module bundles all the generally available Az modules together with preview modules for services that haven't reached GA status yet. Preview modules don't follow the same breaking change policies as GA modules, a cmdlet can change its parameters, return type, or behavior without the usual warning cycle. For production automation, use the standard Az module and only pull in preview functionality if you specifically need a feature that isn't in the GA module yet, and even then, isolate it carefully. AzPreview is great for testing upcoming features in dev/staging environments.

Which modules are NOT part of Azure PowerShell even though they manage Azure things?

Several important Microsoft tools look like they belong to Azure PowerShell but officially don't, and you should never describe them using the "Azure PowerShell" name because it creates confusion when troubleshooting. The excluded list includes: Azure Active Directory PowerShell (AzureAD), Microsoft.Graph PowerShell, Microsoft.Graph.Entra PowerShell, MSOnline PowerShell, Azure Information Protection PowerShell, Azure Deployment Manager PowerShell, Azure Elastic Database Jobs PowerShell, Azure Service Fabric PowerShell, and Azure Stack PowerShell. Each of these has its own install path, authentication model, and support channel, errors from these modules need to be debugged separately from Az module issues.

How do I figure out what .NET object a cmdlet returns so I can pipe it correctly?

The Az module cmdlets all return .NET objects, which makes them very powerful to work with in pipelines, but you have to know what type you're dealing with. Pipe any cmdlet output to Get-Member to see the full object type, all available properties, and all available methods. For example: Get-AzVM | Get-Member shows you that a VM object has properties like Name, Location, HardwareProfile, and many more. From there you can pipe to Select-Object to pull just the fields you need, or to Where-Object to filter on any property. This is much more reliable than parsing string output, and your scripts stay compatible when Microsoft changes the display format of cmdlet output.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.