Use CM Console scripts node to gather log files from CM Clients

To assist in answering a question in this forum post:

I'm blogging on behalf of Srikant Yadav; he gave me permission to do so.  Thanks Srikant! 

How to make this work..

Step 1:
Make a location on a server you manage/control--which has lots of space.

create a folder called (for example):

Share that out as ClientLogs$
At a minimum, you need these permissions (if you have multiple domains, or support non-domain joined computers, you'll have to figure out what other permissions might be necessary).

 For share permissions, because who will be 'copying' the logs to that share is a computer, add the group:
  <your domain where your computers live>\Domain Computers, with Change, Read.
 On that folder of E:\ClientLogs, for NTFS permissions, add Modify, Read & Execute, List folder contents, read, Write (aka, everything but full control) to
  <that same group you just did for share permissions, aka, \Domain Computers

Step 2:
In the --> attached <-- is a script.  Modify the parameter within that script which is currently...
$Destination = "\\<DummyShare>\ClientLogs$"

To be  \\YourServer\ClientLogs$

Save that modified script as <some location you'll remember>\ImportThisIntoCM.ps1

Step 3:
In your CM Console, go to software library, scripts, create script
ScriptName = Retrieve Client Logs
Script Language = Powershell
Import... and go to <some location you just said you'd never forget> and import that ImportThisIntoCM.ps1 script.
Review the Script Parameters.  You can, if you wish, modify the defaults of the parameters here.  For example, maybe you ALWAYS want to get any ccmsetuplogs, or you know you only want log files that will be within the last 5 days and nothing older.
double-check the Destination is the right servername and sharename
Next, Next, Close.

Step 4:
Approve the script in the Scripts Node.  You may need a peer to do the approval.  In smaller environments, if you are the only admin, you can self approve scripts in the Scripts node if you've configured that in Site Configuration, Site, Hierarchy Settings, uncheck "do not allow script authors to approve their own scripts".  This is a safety feature, that you SHOULD leave checked--because scripts can be powerful.  Some disgruntled admin COULD make a "format c:" type of script, self approve it, and send it as they walk out the door.  Just saying... you might not want to do this.  peer review of scripts is GOOD.

Step 5:
Use it!
As an example, in Assets and Compliance, Devices, pick on a Online device (obviously this only works if the target is online/available), right-click, Run Script.  Pick "Retrieve Client Logs".  At this point, you can change parameters as needed.  Next/next.  You'll see a progress bar. 

When it's done, in the \\yourserver\ClientLogs$ will be Subfolders; CMClientLogs$ for cmclientlogs, WindowsUpdateLogs$ for WindowsUpdateLogs, etc.  Inside those subfolders will be the zipped-up log files, named for the device name targeted.

Step 6:
Have a Cleanup Routine.  The \\YourServer\ClientLogs$ doesn't have any automatic cleanup routine around it.  If say... you were to gather log files all the time, wherever that location exists might fill up the drive.  You want to remember to clear that out either manually occasionally, or setup some kind of maintenance routine on that server to "delete xx when older than yy days" or something.

Possible updates...If you read through the script, you'll see that you can make this extensible yourself.  Perhaps you have a <App Specific to our type of business> which has log files that are always stored in c:\programdata\Widgets\Logs.  You can easily add a new section to the script, with another parameter to grab those log files as needed, if needed.

CMCB, PowerShell

  • Created on .

Politely Schedule restarts of CCMExec Service

Over the years of troubleshooting the SCCM Client, even with the built-in CCMEval task to attempt to watch and remediate client health of the SCCM Client, experience has shown to those of us in the trenches that sometimes, despite everything else, simply restarting the SMS Agent Host (aka, ccmexec service) will clear previously inexplicable issues.  A service restart is often less disruptive to the end user than saying "have you tried a reboot yet".

If that scenario is something you've encountered in your environment, or you just want to be proactive (like some other companies) one way to accomplish an 'SMS Agent Host' restart is to ask the ccmeval task to do that for you.  Kent Agerlund very kindly shared with me the edits they've done for their customers; and by doing so on their customers it was determined that overall, issues were reduced with the sccm client.

I've taken his edits, and created a couple of Configuration Items.  It's the ccmeval.xml which indicates what tests should be run by the ccmeval scheduled task.  Two tasks are added to ccmeval.xml:
- Restart CCMExec.exe-Stop
- Restart CCMExec.exe-Start

There are two --> attached <-- Configuration items.  One is to modify the ccmeval.xml to add the stop/start actions.  The other is to return the ccmeval.xml back to the original values (as of version Current Branch 1806 clients, but the ccmeval.xml hasn't changed in years, so it is anticipated it won't change in future version... but nothing is certain). 

What you would do to test:

  • Create a Baseline, let's call it "CCMEval Add Action to Restart CCMEXEC".  Add ONLY the 1 Configuration Item, 'ccmeval.xml Add Service Restart', make it optional (not required).
  • Deploy that baseline to a collection of TEST computers; to run daily, make sure you check the box for Remediation (not just monitor).
  • On the client
    • after the baseline of "CCMEval Add Action to Restart CCMEXEC" has run, go look at ccmeval.xml (it's usually in %windir%\ccm folder); and you should see the new actions have been added.
    • if you are patient--wait overnight.  The next day check in %windir%\ccm, for ccmevalreport.xml  Open up that file and look for the actions of "Restart CCMExec.exe-Stop." and "Restart CCMExec.exe-Start."  and they should have resultcodes of 0 (success).  You might also want to take note of the time that ccmevalreport.xml was created.  and then go look at %windir%\ccm\logs, for example, ccmexec.log or clientidmanagerstartup.log for entries around that time--you should notice that the logs indicated a service restart.
    • if you are NOT patient... from cmd-prompt-as-admin, you can run ccmeval.exe from %windir%\ccm, and then look at the files and results as indicated above.


  • Remove the Deployment of the baseline "CCMEval Add Action to Restart CCMEXEC" to your test collection.
  • Create a Baseline called... "CCMEval Return to original", and add just and only 'ccmeval.xml Return to Original', make it optional (not required).
  • Deploy the baseline to your collection of Test Computers, to run daily, make sure you check the box for Remediation (not just monitor)
  • Confirm the ccmeval.xml gets set back to no longer have to 2 additional tasks
  • Manually run ccmeval.exe after the xml is changed back, and/or wait overnight, to confirm that ccmeval runs, and no longer restarts the ccmexec service.
  • Remove the Deployment of the Baseline "CCMEval Return to Original" (hopefully you'll never need this again... but...)
  • Once you've satisfied yourself that you can not only modify the ccmeval.xml, but also return it to a pre-changed condition, then you will be confident (hopefully) to move forward.

Your next step (if you choose to go forward) is to deploy the "CCMEval Add Action to Restart CCMEXEC" to a collection of targets.

One thought...I personally would not deploy the xml change to any Server OS, and definitely not any of my SCCM Servers--because the Management Point processes use ccmexec.  Restarting ccmexec on a Management Point role server might be fine... only you can say what makes sense in your infrastructure.  If you restart SMS Agent Host on your Management Point Role servers outside of a reboot, what does that impact for you?  anything?  if no impacts, then sure.  But YOU need to test, test, test. 

You may be asking yourself why this blog article was titled 'politely' ... that's because the ccmeval scheduled task is designed to only run when the client isn't doing other important things, and the system is quiet.  By design ccmeval tries to be quiet and discreet about when it runs, and randomized.

CMCB, ConfigMgr

  • Created on .

Visual Studio 2017 Editions using ConfigMgr Configuration item

This is a companion to It *might* be a replacement for the previous mof edit; but I haven't tested this enough to make that conclusion--test yourself to see.

Issue to be resolved:  there are licensing groups at my company who are tasked with ensuring licensing compliance.  There is a significant difference between Visual Studio costs for Standard, Professional, and Enterprise.  Prior to Visual Studio 2017, that information was able to be obtained via registry keys, and a configuration.mof + import (see link above) was sufficient to obtain that information.

According to (looks like published date is June, 2017), that information is no longer in the registry.  There is a uservoice published --> <--, requesting that the devs for visual studio put that back--but there's no acknowledgement that it would ever happen.

So that means that us lonely SCCM Administrators, tasked with "somehow" getting the edition information to the licensing teams at our companies have to--yet again--find a way to "make it happen", using the tools provided.  So here's "one possible way". 

This has only been tested on ONE device in a lab... so it's probably not perfect.  Supposedly, using the -legacy switch it'll also detect "old versions" installed--but I have no idea if that works or not.  Might not.

Here's how I plan on deploying this...

1)  configuration Item, Application Type.
    a) 'Detection Method", use a powershell script... this may not be universal, but currently in my lab, this location of 'vswhere.exe' is consistently in the same place.  Here's hoping it'll not change.  So the detection logic for the CI to bother to run at all would be "do you have vswhere.exe where I think it should be":

 $ErrorActionPreference = 'SilentlyContinue'
 $location = ${env:ProgramFiles(x86)}+'\Microsoft Visual Studio\Installer\vswhere.exe'
 if ([System.IO.File]::Exists($location)) {
  write-host $location

    b) Setting, Discovery Script, see the --> attached <-- .ps1 file.  Compliance Rule would be just existential, any result at all.
2)  Deploy that CI in a Baseline, as 'optional'; whether or not I just send it to every box everywhere, or create a collection of machines with Visual Studio 2017 in installed software--either way should work.
3)  Once Deployed and a box with Visual Studio 2017 has run it, confirm that a sample box DOES create a root\cimv2, cm_vswhere class, and there is data inside.
4)  Enable inventory
    a) In my SCCM Console, Administration, Client Settings, right-click Default Client Settings, properties
    b) Hardware Inventory, Set Classes...
    c) Add...
    d) Connect... to "the computer you checked in step 3 above; where you confirmed there is data locally on that box in root \cimv2, cm_vswhere"  and root\cimv2
    e) find the class "cm_vswhere"  check the box, OK. OK. OK.
