{"id":55143,"date":"2008-08-25T23:14:00","date_gmt":"2008-08-25T23:14:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/08\/25\/hey-scripting-guy-how-can-i-troubleshoot-drive-mapping-issues\/"},"modified":"2008-08-25T23:14:00","modified_gmt":"2008-08-25T23:14:00","slug":"hey-scripting-guy-how-can-i-troubleshoot-drive-mapping-issues","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-troubleshoot-drive-mapping-issues\/","title":{"rendered":"Hey, Scripting Guy! How Can I Troubleshoot Drive-Mapping Issues?"},"content":{"rendered":"<p><SPAN class=\"Apple-style-span\">\n<H1><FONT class=\"Apple-style-span\" size=\"3\" face=\"Verdana\"><SPAN class=\"Apple-style-span\"><FONT class=\"Apple-style-span\" size=\"6\" face=\"Arial\"><SPAN class=\"Apple-style-span\"><\/SPAN><\/FONT><\/SPAN><\/FONT><\/H1><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! We have this problem at work. Users seem to always be losing their mapped drives. It is a real mess, and we spend a couple hours every morning trying to help the users remap their drives. We have more than 160 logon scripts, and it seems that one logon script maps a drive, and then another remaps the drive somewhere else. To make matters worse, when we go to the workstation and make the drive-mapping persistent, they seem to disappear for no reason. I am at my wit\u2019s end. It would really help, if we just had a log of what drives are mapped for the workstation. We could then ask the user when things last worked and see what their drive-mapping is supposed to be. Is there anything you can do to help?<BR><BR>&#8211; SN<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><\/A> \n<P>Hi SN,<\/P>\n<P>It seems as if you have a mess on your hands. One hundred and sixty logon scripts? I won\u2019t ask! Sounds as if a little&nbsp;<A href=\"http:\/\/technet.microsoft.com\/en-us\/library\/cc506049.aspx\">Microsoft Operations Framework (MOF) Training<\/A>&nbsp;would not hurt your organization. As a matter of fact, we just came out with MOF version 4.0, which covers the IT management life cycle through three distinct phases: planning, delivery, and operations.&nbsp;<\/P>\n<P>Part of the problem is that you are making changes to your environment without having achieved a reliable, stable situation. Without knowing what the desktop environment is, it is hard to plan and deploy changes in an organized fashion. This is leading to increased problem management and customer service issues. Go ahead and download the&nbsp;<A href=\"http:\/\/technet.microsoft.com\/en-us\/library\/cc506049.aspx\">free documentation<\/A>.<\/P>\n<P>Of course, you know you have a problem, or you would not have asked for a tool to help you with the first step: Document what you actually have. What is the drive-mapping on a user\u2019s machine when they are not having problems? Then document what the drive-mapping is on a user\u2019s computer when they are having problems, and figure out what was changed that may be causing the problem.<\/P>\n<P>In the&nbsp;<B>WriteMappedDrivesToFile.vbs<\/B>&nbsp;script, we will define a couple of WMI queries, create a dictionary to store our WMI information, and use&nbsp;<B>FileSystemObject<\/B>&nbsp;to write our information to a file. (Use of&nbsp;<B>FileSystemObject<\/B>&nbsp;is covered in chapter 6 of the Microsoft Press book&nbsp;<A href=\"http:\/\/www.microsoft.com\/MSPress\/books\/9543.aspx\">Microsoft VBScript Step by Step<\/A>. Along the way, we will use the&nbsp;<B>replace<\/B>&nbsp;function to help us create a file name. I know you can\u2019t wait, so here is the&nbsp;<B>WriteMappedDrivesToFile.vbs<\/B>&nbsp;script:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;<\/p>\n<p>Const networkdisk = 4 \nConst ForWriting = 2\nConst ForAppending = 8\nwmiQuery=&#8221;Select DeviceID, ProviderName from Win32_LogicalDisk &#8221; &amp; _<BR>&#8220;where DriveType =&#8221; &amp; networkdisk<\/PRE><PRE class=\"codeSample\">wmiQuery1 =&#8221;Select Name, UserName from Win32_ComputerSystem&#8221;<\/p>\n<p>Set objDictionary = CreateObject(&#8220;scripting.dictionary&#8221;)\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer)\nset colDrives = objWMIService.ExecQuery(wmiQuery)\nSet colUsers = objWMIService.ExecQuery(wmiQuery1)<\/p>\n<p>For Each user In colUsers\n userName = replace(user.UserName,&#8221;\\&#8221;,&#8221;_&#8221;)\n dnsHostName = user.Name\nNext<\/p>\n<p>if colDrives.count &lt;&gt; 0 Then\n for each drive in colDrives\n  objDictionary.add drive.DeviceID, drive.ProviderName\n  colKeys = objDictionary.Keys\n  colItems = objDictionary.Items\n Next\nElse\n objDictionary.add &#8221; No Drives Mapped &#8220;, &#8221; No Drives Mapped &#8221;\n  colKeys = objDictionary.Keys\n  colItems = objDictionary.Items\nEnd if<\/p>\n<p>sublogDrives <\/p>\n<p>Sub sublogDrives\n LogFile = &#8220;C:\\FSO\\&#8221; &amp; username &amp; &#8220;.txt&#8221;\n Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\n If objFSO.FileExists(LogFile) Then\n  Set objFile = objFSO.OpenTextFile(LogFile, ForAppending)\n  objfile.writeblanklines(2)\n  objFile.Writeline &#8220;******** &#8221; &amp; Now &amp; &#8220;********&#8221;\n  objFile.writeline &#8220;User is: &#8221; &amp; username \n  objFile.writeline &#8220;computer is: &#8221; &amp; dnsHostName\n     For Each strKey In colKeys\n      objFile.writeline vbtab &amp; strKey &amp; objDictionary.item(strKey)\n     Next \n Else\n   Set objFile = objFSO.CreateTextFile(LogFile)\n   objFile.Writeline &#8220;******** &#8221; &amp; Now &amp; &#8220;********&#8221;\n   objFile.writeline &#8220;User is: &#8221; &amp; username \n   objFile.writeline &#8220;computer is: &#8221; &amp; dnsHostName\n     For Each strKey In colKeys\n      objFile.writeline vbtab &amp; strKey &amp; objDictionary.item(strKey)\n     Next \n End If\n objFile.Close\nEnd sub\nWScript.echo &#8220;all done&#8221;\n<\/PRE>\n<P>Our script begins by defining a couple of variables and constants. We then create two strings that will serve as our two WMI queries. The first string, called&nbsp;<B>wmiQuery<\/B>, chooses&nbsp;<B>DeviceID<\/B>&nbsp;and&nbsp;<B>ProviderName<\/B>&nbsp;from the&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa394173.aspx\">Win32_LogicalDisk<\/A>&nbsp;WMI class. We limit the returned data to only drives that are network drives (in other words, mapped drives). The second WMI query, contained in the variable&nbsp;<B>wmiQuery1<\/B>(like everything else in VBScript, it is zero based), chooses the name of the computer and the name of the user from the<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa394102.aspx\">Win32_ComputerSystem<\/A>&nbsp;WMI class. We will use this information for our file output. These two lines of code are seen&nbsp;here:<\/P><PRE class=\"codeSample\">wmiQuery=&#8221;Select DeviceID, ProviderName from Win32_LogicalDisk &amp; _\nwhere DriveType =&#8221; &amp; networkdisk\nwmiQuery1 =&#8221;Select Name, UserName from Win32_ComputerSystem&#8221;\n<\/PRE>\n<P>Now we need to create a couple of objects. The first is the&nbsp;<B>dictionary<\/B>&nbsp;object, which we will use to hold the drive-mappings we obtain from WMI. The next object is our connection into WMI, which is followed quickly by the objects returned by executing our two WMI queries. This code can be seen&nbsp;here: <\/P><PRE class=\"codeSample\">Set objDictionary = CreateObject(&#8220;scripting.dictionary&#8221;)\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer)\nset colDrives = objWMIService.ExecQuery(wmiQuery)\nSet colUsers = objWMIService.ExecQuery(wmiQuery1)\n<\/PRE>\n<P>Because we executed our WMI queries by using the&nbsp;<B>ExecQuery<\/B>&nbsp;method, the objects that are returned are collections. This means we need to use&nbsp;<B>for each next<\/B>&nbsp;to iterate through the collections and extract our data. We first want to obtain the name of the computer and the name of the user. So we use the&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/tywtbxd0.aspx\">for each next<\/A>&nbsp;loop and walk through the collection that is held in the&nbsp;<B>colUsers<\/B>&nbsp;variable. Inside the loop, we use the&nbsp;<B>replace<\/B>&nbsp;function to replace the \u201c\\\u201d that is in the username with an \u201c_\u201d because the \u201c\\\u201d will cause us problems with the file name. The first position of the&nbsp;<B>replace<\/B>&nbsp;function is used to hold the text we want to modify. The second position holds the string we wish to find, and the third position contains the value with which we will perform the replacement. There are three other parameters available for the&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/238kz954.aspx\">replace<\/A>&nbsp;function, but we did not need them here. Once we have the data, we store the values into a couple of variables we will use later:<\/P><PRE class=\"codeSample\">For Each user In colUsers\n userName = replace(user.UserName,&#8221;\\&#8221;,&#8221;_&#8221;)\n dnsHostName = user.Name\nNext\n<\/PRE>\n<P>Now we need to look through the drives that were returned by our query. The first thing we need to do is make sure we actually have some drives. If we do, we will walk through the collection and add the drive letter (<B>deviceID<\/B>) and share mapping (<B>providerName<\/B>) to our&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/x4k5wbx4(VS.85).aspx\">Dictionary<\/A>&nbsp;object. However, if there are no drives, we simply add the string, \u201cNo Drives Mapped\u201d to both the key and the value of our dictionary. This will help to avoid errors later in the&nbsp;script:<\/P><PRE class=\"codeSample\">if colDrives.count &lt;&gt; 0 Then\n for each drive in colDrives\n  objDictionary.add drive.DeviceID, drive.ProviderName\n  colKeys = objDictionary.Keys\n  colItems = objDictionary.Items\n Next\nElse\n objDictionary.add &#8221; No Drives Mapped &#8220;, &#8221; No Drives Mapped &#8221;\n  colKeys = objDictionary.Keys\n  colItems = objDictionary.Items\nEnd if\n<\/PRE>\n<P>Now go into the&nbsp;<B>sublogDrives<\/B>&nbsp;subroutine. Inside here, we first define the path to our output file. We assume there is a folder named<B>c:\\fso<\/B>, but we do not assume the log file itself exists. You could use the&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/5xc78d8d(VS.85).aspx\">folderexists<\/A>&nbsp;method from the&nbsp;<A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/6kxy1a51(VS.85).aspx\">FileSystemObject<\/A>&nbsp;if you wish to check for the existence of the folder. Next, we create the&nbsp;<B>FileSystemObject<\/B>&nbsp;and use the&nbsp;<B>FileExists<\/B>&nbsp;method to see if the log file currently exists. If the log file does exist, we begin the process of writing to the file. To write to the file, we first use the&nbsp;<B>OpenTextFile<\/B>method. Because we know the file already exists, we open the file so that we can append to it. We specify this action by using our previously defined&nbsp;<B>ForAppending<\/B>&nbsp;constant. Because we would like a little bit of space between entries, we use the&nbsp;<B>WriteBlankLines<\/B>method from the&nbsp;<B>FileSystemObject<\/B>. Next we use the&nbsp;<B>WriteLine<\/B>&nbsp;method to print our data to the file. This code is seen&nbsp;here:<\/P><PRE class=\"codeSample\">Sub sublogDrives\n LogFile = &#8220;C:\\FSO\\&#8221; &amp; username &amp; &#8220;.txt&#8221;\n Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\n If objFSO.FileExists(LogFile) Then\n  Set objFile = objFSO.OpenTextFile(LogFile, ForAppending)\n  objfile.writeblanklines(2)\n  objFile.Writeline &#8220;******** &#8221; &amp; Now &amp; &#8220;********&#8221;\n  objFile.writeline &#8220;User is: &#8221; &amp; username \n  objFile.writeline &#8220;computer is: &#8221; &amp; dnsHostName\n     For Each strKey In colKeys\n      objFile.writeline vbtab &amp; strKey &amp; objDictionary.item(strKey)\n     Next\n<\/PRE>\n<P>If the file does not exist, we will want to create the file. To do this, we use the&nbsp;<B>CreateTextFile<\/B>&nbsp;method from&nbsp;<B>FileSystemObject<\/B>. We then use the same pattern of writing blank lines and iterating through the dictionary to populate the file. When we are done, we close the text file. This action is important to prevent possible file locking issues. It is simple enough to do: We call the&nbsp;<B>Close<\/B>&nbsp;method. We are done, and so we print out a friendly \u201call done\u201d by using&nbsp;<B>Wscript.echo<\/B>. If you call this from a logon script, you probably will not want the friendly \u201call done\u201d message. You can comment it out if you&nbsp;wish:<\/P><PRE class=\"codeSample\">Else\n   Set objFile = objFSO.CreateTextFile(LogFile)\n   objFile.Writeline &#8220;******** &#8221; &amp; Now &amp; &#8220;********&#8221;\n   objFile.writeline &#8220;User is: &#8221; &amp; username \n   objFile.writeline &#8220;computer is: &#8221; &amp; dnsHostName\n     For Each strKey In colKeys\n      objFile.writeline vbtab &amp; strKey &amp; objDictionary.item(strKey)\n     Next \n End If\n objFile.Close\nEnd sub\nWScript.echo &#8220;all done&#8221;\n<\/PRE>\n<P>Whew! We are done. Here is what the text file looks like:<\/P>\n<P><SPAN class=\"Apple-style-span\"><IMG border=\"0\" alt=\"Mapped drives image\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/MappedDrivesText.jpg\" width=\"500\" height=\"284\"><\/SPAN>&nbsp;<\/P>\n<P>SN, I hope this script can help you in beginning the long process of weeding out 160 logon scripts, and assist you in gaining a bit of sanity. We don&#8217;t have any scripts for you that have an explicit sanity output yet, but give us time.<\/P>\n<P><FONT class=\"Apple-style-span\" size=\"3\" face=\"Verdana\"><SPAN class=\"Apple-style-span\"><B><B>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/B><\/B><\/SPAN><\/FONT><\/P><FONT class=\"Apple-style-span\" size=\"3\" face=\"Verdana\"><B><\/B><\/FONT><\/SPAN><FONT class=\"Apple-style-span\" size=\"3\" face=\"Verdana\"><\/FONT><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! We have this problem at work. Users seem to always be losing their mapped drives. It is a real mess, and we spend a couple hours every morning trying to help the users remap their drives. We have more than 160 logon scripts, and it seems that one logon script maps a [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,185,12,5],"class_list":["post-55143","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-shared-folders-and-mapped-drives","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! We have this problem at work. Users seem to always be losing their mapped drives. It is a real mess, and we spend a couple hours every morning trying to help the users remap their drives. We have more than 160 logon scripts, and it seems that one logon script maps a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=55143"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55143\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=55143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}