January 9, 2019

PrettifyScp – Code Clean Up

Filed under: General,Scripting — Marcus Tettmar @ 2:10 pm

I often end up working on Macro Scheduler code that is hard to read because of a lack of indentation. Sometimes this is simply because the code has been chopped and changed so many times it’s become a bit messy and needs a bit of a clean up. And I’m not pointing fingers here either – some of this code is my own!

Indenting code inside code blocks makes it much easier to read. But cleaning up code and sorting out the indentation manually is tedious. So I wrote a little script to do it!

So here is my first PrettifyScp script. Just run it and browse to the .scp file you want to fix up. Wait a few seconds and it will pop up a message when it’s done.

//tokens to identify start and end of indented code

//tokens to identify blocks to ignore

//set tab chars
Let>tabs={"  "}


//ask user for input script file
Input>scp_file,Select script file


  //create backup file name

  //read in script lines to loop through
  //temporarily remove percent symbols to avoid unwanted variable resolution
  //split to array of lines

  //if there are lines, loop through them



      //Message>To do: %this_line%

      //left trim the line

      //are we going into a section to ignore?

        //if we are in a section to ignore, are we coming out of it?
        //otherwise we are not in an ignore section so see if we need to do anything

        //should we unindent?
          //capitalise first letter while we're here

        //create the indent chars

        //insert indent chars to line to output

        //should we indent further lines?
          //capitalise first letter


      //output the new line


    //swap percent symbols back in ...

    //backup the file

    //write output to original file name

    MessageModal>Done! Backup saved to %backupfile%


The old script is renamed to a .BAK file so that your original script is backed up. So if there’s something I haven’t thought of in this first stab and something gets messed up, you can’t lose anything, but hopefully you are backing up your code already!

I’m ignoring code inside Dialogs and VBScript blocks as well as comment blocks. Dialogs shouldn’t be messed with and the indentation is handled by the dialog designer. VBScript could be cleaned up but would need a different parser and there are already VBScript code beautifiers out there so you could copy and paste those. So in this version I haven’t touched VBS blocks.

Hope this is useful. Any feedback or suggestions, or if you notice a bug, please post in the comments below.

July 20, 2018

Cross Language 128 and 256 Bit AES Encryption

Filed under: Scripting,Web/Tech — Marcus Tettmar @ 10:47 am

With Macro Scheduler 14.4.10 we have added new 128 and 256 bit AES Encryption methods which interoperate well with other languages.

Cross-platform/cross-language encryption/decryption can be tricky. Different text encodings, different padding formats and understanding how different algorithms derive keys and initialisation vectors can make encrypting and decrypting between one language and another a bit of a pain!

Macro Scheduler’s AES function originally worked only on Unicode strings as this is the standard string format in Macro Scheduler.  Having had some issues trying to make this work between NodeJS and PHP we decided to create some new UTF8 based AES options (available in Macro Scheduler 14.4.10) which we have verified work well with PHP/OpenSSL and NodeJS.  

These new implementations provide 128 and 256 bit AES encryption.  They use CBC chaining method and use a SHA256 password. If using AES 128 the SHA256 password is truncated to the 32 byte key length.  By default the initialisation vector is set to “0000000000000000” but can be set to whatever you want (but must be 16 characters long). Padding is PKCS#5.

Here is an example of AES_256:

AESEncrypt>hello world,mypassword,ENCRYPT,result

Here is a compatible PHP example:

data = "hello world";

$method = 'AES-256-CBC';

// simple password hash
$password = 'mypassword';
$key = hex2bin(substr(hash('sha256', $password),0,64));

echo "Method: " . $method . "\n";
$encrypted = encrypt($data, $key, $method);
echo "Encrypted: ". $encrypted . "\n";
$decrypted = decrypt($encrypted, $key, $method);
echo "Decrypted: ". $decrypted . "\n"; // plain text

function encrypt(string $data, string $key, string $method): string
  $iv = "0000000000000000";
  $encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA, $iv);
  $encrypted = base64_encode($encrypted);
  return $encrypted;

function decrypt(string $data, string $key, string $method): string
  $data = base64_decode($data);
  $iv = "0000000000000000";
  $data = openssl_decrypt($data, $method, $key, OPENSSL_RAW_DATA,$iv);
  return $data;

Try this PHP Code Here

