September 18, 2026

My son is still gaming on my dad’s PC

Filed under: General, Web/Tech — Marcus Tettmar @ 2:10 pm

This morning my son, Jamie, asked me for help with his PC. He’d installed FC27, but it kept giving him a graphics driver warning and then refused to connect to the EA servers.

The graphics driver turned out to be from 2024. Windows insisted it was completely up to date.

It wasn’t.

After a fair amount of messing around, I discovered that his GeForce GTX 970 is now old enough that it no longer gets the normal NVIDIA Game Ready drivers. But NVIDIA does still provide security update drivers for it, and fortunately the latest one was exactly the minimum version FC27 wanted.

Driver updated. Warning gone.

Still wouldn’t connect to EA.

So followed an increasingly familiar sequence of IT troubleshooting: clear caches, repair the game, run things as administrator, check the firewall, try a completely different internet connection, swear at it a bit.

Nothing.

Eventually we gave up.

A couple of hours later Jamie came downstairs.

“It’s working.”

Of course it is.

“What did you do?”

“I uninstalled the EA app and installed it again.”

Naturally.

But somewhere during all this faffing around, it struck me just how old Jamie’s PC actually is.

Because it wasn’t originally his.

It was my dad’s.

Dad built it when it was a pretty powerful machine. He was really into Microsoft Flight Simulator and had a fantastic setup – three monitors, flight controls, pedals, the lot. He was also a keen photographer, so the PC got plenty of use processing and editing his photos.

The GTX 970 that I was trying to coax into running a brand-new football game this morning was once driving three screens of Flight Simulator for Dad.

Dad died three years ago.

The PC eventually came to us, and now his grandson uses it for gaming.

There’s something I really like about that.

Computers aren’t supposed to get more valuable as they get older. They become obsolete remarkably quickly. CPUs get slower relative to everything else, graphics cards stop being supported and eventually some new piece of software comes along that they simply can’t run.

And this one is definitely getting there.

A GTX 970 was a serious graphics card when Dad bought it. More than a decade later, it’s hanging on remarkably well – although FC27 requiring a driver specifically maintained for older NVIDIA cards feels like a fairly substantial hint that retirement isn’t too far away.

At some point we’ll replace the PC.

But not today.

Today it got a new graphics driver. Jamie got FC27 working. And the computer my dad built for Flight Simulator and photography gets to spend a bit longer being used by his grandson.

I think Dad would have rather liked that.

Dad died from mesothelioma three years ago. Next April I’m running the London Marathon in his memory, raising money for Marie Curie, who were there for him – and for us – towards the end.

So perhaps there was something particularly nice about being reminded of him this morning in such an ordinary, unexpected way.

If you’d like to support my London Marathon fundraising for Marie Curie, you can find my page at:

https://runfordad.co.uk

For Dad.

September 15, 2026

AI Can Write the Script. But What Runs It?

Filed under: AI, Automation — Marcus Tettmar @ 1:26 pm

AI Can Write the Script. But What Runs It?

A few weeks ago I wrote about how AI is changing Windows automation.

One of the most obvious changes is that it’s becoming remarkably easy to generate code.

Need a PowerShell script to process a folder full of files? Ask an AI.

Need some Python to call an API and turn the response into a CSV? It can probably get you most of the way there in seconds.

Need a bit of VBScript, JavaScript or even Macro Scheduler code? Same thing.

For developers – and increasingly for people who aren’t developers – AI has dramatically lowered the barrier to creating small pieces of automation.

But there’s an important distinction which I think sometimes gets overlooked:

Writing the script isn’t the same as running the automation.

THE SCRIPT IS ONLY PART OF THE JOB

Imagine you’ve asked an AI to create a PowerShell script which downloads a report, processes it and saves the result somewhere.

Great. You now have a script.

But perhaps the actual requirement is:

– Run it every weekday at 6am
– Run it unattended
– Pass it the correct parameters
– Capture the output
– Know whether it succeeded
– Do something else afterwards
– Retry or take another action if something fails
– Keep a log of what happened

At that point the problem isn’t really “how do I write this script?” any more.

It’s “how do I turn this script into a reliable automation?”

And those are two different problems.

AI IS MAKING THE BUILDING BLOCKS EASIER

