ConfigMgr Inventory: Per User Mapped Drive Information (datashift replacement)

Back when Windows 98 and Windows XP were the norm, there was a script available called "datashift", which would grab information from users regarding their mapped drives.  It worked because everyone was a local admin--that's no longer the case.

This is a replacement for that older utility.  If you still have a need for the per-user information regarding per-user network connections to shares, here is a way to obtain that information.

The basics of how it works is this.  There are two vbscripts that run.  One runs as SYSTEM, and it's only purpose is to create a custom namespace in WMI (if it doesn't already exist), and grant permissions to all of your domain users to that custom namespace--so they can populate it with the results of script #2.  Script #2 runs, only when a user is logged in, with user rights.  That's because the script needs to read information about that specific logged-in users network drive connection information.

The results of the 2nd script end up in that custom WMI namespace, and will have the following information:

DateScriptRan = the exact date and time that the script ran to gather this user-specific information.
Drive = the drive letter mapped (if a drive letter was used, if no drive letter was used for the connection, this is blank)
Location = the share location UserDomain = whomever is logged in when the script ran, what their domain is.
UserName = whomever is logged in when the script ran, what their username is.

End result:  After deploying these two scripts, you will be able to answer the question from your server team of "who is actually mapping to these shares".  Of course, the main limitation is this is per-user information. 

Ok, enough of how it works.  You really want to know *exactly* what to do, right?  Let's start!  

Your Source folder for the package will contain 3 things:

  • WMINameSpaceAndSecurity.VBS
  • WMISecurity.exe
  • Mappeddrives.vbs

The .vbs files are at this link --> Mappeddrives <--.  Note that WMISecurity.exe is not attached here; just search using your favorite search engine to find and download wmisecurity.exe.  The one I used was version --maybe there are later versions of this .exe; but that's the one I found, and it worked.

