AZ-104Chapter 92 of 168Objective 3.1

VM Run Command and Invoke Script

This chapter covers VM Run Command and Invoke Script, a powerful Azure feature that allows you to execute scripts on Azure VMs without requiring inbound network connectivity (SSH/RDP). For the AZ-104 exam, this topic appears in approximately 5-10% of Compute-related questions, often in scenarios involving troubleshooting, configuration, or automation without direct access. Understanding when and how to use Run Command versus other script execution methods (Custom Script Extension, DSC, etc.) is critical for passing the exam.

25 min read
Intermediate
Updated May 31, 2026

Remote Surgeon with Robotic Arms

Imagine a surgeon in a control room operating on a patient in a sterile operating room. The surgeon cannot physically enter the OR without breaking sterility, but they can use robotic arms to perform the surgery. The robotic arms have a control console that sends precise commands (e.g., 'cut here', 'suture') and receives video feedback. This is exactly how VM Run Command works: the Azure fabric (the control room) sends a script (the surgical command) to the VM agent (the robotic arm) inside the VM (the patient). The VM agent executes the script as the local system account (the surgeon's hands) and returns the output (the video feed) to the Azure portal or CLI. The key is that no inbound network connectivity (like SSH or RDP) is required; the VM agent pulls the command from Azure Storage using an outbound HTTPS connection to Azure management endpoints. This is analogous to the robotic arms being controlled wirelessly without needing a physical cable from the control room to the OR. If the VM agent is not installed or is broken, the command cannot be executed — just as a robotic arm with a severed wire cannot respond. Also, the command runs with the privileges of the local system, not the user's Azure RBAC role — the surgeon's credentials are used only to authorize access to the control console, not to perform the surgery itself.

How It Actually Works

What is VM Run Command and Why It Exists

VM Run Command is an Azure feature that enables you to remotely execute scripts on an Azure virtual machine (VM) using the VM agent (either the Windows Guest Agent or Linux Agent). It was introduced to solve a common operational problem: what do you do when a VM becomes unreachable via RDP or SSH due to a misconfigured firewall, network security group (NSG), or broken networking? Traditional troubleshooting requires either console access (which Azure does not provide) or out-of-band management (like Azure Serial Console, which requires boot diagnostics). Run Command fills this gap by leveraging the VM agent's outbound communication channel to Azure management endpoints.

The VM agent on Windows (WindowsAzureGuestAgent) or Linux (waagent) periodically polls Azure Storage for pending commands. When you invoke a Run Command, Azure writes the script to a blob in a hidden storage container associated with the VM, and the agent downloads and executes it. The output is then uploaded back to Azure, where you can retrieve it. This entire process uses only outbound HTTPS from the VM to Azure, so it works even if the VM has no inbound ports open or if the NSG blocks all inbound traffic.

How It Works Internally

The mechanism is as follows:

1.

User initiates a Run Command via Azure portal, Azure CLI, PowerShell, or REST API. The user specifies the script content (inline or a script file) and optionally parameters.

2.

Azure Resource Manager (ARM) receives the request and validates the user's RBAC permissions on the VM (typically Contributor or higher). The user must have Microsoft.Compute/virtualMachines/runCommand/action permission.

3.

ARM writes the script to a blob in a hidden storage container named vm-run-command-{region}-{vmId} within the VM's host storage (not user-visible). This blob is accessible only by the VM agent using a SAS token embedded in the VM's configuration.

4.

The VM agent polls its task queue (stored in the host's metadata service) every few seconds. The agent sees a new task with the script location and SAS token.

5.

The VM agent downloads the script from the blob, executes it using the local system account (SYSTEM on Windows, root on Linux), and captures stdout, stderr, and exit code.

6.

The agent uploads the results back to a different blob in the same container.

7.

The user retrieves the output via the same portal/CLI/API. The output is stored for a limited time (typically 1 hour) and then deleted.

Key details:

The VM agent must be running and healthy. If the agent is stopped, uninstalled, or misconfigured, Run Command fails.

The script runs with elevated privileges (SYSTEM/root), so it can perform any operation the OS allows.

The script execution time is limited to 90 minutes (5400 seconds). If the script exceeds this, it is terminated.

The script output size is limited to approximately 4 MB. Larger outputs are truncated.

Key Components, Values, Defaults, and Timers

Timeout: 5400 seconds (90 minutes). Scripts exceeding this are killed.

Output retention: Output blobs are deleted after 1 hour.

Supported OS: Windows (Windows Server 2012+, Windows 10/11) and Linux (most distributions with waagent 2.2.0+).

Script size: Maximum 256 KB for inline scripts, larger for script files (but subject to overall request size limits).

Parameters: You can pass up to 20 parameters to the script.

Exit code: Returned as part of the output; non-zero indicates failure.

PowerShell on Windows: Runs as %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -Command {script}.

Shell on Linux: Runs as /bin/bash -c {script}.

Configuration and Verification Commands

Azure CLI

# Run an inline script on a Windows VM
az vm run-command invoke -g MyResourceGroup -n MyWinVM --command-id RunPowerShellScript --scripts "Get-Process | Out-String"

# Run an inline script on a Linux VM
az vm run-command invoke -g MyResourceGroup -n MyLinuxVM --command-id RunShellScript --scripts "uptime && df -h"

# Run a script file
az vm run-command invoke -g MyResourceGroup -n MyVM --command-id RunShellScript --scripts @myscript.sh

# Pass parameters
az vm run-command invoke -g MyResourceGroup -n MyVM --command-id RunShellScript --scripts "echo Hello {0}" --parameters "arg1=World"

PowerShell

# Run inline script on Windows VM
Invoke-AzVMRunCommand -ResourceGroupName MyResourceGroup -VMName MyWinVM -CommandId RunPowerShellScript -ScriptPath "C:\scripts\test.ps1"

# Run inline script on Linux VM
Invoke-AzVMRunCommand -ResourceGroupName MyResourceGroup -VMName MyLinuxVM -CommandId RunShellScript -ScriptPath "/home/azureuser/script.sh"

REST API

POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/runCommand?api-version=2023-03-01
{
  "commandId": "RunPowerShellScript",
  "script": ["Get-Process"]
}

How It Interacts with Related Technologies

Custom Script Extension: Both execute scripts on VMs, but Custom Script Extension is designed for provisioning and configuration management (e.g., installing software during deployment). It requires the VM to be reachable during deployment and runs only once per extension deployment. Run Command is ad-hoc and interactive, used for troubleshooting or one-off tasks. The exam often tests when to use each.

Desired State Configuration (DSC): DSC is for continuous configuration management (push/pull). Run Command is for immediate, one-time script execution.

Azure Automation Runbooks: Runbooks can execute scripts on VMs using the Hybrid Runbook Worker, but this requires additional infrastructure (Hybrid Worker). Run Command is simpler and does not require any additional setup beyond the VM agent.

Serial Console: Serial Console provides keyboard/screen access to the VM via the Azure portal, but requires boot diagnostics to be enabled. It works even if the VM agent is broken. Run Command requires the VM agent.

Limitations

Requires a healthy VM agent.

Cannot be used on VMs that are stopped (deallocated) — the VM must be running.

Script execution is not interactive; you cannot provide input during execution.

Output is limited in size and retention time.

Does not support running as a different user (always SYSTEM/root).

Not supported for classic VMs (only Azure Resource Manager VMs).

Exam Tip: Command IDs

There are two built-in command IDs: RunPowerShellScript for Windows and RunShellScript for Linux. You must use the correct one for the target OS. Using RunPowerShellScript on a Linux VM will fail because the agent does not have a PowerShell executable. The exam may present a scenario where you need to choose the correct command ID.

Walk-Through

1

Verify VM Agent Status

Before using Run Command, ensure the VM agent is installed and running. On Windows, check the service 'Windows Azure Guest Agent' (or 'WindowsAzureGuestAgent'). On Linux, check the status of 'waagent' service. Use `az vm get-instance-view -g MyRG -n MyVM --query "instanceView.statuses[?code=='PowerState/running']"` to verify the VM is running. If the agent is not healthy, Run Command will fail with an error like 'VMAgentExtensionProvisioningError'. In the exam, a common distractor is to assume Run Command works even if the VM agent is missing – it does not.

2

Authenticate and Authorize

The user must have appropriate RBAC permissions: typically Contributor role or a custom role with `Microsoft.Compute/virtualMachines/runCommand/action`. This permission is separate from being able to RDP/SSH. The exam tests that Run Command requires RBAC, not just network connectivity. If a user can RDP but does not have the RBAC permission, Run Command will be denied (403 Forbidden). The authentication is via Azure AD, and the authorization is checked by ARM before the command is dispatched.

3

Invoke Run Command via Portal/CLI

The user selects a command ID (RunPowerShellScript or RunShellScript) and provides the script. On the portal, you can type or paste the script. On CLI, you use `--scripts` for inline or `--scripts @file` for a file. The request is sent to ARM, which validates permissions and creates a task in the VM's host metadata. The VM agent polls this task. The script is written to a blob with a SAS token. This step is synchronous from the user's perspective – the CLI/portal waits for the output or a timeout.

4

VM Agent Executes Script

The VM agent downloads the script from the blob using the SAS token. It then spawns a new process: on Windows, it runs `powershell.exe -ExecutionPolicy Unrestricted -Command <script>`; on Linux, it runs `/bin/bash -c <script>`. The script runs with SYSTEM (Windows) or root (Linux) privileges. The agent captures stdout, stderr, and exit code. If the script exceeds 90 minutes, the agent terminates it and returns a timeout error. The agent has no direct network connection to the user; all communication is via Azure Storage blobs.

5

Retrieve and Review Output

After execution, the agent uploads the output (stdout, stderr, exit code) to an output blob in the same container. The user's client (portal/CLI) then downloads this output and displays it. The output is available for up to 1 hour. If the output is larger than ~4 MB, it is truncated. The exam may ask about output retention or size limits. The exit code is particularly useful for scripting: a non-zero exit code indicates failure, which the user can use in automation.

What This Looks Like on the Job

Scenario 1: Troubleshooting a VM with a Misconfigured NSG

A common enterprise scenario: a security administrator accidentally applies an NSG that blocks all inbound RDP (port 3389) and SSH (port 22) traffic to a critical VM. The VM is still running and has outbound internet access. The administrator cannot RDP/SSH to fix the NSG. Using Run Command, the administrator runs a PowerShell script to modify the NSG rules via Azure PowerShell or CLI (since the VM has outbound access, it can call Azure management APIs). For example:

Invoke-AzVMRunCommand -ResourceGroupName 'RG1' -VMName 'VM1' -CommandId RunPowerShellScript -ScriptPath 'C:\scripts\fix-nsg.ps1'

Where fix-nsg.ps1 contains Azure PowerShell commands to update the NSG. This avoids the need for any inbound connectivity. In production, this is often used in conjunction with Azure Automation or as a last-resort recovery method.

Scenario 2: Collecting Diagnostics from Unreachable VMs

A DevOps team manages hundreds of VMs. One VM becomes unresponsive but is still running. The team needs to collect event logs and performance counters to diagnose the issue. Without Run Command, they would need to attach a diagnostic disk or use Serial Console (which requires boot diagnostics). With Run Command, they can execute a script that exports logs to a blob storage account:

az vm run-command invoke -g MyRG -n MyVM --command-id RunShellScript --scripts "dmesg > /tmp/dmesg.log && az storage blob upload -f /tmp/dmesg.log -c logs --account-name mystorageaccount"

This script uses the Azure CLI (installed on the VM) to upload logs. In production, the VM must have the Azure CLI installed and authenticated (e.g., using managed identity). The exam may test that Run Command can run any command the OS supports, including Azure CLI or PowerShell cmdlets, provided the necessary tools are installed.

Scenario 3: Applying Hotfixes or Configuration Changes

A security vulnerability requires an immediate registry change on all Windows VMs in a region. Instead of RDPing into each VM, the security team runs a Run Command script against all VMs using a loop in Azure CLI:

for vm in $(az vm list -g MyRG --query "[].name" -o tsv); do
  az vm run-command invoke -g MyRG -n $vm --command-id RunPowerShellScript --scripts "Set-ItemProperty -Path 'HKLM:\Software\MyApp' -Name 'SecurityLevel' -Value 'High'"
done

This scales well but is not fully automated for large fleets (consider Azure Automation or Policy). Common pitfalls: the script runs simultaneously on many VMs, which may cause contention if they share a backend. Also, if the VM agent is not updated, some VMs may fail. In production, always test on a small subset first.

What Goes Wrong When Misconfigured

Missing VM Agent: The most common failure. The command fails immediately with an error. Always verify agent status.

Script Syntax Errors: The script runs but produces errors. The output shows stderr, but the exit code may still be 0 if the script does not handle errors. Always check stderr.

Timeout: Long-running scripts (e.g., installing updates) may hit the 90-minute timeout. Use Custom Script Extension for provisioning tasks that may take longer.

Output Truncation: If the script produces large output (e.g., Get-Process on a busy server), the output is truncated. Use Out-String -Width 4096 or redirect to a file.

Permission Issues: The script runs as SYSTEM/root, so it can access all local resources, but it cannot access network resources that require user context (e.g., mapped drives). Use managed identity or stored credentials.

How AZ-104 Actually Tests This

AZ-104 Exam Focus: VM Run Command and Invoke Script

Objective Codes

This topic falls under Objective 3.1: Create and configure virtual machines, specifically the sub-objective Configure VM extensions and Troubleshoot VM connectivity. The exam blueprint lists 'Run Command' as a method to execute scripts on VMs. You may also see it in the context of Objective 5.2: Monitor and troubleshoot virtual networking (troubleshooting NSG issues).

Common Wrong Answers and Why Candidates Choose Them

1.

'Run Command requires inbound port 443 to be open' – This is false. Run Command uses outbound HTTPS from the VM to Azure. Candidates confuse it with RDP/SSH. The correct answer is that no inbound ports are needed.

2.

'Run Command can be used on stopped (deallocated) VMs' – False. The VM must be running. Candidates think 'Run Command' is like 'Start VM' but it is not.

3.

'Run Command runs with the user's Azure AD credentials' – False. It runs as SYSTEM/root. Candidates confuse RBAC permissions with OS-level execution context. The user only needs RBAC to invoke the command; the script itself runs with local system privileges.

4.

'Run Command is the same as Custom Script Extension' – False. Custom Script Extension is for deployment-time configuration; Run Command is for ad-hoc troubleshooting. The exam may present a scenario where you need to choose between them. Key difference: Custom Script Extension runs during VM provisioning or extension deployment, while Run Command runs on demand.

Specific Numbers, Values, and Terms

Timeout: 90 minutes (5400 seconds).

Output retention: 1 hour.

Command IDs: RunPowerShellScript (Windows), RunShellScript (Linux).

Script size limit: 256 KB for inline.

Output size limit: ~4 MB (truncated).

RBAC permission: Microsoft.Compute/virtualMachines/runCommand/action.

Supported OS agents: Windows Guest Agent, Linux Agent (waagent 2.2.0+).

Edge Cases and Exceptions

VMs without public IP: Run Command works because the outbound connection to Azure management endpoints does not require a public IP; it uses Azure's internal network (if using Azure DNS). However, if the VM's outbound traffic is blocked (e.g., forced tunneling), Run Command may fail.

VMs in a VNet with no internet access: Run Command still works if the VM can reach Azure management endpoints (e.g., via Service Endpoints or a firewall with proper rules). The endpoints are *.blob.core.windows.net and management.azure.com.

Linux VMs with restrictive SELinux/AppArmor: The script runs under root, but SELinux policies may block certain operations. The exam may not test this deeply, but be aware.

Using Run Command with Azure Bastion: Bastion provides RDP/SSH via the portal, but Run Command does not require Bastion. The exam may ask which method to use when Bastion is not available – Run Command is a valid alternative.

How to Eliminate Wrong Answers Using the Underlying Mechanism

When you see a question about executing a script on a VM that is unreachable via RDP/SSH:

If the VM is running and has a healthy agent, Run Command is the best answer.

If the VM agent is broken, Serial Console is the alternative (requires boot diagnostics).

If the VM is stopped, you must start it first.

If the script needs to run during provisioning, use Custom Script Extension.

If the script needs to run on a schedule or in response to events, use Azure Automation.

Eliminate any answer that mentions inbound ports, user credentials, or stopped VMs.

Key Takeaways

VM Run Command executes scripts on Azure VMs via the VM agent, requiring no inbound network connectivity.

The script runs as SYSTEM on Windows and root on Linux, with a 90-minute timeout.

Output is retained for 1 hour and limited to approximately 4 MB.

The user must have RBAC permission `Microsoft.Compute/virtualMachines/runCommand/action` (e.g., Contributor role).

Use `RunPowerShellScript` for Windows and `RunShellScript` for Linux.

Run Command cannot be used on stopped VMs or VMs with a broken agent.

For provisioning-time scripts, use Custom Script Extension instead of Run Command.

Run Command is ideal for troubleshooting connectivity issues caused by NSG or firewall misconfigurations.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

VM Run Command

Ad-hoc, on-demand execution

No inbound ports required

Runs as SYSTEM/root

Output available for 1 hour

Maximum 90-minute timeout

Custom Script Extension

Used during VM provisioning or template deployment

Requires VM agent and outbound connectivity

Runs as SYSTEM/root

Output stored in Azure Storage indefinitely (if configured)

No hard timeout (but script should complete within extension timeout)

Watch Out for These

Mistake

Run Command requires inbound RDP or SSH ports to be open.

Correct

Run Command uses outbound HTTPS from the VM to Azure. No inbound ports are needed. The VM agent polls Azure Storage for commands.

Mistake

Run Command runs with the Azure AD credentials of the user who invokes it.

Correct

The script runs as SYSTEM on Windows or root on Linux, regardless of the user's Azure AD identity. The user only needs RBAC permission to invoke the command.

Mistake

Run Command can be used on a VM that is stopped (deallocated).

Correct

The VM must be in the 'Running' state. A stopped VM has no agent running to receive commands.

Mistake

Run Command and Custom Script Extension are interchangeable.

Correct

Custom Script Extension is for provisioning and configuration management (runs once per extension deployment). Run Command is for ad-hoc, on-demand script execution. They have different use cases.

Mistake

The script output is stored indefinitely.

Correct

Output is retained for only 1 hour, then deleted. You must retrieve it within that window.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Can I use Run Command on a VM that has no public IP address?

Yes, Run Command works on VMs without public IPs as long as the VM has outbound HTTPS connectivity to Azure management endpoints. This can be achieved via Azure's default outbound access, a NAT gateway, or a firewall with proper rules. The VM agent communicates with Azure Storage and ARM endpoints using internal Azure IP ranges.

What happens if my script exceeds the 90-minute timeout?

The VM agent terminates the script after 90 minutes (5400 seconds). The output will contain a timeout error message. For long-running tasks, consider using Custom Script Extension or Azure Automation, which have longer or no hard timeouts.

Does Run Command work on Azure VMs with Linux?

Yes, Run Command supports Linux VMs running a supported Linux distribution with the waagent version 2.2.0 or later. Use the command ID `RunShellScript`. The script is executed with `/bin/bash -c`. Ensure bash is installed.

Can I pass parameters to my script in Run Command?

Yes, you can pass up to 20 parameters using the `--parameters` flag in Azure CLI or the `-Parameter` parameter in PowerShell. Parameters are passed as positional arguments to the script. For example: `az vm run-command invoke --parameters "arg1=value1" "arg2=value2"`.

Is Run Command available for Azure VMs in a private network with forced tunneling?

It depends. If forced tunneling routes all outbound traffic through an on-premises firewall that blocks access to Azure management endpoints, Run Command will fail. You need to ensure that the VM can reach `*.blob.core.windows.net` and `management.azure.com` via allowed routes. Using Service Endpoints or a firewall with proper rules can enable it.

How do I retrieve the output of a Run Command after invocation?

The output is returned directly in the response of the invocation command (e.g., in the CLI or PowerShell output). If you lose the output, you cannot retrieve it later because the output blob is deleted after 1 hour. To preserve output, modify your script to write results to a persistent location (e.g., Azure Storage, Log Analytics).

Can I use Run Command to run a script that requires user interaction?

No, Run Command is non-interactive. The script runs in the background without any user input. If your script requires prompts or input, it will hang until the timeout. Use a different method (e.g., RDP/SSH with interactive session) for interactive tasks.

Terms Worth Knowing

Ready to put this to the test?

You've just covered VM Run Command and Invoke Script — now see how well it sticks with free AZ-104 practice questions. Full explanations included, no account needed.

Done with this chapter?