{"id":47,"date":"2024-03-03T17:20:00","date_gmt":"2024-03-03T14:20:00","guid":{"rendered":"https:\/\/fsaeed.blog\/?p=47"},"modified":"2026-10-31T00:18:53","modified_gmt":"2026-10-30T21:18:53","slug":"windows-task-scheduler-python-scripts","status":"publish","type":"post","link":"https:\/\/fsaeed.blog\/index.php\/2024\/03\/03\/windows-task-scheduler-python-scripts\/","title":{"rendered":"Run Your Python Scripts Automatically with Windows Task Scheduler"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hello again, tech enthusiasts! \ud83d\udc4b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You wrote a great Python script. It cleans a report, or saves attachments, or builds a summary. But you still have to remember to run it. If you are on holiday, or busy in a meeting, the script just waits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Today we will make Windows run the script for you, every day, at the same time. We will use <strong>Task Scheduler<\/strong>. It is a program that comes with Windows. Think of it like an alarm clock: when the time comes, it does not ring, it starts your program.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Many people try this and the task &#8220;runs&#8221; but nothing happens. In this post, we will avoid the usual mistakes with three simple tricks: the full path to Python, the &#8220;Start in&#8221; folder and a log file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What you need<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Windows 10 or 11<\/li>\n\n\n<li>Python 3 from <a href=\"https:\/\/www.python.org\">https:\/\/www.python.org<\/a><\/li>\n\n\n<li>A script, for example <code>C:\\Scripts\\daily_report.py<\/code><\/li>\n\n\n<li>15 minutes<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Find the full path to python.exe<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Task Scheduler does not always know where Python is. So we give it the full address. Open the Command Prompt and type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>where python<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will see something like <code>C:\\Users\\YourName\\AppData\\Local\\Programs\\Python\\Python312\\python.exe<\/code>. Copy this path. We will need it soon.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you see two paths, use the one that you normally use (the one where you installed your libraries with <code>pip<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Add logging to your script<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a task runs in the background, you cannot see any messages. A <strong>log file<\/strong> is like a diary for your script. It writes down what happened and when. If something goes wrong at 6 in the morning, you can read the diary later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add this to the top of your script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import logging\nfrom pathlib import Path\n\n# Save the log next to the script, not in a random folder\nLOG_FILE = Path(__file__).parent \/ \"daily_report.log\"\n\nlogging.basicConfig(\n    filename=LOG_FILE,\n    level=logging.INFO,\n    format=\"%(asctime)s %(levelname)s %(message)s\",\n)\n\ndef main():\n    logging.info(\"Script started\")\n    # ... your real work goes here ...\n    logging.info(\"Script finished\")\n\nif __name__ == \"__main__\":\n    try:\n        main()\n    except Exception:\n        logging.exception(\"Script failed\")  # writes the full error to the log\n        raise<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Path(__file__).parent<\/code> means &#8220;the folder where this script lives&#8221;. This keeps the log in a place you can find.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create a .bat wrapper<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>.bat file<\/strong> (batch file) is a small text file with Windows commands. Double-click it, and Windows runs the commands one by one. We use it as a wrapper: a small box around our script that sets everything up first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open Notepad and paste this. Change the paths to match your computer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@echo off\nREM Move to the script folder, so relative file names work\ncd \/d \"C:\\Scripts\"\n\nREM Run the script with the full path to python.exe\nREM Any extra messages and errors go to run_output.log\n\"C:\\Users\\YourName\\AppData\\Local\\Programs\\Python\\Python312\\python.exe\" \"C:\\Scripts\\daily_report.py\" &gt;&gt; \"C:\\Scripts\\run_output.log\" 2&gt;&amp;1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save it as <code>C:\\Scripts\\run_daily_report.bat<\/code>. In Notepad, choose <strong>Save as type: All Files<\/strong>, or Windows may save it as <code>.txt<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>2&gt;&amp;1<\/code> means &#8220;send errors to the same file as normal messages&#8221;. So even a crash before logging starts will be recorded.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Double-click the <code>.bat<\/code> file to test it. Then open the log files and check that you see &#8220;Script started&#8221; and &#8220;Script finished&#8221;.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Create the task<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Press the Windows key, type <strong>Task Scheduler<\/strong> and open it.<\/li>\n\n\n<li>On the right, click <strong>Create Basic Task<\/strong>.<\/li>\n\n\n<li>Give it a name, like <code>Daily Report<\/code>, and click <strong>Next<\/strong>.<\/li>\n\n\n<li>Choose <strong>Daily<\/strong>, pick a time (for example 07:00) and click <strong>Next<\/strong>.<\/li>\n\n\n<li>Choose <strong>Start a program<\/strong> and click <strong>Next<\/strong>.<\/li>\n\n\n<li>In <strong>Program\/script<\/strong>, choose your <code>run_daily_report.bat<\/code> file.<\/li>\n\n\n<li>In <strong>Start in (optional)<\/strong>, type <code>C:\\Scripts<\/code> (no quotes here).<\/li>\n\n\n<li>Click <strong>Next<\/strong>, then <strong>Finish<\/strong>.<\/li>\n\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>Start in<\/strong> box is very important. Without it, Windows starts in a system folder, and your script cannot find files like <code>sales.xlsx<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Test the task now<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Do not wait until tomorrow. In Task Scheduler, click <strong>Task Scheduler Library<\/strong>, find <code>Daily Report<\/code>, right-click it and choose <strong>Run<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Press <code>F5<\/code> to refresh. Look at the <strong>Last Run Result<\/strong> column. <code>The operation completed successfully. (0x0)<\/code> means all is good. Then check your log files. \ud83c\udf89<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common problems<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Last Run Result is <code>0x1<\/code>.<\/strong> \u2192 Your script had an error. Open <code>run_output.log<\/code> and <code>daily_report.log<\/code> to see the message.<\/li>\n\n\n<li><strong>&#8220;No module named pandas&#8221;.<\/strong> \u2192 The task uses a different Python. Check the path from <code>where python<\/code> and use the one where you installed your libraries.<\/li>\n\n\n<li><strong>The task does not run when the laptop is on battery.<\/strong> \u2192 Open the task&#8217;s <strong>Properties<\/strong> &gt; <strong>Conditions<\/strong> and uncheck <strong>Start the task only if the computer is on AC power<\/strong>.<\/li>\n\n\n<li><strong>Scripts that use Outlook or Excel fail.<\/strong> \u2192 These apps need you to be logged in. Keep the option <strong>Run only when user is logged on<\/strong>.<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Wrap-up<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now your script works even when you forget it. The log file tells you what happened, and the <code>.bat<\/code> wrapper keeps everything in one place.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, try adding a second trigger in the task&#8217;s <strong>Triggers<\/strong> tab, like &#8220;At log on&#8221;. Then the script also runs every time you start your computer. Happy automating!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Make your Python scripts run by themselves every day with Windows Task Scheduler, a small batch file and a log file.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[7,12,17,16],"class_list":["post-47","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-automation","tag-python","tag-task-scheduler","tag-windows"],"_links":{"self":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/47","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/comments?post=47"}],"version-history":[{"count":1,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/47\/revisions"}],"predecessor-version":[{"id":86,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/47\/revisions\/86"}],"wp:attachment":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/media?parent=47"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/categories?post=47"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/tags?post=47"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}