*Update. Changes made due to API only allowing 100 licenses to be released at one time.*
Building on getting the licenses on the last post, how about a way to release them? Obviously you will need to follow the guidelines laid out by Citrix EULA on when you can release licenses: Citrix License Usage.
You do have the option to use the console in Citrix Cloud, but if you prefer to do things via script, you can do that as well!
Important note to make…. The format of the consumerList is what presented the biggest issue. With a bit of assistance from a teammate, it was possible to get the proper way to format the data.
This is the format to have the data in:
You’ll notice the consumerList = @() in there. It is expecting to have an array of consumerList be passed to it. If you do not format this way, you will get invalid character errors.
Example of format that will fail all so miserably and give you that wonderful invalid character error:
This is an example of the output that will work and prevent frustration:
Example with five of users:
Example of result of successful release of 5 users:
# Script to release licenses from Citrix Cloud. Tested with PowerShell ISE. Also requires secure-client.csv with ID, Secret, and CustomerID in CSV to pass to Citrix Cloud.
# This must be used in accordance with Citrix EULA for users not having accessed in 30+ day period. Example below is targeting where users that have not logged in over 60 days.
# This will report on what users are in that group over 60 days. You can do a quick check using $releaseUsers.count before doing the release to see how many licenses will be released.
# ALWAYS check the exported report of users before releasing to make sure you are releasing the licenses you are expecting to.
$date = (Get-Date).AddDays(-60)
$creds = Import-Csv "c:\scripts\secure-client.csv"
$CLIENT_ID = $creds.ID
$CLIENT_SECRET = $creds.Secret
$CUSTOMER_ID = $creds.CustomerID
$tokenUrl = 'https://api-us.cloud.com/cctrustoauth2/root/tokens/clients'
$reportName = "user-license-toRelease.csv"
$getDate = Get-Date -Format MMddyyyy
$reportLocation = "C:\scripts\logs"
$response = Invoke-WebRequest $tokenUrl -Method POST -Body @{
grant_type = "client_credentials"
client_id = $CLIENT_ID
client_secret = $CLIENT_SECRET
}
$token = $response.Content | ConvertFrom-Json
$headers = @{
Accept = "application/json"
Authorization = "CwsAuth Bearer=$($token.access_token)"
'Citrix-CustomerId' = $CUSTOMER_ID
}
$resourceLocUrl = "https://api-us.cloud.com/catalogservice/$CUSTOMER_ID/sites"
$response = Invoke-WebRequest $resourceLocUrl -Headers $headers
$content = $response.Content | ConvertFrom-Json
$siteID = $content.sites.id
$headers = @{
Accept = "application/json"
Authorization = "CwsAuth Bearer=$($token.access_token)"
'Citrix-CustomerId' = $CUSTOMER_ID
'Citrix-InstanceId' = $siteID
}
$consumerList = Invoke-RestMethod "https://api-us.cloud.com/licensing/license/enterprise/cloud/cvad/ud/users" -Method GET -Headers $headers | Select-Object consumerList -ExpandProperty consumerList -ExcludeProperty consumerList
$releaseUsers = $consumerList | Where-Object {[DateTime]$_.latestLogonTime -lt $date}
$releaseUsers | Export-Csv "$reportLocation\$getDate-$reportName" -Append -NoTypeInformation
if($releaseUsers.count -gt 100){
$smallerCounter = $releaseUsers.Count
$toSkip = 0
Do{
$smallerList = $releaseUsers | Select-Object -Skip $toSkip -first 100
$body = @{
productEdition = "XAXDFull"
licenseType = "user"
consumerList = @(
$smallerList.consumerId
)
} | ConvertTo-Json
Invoke-RestMethod "https://api-us.cloud.com/licensing/license/enterprise/cloud/cvad/ud/licenserelease" -Method POST -Body $body -Headers $headers -ContentType 'application/json'
$toSkip += 100
$smallerCounter -= 100
} Until ($smallerCounter -lt 100)
$smallerList = $releaseUsers | Select-Object -Skip $toSkip -first $smallerCounter
$body = @{
productEdition = "XAXDFull"
licenseType = "user"
consumerList = @(
$smallerList.consumerId
)
} | ConvertTo-Json
Invoke-RestMethod "https://api-us.cloud.com/licensing/license/enterprise/cloud/cvad/ud/licenserelease" -Method POST -Body $body -Headers $headers -ContentType 'application/json'
}