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-CliXmlConvertTo-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 the same xml, however we …

Developing PowerShell modules for REST APIs – Part2

This is part 2 of the REST API blogpost. In part1 we successfully setup two REST API endpoints using the UniversalDashboard PowerShell module. In this part we are going to create a simple module that support some CRUD operation against our API. As we are trying to keep things as simple as possible, we will not use any fancy framework (like Plaster) to build our module. We are also going to skip a very important step you should familiarize yourself with, Pester tests. Lets get to it.


The moduleWe will build a module called FilesAPI. The module folder will look like this:



In the functions folder I have already added the 2 helper functions from part 1, Get-AuthorizationHeader and ConvertTo-Base64. The other folders are just placeholders for important stuff like classes, private functions that you do not want to make available for the module consumer and tests for Pester tests. For such a small module that we are going to create, one could argue that it is much easier to just add the functi…