I’ve been writing automation software for nearly 30 years, and one thing that has remained fairly constant is that useful automations tend to be made up of lots of different pieces.

A Macro Scheduler script might launch an application, interact with its user interface, run a command-line utility, execute some PowerShell, query a database, move some files and send an email.

It doesn’t particularly matter where those individual pieces came from.

You might have written them yourself.

A colleague might have written them ten years ago.

You might have copied and adapted something from Stack Overflow.

Or, increasingly, you might have asked an AI to create them five minutes ago.

The interesting thing about AI is that it makes many of those building blocks much easier to create.

That doesn’t necessarily remove the need for automation tools.

Arguably, it gives us more things to automate.

ORCHESTRATION STILL MATTERS

This is where I think traditional automation tools still have an important role.

Something needs to join all those pieces together.

Something needs to decide when they run, in what order, with what parameters and what happens when something goes wrong.

And sometimes the thing you’re trying to automate doesn’t have an API or a convenient command-line interface at all.

It’s still a Windows application with buttons, menus, dialogs and fields that somebody would otherwise have to operate manually.

AI can help you write code.

But code generation doesn’t magically make every application programmable, nor does it automatically give you reliable unattended execution.

USE AI AND AUTOMATION TOGETHER

I don’t see this as AI versus traditional automation.

The more interesting combination is AI plus automation.

Use AI to help create scripts, regular expressions, SQL, PowerShell, Python or whatever other building blocks you need.

Then use the appropriate automation tools to put those pieces together and run them reliably.

That might be Macro Scheduler. It might be Windows Task Scheduler. It might be a CI system, a cloud service or something else entirely.

Use the simplest tool that solves the problem.

But don’t confuse generating a piece of code with solving the whole automation problem.

AI can write the script.

Something still has to run it.

August 4, 2026

AI Is Changing Windows Automation – But Not in the Way You Might Think

Filed under: AI, Automation, Scripting — Marcus Tettmar @ 1:21 pm

If you’ve worked in IT over the past year, you’ve probably asked ChatGPT, Claude or Cursor to write some code for you. I certainly have.

AI has become an incredibly useful programming assistant. Need a Python script to rename files? Ask AI. Need to scrape a website? AI can usually get you most of the way there in seconds. Even experienced developers are finding themselves writing less code from scratch and spending more time reviewing, refining and testing code generated by AI.

So does that mean traditional automation tools like Macro Scheduler are becoming obsolete?

I don’t think so.

What AI has changed is how we create automation, not necessarily how automation gets done.

The hard part isn’t writing the code

When people think about automation, they often assume writing the code is the biggest challenge.

In reality, it often isn’t.

The hard part is understanding the application you’re trying to automate.

If you’re automating a modern web application with well-structured HTML and APIs, AI has an enormous advantage. It can reason about the page, generate Playwright or Selenium code, and often produce something that works remarkably well.

But many businesses don’t live entirely in the browser.

They still rely on Windows desktop software that may have been written ten, fifteen or even twenty years ago. Internal tools. Accounting systems. Manufacturing software. Medical applications. Legacy databases. Remote desktop sessions. Software where there is no API, no documentation, and no obvious way to automate anything.

That’s where the real challenge begins.

Desktop automation is often an investigation

Anyone who has automated Windows applications knows that the process is rarely as simple as writing a few lines of code.

Can the button be identified directly?

If not, can it be found using OCR?

Would image recognition be more reliable?

Has Windows scaling changed?

What happens if the dialog appears a second later than expected?

What if the application has been updated and the button has moved?

These aren’t really coding problems.

They’re automation problems.

And solving them is usually an iterative process. You try an approach, test it, refine it and gradually build a reliable solution.

AI is becoming a brilliant assistant

Ironically, AI makes this process easier rather than replacing it.

Today I regularly use AI to:

  • Explain existing Macro Scheduler scripts.
  • Suggest cleaner or more reliable approaches.
  • Help debug automation that isn’t behaving as expected.
  • Generate code snippets that I can adapt and test.

It’s like having another experienced developer sitting beside you.

The important word there is assist.

AI still needs context. It often needs screenshots, recorded steps, snippets of code or descriptions of what you’re trying to achieve. Building reliable desktop automation remains a collaborative process.

Where we’re experimenting

