Using PowerShell to make Azure Automation Graphical Runbooks – Part 1


Last week saw the release of the Azure Automation Graphical SDK for creating graphical Runbooks programmatically. On its own, it is a library, represented by a single file,  Orchestrator.GraphRunbook.Model.dll. It contains the .NET components required to allow creation of a graphical runbook object, serialize it, then save it to a .graphrunbook file, suitable for importing into Azure Automation.

The SDK is by default installed to C:\Program Files (x86)\Microsoft Azure Automation Graphical Authoring SDK.

The examples given in the documentation that accompanies the download from Microsoft’s web page for this are in C#. This series will show how these same graphical runbooks can be generated in PowerShell.


The next few articles walk through how we can make a runbook, using an existing graphical runbook generated in the Azure Portal, Get-DiceThrow, as a point of reference. It then shows how an identical one can be programmatically made using PowerShell and the SDK.

The Existing Runbook

In the screenshot below is the graphical runbook we mentioned, Get-DiceThrow.

0 - GraphRunbook Design

Get-DiceThrow accepts as input two integer parameters, simulating the roll of two dice. It then identifies if one is greater than the other, or if they are both of the same value. Then, based on that, a message is displayed, describing the result.

When we’re looking at designing a graphical runbook via the SDK, it’s a good idea to first take a look at the structure of our existing one to get an insight of what it’s composed of. This helps later when development of the script starts.

To do this, the classes and properties that represent what we can see in Get-DiceThrow will be described.

Runbook Elements


A runbook, or more specifically a graphical runbook, is repesented by an instance of the the GraphRunbook class. This describes the runbook in its entirety, and consists of the properties Activities, Links, and Parameters. This last one refers to the runbook’s input an output parmeters (see below).

1 - GraphRunbook

Runbook Input and Output Parameters

Input and output parameters are defined by creating an one or more instances of a Parameter class and setting the Paramters property of the Runbook class.


The attributes for the name of the parameter, the parameters type, and whether it is mandatory or not are represented in the Parameter class by the properties of Name, Type, and Optional.

2 - Input and Output

Name, Type, and Optional


Workflow script activities are represented by the WorkflowScriptActivity class. From the image below (anti-clockwise from Label) , the associated properties are Name, Description, CheckPointAfter, and Process.

3 - WorkFlow Script


Links between activities use the aptly named class, Link. Links can either have conditions attached to them (restricting the use of the activity at the end of the link to situations where the condition’s expression evaluates to true), or be simple unconditional ones.

The settings in the image below (top to bottom) are referred to by the properties LinkType, Description,and Condition. Condition is another class, which contains the properties ConditionMode, to specify if a condition should be applied, and Expression for the conditional expression.

6 - Link

The next article will focus on the activities themselves, and the classes which inherit from them. This is probably the part that most of the development time will be spent on, since there is a substantial amount of configuration required.

Thanks for reading,



Using Drag and Drop in PowerShell GUIs

Drag and drop is a wonderful facility that most of us will use every day without even thinking about it. This article shows how it can be implemented in PowerShell GUI applications.

For this particular script, we’ll implement drag and drop functionality to allow us to drag a file from explorer to a textbox in we’ve created. When the drag and drop operation is complete, the textbox will then show the path to the file.

You can find a copy of the PowerShell Studio form and exported PowerShell code at the PowerShell.Amsterdam repository.

Here is what we our application will do once we have completed it:

To achieve our objective, we need to make use of two events, DragOver, and DragDrop.

DragOver occurs when the mouse is over the control on which we wish to ‘drop’ our object. We’ll typically just use this for changing our pointer to show a move or copy operation is in operation.

DragDrop occurs once the actual operation is finished. That is, the object has been dragged into the form and over the control, and the mouse button released.

To implement this in our application, carry out the following:

  • Create a form
  • Create a Textbox on the form
  • Set the following properties for the Textbox
    • Name : txtDragandDrop
    • Label : Contents dragged:
    • AllowDrop : true

1 - form design and properties

We now define the events that will be processed, and their handlers.

  • DragDrop : txtDragandDrop_DragDrop
  • DragOver : txtDragandDrop_DragOver

2 - form design and events

For the event handler code, use the following :

If you are developing this application in PowerShell Studio, you will need to first export the code, either to a standalone EXE, or .PS1 file.

  • Run the application from either of the above.
  • Drag a file of you choice from explorer to the textbox.

The textbox will be populated with the filepath of the file that has been dragged and dropped over it.

4 - running

Thanks for reading!


Asynchronously Save Images in the Clipboard to File

PowerShell v5.0 introduces us with two cmdlets, Get-Clipboard and Set-Clipboard which, just as their names suggest, allow us to obtain and set the contents of the clipboard. What’s not immediately apparent though is that these cmdlets can process more than just text in the clipboard.

