ConfigMgr CCMRecentlyUsedApps blank or mtrmgr.log with StartPrepDriver - OpenService Failed with Error Issue
Issue: ConfigMgr Clients which should be reporting via hardware inventory "CCMRecentlyUsedApps" have nothing to report. An analysis of the client indicates there is nothing in WMI root\cimv2\sms\ccm_recentlyusedapps TO report, and mtrmgr.log on the client contains lines like "StartPrepDriver - OpenService Failed with Error". See --> KB3213242 <-- at Microsoft for more details. UPDATE to script on 2018-01-31
Remediation: What worked for us was to re-register the 'prepdrv.inf', and then restart SMS Agent Host (aka ccmexec)
Before you do anything suggested below--confirm this will fix the issue you are seeing. Login to a box or two with the issue, and from an elevated cmd prompt, run the "remediation" powershell script below. Watch mtrmgr.log; and manually check that root/cimv2/sms select * from ccm_recentlyusedapps gets information. Once you see info, do a hardware inventory, and confirm that box now reports information up to your database, as you expect it to. If manually remediating works, then you can look to completing the steps below to automate the fix across your environment.
What we did to remediate the 'StartPrepDriver - OpenService Failed with Error' using a Configuration Item and Baseline was this:
It is assumed that you are using a "custom client agent setting" for enabling CCM_RecentlyUsedApps, since you normally do NOT want to target "every client". Usually you don't want to target heavily used Application Servers, or Citrix Servers--since hundreds of userIDs can 'launch' applications, the results of CCMRUA on those types of machines often won't process (the MIF file will be bigger than 50mb) and isn't that useful anyway. So go check, in your Custom Client Agent Settings, which collection you are targeting to enable 'ccm recently used apps'. Once you know that, then continue.
1) first, determine with SQL query how big of an issue it might be; maybe it was only a couple of boxes; and you can address them manually. Depending upon the count returned, it'll be up to you if you want to pursue this as a Configuration Item, or manually address.
Declare @CollID as nvarchar(8) = (Select collectionid from v_collection c where c.name = 'The Collection Name You figured out has CCMRUA as a HINV rule')
select count(ws.resourceid) [Count]
from v_gs_Workstations_Status ws
where ws.LastHWScan is not null
and ws.resourceid not in (select resourceid from v_gs_ccm_recently_used_apps)
and ws.resourceid in (select resourceid from v_fullcollectionmembership_valid fcm where fcm.collectionid=@CollID)
2) Create the Collection Query, to target.
- Create a new Collection, using the "limit to collection" as the collection you use for targeting when CCM Recently Used Apps information should be reported via Hardware Inventory. (the one you figured out above)
- The collection query rule should have two conditions... where:
SMS_G_System_WORKSTATION_STATUS.LastHardwareScan is not null
and
SMS_R_SYSTEM.ResourceId not in (Select ResourceId from SMS_G_System_CCM_RECENTLY_USED_APPS)
3) If the count of the SQL query, and the count of the Collection query are the same (or close enough); then you can continue to creating the ConfigItem, and deploying the Baseline to remediate the issue.
4) Create the Configuration Item, where the Detection and Remediation Logic are at the end of this blog post. Both are Powershell scripts. for "what means compliant", it will be a String, equals "Compliant". Make sure you check the box about Remediate if non-compliant.
5) After you create the Configuration Item, create a Baseline, add the CI to the baseline, and deploy the baseline, with remediation, to the collection you created above. (you may want to do a pilot, to a subset of 2 or 3 specific boxes, just to be sure it will all work as you expect it to work)
UPDATE 2018-02-02: Discovered that machines were "re-breaking". So I ended up targeting 'every box' with the Remediation script--it'll only remediate if problem found. Note in my production remediation script, I comment out the ccmexec restart. CCMEval takes care of that overnight, so it's OK.
6) That's it... then it's just a waiting game. You are waiting for the Baseline to run, remediate the issue by doing the rundll routine, restart ccmexec. Once that is done, in a minute or two mtrmgr.log will start to begin recording information into the root\cimv2\ccm_recentlyusedapps WMI location. Once there is information there, then at the next hardware inventory, presuming this client is asked via hinv policy to report that information, it will have something to report. So how long it takes completely depends upon YOUR schedules, that you defined. How frequently the Baseline evaluates, and how frequently your clients do the scheduled HINV action.
PS: you might be tempted to "let me just add a line to the remediation script, to trigger a hinv right at the end". I wouldn't bother. It takes a few minutes for the client, after the ccmexec restart, to populate WMI. It'll all shake out quickly enough.
######### DETECTION Powershell Script for the CI #####################
<#
.SYNOPSIS
This Script is for Detection of a known condition for the inability of CM Client to initialize the StartPrepDriver
.DESCRIPTION
This script finds the CM mgrmgr.log file, and reads it for a known good, or known error, condition.
"what means good" = mtrmgr.log contains lines like this
PREP driver successfully initialized
or
Termination event received for process
"what means bad" = mtrmgr.log contains lines like this
StartPrepDriver - OpenService Failed with error
.NOTES
Steps are to
1) read the regkey for CM Client to find the correct log file location
2) Look for good or Bad entries in the file
3) Exit with 'Compliant' or 'Non-Compliant' depending upon the results
.VERSION
1.0 Sherry Kissinger 2017-03-30
1.1 Sherry Kissinger 2018-01-31 (added -Tail 10 for better accuracy)
#>
$ErrorActionPreference = 'SilentlyContinue'
#Get the LogDirectory for CM Client
$CMLogDir = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\CCM\Logging\@Global" -Name LogDirectory).LogDirectory
#Define the LogFile to Read
$CMLogFile = $CMLogDir + '\mtrmgr.log'
#Read the Log file for the Error Phrase
$GotErrors = (Get-Content -Path $CMLogFile -Tail 10 | where-object {$_ -like '*StartPrepDriver - OpenService Failed with error*'})
#Read the Log File for a known good condition phrases
$GotGoodEntry = (Get-Content -Path $CMLogFile -Tail 10 | where-object {($_ -like '*PREP driver successfully initialized*') -or ($_ -like '*Termination event received for process*')})
if ($GotGoodEntry) {
write-host 'Compliant'
}
else {
if ($GotErrors) {
write-host 'Non-Compliant'
}
}
############## REMEDIATION Powershell Script for the CI ##########################
<#
.SYNOPSIS
This Script is for Detection and Remediation of a known condition for the inability of CM Client to initialize the StartPrepDriver
.DESCRIPTION
This script finds the CM mgrmgr.log file, and reads it for a known good, or known error, condition.
"what means good" = mtrmgr.log contains lines like this
PREP driver successfully initialized
or
Termination event received for process
"what means bad" = mtrmgr.log contains lines like this
StartPrepDriver - OpenService Failed with error
.NOTES
Steps are to
1) read the regkey for CM Client to find the correct log file location
2) Look for good or Bad entries in the file
3) Exit with 'Compliant' or if 'Non-Compliant', to run the fix
3a) the fix is two steps
RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 C:\WINDOWS\CCM\prepdrv.inf
Restart-Service ccmexec
.VERSION
1.0 Sherry Kissinger 2017-03-30
1.1 Sherry Kissinger 2018-01-31 (added -Tail 10 for better accuracy)
#>
$ErrorActionPreference = 'SilentlyContinue'
#Get the LogDirectory for CM Client
$CMLogDir = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\CCM\Logging\@Global" -Name LogDirectory).LogDirectory
#Define the LogFile to Read
$CMLogFile = $CMLogDir + '\mtrmgr.log'
#Read the Log file for the Error Phrase
$GotErrors = (Get-Content -Path $CMLogFile -Tail 10 | where-object {$_ -like '*StartPrepDriver - OpenService Failed with error*'})
#Read the Log File for a known good condition phrases
$GotGoodEntry = (Get-Content -Path $CMLogFile -Tail 10 | where-object {($_ -like '*PREP driver successfully initialized*') -or ($_ -like '*Termination event received for process*')})
if ($GotGoodEntry) {
write-host 'Compliant'
}
else {
if ($GotErrors) {
Try { Set-ExecutionPolicy -ExecutionPolicy 'Bypass' -Scope 'Process' -Force -ErrorAction 'Stop'}
Catch {}
$CMClientDIR = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\SMS\Client\Configuration\Client Properties" -Name 'Local SMS Path').'Local SMS Path'
$ExePath = $env:windir + '\system32\RUNDLL32.EXE'
$CLine = ' SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 ' + $CMClientDIR + 'prepdrv.inf'
#Parse the Parameters
$Prms = $Cline.Split(" ")
#Execute the fix with parameters
& "$Exepath" $Prms
#Restart ccmexec service
#CCMExec should be restarted; If you'd rather wait for a natural client reboot, comment out this line.
#Note that this CI will continue to attempt to remediate until a ccmexec restart or reboot
restart-service ccmexec
}
}
- Created on .