Skip to main content

Licence Compliance Review

Licence compliance review verifies that software usage across the organisation matches contractual entitlements and identifies optimisation opportunities. This task produces a compliance status report, a list of remediation actions for any gaps, and recommendations for licence reallocation or procurement changes. Perform this review quarterly for high-value software (annual cost exceeding £10,000) and annually for all licensed software.

Prerequisites

RequirementDetail
AccessRead access to licence management system, software asset management tools, and procurement records
PermissionsQuery access to identity provider for user counts, endpoint management for device counts
Data sourcesCurrent licence inventory with entitlement quantities, usage telemetry from past 90 days minimum
ToolsSpreadsheet software or licence management platform, access to vendor portals for entitlement verification
InformationContract documents for complex licensing agreements, vendor contact details for clarification
Time4-8 hours for initial review of 20-50 products; 2-4 hours for quarterly refresh

Verify access to the licence inventory before starting:

Terminal window
# If using a software asset management tool, verify data freshness
# Example using ServiceNow SAM
curl -s -u "$SAM_USER:$SAM_PASS" \
"https://instance.service-now.com/api/now/table/alm_license" \
-H "Accept: application/json" | jq '.result | length'
# Expected: Returns count of licence records
# Check last inventory sync date
curl -s -u "$SAM_USER:$SAM_PASS" \
"https://instance.service-now.com/api/now/table/cmdb_ci_spkg?sysparm_query=last_discovered>javascript:gs.daysAgoStart(7)&sysparm_count=true"
# Expected: Records discovered within past 7 days

For organisations without dedicated SAM tools, export licence data from procurement systems and endpoint management:

Terminal window
# Export installed software from Microsoft Intune
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"
Get-MgDeviceManagementManagedDevice |
Select-Object DeviceName, OperatingSystem |
Export-Csv -Path "managed-devices.csv" -NoTypeInformation
# Get detected applications
Get-MgDeviceManagementDetectedApp |
Select-Object DisplayName, DeviceCount, Platform |
Export-Csv -Path "detected-apps.csv" -NoTypeInformation

Procedure

  1. Export the current licence inventory from procurement records or the licence management system. The inventory must include product name, vendor, licence type, quantity owned, maintenance expiry date, and annual cost. Structure the export to enable comparison against usage data:
product_name,vendor,licence_type,quantity_owned,maintenance_expiry,annual_cost_gbp,cost_per_licence
Microsoft 365 E3,Microsoft,Subscription,450,2025-06-30,126000,280
Adobe Creative Cloud,Adobe,Named User,35,2025-03-15,18900,540
Zoom Business,Zoom,Concurrent,100,2025-09-01,15000,150
AutoCAD,Autodesk,Device,12,2025-04-30,21600,1800
Salesforce Enterprise,Salesforce,Named User,85,2025-12-31,127500,1500

Verify entitlement quantities against original contracts. Vendor portals frequently show different numbers than internal records due to true-up adjustments, promotional additions, or contract amendments. Log into each vendor’s licensing portal and record the authoritative entitlement figure.

  1. Collect usage data for each licensed product. The collection method varies by licence type and available telemetry:

    Named user licences require a count of assigned users, regardless of whether they actively use the software:

Terminal window
# Microsoft 365 licence assignment count
Connect-MgGraph -Scopes "User.Read.All", "Directory.Read.All"
$sku = Get-MgSubscribedSku | Where-Object { $_.SkuPartNumber -eq "ENTERPRISEPACK" }
$assigned = $sku.ConsumedUnits
$total = $sku.PrepaidUnits.Enabled
Write-Output "Microsoft 365 E3: $assigned assigned of $total owned"
# Example output: Microsoft 365 E3: 423 assigned of 450 owned

Concurrent licences require peak usage analysis over the review period:

-- Query licence server logs for peak concurrent usage
-- Adjust table and column names for your licence server
SELECT
product_name,
MAX(concurrent_users) as peak_concurrent,
AVG(concurrent_users) as avg_concurrent,
DATE(timestamp) as usage_date
FROM licence_checkouts
WHERE timestamp >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)
GROUP BY product_name, DATE(timestamp)
ORDER BY peak_concurrent DESC;

