I was asked a few days ago if ConfigMgr or SMS could inventory mapped drives, and while the answer is yes we don't do it by default. In effect we report the logical disk but not mapped drives.
In order to inventory mapped drives we first need to extend the sms_def.mof. Mapped drives are in the user context so we need to gather this information from every user. We also need a repository to collect this information; this would be a class in WMI.
So here is how we accomplish this. Add the following lines to the end of the SMS_def.mof:
//====================================================================================== // Mapped Drives Reporting // // Note: The class is created using a advertised vbscript (mapdrives.vbs) //====================================================================================== #pragma namespace("\\\\.\\root\\CIMV2\\SMS") #pragma deleteclass("CX_mappeddrives", NOFAIL) [ SMS_Report(TRUE), SMS_Group_Name("CX Mapped Drives"), SMS_Class_ID("CX_mappeddrives"), Namespace("\\\\\\\\.\\\\root\\\\cimv2")] class CX_mappeddrives : SMS_Class_Template { [SMS_Report(TRUE), Key] string user; [SMS_Report(TRUE), key] string Letter; [SMS_Report(TRUE), Key] string Path; }; // <:[-<>>>>>>>>>>>>>>>>>>>>>>>>>>END>>-Mapped drives Reporting-<<END<<<<<<<<<<<<<<<<<<<<<<<>-]:>
This will extend the mof and create the necessary stored procedures and tables in the SMS database. After compiling the mof on the site server restart the SMS_executive and the component manager. We will need to compile this sms_def.mof on the clients as well to extend WMI and create the repository to store the mapped drive information. You can do this by a logon script or advertisement.
We now need to gather the mapped drive information. Here is the script to do so. I named it mapdrives.vbs
' This code is provided "as-is" and not supported by Microsoft ' ' option explicit on error resume next Dim wbemCimtypeSint16 Dim wbemCimtypeSint32 Dim wbemCimtypeReal32 Dim wbemCimtypeReal64 Dim wbemCimtypeString Dim wbemCimtypeBoolean Dim wbemCimtypeObject Dim wbemCimtypeSint8 Dim wbemCimtypeUint8 Dim wbemCimtypeUint16 Dim wbemCimtypeUint32 Dim wbemCimtypeSint64 Dim wbemCimtypeUint64 Dim wbemCimtypeDateTime Dim wbemCimtypeReference Dim wbemCimtypeChar16 wbemCimtypeSint16 = 2 wbemCimtypeSint32 = 3 wbemCimtypeReal32 = 4 wbemCimtypeReal64 = 5 wbemCimtypeString = 8 wbemCimtypeBoolean = 11 wbemCimtypeObject = 13 wbemCimtypeSint8 = 16 wbemCimtypeUint8 = 17 wbemCimtypeUint16 = 18 wbemCimtypeUint32 = 19 wbemCimtypeSint64 = 20 wbemCimtypeUint64 = 21 wbemCimtypeDateTime = 101 wbemCimtypeReference = 102 wbemCimtypeChar16 = 103 Dim oLocation, oServices, oInstances, oObject, oDataObject, oNewObject, oRptObject Set oLocation = CreateObject("WbemScripting.SWbemLocator") 'Remove class Set oServices = oLocation.ConnectServer(, "root\cimv2") set oNewObject = oServices.Get("CX_mappeddrives") oNewObject.Delete_ 'Create data class structure Set oServices = oLocation.ConnectServer(, "root\cimv2") Set oDataObject = oServices.Get oDataObject.Path_.Class = "CX_mappeddrives" oDataObject.Properties_.add "Letter", wbemCimtypeString oDataObject.Properties_.add "Path", wbemCimtypeString oDataObject.Properties_.add "user", wbemCimtypeString oDataObject.Properties_("Letter").Qualifiers_.add "key", True oDataObject.Properties_("Path").Qualifiers_.add "key", True oDataObject.Properties_("user").Qualifiers_.add "key", True oDataObject.Put_ 'Add Instances to data class Set oServices = oLocation.ConnectServer(, "root\cimv2") Dim sComputerName, sUsername, sQuery Set oInstances = oServices.ExecQuery("SELECT UserName FROM Win32_ComputerSystem") for each oObject in oInstances sUserName = oObject.UserName next sQuery = "select * from win32_MappedLogicalDisk" Set oInstances = oServices.ExecQuery(sQuery) for each oObject in oInstances Set oNewObject = oServices.Get("CX_mappeddrives").SpawnInstance_ oNewObject.Letter = oObject.DeviceID oNewObject.Path = oObject.ProviderName oNewObject.user = sUserName oNewObject.Put_ next '--------------------------------- FUNCTIONS ----------------------------------- Function ParseComp(Stg,Pat) Dim tmpCS, p, q tmpCS = "" p = 1 Do while p < len(Stg) if mid(Stg,p,len(Pat)) = Pat Then q = p + len(Pat) + 1 Do while mid(Stg,q,1) <> chr(34) and q < len(Stg) tmpCS = tmpCS + mid(Stg,q,1) q = q + 1 Loop Exit do Else p = p + 1 end if Loop ParseComp = tmpCS End Function
Now this script can be executed through a logon script.
A few gotchas on the whole process is that the user has to have write access to root/CIMV2 class. We can over come this by explicitly adding the domain user group to CIMV2 using the MMC or you can use a free tool called wmisecurity.exe(http://www.codeproject.com/KB/system/WmiSecurity.aspx )
Once the script is run the class would get populated with the letter and path and user who ran the script.
Then when hardware inventory is run it will populate information in the database that can be used later to create reports. To verify that it worked fine verify Resource explorer for one machine. It will have a new class named cx_mappeddrives:
Here is a sample report you can use to view the data:
select v_R_System.Name0,v_GS_Cx_Mapped_Drives0.Letter0, v_GS_Cx_Mapped_Drives0.Path0, v_GS_Cx_Mapped_Drives0.user0 from v_R_System inner join v_GS_Cx_Mapped_Drives0 on v_GS_Cx_Mapped_Drives0.ResourceId = v_R_System.ResourceId where v_GS_Cx_Mapped_Drives0.Letter0 like '%' and v_GS_Cx_Mapped_Drives0.Path0 like '%' and v_GS_Cx_Mapped_Drives0.user0 like '%'
The report will look like this:
A good use of this script is to determine a valid drive letter for a new server share or what are your clients mapping to.
I hope these steps help to gather information and special thanks to Jason Alanis for creating the vbs script.
Note: This information was originally provided by Alvin Morales, Senior Support Escalation Engineer, on the now-defunct SMSandMOM blog:
http://blogs.technet.com/smsandmom/archive/2008/12/18/configmgr-2007-how-to-inventory-mapped-drives.aspx
Maheshkumar S Tiwari edited Revision 1. Comment: Added Tag