You will need to make 1 change to "WMINameSpaceAndSecurity.vbs", this line: strDomain = "YOURDOMAINHERE" Modify that to be your domain (the domain your users are in that will be logging in and running script #2).

Create two programs; the first runs cscript.exe WMINameSpaceAndSecurity.vbs, whether or not a user is logged in, with Administrator rights.  The second runs cscript.exe MappedDrives.vbs, only when a user is logged in, with user rights.  The 2nd one; you want to "run another program first", and have it run the first one.  It only needs to run the 1st program once, per computer; it doesn't need to re-run.

Advertise the 2nd program to a collection (I recommend a test/pilot first), and confirm that it works as you expect.  If you

want to confirm the data is there, look in root\CustomCMClasses  (not root\cimv2) for cm_MappedDrives, that there are instances there for mapped drives for that user.

If you are satisfied it's there locally, either add the below to sms_def.mof (if you are ConfigMgr07) or import it into Default Client Agent Settings, Hardware Inventory (if you are CM12)


class cm_MappedDrives : SMS_Class_Template
  [SMS_Report(TRUE)] string DateScriptRan;
  [SMS_Report(TRUE),key] string Drive;
  [SMS_Report(TRUE),key] string Location;
  [SMS_Report(TRUE)] string UserDomain;
  [SMS_Report(TRUE)] string UserName;

sit back, relax for a bit... then invoke a hardware inventory on your test boxes, and see if the data shows up in your database in v_gs_MappedDrives0.  If so, deploy the advert to your real target collection of users or computers, and wait for the data to show up.  Depending upon your need for this information; you may or may not want to have the advert run on a recurring basis (weekly? monthly?) or just gather it for a week or so (just enough to answer the question) then delete the advert and change the Inventory from TRUE to FALSE (until the next time they ask).

Here's a potential sql report to get you started:

select sys.netbios_Name0 as [Computer Name],
MD.UserDomain0 as [User Domain],
MD.UserName0 as [User Name],
MD.Drive0 as [Mapped Drive Letter],
MD.Location0 as [Mapped to Location],
md.DateScriptRan0 as [Date Collected]
from v_R_System sys
Inner Join v_GS_MappedDrives0 MD on sys.ResourceID = MD.ResourceID
order by sys.netbios_Name0


Caveat: as of 3/27/2014, the above routine has only been tested in a lab environment.  If people comment or somehow else let me know how well it works for them (or not), I'll update this blog with that information.  But right now... this isn't tested thoroughly at all.  I think it'll work just fine; but only you can confirm that.

  • Created on .

Compliance Setting to Enable WinRM-Updated

This is an update to a previous blog post.  One of the Compliance Settings has modified content. The changes are

  1. Inside the "WinRM Config for v2 or v3", there used to be 4 settings to check if the listener is defined.  I found in my environment; about 3% of machines were "failing" on those 4 settings because they had multiple listeners defined, and those settings didn't take that possibility into account.  This update replaces those 4 settings with 1 scripted test.  if any listener is defined and has the 4 settings we want, then it's compliant.
  2. Inside the "WinRM Config for v2 and v3", for our environment we needed to define TrustedHosts.  It's possible you may not need this setting at all. For this blog posting I've used the common setting of "*"; however, you may need to be more restrictive in your settings.  Or you may want to remove that setting from the ConfigItem completely.  If you have a GPO which configures that, obviously set it to match.

The rest of this is a repeat of the earlier blog posting, just so you don't have to go look up the older post.


The Situation:  ConfigMgr 2012 clients can be managed remotely (and troubleshooting remotely) quite handily... if only Powershell were installed and Remote Management via Powershell (WinRM) were enabled.

This article presumes you are deploying Powershell via other means, and this routine is just 1 of several ways to get WinRM enabled, if Powershell is installed.  Note you don't have to use this at all; by far the most popular method is to simply have a GPO, or if you must, interactively login to a computer and run   winrm quickconfig -q  from a command prompt (if you have the rights).

This situation may or may not be an edge case for you... but in our environment there are a few workstations, which are ConfigMgr Clients, but which for whatever reason are not candidates for the GPO, and to have a human interactively connect to each of those machines and run the winrm config (with our settings) is cumbersome. 

The baseline attached is just a SAMPLE of a Configuration Item; using the settings as created if you were to run winrm quickconfig; however you or your security team may have determined not to use those defaults--you may need to modify the port used, change the ipv4 or ipv6 listening ports, or modify the TrustedHosts setting.  So take the attached as-is ONLY if you know you are using the defaults, and they are acceptable in your environment.  If you've modified how WinRM is configured in your company, you will definitely need to either modify the ConfigItem detection and remediation, or not use this at all.

How to use:

  1. Extract the .cab from --> Here <--  and import that baseline into your Compliance Settings, Baselines; note if you've previously imported the older baseline from me (December, 2013), it MAY overwrite your existing if you don't select the "make a copy" choice.  Be careful what you do when importing!
  2. PARANOIA: Deploy the Baseline to a collection withOUT checking the box about remediation.  
    1. Monitor, and for the machines which say "non-compliant", check that you really cannot remotely connect to them with Powershell Remote Management.  
    2. To a collection of those non-compliants, Deploy the baseline again, but DO check the remediation box.  
    3. Confirm that the remediation Baseline runs, and that you now can remotely connect to them with Powershell remote management.
  3. Repeat the Paranoia steps as many times as you need to until you are comfortable that it's doing what you think it should be doing.
  4. Once you've passed your own internal Paranoia Steps (above), you can remove the test deployments, and deploy it again to your 'main' collection, with the remediation checkbox checked.

Again, to repeat... this is just a sample.  and this sample will only be logical to use in your environment if you simply can't use a GPO to enable WinRM on all of your CM clients.  If you CAN use a GPO against your entire environment; then perhaps all you'd maybe, and I mean MAYBE want this for is to Monitor only (no remediation) and just check if the GPO is in fact getting to all your clients.  I wouldn't bother, personally; if I had a GPO that could get to every client.

Puzzling Behavior: When I was testing, more often than I was comfortable with (when using remediation enabled), client computers would report "Failed"--but at re-run they would report Compliant, and forever after report compliant.  What I suspect is happening (but couldn't verify, because a rerun was compliant) was that during Remediation, AS it was remediating one of the 1st non-compliant results... other tests would fail.  But by the time of a human (me) following up on it, WinRM was all enabled and configured and a re-run of the Baseline would indicate absolutely nothing wrong.  So... if you get a lot of failures in Remediation... just wait for your next cycle or re-run the baseline manually.  I suspect it's fine; just a timing issue.


  • Created on .

ConfigMgr 2012 SQL Report with Collection information about Include or Exclude other collections

Either my web searching skills have left me; or no one else has had occasion to create this type of report for SRS; but I couldn't find a SQL query I could use in SRS to show me collection details about when a particular collection was "including" another collection, or "excluding" another collection.  Here's what I ended up with; perhaps there is an easier or better way, but this worked:

select distinct as [Collection Name],
cdepend.SourceCollectionID as 'Collection Dependency',
cc.Name as 'Collection Dependency Name',
Case When
cdepend.relationshiptype = 1 then 'Limited To ' + + ' (' + cdepend.SourceCollectionID + ')'
when cdepend.relationshiptype = 2 then 'Include '  + + ' (' + cdepend.SourceCollectionID + ')'
when cdepend.relationshiptype = 3 then 'Exclude '  + + ' (' + cdepend.SourceCollectionID + ')'
end as 'Type of Relationship'
from v_Collection c
join vSMS_CollectionDependencies cdepend on cdepend.DependentCollectionID=c.CollectionID
join v_Collection cc on cc.CollectionID=cdepend.SourceCollectionID
where c.CollectionID = @CollectionID

and where, of course, you then (in Report Builder) have another query just for use by the parameter "CollectionID": select c.collectionid, from v_collection c order by

With that, Report Builder 3.0 to publish it into SRS, and then you can then pick a collection by name, and see what types of relationships it has with other collections.  In this example, the collection called "Sample Collection for the Blog", happens to have 3 relationships to other collections.


Of course, you can also get more information about your collections; like...collection queries for that collection

select, crq.queryexpression from v_collectionrulequery crq where [email protected]

or... is that a collection which has direct members and no queries; like...

select count(*) as 'Number of Direct Member Rules' from v_collectionRuleDirect crd where [email protected]

or...are there any service windows applied to that collection:

select sw.Name, sw.Description, sw.Duration, sw.IsEnabled, sw.ServiceWindowID from v_ServiceWindow sw where [email protected]

There's also v_CollectionSettings and v_CollectionVariable which might be interesting.  So you can make up a "everything you wanted to know about this collectionid" report if you so desire.  Just need to be creative with Report Builder and having multiple tables in Report Builder.


  • Created on .

Roger Zander's Client Center for CM12 Browser Version Doc

At our company, we've elected to offer Roger Zander's Client Center for ConfigMgr 2012 utility to the staff who need to support CM12 clients.  Since often that staff is roaming, instead of deploying the MSI version or instructing them to use the Click-once version, we've elected to offer the Browser based version.

With the latest update to Client Center, we've obtained a licensee key.  For the Browser-based version, to avoid a prompt about whether or not to "Run" the web page, that means that you need to sign a couple of the files offered with a code-signing certificate so it is trusted within your company.

I know just enough about IIS in order to support ConfigMgr, so there was a bit of a learning curve for me to understand how to accomplish that signing.  I've posted 'what worked for me' on the documentation page for ClientCenter, if you happen to use the browser based version, you might find that document helpful.

  • Created on .

ConfigMgr Inventory of Powershell Versions

If you happen to be curious about what versions of Powershell are installed/available on your clients, here's one way to pull out the information.  Note that the regkey locations for some of this information has changed from version 2 to higher versions, so it's completely possible that a future update to Powershell and the regkey location will change again; so if that happens a modification to these .mof files will be necessary.  As of Windows 8.1; these worked to report versions of Powershell installed.

Take the --> attached <-- and inside are two .mof files.  If you are ConfigMgr 2012, place the contents of the 'posh-configuration.mof.txt' at the bottom of your <inbox location>\clifiles.src \hinv\configuration.mof file.  In your configMgr 2012 console, in Client Settings, Default Agent Settings, Hardware Inventory, Classes... Import the 'posh-to-be-imported.mof'

Wait for clients to start reporting, once you get some clients reporting, the below sql query should get you started:

;with CTE as (
  select distinct resourceid
   ,RTRIM(substring(ISNULL((select ','+PSCompatibleVersion0  
        from v_GS_PowerShell0 p1
        where p1.ResourceID=t2.resourceid for XML path ('')),' '),2,2000)) as PSCompatibleVersions0
   ,RTRIM(substring(ISNULL((select ','+PowerShellVersion0
        from v_GS_PowerShell0 p1  where p1.ResourceID=t2.resourceid for XML path ('')),' '),2,2000)) as PowerShellVersions0
   ,RTRIM(substring(ISNULL((select ','+RuntimeVersion0
        from v_GS_PowerShell0 p1  where p1.ResourceID=t2.resourceid for XML path ('')),' '),2,2000)) as RunTimeVersions0
 from v_R_System t2
   select distinct sys1.netbios_name0 [ComputerName]
 ,cte.RunTimeVersions0 [RunTime Versions]
 ,cte.PSCompatibleVersions0 [PS Compatible Versions]
 ,cte.PowerShellVersions0 [PowerShell Versions]
 from v_R_System sys1
 left join CTE on cte.ResourceID=sys1.ResourceID



  • Created on .

Copyright © 2018 - The Minnesota System Center User Group