Device licences require a count of devices with the software installed:

Terminal window
# Query endpoint management for installed software
# Example using osquery fleet manager
fleetctl query --query "SELECT name, version, COUNT(*) as device_count
FROM programs
WHERE name LIKE '%AutoCAD%'
GROUP BY name, version;"

Record usage figures alongside entitlements for gap analysis.

  1. Calculate the compliance position for each product by comparing usage against entitlements. The compliance ratio equals usage divided by entitlements, expressed as a percentage:
Compliance Ratio = (Current Usage / Licences Owned) × 100
Under 80% = Potential over-licensing (optimisation opportunity)
80-100% = Optimal range
Over 100% = Compliance gap (remediation required)

Work through each product systematically:

ProductOwnedIn UseRatioStatus
Microsoft 365 E345042394%Optimal
Adobe Creative Cloud3541117%Gap: 6 licences
Zoom Business1006767%Over-licensed
AutoCAD1212100%Optimal
Salesforce Enterprise857892%Optimal

For products showing over 100% usage, determine the shortfall in absolute terms. Adobe Creative Cloud shows 41 users against 35 licences, creating a 6-licence shortfall. At £540 per licence, the unlicensed usage represents £3,240 in potential compliance exposure.

  1. Analyse usage patterns to identify optimisation opportunities. Products below 80% utilisation warrant investigation into whether licences can be reduced or reallocated.

    For the Zoom Business example showing 67% utilisation (67 of 100 licences), examine usage distribution:

-- Identify inactive Zoom licence holders
SELECT
user_email,
last_login_date,
DATEDIFF(CURDATE(), last_login_date) as days_inactive
FROM zoom_users
WHERE licence_type = 'Business'
AND last_login_date < DATE_SUB(CURDATE(), INTERVAL 90 DAY)
ORDER BY days_inactive DESC;

Users inactive for over 90 days are candidates for licence removal. If 25 users have not logged in during the review period, the organisation could reduce to 75 licences at the next renewal, saving £3,750 annually.

+---------------------------------------------------------------+
| LICENCE OPTIMISATION DECISION |
+---------------------------------------------------------------+
|
+------------v------------+
| Utilisation below 80%? |
+------------+------------+
|
+----------------+----------------+
| |
| Yes | No
v v
+-----------+-----------+ +-----------+-----------+
| Identify inactive | | No optimisation |
| users (90+ days) | | action required |
+-----------+-----------+ +-----------------------+
|
v
+-----------+-----------+
| Inactive count > 10% |
| of total licences? |
+-----------+-----------+
|
+-------+-------+
| |
| Yes | No
v v
+----+----+ +----+----+
| Remove | | Monitor |
| at | | next |
| renewal | | quarter |
+---------+ +---------+

Figure 1: Licence optimisation decision flow

  1. Document compliance gaps requiring remediation. For each gap, record the product, shortfall quantity, estimated exposure, and remediation options:

    Adobe Creative Cloud Gap Analysis

    • Shortfall: 6 named user licences
    • Exposure: £3,240 (6 × £540)
    • Root cause: Project team expansion without licence request
    • Remediation options:
      1. Purchase 6 additional licences (£3,240)
      2. Remove licences from inactive users (requires usage analysis)
      3. Downgrade 6 users to lower-tier product if requirements allow

    Investigate whether users actually require the full product. Adobe Creative Cloud includes applications that many users never open. If 8 current licence holders only use Acrobat Pro, they could migrate to the standalone Acrobat licence at £180 per year, freeing full Creative Cloud licences for reassignment.

  2. Prepare documentation for vendor audit defence. Software vendors conduct audits to verify licence compliance, and preparation reduces the risk of unfavourable findings. Assemble an audit defence file containing:

    • Licence purchase records (invoices, contracts, amendments)
    • Current entitlement confirmation (vendor portal screenshots dated within 30 days)
    • Usage evidence (reports from licence management tools, endpoint inventory)
    • User assignment records (who holds each licence)
    • Reconciliation workings (how usage was calculated)