This is exactly why we’ve been experimenting with AI ourselves.

Our experimental tool, Macro Scheduler Agent, can already help explain Macro Scheduler code, identify bugs, answer scripting questions and even generate scripts from screenshots.

It’s still early days, and we’re deliberately taking a cautious approach. AI is incredibly capable, but we also know that reliable desktop automation depends on understanding the environment it’s working in.

Rather than trying to replace Macro Scheduler, we see AI as something that makes Macro Scheduler easier to use.

Nearly 30 years later…

Macro Scheduler was first released back in 1997.

The technology landscape has changed dramatically since then.

Windows has changed.

The web has changed.

Programming languages have come and gone.

And now AI is changing software development again.

But one thing hasn’t changed.

People still have repetitive tasks.

Businesses still rely on software that wasn’t designed to be automated.

And there’s still enormous value in having a reliable tool that can automate almost anything you can do with a keyboard and mouse.

AI is changing the future of automation.

We’re excited to be part of that future – not by competing with AI, but by embracing it where it genuinely helps.

Because the goal has never been to write more code.

The goal has always been to help people get work done faster.

March 16, 2026

Macro Scheduler 15.5.07: SMTPSendMail Now Supports OAuth2

Filed under: Announcements, Web/Tech — Marcus Tettmar @ 1:58 pm

Macro Scheduler 15.5.07 introduces an important update to the SMTPSendMail command, adding support for OAuth2 authentication and improving timeout handling for more reliable email automation.

These changes help ensure Macro Scheduler scripts continue working with modern email services as providers increasingly move away from basic username/password authentication.

Why OAuth2 Support Matters

Many email providers — including Microsoft 365, Outlook.com and Gmail — are gradually disabling SMTP Basic Authentication. Instead they require OAuth2-based authentication.

Without OAuth2 support, automated scripts that send email via SMTP may stop working when basic auth is disabled.

With version 15.5.07, Macro Scheduler’s SMTPSendMail command now supports OAuth2 tokens, allowing scripts to authenticate securely with modern email providers.

Using OAuth2 with SMTPSendMail

To enable OAuth2 authentication simply set:

  • SMTP_OAUTH2 = 1
  • SMTP_OAUTH2_TOKEN = <access token>

Example:

Let>SMTP_OAUTH2=1
Let>SMTP_OAUTH2_TOKEN=ya29.a0AfH6SMBx...
Let>[email protected]
Let>SMTP_SSL=1
Let>SMTP_PORT=465SMTPSendMail>[email protected],smtp.gmail.com,[email protected],Your Name,Test subject,Test body,

Macro Scheduler expects a valid OAuth2 access token in SMTP_OAUTH2_TOKEN.

Token retrieval itself is not handled automatically by SMTPSendMail. Your script (or another process) must obtain the access token from the provider first. This typically involves:

  1. Creating an application with your email provider (e.g. Azure AD or Google Cloud).
  2. Obtaining a client ID and client secret.
  3. Using these credentials to obtain a refresh token.
  4. Exchanging the refresh token for an access token.
  5. Passing the access token to SMTPSendMail via SMTP_OAUTH2_TOKEN.

You can use Macro Scheduler’s HTTPRequest command to perform these token exchanges if needed.

Improved SMTP Timeout Handling

Version 15.5.07 also improves the behaviour of the SMTP_TIMEOUT variable.

Previously this timeout applied only to the initial connection to the SMTP server. In some environments this could still leave scripts waiting indefinitely if a later SMTP operation stalled.

Now the timeout applies to all SMTP operations, including:

  • Authentication
  • Message transfer
  • Server responses

This results in more predictable behaviour when network issues or server delays occur.

Existing Scripts Continue to Work

If your SMTP server still supports username/password authentication, existing scripts will continue to work exactly as before using:

Let>SMTP_AUTH=1
Let>SMTP_USERID=myuser
Let>SMTP_PASSWORD=mypassword

OAuth2 is simply an additional authentication option for providers that require it.

Full Documentation

You can find the full SMTPSendMail documentation here:

https://www.mjtnet.com/manuals/b/v15/topics/smtpsendmail.htm

Download Macro Scheduler 15.5.07

If you rely on SMTP automation in your scripts, we recommend upgrading to Macro Scheduler 15.5.07 to ensure compatibility with modern email systems.

