Tutorial: Use a CSV file to make a graphical menu of PowerShell scripts

I’ve recently been working on a PowerShell module that uses a CSV file to create a custom menu of scripts.

It looks like this:

It hopefully helps to bridge the gap between engineers and automators, who write scripts useful to others, and service desk people and technicians, who may not be confident with the command line. PSScriptMenuGui allows PowerShell coders to put their scripts in a simple menu, usable by anyone.

It’s loosely inspired by (criminally similar to) something I made for a previous employer.

(The main difference is that this version starts instantly. The old version was so slow that I made an entertaining loading screen to fill the void. A good subject for a future blog post…)

If you’d like to dive straight in, please:

The rest of this blog post acts as a tutorial.

If you’d like to be guided through making your own menu, keep reading…

Step 0: System requirements

The module works on Windows only – sorry, rest of world!

Apart from that, it should run pretty much anywhere. It works on:

  • PowerShell for Windows 5.1 which comes with Windows 10.
  • PowerShell 7, currently available as a preview and due to be finished at the start of 2020.

It does not work on PowerShell Core 6. If you have this version, the easiest solution is to use PowerShell 5.1 as it is already on your PC.

Step 1: Install the module and make an example menu

Open a PowerShell prompt and:

# Navigate to where you want to work on your menu - in my case OneDrive:
cd $env:OneDrive
# Install the module:
Install-Module PSScriptMenuGui -Scope CurrentUser
# You may need read and agree to messages about updates and trust
# Make an example menu to get you going:

You should see this:

VERBOSE: Copying example files to PSScriptMenuGui_example...

Step 2: Explore the example

Navigate to your PSScriptMenuGui_example folder and open PSScriptMenuGui.ps1. You should see a bit of boilerplate to ensure that the module is loaded, followed by this line which displays the menu:

Show-ScriptMenuGui -csvPath '.\example_data.csv' -Verbose

Try running the line in your PowerShell window. You should see the example menu from the GIF at the top of this post.

Now open example_data.csv. A text editor is fine but Excel is easier. You can see that every row in the CSV represents an item in the menu.

Step 3: Make it your own

Experiment with editing the CSV and running the Show-ScriptMenuGui command again to see your changes.

A few ideas:

  • Put one of your scripts in the folder and add it to the menu using Method powershell_file and Command .\filename_of_script.ps1.
  • Try including PowerShell commands in the CSV file. Use Method powershell_inline and Command Get-ComputerInfo. Run Show-ScriptMenuGui with -NoExit to stop the PowerShell window from closing.
  • Add a link to an external application. Use Method cmd and enter the path of the program in Command.

Step 4: Next steps

Step 5: Make a shortcut

When you’re happy with your menu, why not make a shortcut to it in File Explorer?

  1. Right click a blank area in a folder window or on your desktop.
  2. Select New → Shortcut
  3. Enter something like this as the location:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File "C:\full\path\PSScriptMenuGui_example\PSScriptMenuGui.ps1"

How to make your free Azure Linux VM actually free

Azure gives you a good amount of stuff free for 12 months when you sign up.

Quite tantalizing among these is a free Linux VM:

But if you make a B1S VM with the Ubuntu Server 18.04 LTS image, you start getting charged a trickle of cash for the disk. I amassed a bill of $1.26 before I noticed – quite shocking!

What’s up?

It turns out the 6 in P6 represents the size of the disk: 64 GB.

And the Ubuntu disk is only 30 GB. So you’re being charged for using too small a disk!

Luckily the fix is simple.

Start by creating your VM as normal:

Once it’s been provisioned, Stop (Deallocate) the VM:

Then open your VM in the Azure portal and navigate to Disks -> click disk name -> Configuration.

Set Size (GiB) to 64 and click Save.

Then start your VM back up. It should now be free of charge – and you’ll have a bit more space to play with.

PowerShell Azure Functions to PowerApps “Hello World” (Part 2)

Last time, we deployed a function to Azure.

