How to Create a Windows Scheduled Task to Run Every Minute (Batch/PowerShell Example)


2 views

In Windows Server administration and automation, there are legitimate cases where you need to check conditions every minute. Common scenarios include:

  • Monitoring log files for specific events
  • Checking resource availability
  • Processing queued items
  • Maintaining heartbeat checks

For Windows Server 2008 R2 (which uses the older Task Scheduler 1.0 interface):

  1. Open Task Scheduler (taskschd.msc)
  2. Right-click "Task Scheduler Library" → Create Task
  3. In General tab:
    • Name: "MinuteCheck"
    • Select "Run whether user is logged on or not"
    • Check "Run with highest privileges" if needed
  4. In Triggers tab → New:
    • Begin the task: "On a schedule"
    • Settings: "One time" (we'll modify this)
    • Advanced settings → Repeat task every: 1 minute
    • Duration: Indefinitely
  5. In Actions tab → New:
    • Action: "Start a program"
    • Program/script: "C:\path\to\your_script.bat" or "powershell.exe"
    • Arguments (if PowerShell): "-File C:\path\to\script.ps1 -ExecutionPolicy Bypass"

For scripting or remote deployment, use schtasks.exe:

schtasks /create /tn "MinuteCheck" /tr "powershell.exe -File C:\scripts\check.ps1" /sc minute /mo 1 /ru SYSTEM /rl HIGHEST

Here's a simple batch file example (check_conditions.bat):

@echo off
set LOGFILE=C:\logs\minutecheck_%date:~-4,4%%date:~-7,2%%date:~-10,2%.log

:: Check for your condition here
tasklist | findstr /i "critical_process.exe" >nul
if %errorlevel% equ 1 (
    echo %time% - Critical process not running >> %LOGFILE%
    start "" "C:\apps\restart_service.bat"
) else (
    echo %time% - Check passed >> %LOGFILE%
)

For more advanced scenarios, use PowerShell (minute_check.ps1):

$logPath = "C:\logs\minutecheck_$(Get-Date -Format 'yyyyMMdd').log"
$condition = Test-Path "C:\temp\process_flag.file"

if ($condition) {
    "$(Get-Date -Format 'HH:mm:ss') - Flag detected" | Out-File $logPath -Append
    & "C:\scripts\take_action.exe" -param value
}
else {
    "$(Get-Date -Format 'HH:mm:ss') - No action needed" | Out-File $logPath -Append
}

After setup:

  • Wait 2-3 minutes to confirm execution
  • Check "Last Run Time" in Task Scheduler
  • Verify system event log (Event Viewer → Windows Logs → System)
  • For PowerShell scripts, check execution policy: Get-ExecutionPolicy -List

When running tasks every minute:

  • Keep script execution time under 30 seconds
  • Implement proper logging to track performance
  • Consider adding random delay (0-30s) if running on multiple servers
  • Monitor Task Scheduler's "Active Tasks" count

When implementing monitoring scripts or rapid-response automation on Windows Server 2008 R2 and newer systems, the Task Scheduler's UI complexity often causes confusion. The critical requirement is ensuring near-real-time execution while maintaining system reliability.

Here's the most reliable method through PowerShell (also works via GUI):

$Action = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-File C:\scripts\monitor.ps1"
$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName "MinuteMonitor" -Action $Action -Trigger $Trigger -RunLevel Highest
  • Run whether user is logged on or not: Prevents interruption
  • Run with highest privileges: If script needs admin rights
  • Configure for: Windows Server 2008 R2 (for compatibility)
  • Start the task immediately: Ensures first run happens right away

The task will:

  • Start immediately after creation
  • Run every minute continuously
  • Survive reboots automatically
  • Maintain schedule even if previous instance is running

For scripts that mostly exit quickly, consider this pattern:

# monitor.ps1 example
$condition = Test-Path "C:\trigger.txt"
if ($condition) {
    # Execute main logic
    Remove-Item "C:\trigger.txt" -Force
}

If tasks miss executions:

  1. Check Task Scheduler event logs (Event Viewer -> Applications and Services Logs -> Microsoft -> Windows -> TaskScheduler)
  2. Verify the task status isn't "Queued"
  3. Ensure "Stop the task if it runs longer than" isn't set too low