+----------------------------------------------------------------+
| AUDIT DEFENCE FILE STRUCTURE |
+----------------------------------------------------------------+
| |
| /audit-defence/ |
| | |
| +-- /contracts/ |
| | +-- microsoft-ea-2023.pdf |
| | +-- adobe-vip-agreement.pdf |
| | +-- salesforce-order-form.pdf |
| | |
| +-- /entitlements/ |
| | +-- microsoft-portal-2025-01-15.png |
| | +-- adobe-admin-console-2025-01-15.png |
| | +-- salesforce-company-info-2025-01-15.png |
| | |
| +-- /usage-reports/ |
| | +-- m365-licence-report-q4-2024.csv |
| | +-- endpoint-software-inventory.csv |
| | +-- licence-server-usage-90day.csv |
| | |
| +-- /reconciliation/ |
| +-- compliance-review-2025-01.xlsx |
| +-- gap-analysis-workings.xlsx |
| |
+----------------------------------------------------------------+

Figure 2: Audit defence file organisation

Store audit defence files in a location accessible to procurement and IT leadership. Update entitlement screenshots quarterly.

  1. Generate recommendations for the next procurement cycle. The compliance review produces input for licence renewal decisions:

    Renewal Planning Recommendations

    ProductCurrentRecommendedChangeAnnual Impact
    Microsoft 365 E3450450None£0
    Adobe Creative Cloud3541+6+£3,240
    Zoom Business10075-25-£3,750
    AutoCAD1215+3+£5,400
    Salesforce Enterprise8585None£0

    Net annual impact: +£4,890 (increase driven by compliance remediation)

    For products approaching renewal within 90 days, escalate recommendations to procurement immediately. Contract negotiations benefit from accurate usage data, particularly when reducing quantities or requesting price concessions.

  2. Update the licence inventory with current figures and review findings. Record the review date, reviewer, and any changes to entitlement records:

-- Update licence inventory with review results
UPDATE licence_inventory
SET
current_usage = 423,
last_review_date = '2025-01-15',
reviewed_by = 'j.smith@example.org',
compliance_status = 'compliant',
notes = 'Optimal utilisation at 94%'
WHERE product_name = 'Microsoft 365 E3';
UPDATE licence_inventory
SET
current_usage = 41,
last_review_date = '2025-01-15',
reviewed_by = 'j.smith@example.org',
compliance_status = 'gap',
notes = 'Shortfall of 6 licences. Remediation in progress.'
WHERE product_name = 'Adobe Creative Cloud';

Schedule the next review based on product risk. High-value products (over £50,000 annually) and those with identified gaps warrant quarterly review. Lower-value products with stable usage can follow an annual cycle.

Verification

Confirm the review is complete by validating each output:

Compliance status verification:

Terminal window
# Generate compliance summary
cat licence_review.csv | awk -F',' '
NR > 1 {
ratio = ($4 / $3) * 100
if (ratio > 100) gaps++
else if (ratio < 80) over++
else optimal++
total++
}
END {
print "Total products reviewed: " total
print "Compliant (80-100%): " optimal
print "Compliance gaps (>100%): " gaps
print "Over-licensed (<80%): " over
}
'
# Expected: All products categorised with zero unreviewed

Gap remediation tracking:

Each identified gap must have a documented remediation path with owner and target date. Verify the gap register includes:

  • Gap identifier and product name
  • Shortfall quantity and financial exposure
  • Assigned owner for remediation
  • Target remediation date
  • Current status (open, in progress, resolved)

Audit defence file completeness:

Verify the audit defence file contains current documentation:

Terminal window
# Check audit defence file freshness
find /path/to/audit-defence -type f -name "*.png" -mtime +90
# Expected: No results (all screenshots within 90 days)
find /path/to/audit-defence/contracts -type f -name "*.pdf" | wc -l
# Expected: One contract file per major vendor

Renewal recommendation delivery:

Confirm procurement has received renewal recommendations for products expiring within 90 days. Obtain acknowledgement from procurement lead.

Troubleshooting

