This post shows how to list the CPU cores of your Azure Arc connected machines in a table.
The Azure Arc agent is a small agent that you can install on your on-premises servers to connect them to Azure. This allows you to manage your on-premises servers with Azure services like Azure Policy, Azure Monitor, Azure Security Center, Azure Automation, Azure Update Management, and more.
Recently there is a big push to Azure Arc because of the end of life of Windows Server 2012/R2.
This is especially interesting for customers that have a lot of servers that are not virtualized and cannot be migrated to Azure - and they need to be supported for months/years because of whatever reasons.
Typically customers then bought Extended Support Updatate (ESU) license. Since September this is now possible through Azure and gives you the flexiblity to only pay for the servers that you need to support.
You do not need ESU if you:
- Migrate to Azure - ESU is free
- Upgrade to a newer version of Windows Server - ESU is not longer needed.
- Decommission the server.
With Azure Arc through ESU you can adjust the license count and benefit from pay as you go terms.
But how many ESU licenses do you need?
Azure Arc does collect the number of CPU cores of your connected machines - but it is not visibly exposed in the Azure Portal (yet?).
You need to click on the connected Machine on the JSON View to see the individual CPU cores:
And then you need to count the cores manually.
Of course, there is a better way. Azure Resource Graph to the rescue!
Use the following link: Azure Resource Graph Explorer
The following query does list the CPU cores of all connected machines in a table:
resources | where type =~ 'microsoft.hybridcompute/machines' and kind !contains "AVS" | extend machineId = tolower(tostring(id)) | extend datacenter = iif(isnull(tags.Datacenter), '', tags.Datacenter) | extend state = properties.status | extend status = case( state =~ 'Connected', 'Connected', state =~ 'Disconnected', 'Offline', state =~ 'Error', 'Error', state =~ 'Expired', 'Expired', '') | extend osSku = properties.osSku | extend os = properties.osName | extend osName = case( os =~ 'windows', 'Windows', os =~ 'linux', 'Linux', '') | extend operatingSystem = iif(isnotnull(osSku), osSku, osName) | join kind=leftouter ( resources | where type =~ "microsoft.hybridcompute/machines/extensions" | extend machineId = tolower(tostring(trim_end(@"\/\w+\/(\w|\.)+", id))) | extend provisioned = tolower(tostring(properties.provisioningState)) == "succeeded" | summarize MDEcnt = countif(properties.type in ("MDE.Linux", "MDE.Windows") and provisioned), AMAcnt = countif(properties.type in ("AzureMonitorWindowsAgent", "AzureMonitorLinuxAgent") and provisioned), WACcnt = countif(properties.type in ("AdminCenter") and provisioned), UMcnt = countif(properties.type in ("WindowsOsUpdateExtension","LinuxOsUpdateExtension", "WindowsPatchExtension") and provisioned) by machineId ) on machineId | extend defenderStatus = iff ((MDEcnt>0), 'Enabled', 'Not enabled') | extend monitoringAgent = iff ((AMAcnt>0), 'Installed','Not installed') | extend wacStatus = iff ((WACcnt>0), 'Enabled', 'Not enabled') | extend updateManagement = iff ((UMcnt>0), 'Enabled', 'Not enabled') | extend hostName = tostring(properties.displayName) | extend manufacturer = properties.detectedProperties.manufacturer | extend name = iif(properties.cloudMetadata.provider == 'AWS' and name != hostName, strcat(name, "(", hostName, ")"), name) | extend isSqlServer = properties.detectedProperties.mssqldiscovered | extend logicalCoreCount = properties.detectedProperties.logicalCoreCount | extend processorCount = properties.detectedProperties.processorCount | extend coreCount = properties.detectedProperties.coreCount | project name, status, manufacturer, processorCount, logicalCoreCount, coreCount, isSqlServer, resourceGroup, subscriptionId, datacenter, operatingSystem, id, type, location, kind, tags, machineId, defenderStatus, monitoringAgent, wacStatus, updateManagement, hostName | project name,manufacturer, processorCount, logicalCoreCount, coreCount, isSqlServer,status,resourceGroup,subscriptionDisplayName,operatingSystem,defenderStatus,monitoringAgent,id,type,location,subscriptionId,tags | sort by (tolower(tostring(name))) asc
This is how it looks like:
You can then export the table to Excel and do the math.
If you only want to see the detected SQL Server, then you can add
| where isSqlServer == true
Hope it helps,