Trial Downloads | Registered Updates

February 1, 2026

Level Up Your Automation: XPath & JSONPath Explained (With Macro Scheduler Examples)

Filed under: Scripting, Web/Tech — Marcus Tettmar @ 4:38 pm

If you automate websites, APIs, or online services with Macro Scheduler, you’ll quickly run into two recurring challenges:

  • Finding the right element on a web page
  • Extracting the right value from structured JSON data

Two technologies solve these problems:

  • XPath — for navigating and selecting HTML elements
  • JSONPath — for querying and extracting values from JSON

We’ve published two practical primer articles that go deep into both topics:

👉 An XPath Primer for Web Automation (with Macro Scheduler examples)
https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples

👉 A JSONPath Primer (with Macro Scheduler examples)
https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples

Below is a high-level overview of each, with real Macro Scheduler examples to show why these skills are so valuable.


🔹 XPath — Find Web Elements Reliably

https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples

When automating Chrome using Macro Scheduler’s Chrome functions, element IDs and class names are often unreliable:

  • IDs may be missing or dynamically generated
  • Class names may change between builds
  • Multiple elements may share the same attributes

XPath lets you locate elements by describing their position and relationship within the page structure.

In Macro Scheduler, XPath is used with:

ChromeFindElements>session_id,xpath,value,elements_array

Example: Find an Input by Attribute

ChromeFindElements>session_id,xpath,//input[@name='q'],elements
ChromeSetElementValue>session_id,elements_1,macro scheduler

This finds an <input> element whose name attribute equals q.


Using Partial Matches

When values are dynamic:

ChromeFindElements>session_id,xpath,//button[contains(@id,'save')],elements

This matches any button whose ID contains the word “save”.


Real-World Scenario: Clicking a Button Based on a Child Element

HTML:

<button>
  <label for="checkbox-123">Pacific Islander</label>
  <input id="checkbox-123">
</button>

You know the ID of the input, but need to click the surrounding button.

XPath:

ChromeFindElements>session_id,xpath,//input[@id='checkbox-123']/ancestor::button,btn
ChromeClickElement>session_id,btn_1

This moves up the DOM from the input to its parent button.


Real-World Scenario: Find a Button Based on Nearby Text

HTML:

<div class="option">
  <h3>Premium Plan</h3>
  <button>Select</button>
</div>

XPath:

ChromeFindElements>session_id,xpath,//h3[text()='Premium Plan']/following-sibling::button,btn
ChromeClickElement>session_id,btn_1

This selects the button associated with the “Premium Plan” heading.


XPath Best Practices

  • Prefer relative paths starting with //
  • Use contains() for dynamic values
  • Avoid full /html/body/... absolute paths
  • Check elements_array_count before using results

For a full walkthrough and many more patterns, see:
https://help.mjtnet.com/article/554-an-xpath-primer-for-web-automation-with-macro-scheduler-examples


🔹 JSONPath — Extract Data from JSON

https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples

JSON is everywhere: APIs, cloud services, configuration files, and web responses.

Macro Scheduler’s JSONParse command uses JSONPath to pull specific values from JSON text.

JSONParse>json_string,json_path,result_array

Results are always returned as an array:

  • result_array_1
  • result_array_2
  • result_array_count

Example: Extract a Simple Value

JSON:

{ "uid": "1234" }

Macro Scheduler:

JSONParse>sJSON,$.uid,result
MessageModal>UID is: %result_1%

Note the required $ at the start of the path.


Working with Arrays

JSONParse>sJSON,$.clients[0],result

Gets the first client.

JSONParse>sJSON,$.clients[*],result

Gets all clients.


Using Filters

Select only books cheaper than 10:

JSONParse>json,$.store.book[[email protected] < 10],cheapBooks

Select books that contain an ISBN:

JSONParse>json,$.store.book[[email protected]],withIsbn

Get titles of books under 15:

JSONParse>json,$.store.book[[email protected] < 15].title,titles

JSONPath Best Practices

  • Always start paths with $
  • Remember results are arrays
  • Check result_count before using values
  • Build paths step by step

For full explanations and more examples:
https://help.mjtnet.com/article/555-a-jsonpath-primer-with-macro-scheduler-examples