And here’s the Javascript equivalent:

let data = 'hello world';
let password = 'mypassword';
let iv = '0000000000000000';

let password_hash = crypto.createHash('sha256').update(password,'utf8').digest('hex');

let key = hex2bin(password_hash);
password_hash = Buffer.alloc(32,key,"binary");

let cipher = crypto.createCipheriv('aes-256-cbc', password_hash, iv);

let encryptedData = cipher.update(data, 'utf8', 'base64') + cipher.final('base64');

console.log('Base64 Encrypted:', encryptedData);

let decipher = crypto.createDecipheriv('aes-256-cbc', password_hash, iv);

let decryptedText = decipher.update(encryptedData, 'base64', 'utf8') + decipher.final('utf8');

console.log('Decrypted Text:', decryptedText)

function hex2bin(hex)
  var bytes = [], str;

  for(var i=0; i< hex.length-1; i+=2)
    bytes.push(parseInt(hex.substr(i, 2), 16));

  return String.fromCharCode.apply(String, bytes);

Try this Javascript code here.

You can try the Javscript and PHP examples at repl.it:


April 4, 2018

Running Powershell Code From Inside Your Macros

Filed under: Automation,Scripting — Marcus Tettmar @ 4:25 pm

A while back I wrote this blog post which shows you how you can have a PowerShell script run Macro Scheduler commands via the MacroScript SDK.

However, what if you want to do it the other way around and run PowerShell code from inside a Macro Scheduler macro instead?

One way would simply be to run a PowerShell script on the command line, like this:

Run>powershell.exe -file "c:\myfolder\myscript.ps1"

But what if you didn’t have a PowerShell script file?  Well, while you could always have your macro create one using the WriteLn command (and delete it after), you don’t need to as you can pass a sequence of commands to PowerShell on the command line:

powershell.exe -executionPolicy bypass -command "Write-Host 'Hello World'; exit 123;"

As you can see all we’re really doing is passing the content of the script instead of a file.

We can also return the exit code of the PowerShell script to a variable in your macro.  Here’s an example:

//This line ensures the powershell script finishes before the macro continues
//Uncomment this line to HIDE the powershell window when ready to go live

Let>localVar=Hello World
Run>powershell.exe -executionPolicy bypass -command "%theScript%"

//display the exit code


$var = '%localVar%';
Write-Host $var;
Start-Sleep -s 10;
exit 555;

What we’ve done here is store our PowerShell code in a label. We get that code into a variable and then pass it to PowerShell on the command line.

Notice how we can embed Macro Scheduler variables in the code too. We use PowerShell’s exit statement to set a return value which Macro Scheduler gets in the RP_RESULT variable.

Setting RP_WAIT to 1 makes sure the macro waits for PowerShell to finish before proceeding with the rest of the script. You may also want to hide the PowerShell window by setting RP_WINDOWMODE to 0, but for testing purposes I’ve left that commented out so that you can actually see it working. That’s also the reason for the 10 second delay at the end of the PowerShell script – apart from showing how we can add multiple lines of code it also gives us a chance to see things happen!

Get Date of Last Monday

Filed under: Scripting — Marcus Tettmar @ 2:59 pm

Someone asked me the other day how to get the date of the most recent Monday.  I came up with two solutions.

Get Date of Last Monday with VBScript

This version works by looping the date backwards one day at a time until the weekday of that date is a Monday.

//Put this VBSTART ... VBEND block at the top of your code ONCE
  Function LastMonday
    LastMonday = Date()
    Do While WeekDay(LastMonday) <> 2
      LastMonday = LastMonday -1
  End Function

//use this line whenever you want to get the date of last monday

To make it work for a different day just change the number it compares the WeekDay to in the Do line. 1 is Sunday, 2 is Monday and so on.

Get Date of Last Monday with MacroScript

This version works out how many days we need to deduct from the current date to get to Monday based on what the current day of the week is. If it’s a Sunday we just deduct 6. If it’s a Monday or onward we deduct the current day number.

//DayOfWeek starts with 1 as Sunday, so Monday is 2.
  //today must be Monday or later ... 
  //So diff we want is 2 - current day of week
  //e.g. if today Monday result would be 0 difference, Tuesday would yield -1 difference, Wednesday, -3 etc
  //curDayOfWeek is 1, so ...
  //today must be sunday, so we just want 6 days ago

