{"id":70403,"date":"2005-02-18T16:01:00","date_gmt":"2005-02-18T16:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/02\/18\/how-can-i-list-the-files-in-a-folder-and-all-its-subfolders\/"},"modified":"2005-02-18T16:01:00","modified_gmt":"2005-02-18T16:01:00","slug":"how-can-i-list-the-files-in-a-folder-and-all-its-subfolders","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-list-the-files-in-a-folder-and-all-its-subfolders\/","title":{"rendered":"How Can I List the Files in a Folder and All Its Subfolders?"},"content":{"rendered":"<p><IMG 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\"> \n<P>Hey, Scripting Guy! How can I list all of the files in a folder, as well as all the files in any subfolders of that folder?<BR><BR>&#8212; MA<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG 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 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> \n<P>Hey, MA. This is a question we get asked quite a bit, and one which have avoided answering up till now. That\u2019s because there is no nice, simple answer to this one: a script that can carry out this task is bound to be a little bit confusing, and isn\u2019t going to lend itself to the easy-to-explain approach we like to take with this column. On the other hand, the customer is always right: if you guys want a script that can list all the files in a folder, as well as all the files in any subfolders of that folder, well, who are we to argue?<\/P>\n<P>Before we begin there are two issues we have to grapple with here. First, we need to pick a scripting technology. WMI, the FileSystemObject, and the Shell object are all capable of listing the files in a folder, as well as listing the subfolders in a folder. However, none of these technologies have a mechanism to automatically list the files in those subfolders (not to mention any sub-subfolders that might be found there). Any of these technologies will do the trick, but none will do it very easily.<\/P>\n<P>We opted to go with WMI. The resulting script is perhaps a little more complicated than a similar script using the FileSystemObject or the Shell object, but a WMI script that can retrieve this kind of information on the local computer can just as easily retrieve this kind of information from a remote computer. That\u2019s not the case with either the FileSystemObject or the Shell object. We voted for the flexibility of WMI.<\/P>\n<P>Second, we noted that none of the scripting technologies has a built-in way to iterate through a folder, list the file names, and then automatically iterate through any and all subfolders and list the files found there. Because of that, we need to use a <I>recursive function<\/I> to perform this task. Explaining recursion is a bit beyond what we can do in this column; for a brief explanation, check out the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_scr_jozd.mspx\"><B>Microsoft Windows 2000 Scripting Guide<\/B><\/A>. Suffice to say that we\u2019re creating a function that can call itself as many times as needed. In other words, if we have a function that accesses a folder and lists all its files, that function can call itself to access a subfolder and list all the files found there. And then call itself again to access a sub-subfolder. It\u2019s hard to visualize, but it works.<\/P>\n<P>There\u2019s another complication, too, but we\u2019ll deal with that in a minute. For now, let\u2019s take a look at a script that lists a folder and any and all of its subfolders (although this first sample doesn\u2019t list any files found in those folders):<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>strFolderName = &#8220;c:\\scripts&#8221;<\/p>\n<p>Set colSubfolders = objWMIService.ExecQuery _\n    (&#8220;Associators of {Win32_Directory.Name='&#8221; &amp; strFolderName &amp; &#8220;&#8216;} &#8221; _\n        &amp; &#8220;Where AssocClass = Win32_Subdirectory &#8221; _\n            &amp; &#8220;ResultRole = PartComponent&#8221;)<\/p>\n<p>For Each objFolder in colSubfolders\n    GetSubFolders strFolderName\nNext<\/p>\n<p>Sub GetSubFolders(strFolderName)\n    Set colSubfolders2 = objWMIService.ExecQuery _\n        (&#8220;Associators of {Win32_Directory.Name='&#8221; &amp; strFolderName &amp; &#8220;&#8216;} &#8221; _\n            &amp; &#8220;Where AssocClass = Win32_Subdirectory &#8221; _\n                &amp; &#8220;ResultRole = PartComponent&#8221;)<\/p>\n<p>    For Each objFolder2 in colSubfolders2\n        strFolderName = objFolder2.Name\n        Wscript.Echo objFolder2.Name\n        GetSubFolders strFolderName\n    Next\nEnd Sub\n<\/PRE>\n<P>What we\u2019re doing here is using an <B>AssociatorsOf<\/B> query to get a list of all the subfolders of the folder C:\\Scripts. Basically our query says this: Get me a list of all the items associated with the directory C:\\Scripts, provided those items are subdirectories (<B>Where AssocClass = Win32_Subdirectory<\/B>). <\/P>\n<P>This gets us a list of all the top-level subfolders: for example, C:\\Scripts\\Folder1 and C:\\Scripts\\Folder2. What it <I>doesn\u2019t<\/I> get us are any second-level folders; this query does not return a folder like C:\\Scripts\\Folder1\\SubfolderA. To get at these sub-subfolders (subfolders of a subfolder) we need to use a recursive query. That\u2019s what the subroutine <B>GetSubFolders<\/B> does. We pass it &#8211; one-by-one &#8211; the name of each subfolder we find (like C:\\Scripts\\Folder1 and C:\\Scripts\\Folder2) and let it query each of those subfolders for any sub-subfolders. If there <I>are<\/I> any sub-subfolders, the function will automatically call itself and look for any sub-sub-subfolders.<\/P>\n<P>Confused? Don\u2019t feel bad; you aren\u2019t the only one. But don\u2019t worry about it; just leave the code as-is and give it a try. To search a different folder (that is, one other than C:\\Scripts) simply change the value of the variable containing the folder you want to search. For example, if you want to search C:\\Windows, then use this line of code:<\/P><PRE class=\"codeSample\">strFolderName = &#8220;c:\\windows&#8221;\n<\/PRE>\n<P>Now, what about the files found in all these folders? Well, this is where things <I>really<\/I> get complicated. That\u2019s because we need to make an additional query: we use one query to get the names of all the subfolders, and then a second query to get the collection of files found in each folder. That second query happens to look a lot like this:<\/P><PRE class=\"codeSample\">Set colFiles = objWMIService.ExecQuery _\n    (&#8220;Select * from CIM_DataFile where Path = &#8216;&#8221; &amp; strPath &amp; &#8220;&#8216;&#8221;)\n<\/PRE>\n<P>That\u2019s not too bad, except for this: in a query such as this, we must \u201cescape\u201d (double-up) any \\\u2019s found in the file paths. We can\u2019t use <B>C:\\Scripts\\Folder1\\<\/B> in our query; we have to use <B>C:\\\\Scripts\\\\Folder1\\\\<\/B> instead. You\u2019ll see code in the script that replaces each \\ with \\\\; that\u2019s just something we need to do when referencing a file path in a query like this. A good chunk of the script is doing nothing more than converting the folder path names so they can be used in the query.<\/P>\n<P>So much for all the caveats. Here\u2019s the script everyone has been dying to get their hands on:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>strFolderName = &#8220;c:\\scripts&#8221;<\/p>\n<p>Set colSubfolders = objWMIService.ExecQuery _\n    (&#8220;Associators of {Win32_Directory.Name='&#8221; &amp; strFolderName &amp; &#8220;&#8216;} &#8221; _\n        &amp; &#8220;Where AssocClass = Win32_Subdirectory &#8221; _\n            &amp; &#8220;ResultRole = PartComponent&#8221;)<\/p>\n<p>Wscript.Echo strFolderName<\/p>\n<p>arrFolderPath = Split(strFolderName, &#8220;\\&#8221;)\nstrNewPath = &#8220;&#8221;\nFor i = 1 to Ubound(arrFolderPath)\n    strNewPath = strNewPath &amp; &#8220;\\\\&#8221; &amp; arrFolderPath(i)\nNext\nstrPath = strNewPath &amp; &#8220;\\\\&#8221;<\/p>\n<p>Set colFiles = objWMIService.ExecQuery _\n    (&#8220;Select * from CIM_DataFile where Path = &#8216;&#8221; &amp; strPath &amp; &#8220;&#8216;&#8221;)<\/p>\n<p>For Each objFile in colFiles\n    Wscript.Echo objFile.Name \nNext<\/p>\n<p>For Each objFolder in colSubfolders\n    GetSubFolders strFolderName\nNext<\/p>\n<p>Sub GetSubFolders(strFolderName)\n    Set colSubfolders2 = objWMIService.ExecQuery _\n        (&#8220;Associators of {Win32_Directory.Name='&#8221; &amp; strFolderName &amp; &#8220;&#8216;} &#8221; _\n            &amp; &#8220;Where AssocClass = Win32_Subdirectory &#8221; _\n                &amp; &#8220;ResultRole = PartComponent&#8221;)<\/p>\n<p>    For Each objFolder2 in colSubfolders2\n        strFolderName = objFolder2.Name\n        Wscript.Echo\n        Wscript.Echo objFolder2.Name\n        arrFolderPath = Split(strFolderName, &#8220;\\&#8221;)\n        strNewPath = &#8220;&#8221;\n        For i = 1 to Ubound(arrFolderPath)\n            strNewPath = strNewPath &amp; &#8220;\\\\&#8221; &amp; arrFolderPath(i)\n        Next\n        strPath = strNewPath &amp; &#8220;\\\\&#8221;<\/p>\n<p>        Set colFiles = objWMIService.ExecQuery _\n            (&#8220;Select * from CIM_DataFile where Path = &#8216;&#8221; &amp; strPath &amp; &#8220;&#8216;&#8221;)<\/p>\n<p>        For Each objFile in colFiles\n            Wscript.Echo objFile.Name \n        Next<\/p>\n<p>        GetSubFolders strFolderName\n    Next\nEnd Sub\n<\/PRE>\n<P>We told you it was complicated. But it works. This script will bind to the C:\\Scripts folder and echo the names of all the files found there; the script will then get a list of all the subfolders found in C:\\Scripts. From there we loop through the collection of subfolders, calling the recursive function GetSubFolders for each one. That function will list all the files found in the subfolder, then check to see if the subfolder has any sub-subfolders. If it does, the recursive function will be called again, and the process will continue to repeat itself until we reach the end of the line: until we\u2019ve listed every file found in C:\\Scripts and in all its subfolders.<\/P>\n<P>Tomorrow we should go back to an easy one. Anybody out there want to know how to get the name of the local computer using a script?<\/P><BR>\n<DIV>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\"><A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/feb05\/hey0218.mspx#top\"><IMG height=\"9\" alt=\"Top of page\" src=\"http:\/\/www.microsoft.com\/technet\/mnplibrary\/templates\/MNP2.Common\/images\/arrow_px_up.gif\" width=\"7\" border=\"0\"><\/A><A class=\"topOfPage\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/feb05\/hey0218.mspx#top\">Top of page<\/A><\/TD><\/TR><\/TBODY><\/TABLE><\/DIV><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I list all of the files in a folder, as well as all the files in any subfolders of that folder?&#8212; MA Hey, MA. This is a question we get asked quite a bit, and one which have avoided answering up till now. That\u2019s because there is no nice, simple [&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":[38,11,3,12,5],"class_list":["post-70403","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-files","tag-folders","tag-scripting-guy","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I list all of the files in a folder, as well as all the files in any subfolders of that folder?&#8212; MA Hey, MA. This is a question we get asked quite a bit, and one which have avoided answering up till now. That\u2019s because there is no nice, simple [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70403","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=70403"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/70403\/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=70403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=70403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=70403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}