The Many Places to run PowerShell in Azure
Intro
PowerShell is a fantastic language not just for managing Azure and related services, but for writing entire applications. I have written applications that sync millions of tickets a month between two systems and support the automatic creation and synchronization of tens of thousands of Microsoft 365 Groups based on business rules and user attributes.
However, the amount of services in Azure that support PowerShell are numerous, and it can be intimidating to decide which is best for your PowerShell script or application. I hope this helps you decide with the various options. Note that I am excluding “interactive” options like your local computer or Azure Cloud Shell, but definitely check out Azure Cloud Shell!
NOTE: This information is current as of December 2021 and stuff is changing all the time. For instance, Azure Automation has been announced to support PowerShell 7 now and that’s a big decision criteria switch.
Summary
|Name | Pros | Cons| Best For|Not Recommended
|—–|——|—–|———|—————
Azure Functions|Dirt Cheap
Auto Scaling
Durable Functions
Awesome Dev Tools (vscode/func core tools/azurite)
Community
App Insights
A/B Testing with Slots
Input/Output Bindings
Export to Containers/K8S|Debug not great
Learning Curve
On-Premise story is either hard (Azure Relay) or expensive (Azure Arc)|Short <10 min scripts
Event Driven Automation
Microservice Architectures and Web APIs, especially burstable demand
Filling in gaps in Power Apps / Power Automate|Out-Of-The-Box Scripts
Long-Running Batch Processes not written for Functions
On-Premise Activities
Azure Automation|Venerable and Stable
Friendly UI
Simple On-Premise Setup (Hybrid Runbook Workers)
|Very slow development loop even if using hybrid runbook workers
Importing/Managing Custom Modules is a nightmare
Tooling is old (ISE only, vscode is broken)
UI Logs are truncated
Small 1CPU 400MB runtime environment shared between jobsPowershell 5.1 Only Powershell 7.1 Preview Support!|Simple Azure Tasks using Az Modules
Out-Of-The-Box Scripts
Automation Scripts requiring low performance (e.g. queries, reports, start/stop VMs, etc)
Long-Running Scripts
Scripts to perform on-premise tasks in an AD domain
Tasks that the helpdesk can be delegated to run on-demand|Scripts that require a large amount of memory (Hybrid Runbook Workers help mitigate but can be costly)
Constantly changing scripts requiring fast feedback/testing
Projects that use lots of modules that must be updated frequently
Container (Azure Container Instances)|Way Cheaper than VMs (only runs when script runs)
Dev and Prod environments are same
Native VSCode Docker/Devcontainer Support
Bring along whatever additional dependencies you want
All other container-style deployment benefits|You need to roll your own “task runner” to start the container instances and verify their results (Functions/Automation/Power Automate make great triggers)
Not a lot of knowledge/documentation/support of specifically PowerShell in ACI
Roll-Your-Own scaling|People who want complete control over the process
High Performance scripts with a known load (Batch Tasks, etc.)
Scripts that need to bundle an external binary/dependency to work|Simple Solutions to hand off to standard Azure workers (limited UI)
Small Tasks to run frequently
People who want an ecosystem of tooling around the running and reporting of scripts.
Apps that require multiple isolated containers/components (AKS/ACA are better solutions)
Container (Azure Container Apps)|Dapr sidecar to interoperate with other Microservices
Run as part of a larger microservices architecture
Scale to Zero for event driven automation
Get a lot of Kubernetes benefits without having to learn Kubernetes|Brand New as of Dec 2021, almost zero support/knowledge around using PWSH here
Must use DAPR .NET libraries, no friendly input/output bindings like Azure Functions|Scripts/Apps that need to behave as part of a larger microservices framework
Scripts that need to interoperate with other apps via Dapr/KEDA event framework
Multi-Container processes that use Powershell
Container (Azure Kubernetes Service)|Great option for Kubernetes-Comforable People
Solution can be portable to any Kubernetes platform including AWS/GCP/onprem
K8s control plane is a managed service|Requires Kubernetes knowledge and ability to build apps via Helm charts, etc.
If you don’t learn/understand Kubernetes you are going to have a bad time.|Multi-cloud apps with minimal Kubernetes knowledge required
Multi-container or microservices platforms that have PowerShell components|Simple Automation Scripts
Scripts needing broad support and tooling
Virtual Machine (Scheduled Task)|Simple to learn and do, same as you do it on premise|One of the most expensive ways to run a script, especially if it is only run periodically e.g. weekly
Extremely opaque to operations, buried in scheduled tasks, who knows what this VM is for 5 years from now?|People who don’t want to learn a better way and have \($ to spend.<br><br>Scripts that have to interact with a components that only runs/supported on a Windows VM after install.|Basically anything that doesn't fit the main criteria
Virtual Machine ([PowerShell Universal](https://ironmansoftware.com/powershell-universal))|Automation and Dashboards, UI framework<br><br>Build Frontend/Backend Web Apps completely in PowerShell<br><br>Excellent Support and Active Community|Commercial Software ($)<br><br>Requires persistently-running VM|Helpdesk Apps<br><br>Simple Script Scheduling that is helpdesk-friendly|Complex multi-tiered applications or apps that need to scale to multiple hosts
Azure App Service ([PowerShell Universal](https://ironmansoftware.com/powershell-universal))|Same benefits as PSUniversal in a VM but on a more PaaS-style platform<br><br>No patches or OS to maintain
Virtual Machine ([ScriptRunner](https://www.scriptrunner.com/))|UI-Based Method of scheduling/Running Scripts|Commercial Software (\)$)
Requires persistently-running VM|A centralized script platform for on-demand scripts with authentication/authorization/auditing|People who are cheap (like me!)