Learn about Windows PowerShell
Hey, Scripting Guy! How can I use a script to show me all the files in a folder? And then how can I modify that script so it shows me all the files in any subfolders of that folder?-- CS
Hey, CS. Yesterday we showed everyone a script that changed all the files in a folder from read-only to read-write. We also promised that, in today’s column, we’d explain how we managed to get a list of all the files in a folder in the first place. Your questions are the perfect lead-in to that explanation.
Let’s start with the easy one: a script that simply lists all the files in a folder. This script reports back the file name of all the files found in the folder C:\Scripts:
Set objFSO = CreateObject("Scripting.FileSystemObject") objStartFolder = "C:\Scripts" Set objFolder = objFSO.GetFolder(objStartFolder) Set colFiles = objFolder.Files For Each objFile in colFiles Wscript.Echo objFile.Name Next
As you can see, there really isn’t much to this. We create an instance of the FileSystemObject, and then we use the GetFolder method to bind to folder C:\Scripts. Pretty straightforward. If we wanted to bind to, say, the Windows folder, all we’d have to do is change the path accordingly, something we do by assigning a different value to objStartFolder:
objStartFolder = "C:\Windows"
After we’ve connected to the folder, we then create a reference to the Files property using this command:
Set colFiles = objFolder.Files
That gives us back a collection consisting of all the files found in the folder. (But- and this has important implications for your second question - this collection does not include files found in any subfolders of C:\Scripts.) At this point the rest is child’s play: we can now use a For Each loop to loop through the collection of files and - if we choose - do something to each and every one. Because you asked how to get a list of all the files in a folder, all we do is echo the name of the file. But we could do a lot more than that; for example, we could report back the DateCreated property or the Size property. For a more complete rundown of the FileSystemObject and how to use it, you might want to check out the Script Runtime Primer in the Microsoft Windows 2000 Scripting Guide.
In other words, getting back a list of all the files in a folder is trivial. Getting back a list of all the files in a folder plus all the files in any subfolders of that folder can be a bit trickier. To do that you need to use a recursive script. We’re not going to explain recursion here; for more details, check out this portion of the Microsoft Windows 2000 Scripting Guide. (Yes, we do seem to be promoting the book quite a bit today, don’t we?) Basically a recursive function is a function that can automatically call itself as many times as needed. That might not make much sense, but think of it this way. The script we showed you above lists all the files in a folder and then stops. It doesn’t matter if there are subfolders in the folder; the script doesn’t really care.
A recursive function, by contrast, does care: it will keep working until it has done everything you asked of it, and more. A recursive function will list all the files in a folder, and then check to see if that folder has any subfolders. Suppose it finds subfolders A and B. In that case, the function will call itself, and list any files found in Subfolder A. And what if Subfolder A has a sub-subfolder C? No problem: the function will call itself again, and list all the files in sub-Subfolder C. This will continue until no more subfolders can be found. At that point, the function will loop back, and start working its way through Subfolder B. Furthermore, it will dutifully keep working until it has gone through each and every subfolder and sub-subfolder and sub-sub-subfolder and - well, until every last file has been listed.
It all sounds terribly complicated, and it is. Fortunately, though, VBScript hides most of this complexity from you. Hey, would we kid you about something like that? Look, here’s a script that uses a recursive function - ShowSubFolders - to list all the files in the folder C:\Scripts and all the files found in any subfolders of C:\Scripts:
Set objFSO = CreateObject("Scripting.FileSystemObject") objStartFolder = "C:\Scripts" Set objFolder = objFSO.GetFolder(objStartFolder) Wscript.Echo objFolder.Path Set colFiles = objFolder.Files For Each objFile in colFiles Wscript.Echo objFile.Name Next Wscript.Echo ShowSubfolders objFSO.GetFolder(objStartFolder) Sub ShowSubFolders(Folder) For Each Subfolder in Folder.SubFolders Wscript.Echo Subfolder.Path Set objFolder = objFSO.GetFolder(Subfolder.Path) Set colFiles = objFolder.Files For Each objFile in colFiles Wscript.Echo objFile.Name Next Wscript.Echo ShowSubFolders Subfolder Next End Sub
As you can see the first part of the script is exactly the same as the one we saw before (with one exception: this one echoes the folder path so we know which folder we’re looking at). After showing all the files in C:\Scripts, it then calls the recursive function ShowSubFolders. This function then starts sifting through all the subfolders and reports back any files found. All this “recursion” happens automatically; all you have to do is just sit back and watch.
If you don’t fully understand what’s happening here, don’t worry about it; it takes awhile to fully grasp how recursive functions work. In the meantime, just copy the preceding script and use it any time you need to do something to all the files in a folder and its subfolders.
WMI method here:
http://blogs.technet.com/heyscriptingguy/archive/2005/02/18/how-can-i-list-the-files-in-a-folder-and-all-its-subfolders.aspx
Regards,
Daz.
Hi Thanks for the above script,
Can this modified to carry out the task such as say,
1. When you get each and every file in all the subfolders, is it possible to change the file type.
Say I have file with an extension .txt can change the file to .doc .., Recursievly each and every file in all the sub folders...!
help very much appreciated....
Thanks
Vinu
When I use this is traverses the same recursion path of folders twice. Can anybody please tell me why?
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "d:\Folder"
Set objRootFolder = objFSO.GetFolder(objStartFolder)
Counter = 0
List = ShowSubFolders(objRootFolder, "--Start--")
wscript.echo List
Function ShowSubFolders(Folder, List)
List = List & vbCRLF & Folder.Name
For Each Subfolder in Folder.SubFolders
Set objFolder = objFSO.GetFolder(Subfolder.Path)
ShowSubFolders = List + ShowSubFolders(SubFolder, List)
Next
End Function
hey, thanks for the tip about listing files in a folder/subfolder/subsubfolder, etc. I have one question: is it possible to regroup this 2 parts together into 1 continuous part (like 2-3 For in a chain) (and without the WScript.Echoes) ?
i have to do a batch file for a program that reads files in folders/subfolders then compress them. when the 2 parts are regrouped, it will become easier to do that.
How do i get the output in a text file..
Thnx!
This might be simpler:
objStartFolder = "d:\stuff"
ShowSubfolders objFSO.GetFolder(objStartFolder)
Sub ShowSubFolders(Folder)
Wscript.Echo Folder.Path
For Each objFile in Folder.files
Wscript.Echo objFile.Name
Wscript.Echo
ShowSubFolders Subfolder
End Sub
Hi,
Can I search the files in the sub folders and copy the same into the another folder by maintianing folder structure? If it is so, can you help me in writing a code on VB Script?
@madhu
XCOPY /?
I have combined two or three source file to make a below scripts for directory listing including sub directories.
It will be fully working even though there are some folders which you don't have permission to access.
Please notes that I just modified or added based on other programer's source.
Brian
------------------------------------------------------------------------------------------------------
On Error Resume Next
Const WINDOW_HANDLE = 0
Const BIF_EDITBOX = &H10
Const BIF_NONEWFOLDER = &H0200
Const BIF_RETURNONLYFSDIRS = &H1
Dim depth
Set objShell = CreateObject("Shell.Application")
Set wshShell = CreateObject("WScript.Shell")
depth = 0
'**Browse For Folder To Be Processed
strPrompt = "Please select the folder to process."
intOptions = BIF_RETURNONLYFSDIRS + BIF_NONEWFOLDER + BIF_EDITBOX
strTargetPath = wshShell.SpecialFolders("C:\")
strFolderPath = Browse4Folder(strPrompt, intOptions, strTargetPath)
Set objNewFile = objFSO.CreateTextFile("C:\filelist.csv", True)
Set objFolder = objFSO.GetFolder(strFolderPath)
ShowSubFolders objFolder, objNewFile, depth
objNewFile.Close
Sub ShowSubFolders(Folder, hFile, ldepth)
Dim txtline
hFile.WriteLine(Folder.Path)
ShowSubFolders Subfolder, hFile, ldepth + 1
'**Browse4Folder Function
Function Browse4Folder(strPrompt, intOptions, strRoot)
Dim objFolder, objFolderItem
Set objFolder = objShell.BrowseForFolder(0, strPrompt, intOptions, strRoot)
If (objFolder Is Nothing) Then
Wscript.Quit
End If
Set objFolderItem = objFolder.Self
Browse4Folder = objFolderItem.Path
Set objFolderItem = Nothing
Set objFolder = Nothing
I tried using this code bit I keep getting an Expected Statement error at the End Sub line. Here is my code... Please help...
FolName = "test"
Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Do While Folname <> -1 and FolName <> ""
FolName = InputBox("Enter Folder Name")
If (ObjFSO.FolderExists(FolName)) Then
MsgBox "Folder Exists"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery _
("SELECT * FROM CIM_Datafile WHERE Path = FolName")
Set objFolder = objFSO.GetFolder(FolName)
For Each objFile in colFiles
Wscript.Echo "File name: " & objFile.Name & vbCRLF & _
"File size: " & objFile.Size & vbCRLF & _
"File type: " & objFile.Type & vbCRLF & _
"Last modified: " & objFile.DateLastModified
ShowSFolders objFSO.GetFolder(FolName)
FolName = ""
Else
MsgBox "Folder Does Not Exists"
Exit Do
Subroutine ShowSFolders(Folder)
For Each Subfolder in Folder.Subfolders
Wscript.Echo Subfolder.Path
Set ObjFolder = objFSO.GetFolder(Subfolder.Path)
ShowSFolders Subfolder
Here is a version of the same script with a few changes...
One, it has been converted to run within Classic ASP, but also so that it is not necessary to start the tree outside of the recursive sub routine. That's accomplished by checking to see if the argument is an object or path (path on the first initiation running the first folder loop)
Other changes are some naming convention and the name of the subroutine itself to ShowFoldersAndFiles since everthing is within one routine with only the FileSystemObject declared outside the Sub. Also dimensioning (Dim) all variables so Option Explicit will work.
Since this will be used for my own use, I provided a DEBUG sub routine that shows the output of each folder/file. That can be turned off by setting the Const DEBUG_ON to False ore removed altogether(but this give same output as the provided script); as I or anyone else may want to do things(other proceedures) within traversing of each of the folders and files, instead of just showing them.
So with this, I'm not doing anything too different form ScriptingGuy1's example but, showing how it can be accomplished all with one routine.
To make this work in WSH, just uncomment the equivalent lines of code that work with WSH, and comment out the ASP specific lines or just remove them.
Hope this helps someone wanting a more contained proceedure.
-Reuben :)+<
'-----------------------------------------------------------------
Option Explicit
Dim m_objFSO
Dim strStartFolder
Const DEBUG_ON = True
Set m_objFSO = Server.CreateObject("Scripting.FileSystemObject")
'Set m_objFSO = CreateObject("Scripting.FileSystemObject")
strStartFolder = Server.MapPath("/")
'strStartFolder = "C:\Scripts"
Call ShowFoldersAndFiles(strStartFolder)
Sub ShowFoldersAndFiles(varStartFolder)
Dim objStartFolder
Dim objFolder
Dim objSubFolder
Dim objFile
Dim objFiles
If IsObject(varStartFolder) Then
' varStartFolder is an object, so we are within a recursion.
' Set varStartFolder to the globally used objStartFolder
Set objStartFolder = varStartFolder
' varStartFolder is most likely a string of the very first start
' folder. The start of tree process begins here.
Set objStartFolder = m_objFSO.GetFolder(varStartFolder)
Call DEBUG(objStartFolder.Path)
Set objFiles = objStartFolder.Files
For Each objFile in objFiles
Call DEBUG(objFile.Name)
Call DEBUG(Null)
' Loop through the sub folders from the current start folder.
For Each objSubfolder in objStartFolder.SubFolders
Call DEBUG(objSubfolder.Path)
Set objFolder = m_objFSO.GetFolder(objSubfolder.Path)
Set objFiles = objFolder.Files
Call ShowFoldersAndFiles(objSubFolder)
Sub DEBUG(strFsoString)
If DEBUG_ON = True Then
If IsNull(strFsoString) Then
Response.Write "<br />" & vbNewline
'Wscript.Echo
Response.Write strFsoString & "<br />" & vbNewline
'Wscript.Echo strFileSystem
I know this has been around for a while and I have modified to read and select some files that I am looking for. However, I have hit a folder with +255 characters. I have on error resume next. It does not fail but the script just stops working at that point. How do I tell it to ignore that directory and go to the next one?
Chuck, I have ran into a similar issue, the 250+ character path breaks this script from fully working. Here what I submitted to hopefully get a solution to it
social.technet.microsoft.com/.../a1da7114-d379-44f4-a8a9-18b6fc9e934a
Hi everyone,
Im new to this vbscripting, but learned lot of things in few days and made few scripts which i needed in daily life for home and office.
I got lot of stuff in my PC which i always make it as hidden to keep away from my cousins.
So i wrote a small script which searches whole PC for a hidden file and make a note in a text file.
Code:
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery("Select * from CIM_Datafile")
If objFile.Hidden = True Then
Set fso = CreateObject("Scripting.FileSystemObject")
Set fl = fso.OpenTextFile("D:\Hidden.txt", 8, True)
fl.Write(vbCrLf & " " & objFile.Name)
fl.Close : Set fl = Nothing
Set fso = Nothing
Msgbox("Done")
But after some time it throws an error 0x8004106C and stops.
Can any one please provide me vbscript that
1. Ask which drive to search( ex: C:\ ,also searches subfolders within)
2. Makes a text file on desktop which includes path and file name which are hidden.
Gulam Mustafa