{"id":55993,"date":"2008-03-15T00:17:00","date_gmt":"2008-03-15T00:17:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/03\/15\/hey-scripting-guy-how-can-i-copy-a-file-to-a-removable-drive-if-i-dont-know-the-drive-letter-of-that-drive\/"},"modified":"2008-03-15T00:17:00","modified_gmt":"2008-03-15T00:17:00","slug":"hey-scripting-guy-how-can-i-copy-a-file-to-a-removable-drive-if-i-dont-know-the-drive-letter-of-that-drive","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-copy-a-file-to-a-removable-drive-if-i-dont-know-the-drive-letter-of-that-drive\/","title":{"rendered":"Hey, Scripting Guy! How Can I Copy a File to a Removable Drive If I Don\u2019t Know the Drive Letter of That Drive?"},"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! How can I determine if a computer has a removable drive attached to it and, if it does, copy a file to that drive? I have no way of knowing what the drive letter of that removable drive would be, assuming it even exists.<\/p>\n<p>&#8212; SN<\/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, SN. You know, when you live in Seattle you don\u2019t really need a calendar in order to know what time of year it is. For example, on Tuesday it rained all morning. Wednesday the Scripting Guy who writes this column had to scrape frost off his windows before he could drive to work. Today (Thursday) it\u2019s raining once again. So, without looking at the calendar, what time of year must it be? You got it: it\u2019s baseball season in Seattle! <\/p>\n<p>Needless to say, the season is off to a smashing start. The Scripting Son\u2019s high school team was supposed to begin play on Tuesday, but they were rained out. They rescheduled the game for Wednesday, and managed to squeeze it in, frost and all. They\u2019re supposed to play again tonight, but a quick glance out the window suggests that the odds of that are pretty slim. If so, that would mean that the season started off with a bang: two rainouts in a span of three days. <\/p>\n<p>And yes, that <i>is<\/i> impressive, but we\u2019ve seen worse. For example, when the Scripting Son was a 13-year-old, his PONY League team had 11 of its first 13 games postponed due to rain. By the time the season reached its halfway point the team had played a grand total 5 of its scheduled 30 games.<\/p>\n<p>Now <i>that\u2019s<\/i> baseball season in Seattle.<\/p>\n<table class=\"dataTable\" id=\"EGD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. As a point of comparison, the Los Angeles Dodgers \u2013 who play 81 home games a year \u2013 have had a grand total of 17 rainouts since 1962. In fact, the Dodgers went nine years (April, 1967 to April, 1976) without having a single home game rained out.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Of course, many of you are probably wondering what the players do when a game gets postponed due to rain. Obviously we can\u2019t speak for <i>all<\/i> the players. However, we can tell you that many of the players do the same thing that major league ballplayers do when a game gets rained out; they spend their time in the locker room writing scripts that can copy a file to a removable drive, even if they have no idea what the drive letter of that removable drive might be. For example, here\u2019s a script that Indians outfielder Grady Sizemore wrote last season, when his team series with Seattle, which was supposed to be played in Cleveland, was <i>snowed<\/i> out:<\/p>\n<pre class=\"codeSample\">Const OverwriteExisting = TRUE\n\nSet objFSO = CreateObject(\"Scripting.FileSystemObject\")\n\nstrComputer = \".\"\n\nSet objWMIService = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")\n\nSet colDrives = objWMIService.ExecQuery _\n    (\"Select * From Win32_LogicalDisk Where DriveType = 2\")\n\nFor Each objDrive in colDrives\n    strDrive = objDrive.DeviceID\n    strTarget = strDrive &amp; \"\\\" \n    objFSO.CopyFile \"C:\\Scripts\\Test.txt\", strTarget, OverWriteExisting\nNext\n<\/pre>\n<p>OK, let\u2019s see if we can figure out how this works. (Yes, go ahead and brush the snow off of it first. We\u2019ll wait.) As you can see, the script starts off by defining a constant named OverwriteExisting and setting the value to True. What\u2019s this constant for? Well, suppose we\u2019re going to copy a file named Test.txt to a removable drive, and suppose the removable drive already <i>has<\/i> a file named Test.txt on it. This constant tells the script to go ahead and replace the existing file with the new version of Test.txt.<\/p>\n<p>After we define the constant our next step is to create an instance of the <b>Scripting.FileSystemObject<\/b>, the object we\u2019ll use to copy the file from our local hard disk to the removable drive.<\/p>\n<p>Speaking of which, we still have a problem here: we don\u2019t even know if our computer <i>has<\/i> a removable drive, let alone know the drive letter for that drive. But that\u2019s easy enough to find out. To get information about all the removable drives on the computer we connect to the WMI service on the computer. As soon as we\u2019ve done that, we can use this line of code to return a collection of all the removable drives attached to that machine:<\/p>\n<pre class=\"codeSample\">Set colDrives = objWMIService.ExecQuery _\n    (\"Select * From Win32_LogicalDisk Where DriveType = 2\")\n<\/pre>\n<p>What we\u2019re doing here is querying the <b>Win32_LogicalDisk<\/b> class, asking to get back a collection of all the disk drives that have a <b>DriveType<\/b> equal to <i>2<\/i>. You probably don\u2019t know this, but a drive that has a DriveType equal to 2 is \u2013 oh, OK; apparently you <i>do<\/i> know this. Well, you\u2019re right: a drive that has a DriveType equal to 2 is a removable drive.<\/p>\n<p>You kind of stole our thunder there, didn\u2019t you?<\/p>\n<p>Our next step is to set up a For Each loop that will walk us through all the removable drives in the collection. What happens if our computer doesn\u2019t <i>have<\/i> any removable drives? Nothing much; in that case the script will simply skip the For Each loop (because there\u2019s nothing for it to walk through) and then coast to a stop. <\/p>\n<p>But what happens if our computer <i>does<\/i> have a removable drive? In that case, we plunge headfirst into the For Each loop, pausing just long enough to assign the value of the drive letter (that is, the value of the <b>DeviceID<\/b> property) to a variable named strDrive:<\/p>\n<pre class=\"codeSample\">strDrive = objDrive.DeviceID\n<\/pre>\n<p>That\u2019s going to make strDrive equal to something like this: F:. This is useful information, but it\u2019s not quite sufficient to copy a file to drive F. Instead, we have to add the trailing \\ to the path, turning F: into F:\\. That\u2019s what this line of code is for:<\/p>\n<pre class=\"codeSample\">strTarget = strDrive &amp; \"\\\"\n<\/pre>\n<p>Why do we have to do that? Well, the trailing \\ tells the FileSystemObject that we want to copy a file to the container F:\\; that is, we want to copy a file to the root folder on drive F. Suppose we tried to copy the file to <i>F:<\/i>, without the \\. In that case, we\u2019d get the following error message:<\/p>\n<pre class=\"codeSample\">Microsoft VBScript runtime error: Permission denied\n<\/pre>\n<p>Why? Because without the \\ on the end the FileSystemObject thinks we want to copy the file to drive F <i>and<\/i> to give the copied file the name <i>F:<\/i>. Needless to say, we can\u2019t have a file named <i>F:<\/i>; we get the error message because the computer thinks we\u2019re trying to replace all of drive F with this single file. <\/p>\n<p>The computer doesn\u2019t like it when we try to do things like that.<\/p>\n<p>Once we add the trailing \\, however, we can copy our file (C:\\Scripts\\Test.txt) to the removable drive by using the following line of code:<\/p>\n<pre class=\"codeSample\">objFSO.CopyFile \"C:\\Scripts\\Test.txt\", strTarget, OverWriteExisting\n<\/pre>\n<p>Could we copy more than one file to the removable drive? Sure; just repeat the preceding line of code as many times as needed. That\u2019s all there is to it. The best part, of course, is that we never had to know the drive letter of the removable drive. As long as the <i>script<\/i> knows the drive letter of the removable drive, well, that\u2019s all that really matters.<\/p>\n<p>Two quick notes about this script. First, it\u2019s quite possible that a computer could have more than one removable drive connected to it. In that case, the script is going to copy Test.txt to each of those drives. (After we copy the file to the first drive in the collection the script will pop back to the top of our For Each loop and then copy the file to the next drive in the collection.) Is there any way to set things up so that the files get copied to only a particular removable drive? Well, maybe, but it wouldn\u2019t be easy; that\u2019s because removable drives generally don\u2019t populate the Win32_LogicalDisk class with much information that would help you separate one drive from another. <\/p>\n<p>Second, this script is designed to run on the local computer only; however, it can be modified to work against a remote computer <i>provided<\/i> that the file to be copied (C:\\Scripts\\Test.txt) resides on that remote computer. In other words, it\u2019s pretty easy to copy a file from drive C of a remote machine to drive F on that same remote machine. How easy? Well, the following script (which we won\u2019t explain today) will do the trick, copying a file from drive C on the computer atl-fs-001 to a removable drive attached to that same computer:<\/p>\n<pre class=\"codeSample\">strComputer = \"atl-fs-001\"\n\nSet objWMIService = GetObject(\"winmgmts:\\\\\" &amp; strComputer &amp; \"\\root\\cimv2\")\n\nSet colDrives = objWMIService.ExecQuery _\n    (\"Select * From Win32_LogicalDisk Where DriveType = 2\")\n\nFor Each objDrive in colDrives\n    strDrive = objDrive.DeviceID\n    strTarget = strDrive &amp; \"\\\" \n\n    Set colFiles = objWMIService.ExecQuery _\n        (\"Select * from CIM_DataFile where Name= 'C:\\\\Scripts\\\\Test.txt'\")\n\n    For Each objFile in colFiles\n        strNewPath = strTarget &amp; objFile.FileName &amp; \".\" &amp; objFile.Extension\n        objFile.Copy(strNewPath)\n    Next\nNext\n<\/pre>\n<p>That should do it, SN; if it doesn\u2019t, please let us know. As for the Scripting Guy who writes this column, he plans to spend the rest of the day sitting around waiting for the phone to ring, and waiting for the Scripting Son to report that the game has been rained out. In case you\u2019re wondering, no, you don\u2019t have to wait with him; if you have other things to do, feel free to do them. And if you <i>don\u2019t<\/i> have other things to do, here are several Seattle rain jokes to help you pass the time:<\/p>\n<p>A newcomer first arrived in Seattle on a rainy day. When he awoke the next morning it was still raining. It continued to rain the next day, and the day after that. In desperation, he spotted a kid walking by and said, &#8220;Hey kid, does it ever stop raining around here?&#8221; &#8220;How should I know?\u201d replied the kid. \u201cI&#8217;m only 6.&#8221;<\/p>\n<p>Well, maybe you\u2019re right: one Seattle rain joke probably <i>is<\/i> enough, isn\u2019t it? See you all tomorrow.<\/p>\n<table class=\"dataTable\" id=\"EUG\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Ed<\/b><b>itor\u2019s Note:<\/b> For those of you on the edge of your seats wondering whether the game <i>was<\/i> rained out: Yes, it was.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I determine if a computer has a removable drive attached to it and, if it does, copy a file to that drive? I have no way of knowing what the drive letter of that removable drive would be, assuming it even exists. &#8212; SN Hey, SN. You know, when you [&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":[216,38,3,12,5],"class_list":["post-55993","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-disk-drives-and-volumes","tag-files","tag-scripting-guy","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I determine if a computer has a removable drive attached to it and, if it does, copy a file to that drive? I have no way of knowing what the drive letter of that removable drive would be, assuming it even exists. &#8212; SN Hey, SN. You know, when you [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55993","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=55993"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55993\/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=55993"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55993"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55993"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}