Clearing Your Akamai Content Delivery Network Cache with Powershell

The API referenced in this article will expire on June 1, 2014.  Please click here to go to the updated article on this information.

Recently, I had to do some work on a project with Akamai caching.  Part of that project required writing some C# code for a service to clear parts of the cache.  As I was working on that and looking around the Internet, I noticed that there were no examples of how to leverage Powershell to perform this task.  The documentation from Akamai showed alternate ways to connect, but these were using either Perl, Javascript, or some flavor of Visual Basic.  Note: You must have an account with Akamai in order to use this script.


The actual script shown is not all that complex.  I basically just wrote a wrapper to collect and format the inputs for the API call.  The biggest amount of work is setting up the web service proxy object and then taking all the parameters and making them fit in the API call.

You will notice that there are specific parameter validations in place.  For a few of these parameters, there are specific words that are to be used to create the request.  While I could have used Switch parameters to accept each one, I didn’t have a great way to prevent the user from entering conflicting values.  So to facilitate that, I set up ValidationSet tags to set the only values that were allowed to be used for those parameters.

Once all the parameters are in, the first thing is to try to connect to the web service.  I use the New-WebServiceProxy cmdlet to instantiate that connection.  There is a catch block to stop execution if the service cannot be contacted.  If the service is contacted and the new object created, then the request arguments are prepared.

The email notification list is the first option parameter that is built.  If an email address is specified, then the parameter gets added.  If there are multiples, an array, then the array is joined into a single string separated by commas.  The remaining arguments are built and added to the options array.

All the other arguments are assembled into the API call to the PurgeRequest() method.  Notice that there is a $network variable that is passing in a blank string.  This is intentional because that argument is deprecated according to the API documentation.  It has to be included, but there is no use for it.

The request gets sent to the remote web service and waits for a response.  Once the response is returned, the results are parsed for success or failure and reports to the user the pertinent information.  If successful, the script returns the estimated time for completion of the request and the session ID.  If unsuccessful, it returns the warning or error message and, if provided, the specific Resource entry that caused the problem.

** UPDATE 01/30/2014 **

A reader recently brought to my attention that even though the script worked, an error was generated.  The error indicated that the ARL failed, even though the Akamai system did, in fact, accept the request and process it.  The reason this did not work is because I had inadvertently used the wrong variable name on line 105.  I was placing the response object from Akamai in the $request variable, and a few lines later, I was testing against a $result variable.  Thanks to Darby Coquet for bringing this error to my attention.  I have corrected the code below to work as expected.

******************

Hopefully, this helps your work.  Let me know if you find any issues with the script.  As always, it is important to test any script on the Internet in a test environment and NOT on production data.  This script was written as a help and I assume no liability for your use in your environment.  USE AT YOUR OWN RISK!

Function Clear-AkamaiCache
{
<#
 .SYNOPSIS
 Used to clear Akamai EdgeControl Cache

.DESCRIPTION
 This function is an interface to the Akamai Content Control Utility web service SOAP interface. By passing in the appropriate
 parameters, the Akamai resources can be purged/invalidated by CPCode or by ARL/URL.

.PARAMETER Action
 Specifies the type of action to perform on the resources. Values can be either "Remove" or "Invalidate."

.PARAMETER Domain
 Specifies whether the command will operate on "Production" or "Staging."

 .PARAMETER EmailNotification
 Specifies an array of email addresses that should be notified when the process is complete.

 .PARAMETER Type
 Specifies the type of resource that will be removed from the cache. Values can be "ARL" or "CPCode."
 ARL can be either the Akamai resource locator or a web URL to the object to be removed.

 .PARAMETER Username
 The username that has access to purge the specified objects from the cache. This is the credentials that
 were supplied by Akamai Customer Care or your local Akamai Account contact.

 .PARAMETER Password
 The password that was assigned to the username by Akamai Customer Care.

 .PARAMETER Resource
 Accepts an array of CPCodes or ARL/URLs that specify the objects to be removed from cache.

.NOTES
 Additional information about the function go here.

.LINK
 https://control.akamai.com/dl/customers/other/CCU/Content_Control_Interfaces.pdf
#>

[CmdletBinding()]
 Param(
 [ValidateSet("Invalidate","Remove")]
 [ValidateNotNullOrEmpty()]
 [string]$Action,
 [ValidateSet("Staging","Production")]
 [ValidateNotNullOrEmpty()]
 [string]$Domain,
 [String[]]$EmailNotification,
 [ValidateSet("ARL","CPCode")]
 [ValidateNotNullOrEmpty()]
 [string]$Type,
 [ValidateNotNullOrEmpty()]
 [string]$username,
 [ValidateNotNullOrEmpty()]
 [string]$password,
 [ValidateNotNullOrEmpty()]
 [String[]]$Resource
 )

 $AkamaiWSDL = "https://ccuapi.akamai.com/ccuapi-dotnet.wsdl"
 Write-Verbose "Connecting to $AkamaiWSDL"
 try
 {
 $purgeProxy = New-WebServiceProxy -Uri $AkamaiWSDL -ErrorAction Stop
 }
 catch [Exception]
 {
 Write-Error "Unable to connect to web service: $_.Message"
 return
 }

 Write-Verbose "Connected to web service."
 $options = @()
 #network variable is deprecated, but still passed in request.
 #Documentation says to send empty string.
 $network = ""

 if ($EmailNotification)
 {
 Write-Verbose "Building email notification list."
 if ($EmailNotification.Length -eq 1)
 {
 Write-Verbose "Only one address to process."
 $emailAddresses = $EmailNotification[0]
 }
 else
 {
 Write-Verbose "Building email list from array."
 $emailAddresses = $EmailNotification -join ','
 }
 Write-Debug "Email = $emailAddresses"
 $options += "email-notification=$emailAddresses"

 }

 Write-Verbose "Building options array."
 $options += "action=$Action"
 $options += "domain=$Domain"
 $options += "type=$Type"

 Write-Verbose "Sending request to server."
 $result = $purgeProxy.purgeRequest($username, $password, $network, $options, $Resource)

 if (($result.resultCode -ge 100) -and ($result.resultCode -lt 200))
 {
 Write-Verbose "Request successful, returning time to completion and Session ID."
 $time = New-TimeSpan -Seconds $($result.estTime)
 Write-Host "Your request has been accepted and should be done in $($time.hours.ToString("00")) hours $($time.minutes.ToString("00")) minutes $($time.Seconds.ToString("00")) seconds."
 Write-Host "Seesion ID: $($result.SessionID)"
 }
 else
 {
 Write-Verbose "Request unsuccessful, present return message and the problem URL, if supplied."
 Write-Warning $result.resultMsg
 if ($result.uriIndex -gt -1)
 {
 Write-Warning "Problem URL is $($Resource[$result.uriIndex]))."
 }
 }
}
Advertisements
This entry was posted in Advanced Function, Cmdlet Help, Scripting and tagged , , . Bookmark the permalink.