SymptomCauseResolution
Usage data unavailable for a productProduct lacks telemetry or licence serverDeploy licence metering agent, or estimate usage from identity provider group membership. For desktop software without metering, use endpoint inventory as a proxy for usage.
Vendor portal shows different entitlement than recordsContract amendment not reflected in internal records, or promotional licences expiredDownload current entitlement report from vendor portal. Reconcile against purchase history. Update internal records to match vendor’s authoritative count.
Usage exceeds entitlements but users report not using softwareLicences assigned but software uninstalled, or test/service accounts holding licencesQuery endpoint management to verify software installation. Identify and remove assignments for accounts without installed software.
Cannot identify licence holders for legacy softwareLicence assignments predate current identity systemCross-reference procurement records with HR data. Contact original requestors if identifiable. For unattributable licences, flag for removal at renewal.
Vendor audit notice received during reviewAudit triggered by renewal negotiation or random selectionPause optimisation actions that reduce licence counts. Accelerate audit defence file completion. Engage legal and procurement before responding to vendor.
Over-licensing identified but cannot reduceMulti-year contract with fixed quantitiesDocument over-licensing for next renewal negotiation. Request contract amendment if reduction exceeds 20% of contract value. Consider reallocation to other products from same vendor.
Usage data shows impossible valuesMetering system malfunction or double-countingVerify metering agent version and configuration. Check for duplicate device records in endpoint inventory. Compare against vendor’s usage reports if available.
SaaS product lacks admin console accessLicence purchased by department without IT involvementContact vendor to claim admin rights using organisational domain ownership. Escalate to procurement to consolidate under organisational agreement.
Cost per licence varies across purchasesVolume discounts, promotional pricing, or currency fluctuationUse weighted average cost for optimisation calculations. Note price variance in renewal recommendations.
Inactive users cannot be removedUsers on extended leave, or system accountsVerify user status with HR before removal. Exclude system accounts from utilisation calculations. Create separate category for suspended-but-retained licences.

Vendor audit timing

Avoid reducing licence quantities immediately before contract renewal. Vendors interpret sudden reductions as audit risk and may initiate compliance verification. Implement reductions at renewal when entitlement changes are expected.

Automation

Automate recurring data collection to reduce manual effort for quarterly reviews:

Terminal window
# Scheduled task for Microsoft 365 licence reporting
# Run weekly, output to shared location for review consolidation
$reportPath = "\\fileserver\licence-reports\m365"
$reportDate = Get-Date -Format "yyyy-MM-dd"
Connect-MgGraph -Scopes "User.Read.All", "Directory.Read.All"
$licenceReport = Get-MgSubscribedSku | ForEach-Object {
[PSCustomObject]@{
ProductName = $_.SkuPartNumber
TotalLicences = $_.PrepaidUnits.Enabled
AssignedLicences = $_.ConsumedUnits
AvailableLicences = $_.PrepaidUnits.Enabled - $_.ConsumedUnits
UtilisationPercent = [math]::Round(($_.ConsumedUnits / $_.PrepaidUnits.Enabled) * 100, 1)
ReportDate = $reportDate
}
}
$licenceReport | Export-Csv -Path "$reportPath\m365-licences-$reportDate.csv" -NoTypeInformation
# Alert if any product exceeds 95% utilisation
$highUtilisation = $licenceReport | Where-Object { $_.UtilisationPercent -gt 95 }
if ($highUtilisation) {
Send-MailMessage -To "it-procurement@example.org" `
-From "licence-monitor@example.org" `
-Subject "High Licence Utilisation Alert" `
-Body ($highUtilisation | ConvertTo-Html | Out-String) `
-SmtpServer "smtp.example.org"
}

For organisations with software asset management platforms, configure automated compliance dashboards:

# Example SAM platform compliance alert configuration
compliance_alerts:
- name: "Over-allocation Warning"
condition: "utilisation_percent > 100"
severity: "high"
notify:
- "it-procurement@example.org"
- "it-manager@example.org"
- name: "Under-utilisation Review"
condition: "utilisation_percent < 70 AND annual_cost > 10000"
severity: "medium"
notify:
- "it-procurement@example.org"
- name: "Maintenance Expiry"
condition: "maintenance_expiry < today + 90"
severity: "medium"
notify:
- "it-procurement@example.org"

See also