//This should give us number of days to subtract from current day 
//to get Monday's date

October 29, 2017

Sending Email via Office 365

Filed under: Scripting — Marcus Tettmar @ 6:23 pm

We’ve had a few questions lately about how to send email using the SMTPSendMail function via the Office 365 SMTP server.

Until Macro Scheduler 14.4.02 which we have released today this wasn’t possible as explicit TLS was required and SMTPSendMail did not support it. We have now added this. So as long as you have updated to Macro Scheduler 14.4.02 (and you have a valid Office 365 account) here’s the code you need to send an email via the Office 365 mail server:


See also:

October 3, 2017

Regular Expressions (RegEx) In Window Commands

Filed under: Scripting — Marcus Tettmar @ 8:04 am

Did you know you can use Regular Expressions inside any of Macro Scheduler‘s window functions (e.g. SetFocus, WaitWindowOpen, WaitWindowClosed) so that you can match a window title using RegEx?

As an example someone recently asked us how they would match a window from an old piece of software where the window title was always the letter “b” followed by any 8 digits, e.g. b23425461. Macro Scheduler uses the PCRE syntax, so to match a window title like this we could use this expression:


If you’re new to RegEx this means: match from the beginning of the string (^), then match a “b” character followed by any digit (\d) 8 times. {8} means match the proceeding token 8 times. So:


I’ve posted a little about Regular Expressions before. This post links to some useful resources if you are new to RegEx.

Regular Expressions for Dummies
My Most Used RegEx
Remove Tags From HTML with RegEx

September 19, 2017

OCR Functions Anyone?

Filed under: Announcements,Scripting — Marcus Tettmar @ 11:29 am

Note: Macro Scheduler 14.4 with OCR was released in October 2017. This post was written prior to that.

A sneaky peak of some new Screen OCR functions we have in development:

Please note that this feature is currently in development and therefore the syntax and final implementation may differ on release.

July 26, 2017

Parsing XML with XMLParse and XPath

Filed under: Announcements,Scripting,Tutorials — Marcus Tettmar @ 10:22 am

Prompted by a recent forum post from Phil Pendlebury the other day I have written a new article on using XMLParse in the knowledge base:

Parsing XML with XMLParse and XPath

Hope it’s helpful. I’m sure you’ll have more questions when you start using it in anger. So when you do, be sure to head over to the forums and ask for help. 🙂

June 1, 2017

Script Development Services

Filed under: Announcements,Scripting — Marcus Tettmar @ 6:35 am

Did you know that we offer script development services? If you’re pushed for time or need a helping hand we can usually be of assistance. We often help people who don’t have the time or resource to build the automation themselves, or just want to get a jump start.

What sort of things do we do? It’s pretty much anything that needs automating, but a common scenario is data entry – usually reading data from Excel and entering it into either a web form or desktop app.

Recently we’ve written a script for a government agency which searches through hundreds of files looking for patterns and attaching them to emails; We’ve written a data entry script for a large oil company which reads through Excel and outputs the data to a web form; Helped a hospital automate entry of patient referrals into a web based system. We’ve reformatted CSV files; scraped data from a website; extracted data from PDF and output to Excel; Extracted patient data from an online dental patient database; assisted with extracting reports from an ordering system; and more.

So you can see we do all kinds of things. We have been automating processes for 20 years. If you have a project you could use some help with give us a shout and we’ll see what we can do.

November 14, 2016

HTTP Request With Custom Headers using Python

Filed under: Scripting — Marcus Tettmar @ 10:16 am

As you will hopefully already know by now we added the ability to use Python code a while back in Macro Scheduler 14.2.

A customer recently had a need to retrieve some data from a web service which requires some custom authentication headers to be sent with the request.

It’s really easy to do this using Python. Here’s a made-up example:

import urllib2

custom_headers={"X-Custom-Application-Id" : "4020c4b37ead0a834c0010a9",
                "X-Custom-REST-API-Key": "49eade9c-d70a-4d3d-b552-4bd9f05966fc"}

request = urllib2.Request(url, headers=custom_headers)
contents = urllib2.urlopen(request).read()
//Load the Python code to a variable
//Run the code and request the value of the contents variable ...

//content of request is now in "contents" variable.

For more on Python in Macro Scheduler see here and here.

Older Posts »