How to Check VMware License Expiration Dates with PowerCLI
Under Broadcom's subscription model, VMware license keys encode an expiration date that reflects the subscription term. The vSphere Client shows you a license list, but it buries expiration dates in property dialogs that you have to click into one at a time. If you're managing multiple vCenter servers and dozens of ESXi hosts, checking each license through the UI is tedious and easy to forget until renewal becomes urgent.
The PowerCLI approach queries the vSphere LicenseManager API directly and returns the expiration date for every license key known to vCenter. This works for evaluation licenses, subscription keys, and legacy perpetual keys with active Support and Subscription terms. The expiration date comes from the license key itself, not from your Broadcom contract, so there's a gap between what the API reports and what your actual entitlement covers. I'll address that gap at the end.
If you haven't set up PowerCLI yet, the VCF PowerCLI complete guide covers installation and the Broadcom module transition. The short version: Install-Module VCF.PowerCLI, then Import-Module VCF.PowerCLI.
What the LicenseManager API returns
Every vCenter server exposes a LicenseManager managed object through the vSphere API. Its Licenses property contains an array of LicenseManagerLicenseInfo objects, each representing one license key added to that vCenter. Each object has a Properties collection of key-value pairs. The property names vary by license type, but the ones that matter for expiration checking are:
expirationDate— the date the key expires, if applicableexpirationHours— hours remaining, primarily for evaluation licensesevaluation— boolean, true for the built-in 60-day evaluation license
Not all licenses populate expirationDate. Perpetual licenses with active SnS may or may not include it depending on when and how the key was generated. Subscription keys typically do. Evaluation keys always do. The Properties collection is where the data lives. There is no dedicated ExpirationDate property on the license object itself. You have to dig into the key-value array.
Querying vCenter for license expiration
Connect to vCenter first:
$vcenter = "vcenter.lab.local"
$credential = Get-Credential -Message "vCenter credentials"
Connect-VIServer -Server $vcenter -Credential $credential
Then query the LicenseManager through the ServiceInstance:
$si = Get-View ServiceInstance
$lm = Get-View $si.Content.LicenseManager
$licenses = $lm.Licenses | ForEach-Object {
$expProp = $_.Properties | Where-Object { $_.Key -eq "expirationDate" }
$isEval = ($_.Properties | Where-Object { $_.Key -eq "evaluation" }).Value -eq $true
$expirationDate = if ($expProp) { [DateTime]$expProp.Value } else { $null }
$daysRemaining = if ($expirationDate) { ($expirationDate - (Get-Date)).Days } else { $null }
[PSCustomObject]@{
Name = $_.Name
LicenseKey = $_.LicenseKey
Edition = $_.EditionKey
Total = $_.Total
Used = $_.Used
IsEvaluation = $isEval
ExpirationDate = if ($expirationDate) { $expirationDate.ToString("yyyy-MM-dd") } else { "No expiration encoded" }
DaysRemaining = if ($daysRemaining -ne $null) {
if ($daysRemaining -lt 0) { "EXPIRED ($([Math]::Abs($daysRemaining)) days ago)" }
else { $daysRemaining }
} else { "N/A" }
}
}
$licenses | Format-Table -AutoSize
This returns a table with the license name, key, edition, total and used counts, whether it's an evaluation license, the expiration date, and days remaining. Licenses that don't have expirationDate encoded show "No expiration encoded" rather than throwing an error.
The Total and Used columns matter for capacity-based licenses. Under the Broadcom per-core model, VVF and VCF licenses have capacity counts. A VVF key with Total: 192 and Used: 192 means all 192 cores of capacity are assigned. That's not an expiration issue, but if you're already querying the license manager, include capacity data in the report while you're there. The license compliance audit script covers the capacity side in detail, including the 72-core per-order minimum and how to reconcile deployed cores against your contract.
Filtering for expiring licenses
The full list is useful for a snapshot, but for alerting you want to filter to licenses expiring within a window:
$warningDays = 60
$today = Get-Date
$expiring = $licenses | Where-Object {
$_.DaysRemaining -is [int] -and $_.DaysRemaining -le $warningDays
} | Sort-Object DaysRemaining
if ($expiring) {
Write-Host "WARNING: $($expiring.Count) license(s) expiring within $warningDays days:" -ForegroundColor Yellow
$expiring | Format-Table Name, LicenseKey, Edition, ExpirationDate, DaysRemaining -AutoSize
} else {
Write-Host "No licenses expiring within $warningDays days." -ForegroundColor Green
}
I set the default warning window to 60 days because Broadcom's late renewal penalty kicks in after the contract expires, and renewal cycles involving procurement and legal review can eat three to four weeks. Sixty days gives enough runway to start the renewal process without hitting the penalty. The Broadcom licensing breakdown covers the 20% late renewal penalty and per-core pricing in detail.
Checking ESXi host licenses directly
If you have standalone ESXi hosts not managed by vCenter, or you want to verify the host's local license assignment independently, connect directly to the host:
Connect-VIServer -Server "esxi01.lab.local" -User root -Password "yourPassword"
# Or prompt securely: Connect-VIServer -Server "esxi01.lab.local" -Credential (Get-Credential)
$si = Get-View ServiceInstance
$lm = Get-View $si.Content.LicenseManager
# The host's evaluation status
$lm.Evaluation | Select-Object `
@{N="State";E={$_.State}},
@{N="ExpirationHours";E={$_.ExpirationHours}},
@{N="ExpirationDate";E={if ($_.ExpirationDate) { $_.ExpirationDate.ToString("yyyy-MM-dd") } else { "None" }}}
# The host's assigned licenses
$lm.Licenses | ForEach-Object {
$expProp = $_.Properties | Where-Object { $_.Key -eq "expirationDate" }
[PSCustomObject]@{
LicenseKey = $_.LicenseKey
Edition = $_.EditionKey
ExpirationDate = if ($expProp) { [DateTime]$expProp.Value } else { "No expiration" }
}
}
The $lm.Evaluation object is specific to ESXi and tells you whether the host is running in evaluation mode and how many hours remain. Property names can vary by ESXi version, so inspect $lm.Evaluation | Select-Object * first and use the properties present in your version. On a fresh ESXi install, the evaluation period is 60 days, reported as 1440 hours when unused.
For a standalone host past its evaluation period with no license applied, the state reads expired. The host keeps running existing VMs, but normal management operations such as powering on new VMs or changing many host and VM settings are restricted. If you're building out a home lab and running ESXi in evaluation mode, this script will tell you how much time you have left before those restrictions apply.
What happens when a license expires
The behavior depends on whether it's an evaluation license or a subscription lapse. These are fundamentally different mechanisms.
Evaluation expiration is the harsher case. When a 60-day ESXi evaluation expires, the host continues running existing VMs, but normal management operations such as powering on new VMs or changing many host and VM settings are restricted. vCenter Server evaluation works similarly: after expiration, vCenter enters a read-only state where you can view the inventory but cannot make changes. This is enforced by the product regardless of whether the host is connected to vCenter, and there is no grace period beyond the 60 days.
A subscription or contract lapse is not the same as ESXi evaluation expiration. In many cases the installed software continues to run, but you may lose entitlement to support, patches, downloads, and renewals, and vCenter may show the key as expired or out of compliance. Confirm enforcement behavior for your specific product and version with Broadcom documentation. The subscription versus perpetual analysis covers the contractual side of this.
There's a nuance worth stating plainly: if you apply a subscription license key that has an expirationDate encoded, and that date passes, the vCenter UI may flag the license as expired even though your contract is still active. This happens when the key's encoded date doesn't match your actual contract term. The fix is to reapply the current key from your Broadcom Customer Portal, which refreshes the encoded dates. I've seen this confuse administrators who assumed their infrastructure was about to shut down when the contract was fine.
Exporting and scheduling
Export to CSV for record-keeping:
$ts = Get-Date -Format "yyyyMMdd"
$reportPath = "C:\Logs\License_Expiration_$ts.csv"
$licenses | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8
Write-Host "Report saved: $reportPath"
For scheduled monitoring, run the script daily via Windows Task Scheduler and alert only when licenses fall inside the warning window. A Teams or Slack webhook replacing the Write-Host lines gives you ops integration without a dedicated monitoring platform. Microsoft's Teams webhook documentation covers the payload format; the Adaptive Card format takes about 15 lines of JSON to produce a readable alert.
# Scheduled task registration
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NonInteractive -File C:\Scripts\check-license-expiration.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "06:00AM"
Register-ScheduledTask -TaskName "License Expiration Check" `
-Action $action -Trigger $trigger -RunLevel Highest
The Read-Only role in vCenter is sufficient for this script in most environments. If the script returns no license data, verify the account has permission to view global license information. You don't need administrator privileges to query the LicenseManager, which means you can hand the scheduled task to a monitoring service account without elevated rights.
What this cannot tell you
The expirationDate property comes from the license key's encoded data, not from Broadcom's contract database. A subscription key might show an expiration date that's shorter or longer than your actual contract term, depending on how the key was generated and when it was applied to vCenter.
For authoritative expiration dates tied to your contract, log into the Broadcom Support Portal and check your entitlements under the License Management section. The script tells you what's encoded in the keys deployed in your environment. The portal tells you what your contract actually covers. You need both to get an accurate picture, and they won't always agree.
If you're running VCF with SDDC Manager, check the Administration menu's Licensing view there first. It consolidates vSphere, vSAN, and NSX license status in one dashboard and surfaces expiration warnings for all components. For environments without SDDC Manager, the script above is the fastest way to get expiration data across multiple vCenter servers. Run it in a loop against each vCenter and aggregate the CSVs into a single view.