5) monitor
    a) on your primary site, <installed location for SCCM>\Logs, dataldr.log 
    b) It'll chat about pending adds in the log.  Once that's done, you'll see a note about how it made some views for you.  "Creating view for..."
6) Wait a day, and then look if there is any information in a view probably called something like... v_gs_cm_vswhere.  But your view might have a different name--you'll just have to look.
    a) if you're impatient, back on that box from step 3 above, do some policy refreshes.  then a hardware inventory.
5) End result, you should get information in the field "displayName0", like "Visual Studio Professional 2017", and you'll be able to make custom reports using that information.  Which should hopefully satisfy your licensing folks.

To reiterate... tested on ONE box in a lab.  Your mileage my vary.  Additional tweaks or customizations may be needed to the script.  That's why in the script I tried to add a bunch of 'write-verbose'.  If you need to figure out why something isn't working right, change the VerbosePreference to Continue, not SilentlyContinue, and run it interactively on a machine--to hopefully figure out and address any un-anticipated flaws.

SCCM, ConfigMgr

  • Created on .

Configuration Manager Current Branch FastChannel Information via SQL Query

A lot of people use the console--but I don't go in there that much.  I'm more of a query SQL kind of person.  Some of the updates lately for Current Branch have been leveraging the "FastChannel" for communications.  If you don't remember, originally the FastChannel was meant for quick-hit communications, primarily around Endpoint protection.  However, over the last several updates, the product team has been adding more communications over the fast channel.  Most of those communications are to make the console experience feel more "real time"--and I get that.  For people who live in the console.  but I don't... so where is that information and how can I use it... using SQL?