Final Thoughts

XPath and JSONPath solve two of the most common automation problems:

  • XPath → finding the right element on a web page
  • JSONPath → extracting the right value from structured data

Mastering these will make your Macro Scheduler scripts more reliable, more flexible, and easier to maintain.

If you regularly automate websites or APIs, these two primers are essential reading.


January 31, 2026

Macro Scheduler 15.5 Released

Filed under: Announcements — Marcus Tettmar @ 5:25 pm

Macro Scheduler 15.5 update is now available.


Macro Recorder

  • Added ability to select an open window to activate
  • Added option to constrain mouse events to selected initial window when recording
  • Added SetFocus lines to macro recorder output when window activated
  • Updated layout of macro recorder

Web Automation

  • Added ChromeWaitForText command
  • Added EdgeWaitForText command
  • Added ‘text’ and ‘partial text’ strategies to ChromeFindElements
  • Added ‘text’ and ‘partial text’ strategies to EdgeFindElements
  • Updated WebRecorder toolbar button to visit the Chrome WebRecorder Extension:
    https://www.mjtnet.com/webrecorder.htm

New Commands & Functions

  • Added PowerShell command to run PowerShell scripts and commands
  • Added GetWindowTitle command
  • Added GetISOTimeStamp command
  • Added StrContains function
  • Added StrStartsWith function
  • Added StrEndsWith function
  • Added GFL_RECURSIVE directive
  • Added MSG_TIMEOUT option

Improvements

  • Updated JSONParse to handle ‘?’ filters and ‘@’ (Current) operator
  • Updated data path / OneDrive handling
  • Updated HTTPRequest, SMTP, POP3, and FTP functions to default to TLS 1.2 and removed deprecated SSLv2/SSLv3 support

Fixes

  • Fixed ReadFile command to cope better with Unicode characters
  • Fixed minor issues in command definition file

Registered Downloads/Upgrades | Trial Downloads

October 6, 2025

How to call REST APIs from Macro Scheduler (with JSON, headers, error handling)

Filed under: Uncategorized — Marcus Tettmar @ 1:03 pm

TL;DR: Use HTTPRequest for GET/POST/PUT/PATCH/DELETE, set HTTP_POSTJSON=1 for JSON bodies, add HTTP_CUSTOM_HEADERS for auth, HTTP_TIMEOUT for reliability, and parse responses with JSONParse.

Why call APIs from Macro Scheduler?

  • Pull or push data (orders, tickets, metrics) as part of a daily job
  • Trigger SaaS workflows without opening a browser
  • Glue apps together (cron-style) with simple, reliable scripts

Everything below runs in plain Macro Scheduler—no external dependencies.


Quick start: GET a JSON endpoint

// 1) Optional: set a timeout (seconds)
Let>HTTP_TIMEOUT=15

// 2) Optional: custom headers (multiple lines use %CRLF%)
Let>HTTP_CUSTOM_HEADERS=Accept: application/json

// 3) Make the request
HTTPRequest>https://api.example.com/status,,GET,,RESP

// 4) Parse JSON (example path)
JSONParse>RESP,$.service,result
If>result_count>0
  MessageModal>Service: %result_1%
Else
  // Log full response if JSON path not found
  WriteLn>%SCRIPT_DIR%\api_log.txt,WF_APPEND,Unexpected response: %RESP%
EndIf

HTTPRequest signature:
HTTPRequest>URL,[LocalFilename],Method,[POST_Data],Result_Variable mjtnet.com

POST JSON (with Bearer token)

Let>HTTP_TIMEOUT=20
Let>HTTP_POSTJSON=1
Let>HTTP_CUSTOM_HEADERS=Authorization: Bearer YOUR_API_KEY%CRLF%Accept: application/json

// JSON body (can be built up dynamically)
Let>payload={"name":"Widget 42","price":19.99}

// POST it
HTTPRequest>https://api.example.com/items,,POST,payload,RESP

// Extract a field from the JSON response
JSONParse>RESP,$.id,itemId
If>itemId_count=1
  MessageModal>Created item id: %itemId_1%
Else
  WriteLn>%SCRIPT_DIR%\api_log.txt,WF_APPEND,Create failed: %RESP%
