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
| Requirement | Detail |
|---|---|
| Access | Read access to licence management system, software asset management tools, and procurement records |
| Permissions | Query access to identity provider for user counts, endpoint management for device counts |
| Data sources | Current licence inventory with entitlement quantities, usage telemetry from past 90 days minimum |
| Tools | Spreadsheet software or licence management platform, access to vendor portals for entitlement verification |
| Information | Contract documents for complex licensing agreements, vendor contact details for clarification |
| Time | 4-8 hours for initial review of 20-50 products; 2-4 hours for quarterly refresh |
Verify access to the licence inventory before starting:
# If using a software asset management tool, verify data freshness# Example using ServiceNow SAMcurl -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 datecurl -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 daysFor organisations without dedicated SAM tools, export licence data from procurement systems and endpoint management:
# Export installed software from Microsoft IntuneConnect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"Get-MgDeviceManagementManagedDevice | Select-Object DeviceName, OperatingSystem | Export-Csv -Path "managed-devices.csv" -NoTypeInformation
# Get detected applicationsGet-MgDeviceManagementDetectedApp | Select-Object DisplayName, DeviceCount, Platform | Export-Csv -Path "detected-apps.csv" -NoTypeInformationProcedure
- 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,1500Verify 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.
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:
# 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 ownedConcurrent 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:
# 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.
- 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:
| Product | Owned | In Use | Ratio | Status |
|---|---|---|---|---|
| Microsoft 365 E3 | 450 | 423 | 94% | Optimal |
| Adobe Creative Cloud | 35 | 41 | 117% | Gap: 6 licences |
| Zoom Business | 100 | 67 | 67% | Over-licensed |
| AutoCAD | 12 | 12 | 100% | Optimal |
| Salesforce Enterprise | 85 | 78 | 92% | 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.
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
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:
- Purchase 6 additional licences (£3,240)
- Remove licences from inactive users (requires usage analysis)
- 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.
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.
Generate recommendations for the next procurement cycle. The compliance review produces input for licence renewal decisions:
Renewal Planning Recommendations
Product Current Recommended Change Annual Impact Microsoft 365 E3 450 450 None £0 Adobe Creative Cloud 35 41 +6 +£3,240 Zoom Business 100 75 -25 -£3,750 AutoCAD 12 15 +3 +£5,400 Salesforce Enterprise 85 85 None £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.
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:
# Generate compliance summarycat 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 unreviewedGap 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:
# Check audit defence file freshnessfind /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 vendorRenewal recommendation delivery:
Confirm procurement has received renewal recommendations for products expiring within 90 days. Obtain acknowledgement from procurement lead.
Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
| Usage data unavailable for a product | Product lacks telemetry or licence server | Deploy 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 records | Contract amendment not reflected in internal records, or promotional licences expired | Download 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 software | Licences assigned but software uninstalled, or test/service accounts holding licences | Query endpoint management to verify software installation. Identify and remove assignments for accounts without installed software. |
| Cannot identify licence holders for legacy software | Licence assignments predate current identity system | Cross-reference procurement records with HR data. Contact original requestors if identifiable. For unattributable licences, flag for removal at renewal. |
| Vendor audit notice received during review | Audit triggered by renewal negotiation or random selection | Pause optimisation actions that reduce licence counts. Accelerate audit defence file completion. Engage legal and procurement before responding to vendor. |
| Over-licensing identified but cannot reduce | Multi-year contract with fixed quantities | Document 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 values | Metering system malfunction or double-counting | Verify 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 access | Licence purchased by department without IT involvement | Contact vendor to claim admin rights using organisational domain ownership. Escalate to procurement to consolidate under organisational agreement. |
| Cost per licence varies across purchases | Volume discounts, promotional pricing, or currency fluctuation | Use weighted average cost for optimisation calculations. Note price variance in renewal recommendations. |
| Inactive users cannot be removed | Users on extended leave, or system accounts | Verify 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:
# 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 configurationcompliance_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
- Software Asset Management -inventory management concepts and SAM tool selection
- Vendor and Licensing Management -contract management and vendor relationship procedures
- SaaS Management -cloud subscription management and shadow IT discovery
- IT Budgeting -incorporating licence costs into budget planning