ConfigMgr 2007: How to inventory mapped drives
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(https://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.
Alvin Morales - Senior Support Engineer
Comments
Anonymous
January 01, 2003
    I was asked a few days ago if ConfigMgr or SMS could inventory mapped drives, and whileAnonymous
January 01, 2003
thank you