In Azure we have a few different places where we can run our scripts and even more ways to let our scripts access VMs remotely. One of the original methods was to use Hybrid Worker, but that is retiring at the end of this month (August 2024). This time I would like to compare those options.
Methods - Remote Script Execution Tools for Azure VMs
Here are some of the commonly used methods that are easy to setup and use, and do not rely on any third party tools.
PowerShell Remoting (WinRM)
Allows you to remotely run PowerShell commands on Windows VMs using WinRM (Windows Remote Management). It works like a remote PowerShell session — ideal for admins or automation scripts.
Requirements:
- WinRM enabled and configured (HTTPS recommended)
- NSG allows inbound TCP 5986
- Valid credentials
Example:
1
2
3
Invoke-Command -ComputerName "vm.domain.com" -Credential $cred -ScriptBlock {
Get-Service
}
Extension-based Hybrid Runbook Worker
A VM extension that turns your VM into a local executor of Azure Automation Runbooks. Your runbooks in Azure run inside the VM, securely and on schedule.
Requirements:
- Azure Automation Account
- VM must have system-assigned managed identity
- Install the Hybrid Worker extension
Custom Script VM Extension
Used to run scripts (PowerShell/Bash) on a VM during or after provisioning. The script is pulled from a public or SAS-protected URL and executed once.
Requirements:
- Script hosted on Blob Storage or URL
- Can be applied via ARM, PowerShell, CLI, or portal
Example:
1
2
3
Set-AzVMExtension -ResourceGroupName "rg" -VMName "myVM" `
-Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" `
-SettingString "{'fileUris': ['https://myblob/setup.ps1'], 'commandToExecute': 'powershell -File setup.ps1'}"
Invoke-AzVMRunCommand
A direct method to run inline PowerShell (Windows) or Bash (Linux) commands inside a VM via the Azure control plane — no open ports needed. Lightweight and quick.
Requirements:
- Azure VM with the Azure VM Agent installed (default for most)
- IAM permissions on the VM for Automation or identity
Example:
1
2
Invoke-AzVMRunCommand -ResourceGroupName "rg" -VMName "myVM" `
-CommandId "RunPowerShellScript" -ScriptString @("Get-Process")
Agent-based Hybrid Runbook Worker (Retired)
This older model required the Log Analytics agent and worked similarly to the new Hybrid Worker, but with more manual setup and tighter dependencies. Agent-based Hybrid Runbook Worker is going to be retired at the end of this Month (August 31st, 2024), and therefore I will reffer to it as retired. If you are currently using it, you should migrate to the extension-based Azure Hybrid Worker version.
Comparison - Remote Script Execution Tools for Azure VMs
Purpose & Use Case
Feature | PowerShell Remoting | Extension-based Hybrid Worker | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Designed for | Manual/scripted remote sessions | Scheduled automation & long-term management | One-time post-deployment config | Ad-hoc script execution via Azure control plane | Same as extension-based, now retired |
Use case | Ad-hoc admin tasks | Routine jobs, updates, patching, automation | Install apps, set config once | Troubleshooting or small quick scripts | Same use case |
Deployment | Needs open ports (5985/5986) | As VM extension | As VM extension | No ports needed | Required Log Analytics agent |
Where the Logic Lives
Feature | PowerShell Remoting | Hybrid Worker (Ext-based) | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Script source | Inline in session | Azure Automation Runbook | Script from URL or inline | Inline in cmdlet | Runbook in Automation |
Centralized logic | ❌ (local script) | ✅ | ❌ (script hosted externally) | ✅ (inline or in script block) | ✅ |
Easy to update | ✅ | ✅ | ⚠️ Must update script in storage | ✅ | ✅ |
Frequency & Reusability
Feature | PowerShell Remoting | Hybrid Worker (Ext-based) | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Run frequency | Ad-hoc/manual | Unlimited, scheduled or ad-hoc | One-time (unless re-deployed) | Ad-hoc/manual | Same as extension-based |
Scheduled runs | ❌ | ✅ Native with Automation | ❌ | ❌ | ✅ |
Built-in retry/error handling | ❌ | ✅ | ❌ | ⚠️ Minimal | ✅ |
Security & Identity
Feature | PowerShell Remoting | Hybrid Worker (Ext-based) | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Uses Managed Identity | ❌ (uses local creds) | ✅ | ❌ | ✅ (if configured) | ✅ |
Port requirements | ✅ 5985/5986 | ❌ (runs locally) | ❌ | ❌ | ❌ |
Network dependencies | Needs open inbound ports & NSG rules | None (runs inside VM) | None | None | Needs connection to Azure + Log Analytics |
Logging & Output
Feature | PowerShell Remoting | Hybrid Worker (Ext-based) | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Output capture | ✅ In PowerShell | ✅ Azure job output | ❌ Logs only in VM | ✅ Output captured | ✅ |
Centralized logs | ❌ (local session only) | ✅ | ❌ (logs in /var/log/azure or C:\... ) | ✅ Partial | ✅ |
Diagnostics | Manual | Integrated with Log Analytics | Basic logs | Returns output via object | Integrated with Log Analytics |
Setup & Management
Feature | PowerShell Remoting | Hybrid Worker (Ext-based) | Custom Script Extension | Invoke-AzVMRunCommand | Agent-based Hybrid Worker |
---|---|---|---|---|---|
Easy to deploy | ⚠️ Requires WinRM config + certs | ✅ | ✅ | ✅ Very simple | ❌ Manual agent install, retired |
Auto-updates | N/A | ✅ | ❌ | N/A | ❌ |
Best suited for | Admins/scripts running tools | Long-running jobs, routine automation | One-time provisioning | Quick troubleshooting & diagnostics | Legacy environments |
Summary of Azure VM Script Execution Options
Method | Description | Best For | Requires |
---|---|---|---|
PowerShell Remoting (WinRM) | Remotely runs PowerShell commands over WinRM on Windows VMs. | Admin scripts, remote sessions | Open port 5985/5986, WinRM config, credentials |
Extension-based Hybrid Runbook Worker | Runs Azure Automation Runbooks inside the VM via extension. | Scheduled jobs, patching, secure local execution | Automation Account, Managed Identity, extension |
Custom Script VM Extension | One-time script execution via extension, usually at provisioning. | Bootstrapping, installs, quick config | Script hosted via URL, deployed via ARM/CLI/PowerShell |
Invoke-AzVMRunCommand | Sends a command to execute inside the VM using the Azure agent. | Quick fixes, ad-hoc commands, diagnostics | Azure VM Agent, permissions, script string |
Agent-based Hybrid Runbook Worker (Retired) | Legacy method to run Automation Runbooks via Log Analytics agent. | Legacy environments (migrate now!) | Log Analytics agent, Automation Account (retired) |
Final thoughts
I’ve been using the Agent based Azure Hybrid Worker for years. But as this technology sunsets, the Azure ecosystem offers multiple modern alternatives for script execution, each with its own strengths and ideal use cases. There’s no one-size-fits-all solution, but it is great that we have a plenty of options.
Thanks for reading and keep clouding around.
Vukasin Terzic