Skip to content

SCCM RecentlyUsedApps: evidence of execution in WMI

Read CCM_RecentlyUsedApps from the WMI repository: which programs each user ran, when last and how often, including older copies carved from OBJECTS.DATA.

Published on 4 min read

TL;DR. On machines with the Configuration Manager (SCCM / ConfigMgr) client, the WMI repository holds CCM_RecentlyUsedApps: one record per executable and user, with the full path, the file's version information, the last user, LastUsedTime and a LaunchCount. It is evidence of execution that survives the deletion of the binary, it sits in the same OBJECTS.DATA you already collect for WMI persistence, and older copies of each record can be carved from freed space.

Where it comes from

The ConfigMgr client's software-metering component watches program starts and keeps a summary in WMI, in the namespace root\ccm\SoftwareMeteringAgent, class CCM_RecentlyUsedApps. Configuration Manager uses it for software usage reporting; for an investigator it is a per-user record of what ran. No ConfigMgr client, no data — so check first:

Get-Service CcmExec -ErrorAction SilentlyContinue
Get-CimInstance -Namespace root/ccm/SoftwareMeteringAgent -ClassName CCM_RecentlyUsedApps |
  Sort-Object LastUsedTime -Descending |
  Select-Object LastUsedTime, LastUserName, FolderPath, ExplorerFileName, LaunchCount, CompanyName

That query shows live records only, through WMI itself. For the investigation, collect the whole Repository folder: nothing extra is needed for SCCM, the class lives in the same files.

The fields that matter

PropertyWhat it tells you
FolderPath, ExplorerFileNameWhere the executable ran from, and its name on disk
LastUserNameThe account that launched it (one record per user)
LastUsedTimeThat user's most recent launch of that file
LaunchCountLaunches the client has counted
CompanyName, ProductName, FileDescription, FileVersion, ProductVersion, OriginalFileNameThe file's version information
FileSize, FilePropertiesHash, SoftwarePropertiesHashSize and the client's own hashes of the file and product properties
msiDisplayName, msiPublisher, msiVersion, ProductCodeThe installed MSI product the file belongs to, when there is one

OriginalFileName and the version fields come from the file itself: a renamed tool keeps its original name there, and a tool without any version information stands out next to signed vendor software.

Reading LastUsedTime correctly

LastUsedTime is a CIM DATETIME string: yyyymmddHHMMSS.mmmmmm, then a sign and three digits of offset from UTC in minutes. 20260914100914.000000+000 is 10:09:14 UTC. A value ending in +120 would be written two hours ahead of UTC, so its UTC time is two hours earlier. Convert with the offset that is in the value rather than assuming a zone, and keep the raw string in your notes.

Two limits to keep in mind:

  • It is the last launch by that user, not the first and not every one. The first launch is usually better placed by Prefetch or Amcache.
  • LaunchCount is cumulative since the client started tracking the file. A count of 1 is a single run; a count of 2 with a recent LastUsedTime means at least one earlier run.

Older copies in OBJECTS.DATA

Each update rewrites the record. As with deleted WMI subscriptions, the previous version is not wiped: it stays in an unmapped page or in page slack until WMI reuses the space. Carving for the record header (the hash of the class name) recovers those copies with their own LastUsedTime and LaunchCount. A freed copy with a count of 1 and an earlier time next to a live copy with a count of 2 dates the first run too.

The same approach was used by David Pany's CCM_RUA_Finder.py (WMI_Forensics); python-cim reads the live records through the index.

What to look for

  • User-writable folders: C:\Users\Public\, AppData, Downloads, C:\ProgramData\, C:\Windows\Temp\. Software installed by an administrator lives in Program Files or Windows.
  • No version information (empty CompanyName) for an executable outside the usual folders.
  • LaunchCount = 1 for a tool: staging, exfiltration or cleanup is often run once.
  • Rare entries: the only program seen in its folder, or seen on one machine of the fleet.
  • Timing: last launches in the incident window, or close to the creation of a WMI subscription on the same host.

None of these is proof on its own. Identify the file (hash from disk or backups, vendor, installer) before concluding.

A worked example

The sample repository in the tool (fictional host FIN-WKS-07) has m64.exe in C:\ProgramData\Intel\ launched by FIN\svc_backup at 10:09 UTC with a count of 2 and no version information, and rclone.exe in C:\Users\Public\ launched once at 10:47. A freed copy of the m64.exe record shows a first launch at 10:02 with a count of 1. In the WMI subscriptions of the same repository, a consumer whose record header time is 10:31 runs that same m64.exe a few minutes after every boot. Open the tool, load the sample and switch to Evidence of execution (SCCM) to follow it with the time range.

Related articles

Why deleted WMI filters, consumers and bindings survive in OBJECTS.DATA, how index walking and carving differ, and how python-cim and PyWMIPersistenceFinder compare.
How the WMI CIM repository stores objects: OBJECTS.DATA pages, INDEX.BTR keys, the three MAPPING files, class definitions, instances and name hashes.
Step-by-step checklist for WMI persistence: live queries, the repository, event IDs 5860 and 5861, Sysmon 19-21, execution evidence and a safe clean-up.