Creating ThinPrint license reports

1075 views 0

As a ThinPrint service provider you have the availability, as of License Server version 10.6 (and later), for automatic assignment of ThinPrint licenses to users. So users can be automatically assigned a license immediately, the first time they print.

This facility offers greatly simplified license administration and provides for accurate bill­ing from ThinPrint, based on actual usage. These are both big advantages, especially in environments with fluctuating user numbers.

In addition, you can still assign licenses to users and user groups manually (for example, when importing from Microsoft Active Directory) or you can make exclu­sions from the automatic license allocation.

Billing from ThinPrint to you as a service provider is based on monthly reports, wherein your ThinPrint clients remain anonymous. As the service provider, you can also create a second internal report in which you can view the assignment of licenses for your individual clients. This report enables you in turn, to accurately bill clients, based on usage.

This document explains how these report files, that identify the active users, can be generated automatically.

Creating a report file

With License Server version 10.6 (and later), it is possible to create a report file from the command line. To do so, go to the appropriate directory on the license server. By default, the command is in the following directory:

C:\Program Files\Common Files\ThinPrint

  • Start the command line with administrative rights. The invoked command is:

cclucs.exe -report [FILE]

[FILE] is the path and file name. Example:

cclucs.exe -report c:\temp\ThinPrintLicenseReport.xml

The file suffix type is arbitrary. But the content is always created as XML. So it is advisable to select XML as the format.

Contents of the report file

The file contains a signature at the end, to verify it to ThinPrint. For further processing or to import the file into other applications for internal use, the signature may need to be removed (arrow).

Creating the report file automatically

Automatic file creation or periodic update can be achieved using Windows tools e. g. Task Scheduler. Here is an example, showing an update set to occur daily at 2 am.
Please note: Entries will not be overwritten, but will be supplemented with each new creation, so long as the report file is in the same folder.
The command line call can be outsourced to a batch file – e. g. RunReport.bat:

cd C:\Program Files\Common Files\ThinPrint

cclucs -report c:\temp\ThinPrintLicenseReport.xml

This file is then run regularly to perform the task.

  • Select in the Task Scheduler: Create Basic Task.
  • Enter when the task is to be triggered.

  • Choose the batch file you created before, in this example: RunReport.bat.

  • Enter a task name and a description.

  • Check whether settings on the Triggers and Actions tabs.

Task Scheduler: batch file on the Actions tab

Using this simple task scheduling, the report file is updated daily at 2 o’clock at night.
The file will include the ThinPrint license key with registration and activation keys, as well as the number of active users per domain at the time of the command call.

Domain remains anonymous

The domain is visible only as SID and is thus made anonymous to ThinPrint. For internal purposes, you can determine the actual names of the respective domains, using tools such as PSGetSID from Sysinternals.


A better laid out display can be created using, for example, the Transform function in Excel. For this purpose, a suitable stylesheet must be created (in this example: ThinPrintLicenseReport.xsl):

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
<xsl:template match="/">
   <table border="2" bgcolor="yellow">
      <xsl:for-each select="LicenseReport/Product/Domain[@DomainSid!='S-1-5-32']">
       <td><xsl:value-of select="@DomainSid"/></td>
       <td><xsl:value-of select="@Date"/></td>
       <td><xsl:value-of select="@UserCount"/></td>


Convert XML format into a readable form

Using PowerShell script the original report file in XML format can then be converted into a visually more readable form (in this example: ThinPrintLicenseReport.ps1):

param ($xml, $xsl, $output)
if (-not $xml -or -not $xsl -or -not $output)
Write-Host "& .\xslt.ps1 [-xml] xml-input [-xsl] xsl-input [-output] transform-output"
trap [Exception]
Write-Host $_.Exception;
$tempFile = [System.IO.Path]::GetTempFileName();
(Get-Content $xml) -notmatch "[0-9a-f].*" | Out-File $tempFile
Import-Module ActiveDirectory
<# Get Distinguished Name #>
$objDomain = Get-ADDomain
$objDomainDN = (Get-ADDomain).DistinguishedName

<# Get current Domain SID #>
$CurrentDomainSID = (Get-ADDomain).DomainSID

<# Get Forest Domains #>
$objForestDomains = (Get-ADForest).Domains

<# Replace all SIDs in $tempFile that match any of the Forest Domains #>
foreach ($Domain in $objForestDomains) {
try {
$DomainResult = Get-ADDomain -server $Domain -ErrorAction SilentlyContinue | select DNSroot, DomainSID -ErrorAction SilentlyContinue
$xmlContent = (Get-Content $tempFile)
If ($xmlContent -match ($DomainResult | select -ExpandProperty DomainSID)) {
$xmlContent = $xmlContent -replace ($DomainResult | select -ExpandProperty DomainSID), ($DomainResult | select -ExpandProperty DNSroot)
$xmlContent | Out-File $tempFile
} catch {
Write-Host ("Exception while contacting Domain " + $Domain + ".")
Write-Host ($Error[0].Exception)
<# Get Trusted Domains #>
$objTrustedDomains = Get-ADObject -SearchBase "CN=System,$objDomainDN" -SearchScope OneLevel -LDAPFilter "(&(objectClass=trustedDomain)(!trustAttributes=32))" -Property name, securityIdentifier
$TrustedDomainSIDs = $objTrustedDomains | select -ExpandProperty securityIdentifier
$TrustedDomName = Get-ADObject -SearchBase "CN=System,$objDomainDN" -SearchScope OneLevel -LDAPFilter "(&(objectClass=trustedDomain)(!trustAttributes=32))" -Property name, securityIdentifier | select -ExpandProperty Name
<# Replace all SIDs in $tempFile that match any of the Trusted Domains #>
foreach ($TrustedDomain in $objTrustedDomains) {
try {
$xmlContent = (Get-Content $tempFile)
If ($xmlContent -match ($TrustedDomain | select -ExpandProperty securityIdentifier)) {
$xmlContent = $xmlContent -replace ($TrustedDomain | select -ExpandProperty securityIdentifier), ($TrustedDomain | select -ExpandProperty Name)
$xmlContent | Out-File $tempFile
} catch {
Write-Host ("Exception while contacting Domain " + $Domain + ".")
Write-Host ($Error[0].Exception)
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Transform($tempFile, $output);
remove-item -path $tempFile;

The call for an appropriate nam­ing convention for the provided script would go as follows:

.\ThinPrintLicenseReport.ps1 C:\temp\ThinPrintLicenseReport.xml c:\temp\ThinPrintLicenseReport.xsl c:\temp\ThinPrintLicenseReport.html

The display of the resultant ThinPrintLicenseReport.html file would look like in Illus. following.


To show the license consumption from ThinPrint GmbH send us the report file in XML format – e. g. ThinPrintLicenseReport.xml.

For internal accounting, and the respective billing of your clients, you can generate reports that will show the license consumption per domain. For that purpose, you can use the sample script above.

If the domain cannot be resolved, it will be displayed in the domain name position on the SID.

Previous Page
Next Page

Was this helpful?