One of the topics for the CCNA was about Describing characteristics of REST-based APIs. That's one of the reasons the CCNA is a very good entry level certification, it overlaps in a few different topics that are related to networking.
For the CCNA you should be familiar with the acronym CRUD which Stands for create, read, update and delete. They are the different operations you can carry out with rest APIs.
What are REST APIs?
A good analogy of an API is the function of a waiter. You tell the waiter what you want and the waiter goes to the kitchen to tell the chef what you want, then the waiter will bring the food to you. It’s like the middle man between two software applications. APIs open up an applications data so that other applications can access it.
A Representational State Transfer (REST) API is available over a network, they allow you to send requests to webservices that will carry out an operation, you specify the operation using a method is which explained below.
REST APIs follow a set of principles that defines how these APIs are to be designed and work. One of the these principles is that REST doesn’t keep track of previous requests therefore you must provide authentication details in each request, this is normally provided in the header of the request.
Request URI
The different parts of the URI are as follows
Scheme - Typically this will be https or http, in other words the protocol
Target host
Resource or endpoint - This would generally describe what type of resource you are going to work with , for example users, devices
Parameters - they are also know as the query string. It starts from the ? and additional parameters are separated by &. These are optional
Methods
A method tells the web service what you want to do and they relate to the CRUD acronym I mentioned earlier. The POST method is typically used to create a new resource. The GET method gets information. the PUT and PATCH methods update something. PUT will replace and PATCH will add to what already exists. DELETE as you might have guessed deletes a resource. You need to provide the method as part of the request along with the URI.
Response Codes
Response codes tell you if your request was successful. Some of the more common response codes are:
200 - OK
201 - Created
403 - Forbidden
404 - Not found
500 - Internal server error
PowerShell speaks REST
I recently found the rest APIs for Sophos Central really useful for automating disabling tamper protection to be able to uninstall the Sophos agents from remote systems. We had over 200 to do and the manual effort would have been too slow and disruptive to the user.
The command you would use in PowerShell is Invoke-RestMethod. The great thing is that it returns a PS custom object from the response it gets, you might get a response in JSON format but the command converts that into an object you can use in scripts.
Authentication and access tokens
Because REST is stateless you will need to provide authentication in each request. One way to provide this is by obtaining an access token from an authentication server and providing this in each request.
For Sophos I had to first create an API credential and I use the client ID and secret of that credential to obtain an access token.
So for example, I used the following to get the access token:
$body = "grant_type=client_credentials&scope=token&client_id={0}&client_secret={1}" -f $clientid, $clientsecret
$headers = @{"Content-Type" = "application/x-www-form-urlencoded" }
$response = Invoke-RestMethod -Uri 'https://id.sophos.com/api/v2/oauth2/token' -Method 'POST' -Headers $headers -Body $body
The response would be something like this
{
"access_token": "<jwt>",
"errorCode": "success",
"expires_in": 3600,
"message": "OK",
"refresh_token": "<token>",
"token_type": "bearer",
"trackingId": "<uuid>"
}
You can then get the variable using the $response variable
$response.access_token
With the access token I can then make subsequent calls by including the token in the headers of the request.
Requests
Because I created a module with different functions for different type of requests I decided to save the access token, tenant id and data region for other functions to use.
I created another function which I haven’t shown to get the tenant information like the tenant ID and data region and saved that to the $data variable. I used the script scope modifier to save those variables in the script scope.
# The response from the above command need to be available for subsequent API calls
$script:token = $response.access_token
$script:TenantId = $data.TenantId
$script:DataRegion = $data.dataRegion
I can then use the script variables in other functions.
$headers = @{
"Authorization" = "Bearer $script:token"
"X-Tenant-ID" = $script:TenantID
"Accept" = "application/json"
}
I also include the header in each request. In this example I used splatting to pass the header, URI and method to the Invoke-RestMethod command.
$url = "{0}/endpoint/v1/endpoints/{1}?view=full" -f $script:dataregion, $endpointId
$invokeRestMethodSplat = @{
Uri = $url
Method = 'GET'
Headers = $headers
}
Invoke-RestMethod @invokeRestMethodSplat
In the above example you will notice that I needed a data region variable for the beginning of the URI, which is basically https://api-eu02.central.sophos.com.
You can also see that the method is GET and that there is also a parameter in the URI which specifies the view, in this case I pass ‘full’.
Conclusion
I am still learning about how to use Rest APIs and also improving on creating PowerShell modules. Wrapping different API requests into functions make it easier to make these requests without having to generate the headers each time and have to remember things like the endpoints. For example, I would simply use this command to get info on a device:
Get-PSSophosCentralEndpoint -DeviceId fec1ceb4-c546-44cd-a9e5-312hsf6658c0b
The function would take care of formatting the URI and generating the header for the request.
It is far from finished but you can find the module files in this GitHub repository: https://github.com/adrimus/PSSophosCentral. Feel free to give any recommendations or feedback, I would appreciate it.
Resources
Call REST APIs with Invoke-RestMethod in PowerShell - Adam Driscoll
What are REST APIs and how to use them with PowerShell - PDQ
HTTP Request Methods - W3Schools
I think knowing how to interact with REST APIs using PowerShell is key. It solves a lot of issues you may have. In addition, it allows you to run quick PoC and test things.
Great article!!!