EndIf
  • For JSON bodies, set HTTP_POSTJSON=1 (Macro Scheduler sets the content type for you). mjtnet.com
  • JSONParse returns an array (result_1result_2, …) with a *_count—use JSONPath like $.idmjtnet.com

Custom headers, SSL/TLS & timeouts (reliability)

Let>HTTP_TIMEOUT=30
Let>HTTP_CUSTOM_HEADERS=Authorization: Bearer YOUR_API_KEY%CRLF%X-Trace: msched
  • Timeouts: set HTTP_TIMEOUT (seconds) so a hung API doesn’t block your run. mjtnet.com
  • Headers: set multiple lines via HTTP_CUSTOM_HEADERS—great for auth, idempotency keys, etc. mjtnet.com
  • HTTPS/TLS: Use an https:// URL (or set HTTP_SSL=1). If you must pin a TLS version, set TLS_VER (12 for TLS 1.2). 

Example: create a short link with a custom Open Graph preview (ogli)

Swap in your endpoint/headers if you’re using another service—the pattern is the same.

This example uses the Ogli link shorter service. Grab a free API key from Ogli to try out the code below.

// Go get a free API key from app.ogli.sh
Let>OGLI_API_KEY=YOUR_API_KEY_HERE

// Timeouts & JSON
Let>HTTP_TIMEOUT=20
Let>HTTP_POSTJSON=1

// Auth (Bearer) + accept JSON
Let>HTTP_CUSTOM_HEADERS=Authorization: Bearer %OGLI_API_KEY%%CRLF%Accept: application/json

// Build the request body
/*
PAYLOAD:
{
"targetUrl":"https://example.com/product/1232",
"title":"SuperWidget — Launch Day"
}
*/
LabelToVar>PAYLOAD,postBody

// POST
HTTPRequest>https://api.ogli.sh/link,,POST,postBody,RESP

// Parse shortUrl from response
JSONParse>RESP,$.url,short_link
If>short_link_count>0
  Let>the_link=short_link_1
  MessageModal>short link is %the_link%
Endif

Later, PATCH the same link to swap the OG image and platforms will refresh the preview when reshared.

Error handling & logging pattern

Let>LOG=%SCRIPT_DIR%\api_log.txt

// After any HTTPRequest:
If>RESP=
  // If you saved to a LocalFileName, RESP will be blank on success.
  // Otherwise blank usually means an error occurred – log it:
  WriteLn>%LOG%,WF_APPEND,Blank response (check URL/timeout/SSL)
Else
  // Try to parse a known field; if none, log full response
  JSONParse>RESP,$.status,status
  If>status_count=0
    WriteLn>%LOG%,WF_APPEND,Unexpected JSON: %RESP%
  EndIf
EndIf

Tip: when you save to a file (use the LocalFilename parameter), a successful call leaves the result variable blank by design; otherwise it contains the response or an error message. mjtnet.com


Parse more JSON with JSONPath

/*
RESP:
{
  "id":"lnk_abc123",
  "shortUrl":"https://ogli.sh/launch-123",
  "stats":{"clicks":42,"countries":["GB","US"]}
}
*/
JSONParse>RESP,$.stats.clicks,c
If>c_count=1
  Let>clicks=%c_1%
EndIf

// Loop an array (countries)
JSONParse>RESP,$.stats.countries[*],cc
Let>k=0
Repeat>k
  Let>k=k+1
  Let>country=cc_%k%
  // do something with %country%
Until>k=cc_count

JSONParse returns an array and a *_count—loop over it with Repeat/Until

Common gotchas

  • For JSON, always set HTTP_POSTJSON=1 (don’t hand-craft Content-Type). mjtnet.com
  • Escape quotes inside JSON strings correctly.
  • Use timeouts so a bad endpoint doesn’t hang your run (Let>HTTP_TIMEOUT=15). mjtnet.com
  • If an API returns HTML (error pages), JSONParse will fail—log RESP to inspect.

Further reading

  • Macro Scheduler: HTTPRequest (methods, headers, files, SSL, timeouts). mjtnet.com
  • Macro Scheduler: JSONParse (JSONPath, arrays, examples). 
  • If you prefer you can use Python requests with PyExec.

August 25, 2025

Let Us Automate It For You

Filed under: Announcements, General, Scripting — Marcus Tettmar @ 1:17 pm

