{"id":56073,"date":"2008-03-04T23:56:00","date_gmt":"2008-03-04T23:56:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/03\/04\/hey-scripting-guy-how-can-i-map-a-drive-based-on-the-computers-subnet\/"},"modified":"2008-03-04T23:56:00","modified_gmt":"2008-03-04T23:56:00","slug":"hey-scripting-guy-how-can-i-map-a-drive-based-on-the-computers-subnet","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-map-a-drive-based-on-the-computers-subnet\/","title":{"rendered":"Hey, Scripting Guy! How Can I Map a Drive Based on the Computer\u2019s Subnet?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! I have a CAD staff that occasionally travels between sites. What I would like to do, in a logon script, is map a set of drives based on their current location, that is, their current subnet. I need the script to first check and see if the drives are already mapped; if so then the script should just leave the drives as-is. If not, I would like the drives mapped according to the current subnet. How can I do that?<\/p>\n<p>&#8212; GM<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, GM. No doubt many of you are thinking, \u201cAs much as we enjoyed the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/default.mspx\"><b>2008 Winter Scripting Games<\/b><\/a>, now that the Games are over the Scripting Guy who writes that column will finally talk about something new for a change.\u201d Well, you <i>would<\/i> think that, wouldn\u2019t you? As it turns out, though, the Scripting Guy who writes this column has been so immersed in the Games for the past month or so that he truly has no idea what else is going on in the world. No idea at all.<\/p>\n<p>Well, OK, except when it comes to sports; needless to say, he <i>always<\/i> finds time to keep up with \u2013 and watch \u2013 his beloved college basketball, no matter what. However, because the Washington Huskies refuse to abandon their up-and-down season on the basketball court (16 wins, 14 losses) he just doesn\u2019t feel like talking about sports right now.<\/p>\n<p>And yes, there <i>are<\/i> primary elections going on all over the US, all of them moving us closer to selecting a new President in November. But the Scripting Guy who writes this column doesn\u2019t want to talk about politics, either. Why not? Because, by definition, someone <i>has<\/i> to win. And that hardly ever turns out to be a good thing.<\/p>\n<p>Let\u2019s see, what else is there \u2026. Oh, here\u2019s something he heard on TV the other day. Apparently a few years ago teachers in the United Kingdom seriously considered a proposal to change the term \u201cfailed\u201d to \u201cdeferred success.\u201d Get a 0 on a test? You didn\u2019t fail; you just deferred your success to a later date. The proposal was voted down in the UK, but now people in the US are jumping on the \u201cdeferred success\u201d bandwagon. To tell you the truth, the Scripting Guy who writes this column isn\u2019t too keen on the idea. <\/p>\n<p>And that despite the fact that no one has more deferred successes than he does.<\/p>\n<p>Hey, we <i>told<\/i> you we didn\u2019t have anything to talk about today. On the bright side, though, the 2009 Winter Scripting Games will be here before we know it. What can you do between now and then? Beats us. But you can spend at least a <i>little<\/i> time taking a look at the following script, one that maps a drive based on a computer\u2019s current subnet:<\/p>\n<pre class=\"codeSample\">Set objNetwork = CreateObject(\"Wscript.Network\")\n\nstrComputer = \".\"\n\nSet objWMIService = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")\n\nSet colAdapters = objWMIService.ExecQuery _\n    (\"Select * From Win32_NetworkAdapterConfiguration Where IPEnabled=True\")\n\nFor Each objAdapter in colAdapters\n    For Each strAddress in objAdapter.IPAddress\n        arrOctets = Split(strAddress, \".\")\n        If arrOctets(0) &lt;&gt; \"\" Then\n            strSubnet = arrOctets(0) &amp; \".\" &amp; arrOctets(1) &amp; \".\" &amp; arrOctets(2)\n            x = 1\n            Exit For\n        End If\n        If x = 1 Then\n            Exit For\n        End If\n    Next\nNext\n\nSet colItems = objWMIService.ExecQuery _\n    (\"Select * From Win32_LogicalDisk Where DeviceID = 'H:'\")\n\nIf colItems.Count = 0 Then\n    Select Case strSubnet\n        Case \"192.168.1\" \n            objNetwork.MapNetworkDrive \"H:\", \"\\\\arizona-fs-01\\public\"\n        Case \"192.168.2\" \n            objNetwork.MapNetworkDrive \"H:\", \"\\\\newmexico-fs-01\\public\"\n        Case \"192.168.3\" \n            objNetwork.MapNetworkDrive \"H:\", \"\\\\texas-fs-01\\public\"\n    End Select\nEnd If\n<\/pre>\n<p>Before we begin we should note that we\u2019re just going to show you how to map a single drive today. But that should be no big deal; after all, to map additional drives all you need to do is:<\/p>\n<table class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<tbody>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>Copy the code that checks for the existence of the drive.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>Copy the code that maps the drive according to the subnet.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>Change the drive letter and drive path as needed.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>That should be fairly easy. Besides, the 2009 Winter Scripting Games are less than a year away; it\u2019s never too early to start writing code and to start training.<\/p>\n<p>As for the code that <i>we<\/i> wrote, we start off by creating an instance of the <b>Wscript.Network<\/b> object; this is the object that enables us to map drives using VBScript. From there we connect to the WMI service on the local computer, then use this line of code and the <b>ExecQuery<\/b> method to retrieve a collection of all the TCP\/IP-enabled network adapters on the computer:<\/p>\n<pre class=\"codeSample\">Set colAdapters = objWMIService.ExecQuery _\n    (\"Select * From Win32_NetworkAdapterConfiguration Where IPEnabled=True\")\n<\/pre>\n<p>As you know, in this day and age it\u2019s not impossible for a computer to have more than one IP address; for example, a computer might be simultaneously connected to the network by both a wired and a wireless connection. We\u2019re assuming that this doesn\u2019t matter, that even if a computer <i>does<\/i> have multiple IP addresses those addresses will be on the same subnet. Admittedly, that might not be the case and, admittedly, those multiple IP addresses might make a difference. Like we said, though, we\u2019re going to assume that this <i>isn\u2019t<\/i> the case; instead, we\u2019re simply going to find the first IP address on the computer and call it good. <\/p>\n<p>What if that doesn\u2019t work for you? For example, what if you want to ensure that the wired connection gets priority over the wireless connection; how do you do that? That\u2019s something we\u2019ll have to address in the future.<\/p>\n<p>For now, we retrieve a collection of all the TCP\/IP-enabled network adapters on the computer, then set up a For Each loop to loop us through each adapter in the collection:<\/p>\n<pre class=\"codeSample\">For Each objAdapter in colAdapters\n<\/pre>\n<p>Just to complicate things even more, it\u2019s also possible for a single network adapter to have more than one IP address; in fact, the <b>IPAddress<\/b> property in WMI\u2019s <b>Win32_NetworkAdapterConfiguration<\/b> class is designed to store IP addresses as an array. What does that mean? That means that, to determine the IP address for a computer, we need to set up a second For Each loop, this one configured to walk us through the IP addresses assigned to a given network adapter:<\/p>\n<pre class=\"codeSample\">For Each strAddress in objAdapter.IPAddress\n<\/pre>\n<p>Inside this second loop we use the <b>Split<\/b> method to split the IP address on the period:<\/p>\n<pre class=\"codeSample\">arrOctets = Split(strAddress, \".\")\n<\/pre>\n<p>What\u2019s the point of that? Well, subnets are typically composed of the first 2 or 3 \u201coctets\u201d in an IP address (depending on your definition of a subnet). For example, the IP address 192.168.1.1 is typically considered to be on the subnet 192.168.1. An easy way to get at the first 3 octets of an IP address is to split the address into an array consisting of the following elements:<\/p>\n<table class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<tbody>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>192<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>168<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p>1<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Once we have our array our next step is to use this line of code to verify that we actually <i>have<\/i> an IP address rather than an empty string:<\/p>\n<pre class=\"codeSample\">If arrOctets(0) &lt;&gt; \"\" Then\n<\/pre>\n<p>Assuming we do, we then create a new subnet string, one consisting of the first three octets (plus the periods in between):<\/p>\n<pre class=\"codeSample\">strSubnet = arrOctets(0) &amp; \".\" &amp; arrOctets(1) &amp; \".\" &amp; arrOctets(2)\n<\/pre>\n<p>In other words, strSubnet will now be equal to this: 192.168.1.<\/p>\n<p>Just like we said we would, now that we\u2019ve found a valid IP address we\u2019re going to call it good. With that in mind, we set the value of a variable named x to 1, then call the <b>Exit For<\/b> statement to exit our interior For Each loop:<\/p>\n<pre class=\"codeSample\">x = 1\nExit For\n<\/pre>\n<p>Once we\u2019re out of the loop we check the value of x. If x is 0 that means we haven\u2019t found an IP address yet; therefore, we go back to the top of our outside loop and try again with the next network adapter in the collection. If x <i>is<\/i> equal to 1 that means that we <i>have<\/i> found an IP address; consequently, we call the Exit For statement again, this time to exit our outside loop (the one that loops us through the collection of network adapters).<\/p>\n<p>A little clunky and cumbersome, perhaps, but it works.<\/p>\n<p>At this point we\u2019re ready to map a drive (drive H), assuming that this drive isn\u2019t already mapped somewhere else. To verify that, we run the following WMI query, a query that returns a collection of all the drives with a <b>DeviceID<\/b> (drive letter) equal to <i>H:<\/i><\/p>\n<pre class=\"codeSample\">Set colItems = objWMIService.ExecQuery _\n    (\"Select * From Win32_LogicalDisk Where DeviceID = 'H:'\")\n<\/pre>\n<p>After we issue the query and get back our collection, we can determine whether or not we already have a drive H simply by checking the value of the collection\u2019s <b>Count<\/b> property, which tells us how many items (drives) are in the collection:<\/p>\n<pre class=\"codeSample\">If colItems.Count = 0 Then\n<\/pre>\n<p>If the Count is equal to 0 that means the computer does not have a drive H; if the Count is equal to 1 then the computer <i>does<\/i> have a drive H. If the Count is equal to 1 we leave well-enough alone. If the count is equal to 0, we then check the value of strSubnet and map drive H based on that value:<\/p>\n<pre class=\"codeSample\">Select Case strSubnet\n    Case \"192.168.1\" \n        objNetwork.MapNetworkDrive \"H:\", \"\\\\arizona-fs-01\\public\"\n    Case \"192.168.2\" \n        objNetwork.MapNetworkDrive \"H:\", \"\\\\newmexico-fs-01\\public\"\n    Case \"192.168.3\" \n        objNetwork.MapNetworkDrive \"H:\", \"\\\\texas-fs-01\\public\"\nEnd Select\n<\/pre>\n<p>As you can see, if our subnet is equal to 192.168.1 we map drive H to the folder \\\\arizona-fs-01\\public. If our subnet is equal to 192.168.2 then we map drive H to \\\\newmexico-fs-01\\public. Etc., etc.<\/p>\n<p>That should do it, GM. Incidentally, if you or anyone else had \u2026 deferred success \u2026 in the 2008 Winter Scripting Games, well, remember, the Games aren\u2019t over until the Scripting Guys say they\u2019re over. And we have no intention of saying that they\u2019re over until Thursday, March 6, 2008; up until that point you can resubmit any event in which you got a 0. (And yes, that includes the Sudden Death Challenge.) Figure out what you did wrong, send us the corrected script and, assuming it works, we\u2019ll erase that 0 and replace it with however many points we\u2019re handing out for the event. Now <i>that\u2019s<\/i> deferred success, eh? <\/p>\n<p>It\u2019s just too bad the Scripting Guys aren\u2019t running college basketball. If we were, the Huskies would be doing far better than they are now. Lose a game? No problem; we\u2019ll just let them play again until they finally get it right.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have a CAD staff that occasionally travels between sites. What I would like to do, in a logon script, is map a set of drives based on their current location, that is, their current subnet. I need the script to first check and see if the drives are already mapped; if [&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-56073","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! I have a CAD staff that occasionally travels between sites. What I would like to do, in a logon script, is map a set of drives based on their current location, that is, their current subnet. I need the script to first check and see if the drives are already mapped; if [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56073","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=56073"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56073\/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=56073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=56073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=56073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}