In this blog, we’ll focus on using Get-Clipboard, and create a script which is used in combination with Register-EvengineEvent to save an image to file any time that one is detected in the clipboard during the current session. A repo containing the script is available at GitHub

Get-Clipboard supports the processing of several types of data that is in the clipboard, one of which is that of an image type. Examples of these would be print screens or copying an image created in Paint into the clipboard.

When an image is in the clipboard, and we use Get-Clipboard -Format Image, an object of Bitmap type (inherited from System.Drawing.Image) is returned. One of the methods this class provides is Save. Save has several overloads, one of which writes to a file and a variety of formats of your choice.

The script below requires use of the ISE, and uses Register-EngineEvent to register a scriptblock, which runs when a PowerShell.OnIdle event is raised. In the scriptblock, we check to see if there is any content in the clipboard of image type. If there is, we take the details of the current file open in ISE the editor, and use it to generate a unique filename. Then, the content of the clipboard is saved to this filename using the method mentioned above. Finally, we clear the clipboard to ensure that there we don’t end up in a continuous looping operation.

Thanks for reading!


Font Anti-Aliasing in PowerShell GUIs


The text on winform projects may seem blocky sometimes, particularly at larger font sizes. It never seems to look as polished as those we see with Microsoft products.

Here’s a standard form using Segio 24pt in white. It’s pretty blocky, especially around letters such as ‘S’ and ‘P’. Click on the image below to see it in normal size to get an idea how this looks.


Text without Anti-Aliasing

In order to make our text smoother and more, anti-aliasing will need to be used.

What’s Anti-Aliasing?

Anti-aliasing is the name given to actions which aim to minimise this type of blockiness. It works by shading the pixels along the borders of an image. In order to achieve this for ourselves, we need to dig into some .NET methods and events.

This post shows how we do just that for our fonts in PowerShell Studio, but can be applied in whatever way you develop your GUI apps.

Create a Project

Create a new forms project, making the form a good size. Now, drag a PictureBox control onto the form, and set the size of it close to the size of the form itself.

Set the properties for the PictureBox as follows :

Dock = ‘Top’
BackColour = 1;3;86

Create Positioning Functions

Because we’re going to be working with graphics, we need to define placement based on a horizontal and vertical basis. Whilst we could use absolute positioning, where we manually specify a fixed location, this style is rendered invalid if we make changes to size of the control or the graphic itself. Its relative positioning is changed.

Instead, if we use calculations for positioning, it gives us the flexibility to change control and graphic sizes after the code has been written without having to modify it later.

Thinking about this, there are several things we need to do :

  • Get the midpoint of the control (our picture box)
  • Get the midpoint of the graphic (our drawn string)
  • Get the position for placement of the graphic on the control

Picture Box Control

In this function, we simply pass in the PictureBox control, and work out its center point by adding the left most point with its width, and then divide by two. This gives us the horizontal (aka x) location. Similarly, we add the control’s top most point with it’s height and divide by two to get its vertical center point. These values are then returned as an object.

Drawn String

We’re working in a similar manner to the above function, but require to do a bit more calculation. We pass in a graphics object, previously instantiated, the string to be drawn, and the font itself. The MeasureString method of the grahpics control is then invoked, using the other two parameters we’ve just mentioned. Once that is completed, we obtain the horizontal and vertical midpoints.

Position from Drawn String

Now that we have our two sets of midpoints, we can calculate where the drawn string should be placed. This is done by subtracting the result of the latter function from the former for both x and y positions, and returning the results.

Create Event Code

Now that we’ve defined out functions, we can setup the event action and code.

The Paint event occurs when a control requires repainting. This can happen as a result of other actions on a form or control, such as scrolling to the bottom of a form at to the top again.
Go to the Paint event of the PictureBox in the properties panel, and double click on it. Insert the following :

Code explanation

What happens in this code is the following:

  • We obtain the Graphics properties from the event data and assigning it to a variable $g.
  • We define some of the properties of the picturebox control.
  • A Font type variable is created using Sergoe UI typeface in size 84 as the supplied parameters
  • A SoldBrush object is created. This is the drawing style we use, just like in the Paint application.
  • The functions mentioned previously are then used
  • With the above completed, we define a floating point coordinate object
  • We also set the type of anti-alias rendering to be carried out. Several options are available. See the links at the bottom of this page to get more information on these
  • We now run the DrawString method to create and position the anti aliased rendering of the font.

View the New Results

Now run the project to see a much smoother version.


Text with Anti-Aliasing

I’d recommend taking a look at the System.Drawing namespaces documentation on MSDN to get more information on the methods, properties, and enumerations used in this code, which will explain in more detail about each.

You can find the Project code and exported code (for those not using PSStudio) at my GitHub repository, and also a video of this in action on my YouTube channel.