At MJT Net we’ve been helping people automate Windows applications for more than 25 years with Macro Scheduler. Thousands of users have built their own scripts to save time, eliminate repetitive tasks, and connect systems that otherwise don’t talk to each other.

But did you know we also offer done-for-you automation services?

We understand that not everyone has the time to dive into scripting, or sometimes the task at hand is a little too complex to tackle alone. That’s where our team comes in.

Automation Built for You

We’ve created custom automations for organizations of all sizes — from small businesses right through to the NHS and other major healthcare providers. Whether it’s:

  • Filling out forms automatically
  • Extracting and processing data
  • Integrating with legacy systems
  • Or orchestrating complete workflows across multiple applications

…our team can design, script, and deliver a solution that works seamlessly for you.

And if you already have a Macro Scheduler script — whether it’s partly built, needs fixing, or could do with enhancements — we can adapt, maintain, and improve your existing routines too.

How It Works

To automate something properly, we need to see the process in action. That means we’ll ask you to walk us through the steps, and in most cases we’ll need secure remote access to your system so we can interact directly with the applications involved.

Once we’ve observed the process, we’ll design and build a Macro Scheduler script or set of scripts that replicate your workflow reliably. These run inside Macro Scheduler — giving you flexibility to adapt, extend, and manage your automations over time.

From simple repetitive actions to complex multi-application workflows, our goal is to remove the manual effort so you can focus on more important things.

Why Use Our Services?

  • Save time quickly — no need to learn scripting from scratch.
  • Tailored solutions — we adapt to your processes, not the other way around.
  • Proven experience — decades of automation expertise across industries.
  • Ongoing support — we can update and enhance scripts as your needs evolve.

Ready to Talk?

If you’ve got a task in mind — whether it’s something you do dozens of times a day, or a regular process that eats into your team’s time — let’s discuss how we can automate it for you.

👉 Contact us today and let’s see how much time we can save you.

June 11, 2025

Announcing – Macro Scheduler WebRecorder Extension – Beta

Filed under: Announcements, Automation, Scripting, Web/Tech — Marcus Tettmar @ 8:40 pm

Announcing the Macro Scheduler WebRecorder Chrome Extension. Old timers will remember the WebRecorder. Well it’s back. Kinda.

What is it?

A Chrome browser extension that records user interactions on web pages and generates Macro Scheduler automation scripts with Chrome WebDriver commands.

  • Records user interactions such as clicks, typing and form submissions
  • Generates optimized Macro Scheduler scripts with proper syntax
  • Supports Chrome WebDriver commands (ChromeStart, ChromeNavigate, ChromeFindElements, etc.)
  • Smart duplicate event removal for cleaner scripts
  • One-click script download

Beta Installation Instructions

Download here:

https://www.mjtnet.com/software/macro-scheduler-extension-1-5-7.zip

Since this extension is in beta testing and not yet published to the Chrome Web Store, you’ll need to install it as an “unpacked extension”:

Step 1: Extract the Extension

  1. Download and extract the macro-scheduler-extension.zip file to a folder on your computer
  2. Remember the location of this folder – you’ll need it in Step 3

Step 2: Enable Developer Mode in Chrome

  1. Open Google Chrome
  2. Click the three dots menu (⋮) in the top-right corner
  3. Go to More tools → Extensions
  4. Or directly navigate to: chrome://extensions/
  5. Toggle “Developer mode” ON in the top-right corner of the Extensions page

Step 3: Load the Extension

  1. Click “Load unpacked” button (appears after enabling Developer mode)
  2. Navigate to and select the folder where you extracted the extension files
  3. Click “Select Folder”
  4. The extension should now appear in your extensions list

Step 4: Pin the Extension (Optional but Recommended)

  1. Click the puzzle piece icon (🧩) in Chrome’s toolbar
  2. Find “Macro Scheduler Recorder” in the list
  3. Click the pin icon (📌) next to it
  4. The extension icon will now appear directly in your toolbar

How to Use

  1. Start Recording: Click the extension icon and press “Start Recording”
  2. Perform Actions: Navigate to any website and perform the actions you want to automate (clicking, typing, form submissions, etc.)
  3. Stop Recording: Click the extension icon again and press “Stop Recording”
  4. Download Script: Review the generated script and click “Download Script” to save it as a .scp file

