Learn how to trigger Power Automate Desktop flows on a schedule using Windows Task Scheduler and the PAD Machine Runtime. This lesson covers session configuration for attended and unattended bots, PowerShell-based run logging, and common scheduling failure modes — with step-by-step setup you can apply immediately.

Imagine you've built a solid desktop flow that pulls overnight sales data from your company's legacy ERP system, transforms it in Excel, and emails a summary to your team every morning. The flow works perfectly when you run it manually. The problem? You have to be at your desk at 6:45 AM to click the button — or you have to trust a colleague to do it on vacation days. That's not automation. That's just delegation with extra steps.
This is exactly the gap that scheduled execution fills. By combining Windows Task Scheduler with the Power Automate Machine Runtime, you can trigger desktop flows on a precise schedule — even when no one is logged in, even at 3 AM, even on a machine sitting in a server room. You get the full power of unattended RPA without needing a cloud-triggered flow or a premium-licensed orchestration platform for every use case. And when something goes wrong (it will), you'll have logs to tell you exactly what happened.
By the end of this lesson, you'll know how to configure Windows Task Scheduler to trigger desktop flows via the Machine Runtime command-line interface, manage Windows session state so your bot has a desktop environment to work in, choose the right approach for attended versus unattended scenarios, and write run logs that make troubleshooting a straightforward process rather than a detective mystery.
What you'll learn:
Before diving in, you should be comfortable with the basics of Power Automate Desktop. If you haven't built and run a desktop flow yet, start with Getting Started with Power Automate Desktop: Installing, Recording, and Running Your First Desktop Flow first, then come back here. You should also understand the conceptual difference between attended and unattended automation — if that's fuzzy, Attended vs Unattended RPA: Choosing a Run Mode and Configuring Machines in Power Automate covers it thoroughly.
On the tooling side, you'll need:
Before you configure anything, it's worth understanding what's actually happening under the hood. Power Automate Desktop doesn't just run flows on its own — it relies on a background Windows service called the Power Automate Machine Runtime (also referred to as the Machine Runtime Agent) to manage flow execution requests, maintain the connection to the Power Automate cloud service, and handle session state.
When you trigger a desktop flow from the cloud (say, from a cloud flow calling into a machine), the Machine Runtime receives that trigger and launches the flow in the appropriate Windows session. When you trigger a flow locally through Task Scheduler, you're bypassing the cloud trigger but still relying on the Machine Runtime to handle the execution environment correctly.
The command-line executable you'll use is PAD.Console.Host.exe, located in your Power Automate Desktop installation folder, typically:
C:\Program Files (x86)\Power Automate Desktop\PAD.Console.Host.exe
This executable accepts arguments that tell it which flow to run and under what context. It's the bridge between your scheduled task and the flow engine.
Note
The Machine Runtime service (UIFlowService) must be running for scheduled execution to work. You can verify this by opening Services (press Windows + R, type services.msc, press Enter) and looking for "Power Automate" in the list. If it's stopped, right-click and start it — and consider setting it to start automatically.
The Machine Runtime also manages the machine registration with Power Automate cloud. Even when you're triggering flows locally, the runtime still maintains this registration so that run history, status updates, and machine availability signals are sent back to the Power Automate portal. This is useful for monitoring, which we'll cover in the logging section.
Here's the single most important concept in this entire lesson: desktop flows need a Windows desktop session to interact with UI elements. This is not a Power Automate limitation — it's a fundamental constraint of how Windows works. Applications render their interfaces inside a user session, and automation actions like clicking buttons, typing into fields, and reading screen content require access to that rendered environment.
This creates different requirements depending on your scenario.
In attended mode, the flow runs alongside a logged-in user. The user's session is already active, the desktop is visible and unlocked, and the flow can interact with whatever is on screen. The scheduling challenge here is simpler: you just need the user to be logged in when the task fires. This works well for tasks that run during business hours when the machine is in use anyway — for example, a flow that processes a report at 8:00 AM when staff are already at their desks.
For attended scheduled flows, the Task Scheduler task should run as the same user who is logged in interactively. If the logged-in user is CORP\jane.doe, your scheduled task should run under that account. This ensures the task fires in the correct session.
Unattended automation is where things get more nuanced. If no one is logged into the machine, there's no Windows session, and therefore no desktop for the flow to interact with. You have two main approaches:
Option 1: Auto-login with a dedicated service account. Configure the machine to automatically log in to a specific Windows account when it starts up. This keeps an active session alive around the clock. The user account doesn't need to be physically present — Windows maintains the session even when the screen is locked, as long as it was logged in (not locked before login).
Option 2: Keep an RDP session alive. If the machine is a server or remote VM, connect via Remote Desktop Protocol (RDP) and leave the session running — either by disconnecting without logging out, or by using tools that maintain the session. Note that disconnected RDP sessions still provide a valid Windows session for automation purposes.
Warning
Screen locking is not the same as session absence. A locked screen (Windows + L) still has an active session underneath — UI automation can still operate in that session. However, some flows that depend on the active foreground window or specific screen state may behave differently on a locked screen. Test your specific flow in a locked-screen scenario before relying on it in production.
A third approach — using a Windows service account with "Log on as a batch job" privileges configured to run a virtual desktop session — exists for enterprise environments and involves Group Policy configuration. For most teams at this level, the auto-login approach is the practical starting point.
Open Task Scheduler by pressing Windows + S, typing "Task Scheduler," and selecting it from results. You'll see the main console with a task library on the left, task list in the center, and an Actions panel on the right.
In the right-hand Actions panel, click Create Task (not "Create Basic Task" — the full dialog gives you the controls you need).
On the General tab:
Give the task a clear, descriptive name — something like PAD - Morning Sales Report Flow. In the description field, add the flow name, who owns it, and when it was created. This documentation matters when someone is debugging the task six months from now.
Under "Security options," click Change User or Group and enter the Windows account that should run the flow. For unattended scenarios, this should be a dedicated service account. For attended scenarios, this should be the user who will be logged in.
Check the box "Run whether user is logged on or not" for unattended scenarios. This tells Windows to run the task even if that user doesn't have an active interactive session — though remember, the flow itself still needs a session to work in (handled by your auto-login configuration). For attended scenarios where you need the flow to interact with the active desktop, leave this at "Run only when user is logged on".
Also check "Run with highest privileges" if your flow interacts with applications that require elevation. Many legacy business applications do.
On the Triggers tab:
Click New to create a trigger. Choose "On a schedule" from the Begin the task dropdown. Set your recurrence — daily, weekly, specific days — and set the start time. For our morning sales report example, you'd set this to 6:30 AM daily, giving the flow time to complete before staff arrive at 8:00 AM.
You can add multiple triggers to the same task. For example, you might also add an "At startup" trigger as a safety net — if the machine reboots overnight, the task fires when Windows starts, ensuring the flow still runs.
On the Actions tab:
Click New. Under Action, select Start a program.
In the "Program/script" field, enter the full path to the PAD console host:
"C:\Program Files (x86)\Power Automate Desktop\PAD.Console.Host.exe"
In the "Add arguments" field, you'll pass the flow identifier. The argument structure looks like this:
-flowName "Morning Sales Report" -environmentId "your-environment-id"
To find your environment ID, open the Power Automate portal (make.powerautomate.com), navigate to your environment, and look at the URL — the GUID in the path is your environment ID.
Tip
Flow names with spaces must be wrapped in quotes in the arguments field. If your flow name contains special characters, consider renaming it to use underscores instead — it removes a whole category of escaping problems.
On the Conditions tab:
Uncheck "Start the task only if the computer is on AC power" unless you're genuinely concerned about battery-powered laptops running automation. For dedicated RPA machines, this condition causes unexpected skips.
Consider checking "Wake the computer to run this task" if the machine goes to sleep during off-hours. This uses Windows WoL (Wake on LAN) capabilities to bring the machine out of sleep before firing the task.
On the Settings tab:
Set "If the task is already running, then the following rule applies" to "Do not start a new instance." This prevents concurrent flow executions if one run is still in progress when the next trigger fires — a common issue with slow flows on shared machines.
Set a reasonable Stop the task if it runs longer than value. If your flow normally completes in 10 minutes, a 45-minute timeout gives buffer while catching infinite loops or hung states.
Click OK and enter the account password when prompted. Your task is now scheduled.
The Machine Runtime sends run status back to the Power Automate cloud, so you can see executions in the portal under Monitor → Desktop Flow Runs. But cloud logging has a lag and requires internet connectivity. Local logging gives you an immediate, always-available record — and it lets you capture details that the portal doesn't, like intermediate variable states or application-specific error messages.
The simplest approach is to add logging actions directly inside your desktop flow. At the start of your flow's Main subflow, use a Write text to file action (under File → Write text to file) to append a start entry to a log file:
Log file path: C:\AutomationLogs\SalesReport\run_log.txt
Text to write: %CurrentDateTime% | RUN STARTED | Flow: Morning Sales Report
Write mode: Append
At the end of the flow, write another entry:
Text to write: %CurrentDateTime% | RUN COMPLETED | Status: SUCCESS
Inside your error handling blocks — which you should have, as covered in Error Handling in Desktop Flows: On Block Error, Retry Policies, and Recovery Screenshots — write failure entries:
Text to write: %CurrentDateTime% | RUN FAILED | Error: %LastError%
This gives you a simple, human-readable log file at C:\AutomationLogs\SalesReport\run_log.txt that looks like:
2024-03-15 06:31:02 | RUN STARTED | Flow: Morning Sales Report
2024-03-15 06:31:02 | STEP: Opening ERP application
2024-03-15 06:38:47 | RUN COMPLETED | Status: SUCCESS
2024-03-16 06:31:01 | RUN STARTED | Flow: Morning Sales Report
2024-03-16 06:33:12 | RUN FAILED | Error: Application window not found
A more robust approach uses Task Scheduler to call a PowerShell script, which then calls PAD.Console.Host.exe and captures its exit code and any console output. This gives you OS-level logging independent of what the flow itself does.
Create a file called Run-SalesReportFlow.ps1:
# Run-SalesReportFlow.ps1
# Wrapper script for Morning Sales Report desktop flow
$LogPath = "C:\AutomationLogs\SalesReport\scheduler_log.txt"
$FlowName = "Morning Sales Report"
$EnvId = "your-environment-id-here"
$PADExe = "C:\Program Files (x86)\Power Automate Desktop\PAD.Console.Host.exe"
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $LogPath -Value "$Timestamp | SCHEDULER: Task triggered for flow '$FlowName'"
try {
$Process = Start-Process -FilePath $PADExe `
-ArgumentList "-flowName `"$FlowName`" -environmentId `"$EnvId`"" `
-Wait `
-PassThru `
-NoNewWindow
$ExitCode = $Process.ExitCode
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
if ($ExitCode -eq 0) {
Add-Content -Path $LogPath -Value "$Timestamp | SCHEDULER: Flow completed successfully (Exit code: 0)"
} else {
Add-Content -Path $LogPath -Value "$Timestamp | SCHEDULER: Flow exited with code $ExitCode — investigate run log"
}
} catch {
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $LogPath -Value "$Timestamp | SCHEDULER: EXCEPTION launching flow — $_"
}
In Task Scheduler, update your Action to call PowerShell:
Program/script: powershell.exe
Arguments: -ExecutionPolicy Bypass -File "C:\AutomationScripts\Run-SalesReportFlow.ps1"
Tip
The -ExecutionPolicy Bypass flag is necessary because Windows often blocks unsigned script execution by default. For production environments, consider signing your scripts and using a less permissive policy — but for internal RPA scripts on dedicated machines, Bypass is a practical starting point.
Even with a perfectly configured Task Scheduler task, your flow will fail silently if the Windows session isn't in the right state. Here are the session conditions you need to manage.
To configure automatic login for a dedicated service account, open Registry Editor (Windows + R, type regedit, press Enter) and navigate to:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Set the following values (create them if they don't exist):
AutoAdminLogon = 1 (string value)DefaultUserName = your-service-account-username (string value)DefaultPassword = the-account-password (string value)DefaultDomainName = your-domain (string value, leave blank for local accounts)Warning
Storing a password in the registry in plaintext is a security risk. This approach is acceptable for dedicated, physically secured RPA machines on isolated networks. For machines with broader access or in shared environments, use Windows Autologon (Sysinternals tool), which stores the password in an encrypted form, or configure Group Policy to manage this more securely. Never use this approach on a machine that stores sensitive data accessible to other users.
Your flow may depend on certain applications already being open, or it may need to launch them fresh. The Machine Runtime doesn't pre-warm application states — each run starts from whatever the current session state is. This is why Automating Windows Service and Process Management in Power Automate Desktop: Starting, Stopping, and Monitoring Applications Before and After Desktop Flow Execution is a valuable companion topic. Building explicit "ensure application is running" logic at the start of your flow is far more reliable than assuming state.
A typical flow structure for scheduled unattended execution looks like this:
This restart-clean approach prevents state carryover from failed previous runs from corrupting new ones.
Let's build a complete scheduled execution setup for a realistic scenario: a flow that opens a CSV file of daily expenses, calculates the total, and writes the result to an Excel summary sheet — run automatically every weekday at 7:00 AM.
Step 1: Prepare the desktop flow
Open Power Automate Desktop and create a new flow called Daily Expense Totaller. Add these actions:
%CurrentDateTime% | START to C:\AutomationLogs\expense_log.txtC:\Data\DailyExpenses.csvC:\Data\ExpenseSummary.xlsx%CurrentDateTime% | COMPLETE | Total: %ExpenseTotal% to the logAdd an On Block Error handler that writes %CurrentDateTime% | FAILED | %LastError% to the log.
Save and test the flow manually to confirm it works.
Step 2: Create the PowerShell wrapper
Create C:\AutomationScripts\Run-ExpenseFlow.ps1 using the template from the logging section above, substituting your flow name.
Step 3: Configure Task Scheduler
Open Task Scheduler and create a new task named PAD - Daily Expense Totaller. Configure:
powershell.exe with argument -ExecutionPolicy Bypass -File "C:\AutomationScripts\Run-ExpenseFlow.ps1"Step 4: Test without touching the machine
Right-click the task in Task Scheduler and click Run. Watch the log file update in real time by opening a PowerShell window and running:
Get-Content C:\AutomationLogs\expense_log.txt -Wait
The -Wait flag tails the file, refreshing as new entries are added. Verify you see the START entry, then the COMPLETE entry with a total value.
The task fires but nothing visibly happens. This almost always means the task is running in a non-interactive session. Check the General tab — if "Run whether user is logged on or not" is checked but there's no active session for the account, the task will start, but PAD won't have a desktop to work in. Solution: ensure the account is actually logged in, or switch to "Run only when user is logged on" for attended flows.
The flow works manually but fails in Task Scheduler.
The most common cause is a path problem. When Task Scheduler runs a task, the working directory may differ from what you expect. Use full absolute paths everywhere in your flow — for file operations, application launches, and log writes. Never use relative paths like .\Data\file.csv in scheduled flows.
The scheduled task shows "Last Run Result: 0x1" or other error codes. Exit code 0x1 means the process encountered an unhandled error. Check both your PowerShell wrapper log and the Power Automate Desktop run history in the portal. Also check Windows Event Viewer (Application log) for PAD-related errors around the task execution time.
The Machine Runtime service isn't running when the task fires. Add a pre-task that ensures the service is running. You can do this in your PowerShell wrapper:
$service = Get-Service -Name "UIFlowService" -ErrorAction SilentlyContinue
if ($service.Status -ne 'Running') {
Start-Service -Name "UIFlowService"
Start-Sleep -Seconds 5
}
The task runs the flow under the wrong user context. If your machine has multiple user accounts, ensure the task's security principal matches the account that has access to the flow and the target applications. Flow access credentials are account-specific in Power Automate Desktop.
Key insight
Most scheduling failures are infrastructure problems, not flow problems. When a scheduled run fails, check session state, service status, and file paths before assuming the flow logic is broken. The flow probably works fine — it just doesn't have the environment it expects.
You now have a complete picture of how to schedule desktop flow execution using Windows Task Scheduler and the Power Automate Machine Runtime. The core ideas are: use PAD.Console.Host.exe as your execution target, match your session configuration (auto-login for unattended, active user for attended) to your use case, wrap your task in a PowerShell script for robust logging, and build your flows to handle the clean-start environment of scheduled execution.
This approach covers a broad range of use cases, from simple overnight batch processing to daily data pulls from legacy applications. As your automation portfolio grows, you'll likely hit limits with this local scheduling approach — specifically around managing multiple machines, handling concurrent runs, and orchestrating flows that depend on each other. When you reach that point, Managing Machines and Machine Groups for Scalable Unattended Automation in Power Automate shows you how to move to cloud-based orchestration that handles these problems at scale.
For flows that need to be triggered by events in other systems — an email arriving, a SharePoint file being updated, a database record changing — Triggering Desktop Flows from Cloud Flows: Passing Inputs and Returning Outputs explains how to connect your desktop flow into the broader Power Automate ecosystem. And once you have multiple scheduled flows running in production, Monitoring and Troubleshooting Desktop Flow Runs at Scale gives you the visibility tools to catch problems before they become outages.