Skip to main content

Developing PowerShell modules for REST APIs – Part1


AzureFunction

Over the years I have developed different PowerShell modules for different web APIs. I thought it would be a good idea to write a 2 series post about how you could go about to do this. This will be a 2 part blog series where we will run through the entire process of building a module for a REST API. I will try my best to keep this as simple as possible and leave more advanced stuff for a follow up post if the interest is there.

What you need

Depending on your experience with source control and PowerShell in general, you might want to use GIT or some other software repro for the code. In addition we are going to create a test REST API using the splendid UniversalDashboard PowerShell module created by Adam Driscoll. It is available on the PowershellGallery. Other prerequisites are built-in to Powershell. I will assume that you will be following along using at least PowerShell version 5 or greater.

What is HTTP metods for REST API.

The primary or most common HTTP verbs used are POST, GET, PUT, PATCH and DELETE.

  • POST - Create something
  • GET - Read or get something
  • PUT - Update or replace something
  • PATCH - Update or modify something
  • DELETE - Delete something

To keep it as simple as possible, I will focus on using POST and GET in this guide.

Authorization

APIs usually have some sort of requirement of authentication using a key. The UniversalDashboard module does not yet support authorization for REST endpoint, however we are going to fake it. My pseudo authentication method is not something you should ever use in production.

The REST API

We will create an API that enables you to list the files in a folder on your drive, sorry was the best I could come up with. The API will also let you create files with content. I know this is kind of not really exciting, however the overall goal is to keep it simple and everybody understands files.

REST Endpoints

First if you don’t have the UnversalDashboard module installed, fire up PowerShell and download the module from the Gallery:

    Install-Module -Name UniversalDashboardForce

Now we are going to create our first GET endpoint.

We create a New-UDEndpoint with the partial url of "/file/" and we will support the GET method. The endpoint it self is just a scriptblock that is executed in a separate runspace on your machine. Currently an GET Endpoint does not support parameters (Authorization) in the scriptblock like a POST endpoint does, however I included it anyway. You notice we have to extract the Authorization value from the request header from the runspace. The endpoint assumes that you have a folder ($path) on you computer with path "c:\temp\api". If the folder does not exists, you will have to create it. If the request contains the supersecret key "foo:bar" the request will get all the files in c:\temp\api and write them to the pipeline as JSON-object. If you do not understand the authorization key concept, do not worry, we will create an helper function, actually two helper functions, that will help you create the key.

Next up is our POST endpoint which is quite similar.

The POST method supports scriptblock parameters, and we need Authorization, FileName and Content parameters to be able to create files. As you may notice, we have the same decoding of the Authorization key.

Helper functions

To aid us in working with the API, we need 2 helper functions to be able to create an Authorization key. Normally the key is added as an header to a request or in the actual body of the request. We will have to add the key to the body of the request for the POST endpoint.


The Get-AuthorizationHeader is the main function that will create the key for us. The ConvertTo-Base64 function is used by Get-AuthorizationHeader to encode the key.

First test

To make sure everything is working, we will test the GET Endpoint. Copy the helper functions and the endpoint definition to your favorite PowerShell editor. Then we will start the Endpoint and create an key that can authenticate us against the API:

First we start the Endpoints by running Start-UDRestApi. You may get a firewall warning when you run the cmdlet. You have to allow traffic to the port you have selected for this to work. I selected post 11000 as the listening port for my API, however you may choose another port on your computer. Next we create a securestring containing our password "bar". Then we create a PSCredential object and pipe that to our helper function Get-AuthorizationHeader function. To test the Endpoint, we run the Invoke-RestMethod cmdlet and use the key just created. If everything work, you should have something like this in your window:

image

Those are the 3 files I have in my c:\temp\api folder.

That is it for part 1, In part 2 we will start to create a small PowerShell module and make it even more awesome. Stay tuned!

Cheers

Tore

Comments

Popular posts from this blog

Serialize data with PowerShell

Currently I am working on a big new module. In this module, I need to persist data to disk and reprocess them at some point even if the module/PowerShell session was closed. I needed to serialize objects and save them to disk. It needed to be very efficient to be able to support a high volume of objects. Hence I decided to turn this serializer into a module called HashData. Other Serializing methods In PowerShell we have several possibilities to serialize objects. There are two cmdlets you can use which are built in: Export-CliXml ConvertTo-JSON Both are excellent options if you do not care about the size of the file. In my case I needed something lean and mean in terms of the size on disk for the serialized object. Lets do some tests to compare the different types: (Hashdata.Object.ps1) You might be curious why I do not use the Export-CliXML cmdlet and just use the [System.Management.Automation.PSSerializer]::Serialize static method. The static method will generate t

Toying with audio in powershell

Controlling mute/unmute and the volume on you computer with powershell. Add-Type -TypeDefinition @' using System.Runtime.InteropServices; [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { // f(), g(), ... are unused COM method slots. Define these if you care int f(); int g(); int h(); int i(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int j(); int GetMasterVolumeLevelScalar(out float pfLevel); int k(); int l(); int m(); int n(); int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev); } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), Inte

Something completely different – PoshARM

I needed a project for my Xmas holiday and I needed something remotely work related. Thus the dubious PoshARM PowerShell module was born and brought to life during my Xmas holiday. Simply put it is a module that lets you build – for now – simple Azure Resource Manager (ARM) templates with PowerShell .  The module can also import templates from a file or from the clipboard/string. Your partial template or ready made template can be exported as a PowerShell script. This blog post will walk you through how to use it and the features that is currently implemented.  Update 08.02.2017: The module is now published to the PowerShellGallery ( https://www.powershellgallery.com/packages/posharm ). It is still in beta version, however test coverage have increased and some bugs have been squashed during the testing. Also help is present, however somewhat lacking here and there. Update 18.01.2017: The module is now on GitHub. Here is the link to the repro  ( PoshARM on GitHub ) What