[Solved] In Powershell, how to copy files with common file name string (i.e. “ABC*”) last written in a specific date range?


This is a common task, here’s the general approach we take to solving an issue like this in PowerShell.

  1. Get a list of files, VMs, Items, ETC
  2. Pipe this into the Where-Object cmdlet to filter and apply one or more constraints
  3. That’s it!

With your requirements, we’ll actually do Step 2 in two separate steps, to highlight the approach needed. I choose a different date range (From Sept 1 ~ Sept 30) but once you understand the concepts, you’ll know how to change this to fit your needs. To start things off, here is the directory I’m testing against (pay close attention to the LastWriteTime column).

Mode                LastWriteTime         Length Name                                                                                           
----                -------------         ------ ----                                                                                           
-a----        9/22/2017   3:40 PM          64307 AcfBIns.jpg                                                                                    
-a----        9/23/2017  10:15 PM           7047 beer-mug_1f37a.png                                                                             
-a----        6/30/2017  12:15 PM          63304 bg.png                                                                                         
-a----        9/20/2017  10:07 AM            938 certnew (1).p7b                                                                                
-a----         6/1/2017  12:42 PM            822 DistributeMe.cer                                                                               
-a----        7/27/2017   3:38 PM          95234 EFIESP.png                                                                                     
-a----         7/5/2017   2:37 PM        1920416 Encoding Time.csv                                                                              
-a----        9/22/2017   3:46 PM       66932648 en_remote_tools_for_visual_studio_2015.exe                               
-a----        5/26/2017  12:31 PM            306 F0X_PPKG_PROD.cat                                                                              
-a----        5/26/2017  12:31 PM           5529 F0X_PPKG_PROD.ppkg                                                                             
-a----        6/23/2017   3:29 PM          50541 Fox.jpg                                                                                        
-a----         7/8/2017   1:20 AM          10240 GetStats.exe                                                                                   
-a----       10/12/2017   9:49 AM         126868 GIF.gif                                                                                        
-a----        9/21/2017   9:28 AM       10427442 giphy (1).gif                                                                                  

First, a baseline of my folder to see how many items are there.

dir C:\source | measure | select Count
>Count : 14

Now, for Step 2, building a filter: I’ll start by making a pointer to my earliest file start date, using the Get-Date cmdlet. This will give me an ‘earliest file age’ to compare against.

$Sept1  = Get-Date -Year 2017 -Month 09 -Day 01

Here’s the cool part, I can filter the files by looking only for ones Modified AFTER the date contained in $Sept1 with one simple command, the Where-Object cmdlet. In DotNet terms, Greater Than refers to after a date, while Lesser Than refers to taking place before a date.

dir c:\source | where LastWriteTime -ge $Sept1 | measure | select Count
> Count : 6

After applying the first half of the filter, I have a list of only files modified beginning with September 1st. You can then add an additional Where-Object command to narrow down to just your desired timespan like so:

#Make a pointer to the end of Sept
$Sept30 = Get-Date -Year 2017 -Month 09 -Day 30
dir c:\source | where LastWriteTime -ge $Sept1 |
    Where LastWriteTime -le $Sept30 | measure | select Count

>Count : 5

Now, just modify the dates to match your timespan and I think you can get this problem solved.

Older versions of PowerShell

Did you get an error like "cannot bind parameter 'FilterScript'. Cannot convert the 'LastWriteTime" value of type System.String to type "System.Management.Automation.ScriptBlock", if so, then try this syntax instead.

 $Sept30 = Get-Date -Year 2017 -Month 09 -Day 30 
 dir \\0.0.0.100\C$\source | where {$_.LastWriteTime -ge $Sept1} | 
   where {$_.LastWriteTime -le $Sept30} | measure | select Count

4

solved In Powershell, how to copy files with common file name string (i.e. “ABC*”) last written in a specific date range?