We now have a PowerShell script sitting in the cloud which we can talk to via a HTTP REST call.

This time, we’ll create a Custom Connector in PowerApps so that we can hook our script into an app.

Part 2: Create a Custom Connector

You should first make sure that you can talk to your function with PowerShell:

  1. Open your Function in the Azure console and click Get function URL.
  2. Leave default (Function key) selected and copy the URL. You should get something like this:
  3. Append &Name=myName to the end and run with Invoke-RestMethod:
Invoke-RestMethod "https://dan-function.azurewebsites.net/api/a_HelloWorld?code=PA1Twlk/anVrchlbKSZSvZcWQCawE5MjY2JcQ3s0/kMYqpnvI2WEMA==&Name=Dan"

Once you’re happy that your function is working, switch over to Power Apps.

Here’s a video demo:

And here are step-by-step instructions:

Start with Custom Connectors → New custom connector → Create from blank

(Create from Azure Service (Preview) doesn’t work with the Azure Functions 2.x runtime – a to-be-expected example of two preview features not working together.)

  1. General screen
    Host is your Azure Functions domain, in my case:
  2. Security
    Authentication type: API key
    Parameter code: code
    Parameter label: code
    Parameter location: Query
  3. Definition
    Action New action
    1. General
      Summary and Operation ID: hello_world
    2. Request
      click Import from sample
      Verb = POST
      URL = an example of a full query, including Name=myName
      Click Import, then delete the block named code, as it is already handled in the Security section.
    3. Response
      Click Add default response, then run a chunk of PowerShell like this to get an example response that you can paste into the Body field:
$response = Invoke-WebRequest "https://dan-function.azurewebsites.net/api/a_HelloWorld?code=PA1Twlk/anVrchlbKSZSvZcWQCawE5MjY2JcQ3s0/kMYqpnvI2WEMA==&Name=Dan"
# Show response in console
# Copy response body to clipboard
$response.Content | clip

Now save your connector and go to the Test tab.

Under Connections, click New connection. Enter your function key when prompted (the long bunch of characters that appear after code= in a request URL).

When your connection has been created, return to the Test screen, and try out your function. You should hopefully see a familiar and reassuring block of JSON – greetings!

That’s it for now. Next time, we complete the package by adding our PowerShell function to a real life actual PowerApp.

Add PowerShell 7-preview to Windows Terminal in 2 minutes

Edit: The stuff below doesn’t work any more. But this new stuff works.

The new Windows Terminal app is now available from the Microsoft Store, and the world is excited.

Here’s a quick ‘n dirty method to link it to PowerShell 7:

  1. Prerequisites: Windows Terminal app & PowerShell 7 x64.
  2. Run Windows Terminal and open its Settings.
  3. A file in your local AppData called profiles.json will open. Paste the stuff below into the profiles section.
  4. Download the PowerShell .ico file and put it somewhere convenient. Amend the icon path if necessary.
    "acrylicOpacity" : 0.5,
    "closeOnExit" : true,
    "colorScheme" : "Campbell",
    "commandline" : "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
    "cursorColor" : "#FFFFFF",
    "cursorShape" : "bar",
    "fontFace" : "Consolas",
    "fontSize" : 10,
    "guid" : "{4f91b7ed-8cd4-4b20-ba02-429fcebd800a}",
    "historySize" : 9001,
    "icon" : "C:\\Git\\PowerShell\\pwsh_32512.ico", 
    "name" : "PowerShell 7-preview",
    "padding" : "0, 0, 0, 0",
    "snapOnInput" : true,
    "startingDirectory" : "%USERPROFILE%",
    "useAcrylic" : false


  • Windows Terminal will accept icon files in .png and .ico format.
  • But it won’t read the icon from an .exe.
  • Variable expansion does not seem to work in the icon path (so no %APPDATA%… – it stops Windows Terminal from running entirely!)
  • I also show a couple of ways to detect that Windows Terminal is in use: the existence of an environment variable called WT_SESSION and the path of the process’ parent. Does anyone have anything else?