Generated Script Requirements

Important: The generated scripts require Chrome for Testing to be installed on your system.

Beta Testing Notes

This is a beta version for testing purposes. Please report any issues or suggestions:

  • Extension behavior problems
  • Script generation errors
  • UI/UX feedback
  • Feature requests

This is early beta. And anyone who has ever dabbled with automating Chrome and websites will hopefully know how difficult it is to make one-size-fits-all rules. There are bound to be things this can’t automate. It might not always be able to find the best element selectors, or ones that are unique. So your mileage WILL vary. But we’ve tested a few thorny scenarios – frames, new tabs opening as well as forms and clicks and so far we’re happy with what it can do. Have a play. And drop your comments and feedback in the forums or drop us a line here.

Supported Actions

The extension currently records and generates scripts for:

  • Element clicks (buttons, links, etc.)
  • Text input (input fields, textareas)
  • Form submissions
  • Keyboard interactions
  • Focus events

Note: The initial page URL is automatically included when recording starts. Subsequent page changes should result from user interactions (clicks, form submissions) rather than manual URL changes.

Script Output Format

Generated scripts use Macro Scheduler syntax with Chrome WebDriver commands:

ChromeStart>session_id
ChromeNavigate>session_id,url,https://example.com
ChromeFindElements>session_id,css selector,input[type='text'],elements
ChromeSetElementValue>session_id,elements_1,Hello World
ChromeElementAction>session_id,elements_1,click
ChromeQuit>session_id

Troubleshooting

Extension Not Loading

  • Make sure Developer mode is enabled
  • Verify all extension files are in the selected folder
  • Check Chrome’s console for error messages (F12 → Console tab)

Recording Not Working

  • Refresh the page after starting recording
  • Make sure the extension has permission to access the website
  • Check that you’re performing supported actions (clicks, typing, etc.)

Script Generation Issues

  • Ensure you have recorded at least one action
  • Verify the recorded events appear in the extension popup
  • Try clearing and re-recording if the script appears empty

June 4, 2025

Introducing Macro Scheduler Agent — AI-powered help for your scripts (Beta)

Filed under: Announcements, Automation, Macro Recorder — Marcus Tettmar @ 9:16 pm

We’re excited to share an early Beta version of something we’ve been experimenting with here at MJT Net:

👉 Macro Scheduler Agent — an AI-powered web tool to help you write, improve, and troubleshoot Macro Scheduler scripts.


What can it do?

  • 📝 Explain a script — upload a script and get a plain English explanation, plus suggestions to improve it
  • 🕵️ Why doesn’t this work? — submit a script you’re having trouble with, and get ideas for what might be going wrong
  • 🤖 How would I automate this? — upload screenshots and describe what you want to automate
  • 🌐 Web form automation (experimental) — upload a CSV and a web form URL, and it will try to generate a script to fill out the form

Important caveats — this is Beta!

We’re calling this an experimental Beta for good reason:

✅ It’s an AI-based tool — results will vary
✅ It’s still learning — sometimes it will get things wrong
✅ It may suggest improvements, but they’re not guaranteed to be optimal
✅ For the Web Automation wizard in particular, success depends heavily on the structure of the form

Please treat this as a helpful assistant, not an infallible authority!
Always test any generated scripts before using them in production.


Who can use it?

Currently, access is limited to licensed Macro Scheduler users — it will check your email against our license database.
For now, it’s free to use for licensed users while we continue to develop and refine it.


Why are we building this?

Macro Scheduler users are an incredibly creative bunch, building automations for all kinds of applications and workflows.

We see the potential for AI to:

✅ Help users learn the language faster
✅ Speed up troubleshooting
✅ Provide inspiration for better automation techniques
✅ Bridge the gap for newer users


Try it out:
👉 https://agent.mjtnet.com/


We need your feedback!

If you try it out, we’d love to hear:

✅ What worked well
✅ What didn’t
✅ What else you’d like to see it do

This will help us improve it and guide future development.

Head over to the forums here:

https://forum.mjtnet.com/topic/20710


Final note

Again — this is Betaexperimental, and still learning.
It won’t always get things right — but we think it can already be a useful assistant.


Give it a go — and happy scripting!