Taking care of the CDN can be a hassle sometimes. Unless you implement the perfect system with unique keys for every item update you will need to purge content once in a while.

We asked for some guiding from Limelight but they did not have any example for Powershell themselves so I had to translate the existing one from Perl. Hardest part was the authentication and getting the hash right but with some help from the nice people at stackoverflow it worked out in the end.

Kudos also to Limelight for having a good API documentation.

As always, if you improve it then please share it.

Contributions is always appreciated!

#############################################################################################################################
#
#		Limelight clear cache script
#
#		Version		Change								Author
#		1.0			Initial version						Patrik Jonsson	
#
#############################################################################################################################

#############################################################################################################################
#
#	Begin Configuration
#
#############################################################################################################################

$Global:LimeLightUserName = ""
$Global:LimeLightShortName = ""
$Global:LimeLightApiKey = ""
$Global:LimeLightApiEndpointBase = "https://control.llnw.com/purge-api/v1/"

#############################################################################################################################
#
#	End Configuration
#
#############################################################################################################################

#############################################################################################################################
#
#	Function to build the authentication headers
#
#############################################################################################################################

function Build-Headers {
    param($url, $httpMethod, $queryparameters, $postData)
	
	$timestamp = [math]::round(([decimal]((Get-Date -UFormat %s).Replace(",", ".")))*1000)
	
    $datastring = -join @(
        $httpMethod
        $url
        $queryparameters
        $timestamp
        $postData
    )
	
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.Key = @($Global:LimeLightApiKey -split '(?<=\G..)(?=.)' | ForEach-Object { [byte]::Parse($_,'HexNumber') })
	
    $token = [BitConverter]::ToString($hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($datastring))).Replace('-','').ToLower()
	
	$Headers = @{
				"Accept-Encoding" = "identity";
				"Content-Type" = "application/json"; 
				"Accept" = "application/json";
				"X-Llnw-Security-Principal" = $Global:LimeLightUserName; 
				"X-Llnw-Security-Token" = $token ; 
				"X-Llnw-Security-Timestamp" = $timestamp;   
	}
	
	Return $Headers
	
}

#############################################################################################################################
#
#	Function to purge origin by regex
#
#############################################################################################################################

function purgeByRegex {

	Param([string]$RegexString)
	
	$apiUrl = $Global:LimeLightApiEndpointBase + "request"
	$queryParameters = ""
	
	$entries = @{
		"url" = $RegexString;
		"regex" = $true;
		"shortname" = $Global:LimeLightShortName;
		"delete" = $true;
	}
	
	$postData = @{ "entries" = @($entries) } | ConvertTo-Json -Compress

	$RequestHeaders = Build-Headers -url $apiUrl -httpMethod "POST" -postData $postData
	
	Invoke-RestMethod -Method "POST" -Uri $apiUrl -Body $postData -Header $RequestHeaders
}

#############################################################################################################################
#
#	Function to check status of a specific purge
#
#############################################################################################################################

function checkPurgeById{
	Param([string]$PurgeId)
	
	$queryparameters = "includeDetail=true&dataLimit=5"
	$apiUrl = $Global:LimeLightApiEndpointBase + "requestStatus/" + $PurgeId
	
	$RequestHeaders = Build-Headers -httpMethod "GET" -url $apiUrl -queryparameters $queryparameters

	Invoke-RestMethod -Method "GET" -Uri $($apiUrl + "?" + $queryparameters) -Header $RequestHeaders
	
}

#############################################################################################################################
#
#	Function to check how many jobs we have running
#
#############################################################################################################################

function Get-CurrentActiveJobs{
	
	$queryparameters = "includeDetail=true"
	$apiUrl = $Global:LimeLightApiEndpointBase + "statusList/" + $Global:LimeLightShortName
	
	$RequestHeaders = Build-Headers -httpMethod "GET" -url $apiUrl -queryparameters $queryparameters

	$RecentJobs = Invoke-RestMethod -Method "GET" -Uri $($apiUrl + "?" + $queryparameters) -Header $RequestHeaders
	
	([array]($RecentJobs.entryStatuses | Where-Object { $_.status -ne "Complete" })).Count
	
}


#############################################################################################################################
#
#	Function to list what you have access to
#
#############################################################################################################################

function checkEntitlements {
	
	$apiUrl = $Global:LimeLightApiEndpointBase + "purgeEntitlements"
	
	$RequestHeaders = Build-Headers -httpMethod "GET" -url $apiUrl

	Invoke-RestMethod -Method "GET" -Uri $apiUrl -Header $RequestHeaders
	
}

if(Get-CurrentActiveJobs -gt 0){
	"Too many current jobs"
} else {
	"Purging"
	$PurgeID = (purgeByRegex -RegexString ".*/resources/static/sorry/starcasino.*").id

	Sleep 60
	$Result = (checkPurgeById -PurgeId $PurgeID).entryStatuses[0]
	While($Result.status -eq "Pending" -or $Result.status -eq "In Progress"){
		Sleep 20
		$Result = (checkPurgeById -PurgeId $PurgeID).entryStatuses[0]	
	}

	"Finished with status: " + $Result.Result

}