Running a single RPA bot on one VM is a proof of concept. Running an automation fleet that handles enterprise workloads, survives machine failures, and scales with your business is an engineering discipline. This lesson teaches you the architecture, configuration, and operational patterns behind Power Automate machine groups — so your unattended bots run reliably at scale, not just on demo day.

Picture this: your finance team runs a nightly batch process that scrapes data from three legacy systems, consolidates it into Excel, and pushes the results to a SharePoint list. It works beautifully on the single VM you set up six months ago. Then the business grows. Now there are five batch processes, each with its own deadline window, and they all need to run between 11 PM and 3 AM. Your single machine is the bottleneck. Flows queue up, deadlines slip, and someone is going to get a very uncomfortable Monday morning email.
This is the moment where machine groups stop being a nice-to-have and become essential infrastructure. Power Automate's machine management layer — machines, machine groups, and the orchestration logic that sits above them — is the difference between a single RPA bot that runs on one PC and a genuine, scalable automation fleet that can handle enterprise workloads. By the end of this lesson, you'll understand how to register machines correctly, design machine groups for load balancing and high availability, configure connection credentials that survive reboots, and build the kind of operational discipline that keeps unattended automation running reliably at scale.
What you'll learn:
You should be comfortable with the difference between attended and unattended RPA before diving in — if that's fuzzy, work through Attended vs Unattended RPA: Choosing a Run Mode and Configuring Machines in Power Automate first. You'll also want a working Power Automate Desktop installation on at least one Windows machine, and a Power Automate Premium license (or a trial) since unattended runs require Premium. Familiarity with cloud flows that trigger desktop flows will help — see Triggering Desktop Flows from Cloud Flows: Passing Inputs and Returning Outputs for a full treatment of that integration.
Before you can manage machines intelligently, you need a mental model of what's happening behind the scenes. When you install Power Automate Desktop and register a machine, you're not just installing software — you're establishing an outbound connection from that Windows machine to Microsoft's cloud service. The agent running on the machine (the Power Automate Machine Runtime) maintains a persistent, outbound HTTPS connection to the service bus endpoints in Azure. This is a critical architectural point: no inbound ports need to be opened on the machine or your firewall. The machine calls out; the cloud calls back through that established channel.
This design has significant implications. It means your RPA bots can run on machines behind corporate firewalls with no special network configuration beyond allowing outbound HTTPS to *.servicebus.windows.net and a handful of Microsoft endpoints. It also means that if the machine loses its connection — a network hiccup, a reboot, a sleep state — the orchestration service knows the machine is unavailable and will either wait or route the job elsewhere (if you've configured a group).
The runtime agent runs as a Windows service (UIFlowService) and, separately, a second service handles the machine management registration. When an unattended flow triggers, the cloud flow sends a job to the machine (or group) connection. The runtime agent picks up that job, creates a new Windows session if needed (on Server OS) or uses the existing locked session (on Windows 10/11), executes the desktop flow, and reports results back through the same outbound channel. On Windows Server, this session creation is what allows true parallelism — multiple flows can run simultaneously in separate RDP sessions, each with its own desktop context.
Key insight
Windows 10 and Windows 11 only support a single interactive session at a time. This means a machine running Windows 10/11 can only execute one unattended desktop flow at a time, no matter how many cores it has. Windows Server with Remote Desktop Services properly licensed is the correct choice for any machine that needs to handle concurrent flows.
Older documentation and older environments may reference the "on-premises data gateway" as the connection mechanism for desktop flows. This was the original approach, and it still works — but it's the legacy path. The modern approach is direct machine registration, which gives you tighter control, better visibility, and machine group support. If you're starting fresh, always use machine registration. If you have existing gateway-connected desktop flows, Microsoft's migration tooling can help you move them, but test carefully — connection references and environment targeting behave differently between the two models.
The basic registration flow is straightforward: open Power Automate Desktop, click the machine name in the top bar, sign in with your organizational account, and the machine appears in your environment. But doing it correctly at scale requires more thought.
For unattended automation, the Windows account that runs the desktop flow matters enormously. You have two layers to get right:
For production unattended bots, you should create dedicated service accounts (standard Active Directory or Azure AD joined accounts) rather than using personal user accounts. The reasons are operational, not just security theater: personal accounts get MFA prompts, password expiration policies hit unexpectedly, and when someone leaves the organization their flows break. A dedicated svc-rpa-finance@contoso.com account with a managed password and a calendar reminder for renewal is far more reliable.
Warning
If your Windows session account has MFA enforced on the account level — not just at application sign-in — unattended flows will fail because there's no human present to approve the MFA challenge. Either use conditional access policies to exempt your service accounts from MFA (with compensating controls like IP restrictions), or use accounts that use certificate-based authentication. Coordinate with your identity team before going to production.
In small environments, John's Laptop is fine. In enterprise environments, machine names become your primary operational handle. Build a naming convention before you register your first production machine. A reasonable pattern:
{environment}-{team}-{purpose}-{number}
So: prod-finance-rpa-01, prod-finance-rpa-02, uat-finance-rpa-01. This naming pays off immediately when you're looking at run history at 2 AM trying to figure out which machine in a group is failing.
Power Automate Desktop lets you set the machine's display name in the portal independently of the Windows computer name. Use this — the Windows computer name may follow your IT department's asset naming scheme (WS-00847-A) while the Power Automate display name follows your operational scheme (prod-finance-rpa-01).
Machines are registered to a specific Power Automate environment. This is one of those decisions that's easy to get wrong and painful to reverse. A machine registered to your Default environment cannot be used by flows in your Production environment without re-registration. Map your environments before you register machines:
This isn't just organizational hygiene — it's a security boundary. Flows in your production environment cannot reach machines registered to your dev environment, and vice versa.
A machine group is, at its core, a load balancing construct. When a cloud flow targets a machine group connection instead of a single machine connection, Power Automate's orchestration layer picks the best available machine in the group to run the job. "Best available" follows a simple priority: the machine in the group with the fewest active flows running gets the next job.
But machine groups are more than load balancers. They provide:
In the Power Automate portal (make.powerautomate.com), navigate to Monitor > Machines, then select "Machine groups" from the left navigation. Click "New machine group." You'll provide a display name, optional description, and a group password.
That group password is important and often misunderstood. When a machine joins a group, it uses that password to authenticate its membership. The password isn't a user credential — it's a shared secret for the group itself. Store it in a secure location (your enterprise password manager, or Azure Key Vault if you're using the patterns described in Integrating Power Automate with Azure Key Vault and Managed Identities). If you need to rotate the group password, every machine in the group will need to re-join with the new password.
On each machine, open Power Automate Desktop, navigate to Settings > Machine, and you'll see the option to join a machine group. Enter the group name and password. The machine then appears in the portal under that group. Critically: a machine can only belong to one group at a time. If you need to reorganize groups, you'll need to remove the machine from its current group first.
Tip
Joining a machine to a group doesn't prevent that machine from being targeted individually. A machine in a group still has its own individual machine connection. You might use the individual connection for development/debugging (so you can target one specific machine) and the group connection for production scheduling.
How you organize machines into groups depends heavily on your automation portfolio. Here are the common patterns and the trade-offs:
Single-function groups: One group per automation team or workload type. Finance RPA machines form one group; HR automation machines form another. This gives you workload isolation — a runaway finance process doesn't compete with HR flows for machine capacity. The downside is that machines sit idle when their team's flows aren't running.
General-purpose pools: All production RPA machines in a single group. Maximum resource utilization, but you lose isolation. A poorly written flow that consumes all CPU on one machine affects queue time for everything else. Only viable when all your flows are well-behaved and you have monitoring in place.
Priority groups: Multiple groups targeting the same machines, organized by priority tier. This isn't a native Power Automate feature, but you can approximate it by giving high-priority flows dedicated machines (a small "critical" group) and lower-priority flows a larger shared group. Machines appear in both groups independently — remember, a machine can only be in one group, so the physical machine allocation is fixed.
Environment-mirrored groups: Your UAT group has the same number of machines as your production group. Every machine added to production gets a UAT counterpart. This sounds expensive but dramatically reduces "works in UAT, fails in prod" incidents when the failure is environment-related rather than flow-related.
Credential management is where most unattended automation implementations accumulate technical debt. Getting it right from the start saves enormous pain later.
When Power Automate runs an unattended flow on a machine, it needs to create or use a Windows session. On Windows Server, this means logging in (or reconnecting to an existing session) as a specific Windows user. That user's credentials are stored in the machine connection in the Power Automate portal.
Navigate to your machine connection in the Power Automate portal, and you'll see a "Desktop flows connection" that includes a Windows username and password. This is the account Power Automate will log in as when running unattended flows through this machine. If that password changes (Windows password expiration policy, manual reset, account locked), your flows fail immediately with a session creation error.
Warning
Windows Server's default password expiration policy is 42 days. If your service accounts are subject to this policy and you don't have alerts configured, you'll have a production outage every 42 days on a predictable schedule. Set password expiration reminders 7 days before expiration, or better, work with IT to set a non-expiring password policy for your dedicated RPA service accounts (with appropriate compensating controls).
The connection stored in your cloud flow that points to your machine or machine group is called a connection reference. This is the bridge between the cloud flow and the physical machine infrastructure. When you move flows between environments (dev → UAT → prod), you don't want to hard-code machine connections in the flow — you want the connection reference to resolve differently per environment.
This is where environment variables for connections come in. In solution-aware flows (which you should be using for anything going to production — see Deploying and Managing Power Automate Solutions Across Environments), connection references are environment-scoped. When you import a solution into production, you remap the connection references to your production machine group connections. The flow itself doesn't change; only the connection mapping changes.
By default, Power Automate unattended flows attempt to reuse an existing Windows session on the machine if one exists for that user account. This is faster (no login screen rendering, no profile load time) but can cause subtle state issues. If a previous flow run left behind a modal dialog, an open file lock, or an application in an unexpected state, the next flow picks up that polluted environment.
For critical flows where isolation matters, explicitly add a "Close all windows" action at the start of your desktop flow (targeting every application your flow uses), and include a structured cleanup sequence in your error handling. This approximates a fresh session without the overhead of a full logout/login cycle.
For flows that are highly sensitive to state contamination — particularly those automating legacy Windows applications that have notoriously bad session cleanup behavior — consider using a dedicated machine per flow with session recycling configured. Windows can be configured to log out after a session ends via Group Policy (Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Set time limit for disconnected sessions).
Building the infrastructure is the easy part. Sizing it correctly for your actual workload is where engineering judgment comes in.
Before adding machines, instrument what you're running. In the Power Automate portal, navigate to Monitor > Desktop flow runs. You can filter by machine, machine group, time window, and flow name. Export this data and look for:
Key insight
The Power Automate portal's monitoring view shows run-level data, not queue-level data in real time. For production environments, pipe your run data to a Power BI dashboard via the Power Automate Management connector or the CoE Toolkit. You want to see queue depth trends over time, not just current state.
On Windows Server with RDS properly configured, the practical limit on concurrent desktop flow sessions per machine depends on RAM and CPU more than on any software limit. A common production sizing:
These are starting points, not gospel. Your flows' actual resource profiles depend entirely on the applications they're automating. Test with realistic workloads before you commit to a VM size in production.
Power Automate queues jobs for a machine group when all machines are busy. The default timeout for a queued job is 3 hours — meaning if a flow can't get a machine in 3 hours, it fails with a timeout error. For most batch workloads, 3 hours is too generous (it masks capacity problems) or too short (for very large queues with long-running jobs). You can configure the desktop flow run timeout in the cloud flow trigger or run action settings.
For a nightly batch that processes invoices, a sensible design might be:
Production machines need patching. Windows Update doesn't care about your automation schedule. Build maintenance windows into your operational model:
Security in RPA tends to be underdiscussed because "it's just automating what a human does." That framing is wrong and dangerous. Your RPA bots often have broader access than individual humans (they're logged in as service accounts with access to multiple systems), they run unattended (no human to notice something wrong), and they store credentials that span multiple systems.
The Windows service account used for unattended runs should have exactly the permissions needed to do its job — no more. For a flow that reads from a legacy ERP system and writes to SharePoint, that account needs:
It does not need local administrator rights on the RPA machine (create a dedicated group for the specific rights needed — typically "Log on as a service" and "Log on locally"), domain admin rights, global SharePoint admin rights, or access to systems unrelated to its flows.
Warning
Many RPA implementations give service accounts local administrator rights "to make things work." This is a significant security risk. If your desktop flow can be hijacked (malicious input, prompt injection in scraped web content, a compromised trigger), an admin-privileged bot can do far more damage than a least-privilege bot. Do the work to identify the minimum required permissions.
RPA machines should be on a dedicated subnet or VLAN where possible. This allows your network team to implement strict egress filtering — the machine can only reach the systems it legitimately needs, plus the Microsoft cloud endpoints for the Power Automate service. Inbound connections to the machine should be blocked at the firewall level (remember, the Power Automate agent uses outbound connections only).
For flows that access external web services or automate browsers (web automation flows in particular), consider whether the automation machine needs unrestricted internet access or can be limited to specific FQDNs. A flow that only ever accesses vendor-portal.contoso-supplier.com doesn't need unrestricted internet.
Every unattended flow run is logged in Power Automate's run history with the machine it ran on, the credentials used, start and end time, and status. This is valuable audit trail data, but it ages out — Power Automate retains desktop flow run history for 28 days by default. For compliance-sensitive automation, you need to export this data before it expires.
Build a daily scheduled cloud flow that reads the desktop flow run history via the Power Automate Management connector and writes it to a Dataverse table or Azure Data Lake for long-term retention. This gives you the audit trail your security and compliance teams will eventually ask for, and it provides the historical data you need for capacity planning.
With a well-configured machine fleet, you can implement orchestration patterns that go well beyond "run this flow at 11 PM."
The canonical pattern for batch processing at scale: a parent cloud flow reads a list of work items (invoices to process, employees to onboard, records to validate), splits that list into individual items, and fans out one desktop flow run per item to the machine group. The machine group's load balancer distributes the work across available machines.
In Power Automate, this looks like:
Tip
When fanning out to a machine group with an Apply to each loop, set the loop's concurrency control to a value slightly higher than your machine group capacity. If you have 5 machines, set concurrency to 6–8. This keeps the queue from growing too large while ensuring machines are never starved waiting for the parent flow to submit the next job. Setting concurrency too high doesn't improve speed — machines can only work so fast — and it increases the risk of hitting API rate limits on the downstream systems your flows are accessing.
For more sophisticated orchestration, replace the simple fan-out with a work queue backed by Dataverse. This pattern decouples the job submission from the job execution and gives you retry semantics, priority queuing, and better failure isolation.
The architecture:
WorkQueue table with pending items, each with a status of PendingInProgress with a timestamp and the claiming flow's IDComplete or Failed with error details on completionThis pattern survives partial failures (if a worker flow crashes mid-batch, items that were InProgress for more than a configurable timeout are reset to Pending by a cleanup flow), supports priority (add a priority column and the dispatcher claims high-priority items first), and gives you fine-grained visibility into exactly what's in progress.
Power Automate's Apply to each loop, when configured with concurrency enabled, naturally creates parallel execution. With a machine group as the target, those parallel runs distribute across machines. This is the most common parallelism pattern and is covered in detail in Implementing Parallel Branching and Concurrency Control in Power Automate — particularly the section on preventing race conditions when multiple bot runs write to the same data store.
The critical rule for parallel desktop flows: never have two concurrent flows write to the same file, the same database record, or the same application state without a locking mechanism. Two flows writing to the same Excel file simultaneously is a classic failure mode for fan-out patterns. Solutions include:
This exercise builds a production-grade machine group setup with a simple fan-out orchestration. You'll need at least one Windows machine with Power Automate Desktop installed, a Premium Power Automate license, and admin access to the Power Automate portal.
exercise-rpa-group-01 and a description noting this is for the exerciseexercise-rpa-group-01 and the password you createdCreate a simple desktop flow that accepts a WorkItemId input variable and simulates processing:
Input variables:
WorkItemId (Text) — "The ID of the work item to process"
Main:
Log message: "Processing work item: " + WorkItemId
Wait 10 seconds (simulates work being done)
Set variable ProcessingResult to "Completed: " + WorkItemId
Output variables:
ProcessingResult (Text) — "Result of processing"
This is deliberately simple — you're exercising the machine group infrastructure, not the flow logic. In a real scenario, this flow would be automating Excel, pulling from a legacy system, or executing complex subflow logic.
WorkItems as an array: ["WI-001","WI-002","WI-003","WI-004","WI-005"]WorkItems, with concurrency set to 3exercise-rpa-group-01 group)WorkItemId inputRun the flow and immediately navigate to Monitor > Desktop flow runs in the portal. Watch as jobs appear with status "Running" or "Queued." If you have multiple machines in your group, you'll see jobs distribute across them. With a single machine, you'll see some jobs queue while others run (since our test flow has a 10-second wait, the 5 jobs will run sequentially on one machine, demonstrating why adding more machines to the group speeds up the batch).
Challenge: Add a second machine to the group and rerun. Compare total wall-clock time for the batch with one machine vs. two.
Symptom: Jobs stay in "Queued" status even though the portal shows machines as online.
Cause: Usually one of three things — the Windows session account credentials stored in the machine connection are incorrect or expired, the machine's Power Automate runtime service is running but the machine has lost its service bus connection, or the desktop flow's targeted connection is pointing to an individual machine connection rather than the group connection.
Fix: Navigate to the machine in the portal and check its status (Online vs. Offline). If Online, test the connection by clicking "Test connection" (available in the machine settings). If that fails, re-enter the Windows credentials. Check Windows Event Viewer on the machine under Applications and Services > Microsoft > Power Automate for specific error codes from the UIFlowService.
Symptom: The exact same flow runs perfectly in UAT, fails immediately in production with UI automation errors.
Cause: Screen resolution differences between UAT and production VMs. Many UI selectors that appear robust actually contain absolute coordinate fallbacks that break when the desktop resolution changes. A 1920x1080 UAT VM and a 1280x1024 production VM will produce different element positions, different window sizes, and different font rendering.
Fix: Standardize screen resolution across all RPA machines via Group Policy. Also audit your selectors for coordinate-based fallbacks and replace them with attribute-based selectors. For RDP sessions, set the remote session resolution in the Remote Desktop Connection settings to a fixed value rather than "match client resolution."
Symptom: When flows run concurrently, results are wrong or some updates are lost.
Cause: Two flows simultaneously writing to the same SharePoint list, Excel file, or database table without concurrency control. This is a race condition.
Fix: As described in the orchestration patterns section above, use Dataverse for shared state (it handles row-level locking), or assign each parallel flow a uniquely scoped output target (its own file, its own row range, its own database partition). If you must share state, implement a lock mechanism. See Implementing Parallel Branching and Concurrency Control in Power Automate for locking patterns.
Symptom: Machines intermittently show as Offline in the portal, particularly overnight.
Cause: Windows Update auto-restart, sleep/hibernate settings not disabled, or the machine's network adapter going into power-save mode and dropping the outbound connection.
Fix: On all RPA machines, configure via Group Policy or registry:
powercfg /change standby-timeout-ac 0powercfg /change disk-timeout-ac 0Computer Configuration > Policies > Administrative Templates > Network > Network Connections)Symptom: Flows fail at the first UI interaction because the application isn't fully loaded.
Cause: The flow opens an application and immediately tries to interact with it before it's rendered. On a freshly started session, application load times can be 3–5x longer than on a warmed-up session.
Fix: Add explicit wait conditions rather than fixed Wait actions. Use "Wait for element to exist" targeting a reliably present UI element that only appears when the application is fully loaded. This is more resilient than Wait 5 seconds and faster on fast machines. This is discussed in detail in the context of automating legacy applications.
Managing machines and machine groups well is the operational foundation that separates fragile one-bot experiments from scalable enterprise automation. Here's what you've covered:
Architecture: The Power Automate machine runtime uses outbound connections to Azure Service Bus, requiring no inbound firewall rules. Machine groups provide load balancing and high availability. Windows Server (not Windows 10/11) is the right platform for concurrent unattended flows.
Registration and configuration: Dedicated service accounts, consistent naming conventions, environment-targeted registration, and careful group design are decisions that pay dividends for years.
Credentials: Store Windows credentials carefully, plan for password expiration, and use connection references in solution-aware flows to make environment promotion clean.
Capacity planning: Instrument your existing runs before adding machines. Understand the concurrency limits of your OS and your applications. Build maintenance windows into your operational model.
Security: Least privilege for service accounts, network isolation for RPA machines, and long-term audit log retention are non-negotiable for production deployments.
Orchestration patterns: Fan-out with Apply to each + concurrency control is your workhorse pattern. Work queues backed by Dataverse are the right architecture when you need retry semantics, priority, or complex failure handling.
For your next steps, dig into the cloud-side orchestration that drives your machine fleet: understanding how to structure the cloud flows that trigger desktop flows at scale is covered in Triggering Desktop Flows from Cloud Flows: Passing Inputs and Returning Outputs. If your flows are processing large volumes of data across multiple systems, the error handling discipline in Error Handling in Desktop Flows: On Block Error, Retry Policies, and Recovery Screenshots will save you when something inevitably goes wrong at 2 AM. And for the governance layer that sits above your entire automation estate, explore Auditing and Governing Power Automate at Scale with the CoE Toolkit.