Here's a couple things to have in your SQL query backpocket.

If you are Current Branch 1710 or higher, the 1710 clients will communicate back about if they have 1 or more of 4 specific "reboot pending" reasons.  You can see that in console--but as a SQL report, here's a summary query to show you counts of devices and what reboot pending state (and why) they are in:

select cdr.ClientState [Pending Reboot],
Case when (1 & cdr.ClientState) = 1 then 1 else 0 end as [Reason: ConfigMgr],
Case when (2 & cdr.ClientState) = 2 then 1 else 0 end as [Reason: Pending File Rename],
Case when (4 & cdr.ClientState) = 4 then 1 else 0 end as [Reason: Windows Update],
Case when (8 & cdr.ClientState) = 8 then 1 else 0 end as [Reason: Windows Feature],
Count(*) [Count]
from vSMS_CombinedDeviceResources cdr
where CAST(right(left(cdr.ClientVersion,9),4) as INT) >= 8577 and cdr.clientversion > '1'
Group by cdr.ClientState
order by cdr.clientstate

It'll only tell you about clients which are version 8577 or higher (aka, 1710).  If you are absolutely certain all your clients are 1710 or higher, you can remove that section of the "where" clause.
asking for clientversion > 1 is because you "might" have mobile clients reporting to your CM.  You really only want to know about Windows-based clients.  Essentially, those where clauses are so that you can be a little more accurate about pending reboots.  If you have a lot of clients less than version 1710, they can't communicate their clientState via the FastChannel, so you might think "great, these devices don't have a pending reboot"--when what it really means is "these clients aren't able to tell me if they need a pending reboot, because their client version is not capable of telling me that, via this method".

