Clearing Your Akamai CDN Cache with Powershell – Redux

About a year ago, I wrote an entry concerning clearing your Akamai Content using Powershell and the SOAP API they published then.  I have noticed that article has been getting some additional love recently.  Since it has surged in popularity, I thought I would offer an updated version of the script.  Akamai has changed the API to use a REST API now, which makes it a little simpler to use Powershell…but also throws a little gotcha out there too.  As a side note, Akamai will no longer support the older SOAP API as of June 1, 2014.  The method below is available now and will need to be used after that date.

First things first, you can find the information on the changes to the API here.  This document is much smaller than the original SOAP API because it really is a lot simpler to use.

The first thing you will notice is that there are now two scripts included.  The reason for this is Akamai has changed the procedure for how they report back.  On the old system, you could subscribe to an email alert that would provide you the status of your request.  On the new system, the caller immediately gets a response to say if it was accepted or not.  But to find out if the request was completed, you have to call back to Akamai with a “progressUri,” but you can only do so after the time passes that they recommend (usually seven minutes).

To help with keeping track of when the requests are done, I am using a second script, Get-AkamaiStatus, to accept the response from the first script.  Included in that PSObject are the credentials used in the first request, the specific progressUri that you need to check on your request, and the number of seconds to wait before querying the status.

The second script takes the information and creates a Powershell job to run in the background.  That script will sleep in the background for the specified number of seconds, and then call the progressUri for the results.  Additionally, the second script will also register an event to watch for the status of the background job to change.  Once it changes, it will notify you at the console and unsubscribe the event that was created to watch that background job.  The notification will tell you the commands you need to retrieve and, if desired, remove the background job.

To use these two scripts together, pipe the output of Clear-AkamaiCache to Get-AkamaiStatus

Clear-AkamaiCache -Action Invalidate -Domain Production -Type arl -username joeuser -password 'Pa$$w0rd' -Resource @("http://www.myurl.nosite/page/page1.aspx", "http://www.myurl.nosite/page/page2.aspx") | Get-AkamaiStatus

To give credit where it is due, I borrowed code from Powershell.com to set up the background task notification.

Just like before, this code is provided for reference.  You must have an account with Akamai to be able to use this code.  Test this first in a non-production environment.  I assume no responsibility if you use this and it breaks your system.  Use code from the Internet at your own risk!

Here is the code:

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.

 .LINK
 https://api.ccu.akamai.com/ccu/v2/docs/index.html

#>

 [CmdletBinding()]
 Param(
 [ValidateSet("invalidate","remove")]
 [ValidateNotNullOrEmpty()]
 [string]$Action,
 [ValidateSet("staging","production")]
 [ValidateNotNullOrEmpty()]
 [string]$Domain,
 [ValidateSet("arl","cpcode")]
 [ValidateNotNullOrEmpty()]
 [string]$Type,
 [ValidateNotNullOrEmpty()]
 [string]$username,
 [ValidateNotNullOrEmpty()]
 [string]$password,
 [ValidateNotNullOrEmpty()]
 [String[]]$Resource
 )

 $AkamaiRESTUrl = "https://api.ccu.akamai.com/ccu/v2/queues/default"

 $options = @{}

 Write-Verbose "Building options array."
 $options.Add("action",$Action.ToLower())
 $options.Add("domain",$Domain.ToLower())
 $options.Add("type",$Type.ToLower())
 $options.Add("objects",$Resource)

 Write-Verbose "Sending request to server."
 $body = ConvertTo-Json -InputObject $options
 $cred = new-object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $(ConvertTo-SecureString -String $password -AsPlainText -Force)
 $result = Invoke-RestMethod -Method Post -Uri $AkamaiRESTUrl -Credential $cred -ContentType "application/json" -Body $body
 $properties = @{}
 $result.psobject.properties | ForEach-Object {$properties.Add($_.Name, $_.Value)}
 $properties.Add("Credential", $cred)
 Write-Output (new-object -TypeName PSObject -Property $properties)
}

Function Get-AkamaiStatus
{
 [CmdletBinding()]
 Param(
 [Parameter(
 ValueFromPipeline=$true)]
 [PSObject]$PurgeResponseObject
 )

 if ($PurgeResponseObject.httpStatus -ne "201")
 {
 $PurgeResponseObject | select httpStatus, detail, purgeId, supportId
 Write-Error "Looks like your request was not accepted by Akamai. See information above."
 return
 }

 $job = Start-Job -Name "GetAkamaiStatus" -ArgumentList $PurgeResponseObject -ScriptBlock {
 $obj = $args[0]
 $akamaiUrl = "https://api.ccu.akamai.com"
 $progressUrl = $akamaiUrl + $obj.progressUri
 Start-Sleep -Seconds $($obj.pingAfterSeconds)
 Invoke-RestMethod -Uri $progressUrl -Credential $obj.Credential
 }

 Register-ObjectEvent $job -EventName StateChanged -Action {
 Write-Host ('Job #{0} ({1}) complete.' -f $sender.Id, $sender.Name)
 Write-Host 'Use this command to rectrieve the result.'
 Write-Host (prompt) -NoNewline
 Write-Host ('Receive-Job -ID {0}; Remove-Job -ID {0}' -f $sender.Id)
 Write-Host (prompt) -NoNewline
 $eventSubscriber | Unregister-Event
 $eventSubscriber.Action | Remove-Job
 } | Out-Null
}
Advertisements
This entry was posted in Advanced Function, Cmdlet Help, PSObjects, Scripting and tagged , , . Bookmark the permalink.