{"id":63383,"date":"2007-12-15T01:19:00","date_gmt":"2007-12-15T01:19:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/12\/15\/hey-scripting-guy-how-can-i-determine-if-any-of-the-files-in-a-folder-have-been-modified-in-the-past-90-days\/"},"modified":"2007-12-15T01:19:00","modified_gmt":"2007-12-15T01:19:00","slug":"hey-scripting-guy-how-can-i-determine-if-any-of-the-files-in-a-folder-have-been-modified-in-the-past-90-days","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-determine-if-any-of-the-files-in-a-folder-have-been-modified-in-the-past-90-days\/","title":{"rendered":"Hey, Scripting Guy! How Can I Determine If Any of the Files in a Folder Have Been Modified in the Past 90 Days?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, Scripting Guy! On my file servers I periodically want to check a folder to see if that folder or any of its subfolders have files that are no longer being updated. What I\u2019d like to do is check each file in each folder to see if they\u2019ve been modified in the past 90 days. If I find a folder in which none of the files have been modified recently I\u2019d like the script to echo back the folder path. How can I write a script that will do that?<BR><BR>&#8212; MM<\/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\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, MM. Well, <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/dec07\/hey1213.mspx\"><B>as we noted yesterday<\/B><\/A>, today marks the last <I>Hey, Scripting Guy!<\/I> for 2007; after today we\u2019ll take a break, then resume posting new columns on January 2, 2008. Seeing as how this <I>is<\/I> the last column of the year, we also thought we\u2019d start out by recalling some of the Scripting Guys more memorable achievements of the past 12 months:<\/P>\n<P>&nbsp;<\/P>\n<P>&nbsp;<\/P>\n<P>OK, maybe \u201cachievements\u201d was the wrong word. Let\u2019s just see if we can recall some of the more memorable <I>events<\/I> which happened over the past 12 months. Here\u2019s one: Scripting Guy Dean Tsaltas received is Master\u2019s degree in Computer Science from Oxford University. Way to go, Dean!<\/P>\n<P>What\u2019s that? He hasn\u2019t gotten his degree yet because he still has written his Master\u2019s thesis? Gee, that doesn\u2019t sound like Dean. Well, OK then, what else happened this year? Let\u2019s, see Scripting Peter Costantini went to Nicaragua, where he was harassed by monkeys. <\/P>\n<P>You know, now that you mention it, that really wasn\u2019t all that big of a deal, was it? After all, Peter gets harassed by monkeys pretty much <I>everywhere<\/I> he goes. Nicaragua, Salt Lake City, 7-11, you name it. There just seems to be something about Peter and monkeys.<\/P>\n<P>What else? Here\u2019s a good thing: Scripting Guy Jean Ross finally <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/teched07\/itmonday.mspx\"><B>made it to Paris<\/B><\/A>! Of course, in all fairness she <I>did<\/I> have mixed emotions about that. On the one hand she got to go to Paris. On the other hand, she missed her 75-year high school reunion. But don\u2019t worry, Jean; your 100<SUP>th<\/SUP> reunion is just around the corner.<\/P>\n<P>As for Scripting Guy Greg Stemp, well, the less said about Scripting Guy Greg Stemp the better.<\/P>\n<P>Anyway, that pretty much sums up the year. Not particularly memorable but, on the bright side, we expect 2008 to be a way better year. After all, it pretty much would <I>have<\/I> to be a way better year.<\/P>\n<P>Now that that\u2019s taken care of let\u2019s see if we can help MM with her problem. MM needs a script that can look at all the files in a folder (and all its subfolders) and report back any folders that have nothing but old files; that is, a folder where none of the files have been modified in the past 90 days. How can she do that? Here\u2019s one way:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<\/p>\n<p>Set objStartFolder = objFSO.GetFolder(&#8220;C:\\Scripts&#8221;)\nSet colFiles = objStartFolder.Files<\/p>\n<p>i = 0<\/p>\n<p>For Each objFile in colFiles\n    dtmDate = objFile.DateLastModified\n    intAge = DateDiff(&#8220;d&#8221;, dtmDate, Date)\n    If intAge &lt; 90 Then\n        i = 1\n        Exit For\n    End If\nNext<\/p>\n<p>If i = 0 Then\n    Wscript.Echo objStartFolder.Path\nEnd If<\/p>\n<p>ShowSubfolders(objStartFolder) <\/p>\n<p>Sub ShowSubFolders(Folder)\n    For Each objSubfolder in Folder.SubFolders\n        Set objFolder = objFSO.GetFolder(objSubFolder.Path)\n        Set colFiles = objFolder.Files<\/p>\n<p>        i = 0<\/p>\n<p>        For Each objFile in colFiles\n            dtmDate = objFile.DateLastModified\n            intAge = DateDiff(&#8220;d&#8221;, dtmDate, Date)<\/p>\n<p>            If intAge &lt; 90 Then\n                i = 1\n                Exit For\n            End If\n        Next<\/p>\n<p>        If i = 0 Then\n            Wscript.Echo objSubfolder.Path\n        End If<\/p>\n<p>        ShowSubFolders objSubfolder\n    Next\nEnd Sub\n<\/PRE>\n<P>OK, yes, we know: this script <I>does<\/I> look awfully big, at least for a <I>Hey, Scripting Guy!<\/I> script. But don\u2019t panic; that\u2019s because \u2013 in order to make things easier to follow \u2013 we\u2019ve duplicated a large hunk of the code. As you\u2019re about to see, it\u2019s nowhere near as intimidating as it might look. For example, there\u2019s nothing very scary about the way the script kicks off. We start out by creating an instance of the <B>Scripting.FileSystemObject<\/B>, then use these two lines of code to bind to the folder C:\\Scripts and return a collection of all the files found in that folder:<\/P><PRE class=\"codeSample\">Set objStartFolder = objFSO.GetFolder(&#8220;C:\\Scripts&#8221;)\nSet colFiles = objStartFolder.Files\n<\/PRE>\n<TABLE id=\"EXE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. What about all the subfolders of C:\\Scripts? Don\u2019t worry; we\u2019ll get to those in a minute.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After we retrieve our collection of files, we set the value of a counter variable named i to 0; we\u2019ll use this variable to keep track of any files that have been modified in the past 90 days. That brings us to this block of code:<\/P><PRE class=\"codeSample\">For Each objFile in colFiles\n    dtmDate = objFile.DateLastModified\n    intAge = DateDiff(&#8220;d&#8221;, dtmDate, Date)\n    If intAge &gt; 90 Then\n        i = 1\n        Exit For\n    End If\nNext\n<\/PRE>\n<P>What we\u2019re doing here is cycling through all the files in the folder C:\\Scripts to see if we can find any files that have been modified in the past 90 days. (What about all the subfolders of C:\\Scripts? Don\u2019t worry; we\u2019ll get to those in a minute. Promise!) For each file in the collection we grab the value of the <B>DateLastModified<\/B> property and assign it to a variable named dtmDate: <\/P><PRE class=\"codeSample\">dtmDate = objFile.DateLastModified\n<\/PRE>\n<P>From there, we use VBScript\u2019s <B>DateDiff<\/B> function to determine the number of days (<B>&#8220;d\u201d<\/B>) that have elapsed between the date the file was last modified (dtmDate) and the current date (the VBScript <B>Date<\/B> function). We then check to see if this value is less than 90: <\/P><PRE class=\"codeSample\">If intAge &lt; 90 Then\n<\/PRE>\n<P>Let\u2019s assume that intAge <I>isn\u2019t<\/I> less than 90, indicating that the file hasn\u2019t been modified in the past 90 days. What does that mean? Well, it means we have yet to find a \u201cnew\u201d file in this folder; therefore, we zip back to the top of the loop and perform this same check with the next file in the collection.<\/P>\n<P>Now, suppose that intAge <I>is<\/I> less than 90; that means that we\u2019ve found a new file. Therefore, we do two things. First, we set the value of our counter variable to 1; after that, we call the <B>Exit For<\/B> statement to exit our For Each loop. <\/P>\n<TABLE id=\"EDG\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Why do we exit the loop? Well, remember, we\u2019re looking for folders that don\u2019t have a single file that has been modified in the past 90 days. All we have to do is find one such file; now that we have, there\u2019s no need to loop through all the other files in the collection.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Our next step is to determine whether or not the counter variable i is equal to 0. If it is, that means this particular folder doesn\u2019t have even <I>one<\/I> file that has been accessed in the past 90 days. That\u2019s exactly what we were looking for, so we echo back the folder path. That\u2019s what this block of code does:<\/P><PRE class=\"codeSample\">If i = 0 Then\n    Wscript.Echo objStartFolder.Path\nEnd If\n<\/PRE>\n<P>So much for C:\\Scripts. But what about all the subfolders of C:\\Scripts?<\/P>\n<P>You know, we\u2019re glad you asked that question. After we dispose of C:\\Scripts, we then use this line of code to call a recursive subroutine named ShowSubfolders, passing this subroutine the path to our starting folder (C:\\Scripts):<\/P><PRE class=\"codeSample\">ShowSubfolders(objStartFolder)\n<\/PRE>\n<P>We aren\u2019t going to discuss recursive functions and subroutines today; that\u2019s more than we can handle in a single <I>Hey, Scripting Guy!<\/I> column. (Especially one written the day before we start an 18-day break.) If you\u2019d like to know a little bit more about recursion, take a peek <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_vbs_kove.mspx\"><B>at this section<\/B><\/A> of the <I>Microsoft Windows 2000 Scripting Guide<\/I>.<\/P>\n<P>For now, we\u2019ll just note that a recursive subroutine is a subroutine that can call itself. What does that <I>mean<\/I>? Well, notice that the first thing we do inside this subroutine is set up a For Each loop to loop through all the top-level subfolders in C:\\Scripts:<\/P><PRE class=\"codeSample\">For Each objSubfolder in Folder.SubFolders\n<\/PRE>\n<P>What are we going to do with each of these subfolders? The very same thing we just finished doing with the parent folder C:\\Scripts: we\u2019re going to check all the files to see if any of them have been modified in the past 90 days. We\u2019ll go through the first subfolder (e.g., C:\\Scripts\\Subfolder1) and check all the files. If appropriate, we then echo back the folder path, indicating that folder doesn\u2019t have a single file that has been modified in the past 90 days. <\/P>\n<P>That takes care of Subfolder1. However, before we go on to Subfolder2 we execute this line of code:<\/P><PRE class=\"codeSample\">ShowSubFolders objSubfolder\n<\/PRE>\n<P>That\u2019s right: even though we\u2019re already in the subroutine ShowSubFolders we go ahead and call ShowSubFolders again. (Weird, but that\u2019s what recursion is all about.) What that\u2019s going to do is cause the script to repeat this process with any subfolders of C:\\Scripts\\Subfolder1, then repeat it again on any sub-subfolders of C:\\Scripts\\Subfolder1. Only when we finally run out of subfolders will we jump back to the top of our original For Each loop and start checking C:\\Scripts\\Subfolder2.<\/P>\n<TABLE id=\"EPH\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. Yes, it <I>is<\/I> kind of hard to visualize, isn\u2019t it? Fortunately, however, you don\u2019t have to understand how recursion works and how the script keeps track of where it is and where it needs to go next. VBScript does all that for you.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>And that\u2019s all we have to do, When the script finishes we\u2019ll see, onscreen, a list of any folders (or subfolders) in which none of the files have been modified in the past 90 days. Which is nice, because that\u2019s what we were hoping to see. <\/P>\n<TABLE id=\"E5H\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. We should note that this script is designed to work only on the local computer; that\u2019s because MM didn\u2019t need it to work against a remote computer. Could it be modified to perform this same task against a remote machine? No, not really; instead it would have to be completely rewritten using WMI rather than the FileSystemObject. We don\u2019t really have any plans to tackle that \u2013 it\u2019s a bit gnarly, to say the least \u2013 but if there\u2019s enough interest we\u2019ll see what we can do. Just <A href=\"mailto:scripter@microsoft.com?subject=Hey, Scripting Guy!\"><B>let us know<\/B><\/A>.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>That should do it for today, MM, and that should do it for 2007 as well. Have a happy holiday everyone (even you, Scripting Editor!) and we\u2019ll see you all back here on January 2, 2008.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! On my file servers I periodically want to check a folder to see if that folder or any of its subfolders have files that are no longer being updated. What I\u2019d like to do is check each file in each folder to see if they\u2019ve been modified in the past 90 days. [&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-63383","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! On my file servers I periodically want to check a folder to see if that folder or any of its subfolders have files that are no longer being updated. What I\u2019d like to do is check each file in each folder to see if they\u2019ve been modified in the past 90 days. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63383","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=63383"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63383\/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=63383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}