Another piece of information that can come in via the Fast Channel, if you are using Current Branch 1806 or higher, 1806 clients can tell you about a CURRENTLY logged in user.  This differs from what we as SMS/ConfigMgr admins are used to in the past.  We have for years been able to tell "last logged on user" or "most likely primary user"--based on heartbeat, hardware inventory, or asset intelligence data.  But that could be "old news"--depending upon how frequent your heartbeat or inventory runs, it could be hours to days old information.  Current logged on user should be at worst a few minutes old (depending of course upon your size, and complexity)

select s1.netbios_name0 [ComputerName], cdr.CurrentLogonUser [Current Logged on User According to FastChannel]
from vSMS_CombinedDeviceResources cdr
join v_r_system s1 on s1.resourceid=cdr.machineid
oder by s1.netbios_name0


  • Created on .

Configuration Manager Collection Cleanup Suggestions

Certainly in your CurrentBranch Console, under "Management Insights", there are some things there regarding collection cleanup; but here's a few other ways to look at your data.

Over the years, Collection plaque and tartar just grows and grows... and over time, people forget what collections were made for, or why they have them.  As a way to help the people who use our console narrow it down a bit to 'possible' stale, old collections which no longer have any purpose, below is a potential starting point.

What the below would list is collectionids and names, which are:
- NOT Currently used for any other collection as a "limited to", "Include", or "Exclude"
- NOT Currently used for any Deployment, whether it's a baseline, an application, an advertisement, or a task sequence
- NOT Currently used to define a Service Window (aka Maintenance Window)
- NOT Currently used for any custom client agent settings you might have configured.
- NOT currently used for any collection variables you might have for OSD
- NOT currently used for Automatic Client Upgrade, as an excluded collection
- NOT a default/out of the box collection (aka, ones that start with SMS)

This isn't of course a definitive list.  For example, perhaps a collection was created to deploy "Really Important Application" 2 weeks ago... but the actual deployment hasn't happened yet--it's destined to begin next week.  In that case of course the collection might show up on this list--but it shouldn't be deleted--it has a future use.  But hopefully if your environment has a lot of collections and determining which ones might be safe to remove, this is a potential starting point.

Select c.collectionid, [CollectionName]
from v_collection c
    c.collectionid not in (Select SourceCollectionID from vSMS_CollectionDependencies) -- include, excludes, or limited to
and c.collectionid not in (Select collectionid from v_deploymentsummary) -- any deployment, apps, advert, baseline, ts
and c.collectionid not in (Select Collectionid from v_ServiceWindow)
and c.collectionid not in (select collectionid from vClientSettingsAssignments)
and c.collectionid not in (select siteid from vSMS_CollectionVariable) -- OSD Collection Variables
and c.collectionid not in (Select a.ExcludedCollectionID from autoClientUpgradeConfigs a) -- ACU exclusion collection
and c.collectionid not in (select collectionid from v_collection where collectionid like 'sms%') -- exclude default collections

Another potential sql query for you to look for "collections not needed" could be this one.  What this one would be is it would sort, by "last time members changed in this collection".  The potential argument goes like this... even *if* that collection is being used for an active deployment... if the members of that machine based (not userbased) collection hasn't changed in years; how important is it to keep that particular deployment going / available?

;with cte as (select t2.CollectionName, t2.SiteID [CollectionID]
 ,(Cast(t1.EvaluationLength as float)/1000) as [EvalTime (seconds)]
 ,t1.LastRefreshTime, t1.MemberChanges, t1.LastMemberChangeTime,sc.SiteCode,
  when c.refreshtype = 1 then 'Manual'
  when c.refreshtype = 2 then 'Scheduled'
  when c.refreshtype = 4 then 'Incremental'
  when c.refreshtype = 6 then 'Scheduled and Incremental'
 end as [TypeofRefresh]
from dbo.collections_L t1 with (nolock)
join collections_g as t2 with (nolock) on t2.collectionid=t1.collectionid
join v_sc_SiteDefinition sc on sc.SiteNumber=t1.SiteNumber
join v_collection c on c.collectionid=t2.siteID
Select cte.collectionID, cte.CollectionName, CTE.[EvalTime (seconds)]
,Right(Convert(CHAR(8),DateADD(SECOND,CTE.[EvalTime (seconds)],0),108),5) [EvalTime (Minutes:Seconds)]
,cte.lastrefreshtime, cte.memberchanges, cte.lastmemberchangetime, cte.typeofrefresh, cte.membercount
from cte
where cte.collectiontype=2
and cte.collectionid not like 'SMS%'
order by lastmemberchangetime


  • Created on .
Copyright © 2021 - The Twin Cities Systems Management User Group