Move files based on Date Time using PowerShell

This post shows how we can use PowerShell to move files from one folder to another say while Archiving the files.

$SrcFolder = "C:\Files"
$DestFolder = "C:\Backup\2017"
$count = 0

 if(-not (Test-Path $DestFolder)){
        New-Item -Path $DestFolder -ItemType Directory
 }
 else{
    Write-Host $DestFolder "Path exists"
 }

 Get-ChildItem -Path $SrcFolder | Where-Object {$_.LastWriteTime -lt (Get-Date).AddMonths(-13)} | ForEach-Object {
    
    Write-Host "Moving: " $SrcFolder"\"$_ $_.LastWriteTime to $DestFolder
    Move-Item -Path $SrcFolder"\"$_ -Destination $DestFolder
    $count = $count + 1
 }

 Write-Host "Moved" $count "items."

The above code takes each item found in the Source Folder and checks LastWriteTime say for 13 months earlier, and moves the file to the Destination folder.

The command used to Move the files is Move-Item which takes -Path and -Destination as parameters.

We have the following tasks that requires to be done on a Windows Server 2012 R2 for this example using PowerShell:

  1. Archive Files from a Source Folder to Destination Folder (could be a Shared folder on the Network) based on time-stamp, only for files older than 2 years in this example.
  2. It takes 2 parameters, Year parameter is mandatory. Destination Folder is optional. Both Source and Destination are however hard-coded into the script.
  3. The script creates a folder with Year as folder-name at the Destination and Archive all the files for that year in the created folder.
  4. A log file is created in the same path on which the script is running under the Logs folder. All Archiving activity including any errors faced for any files are logged.
  5. The progress of the Archiving Files is also shown in the Console.
  6. Errors are handled like no files or folder found for the Year Parameter.
  7. The user running the script has to be an Administrator on the Machine. The Script has to be running in the Admin Mode.
param(
      [Parameter(Mandatory=$True)]
      [int]$Year,      
      [Parameter()]
      [String]$DestinationFolder
      )


Add-Type -AssemblyName System.Windows.Forms

$SourceFolder = "C:\TestSource"
$Date=((Get-Date).AddYears(-2).Year)

if ($Year -gt $Date) 
     {
     [System.Windows.Forms.MessageBox]::Show("Only Process the documents before Year $Date")
     break
     }

if($DestinationFolder -eq "")
  {
  $DestinationFolder = "\\TestDestinationFolder"
  } 

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
[System.Windows.Forms.MessageBox]::Show("Please run powershell application as administator")
break
}

$i=0
$DirectoryChain=(Get-ChildItem -Path $SourceFolder -Recurse)
$DirCount=$DirectoryChain.Count
$time=Get-Date
$DirectoryChain |
ForEach-Object {

$FileYear = (Get-Date($_.LastWriteTime)).Year

      if($FileYear -eq $Year){

        ########Creating Log File############
        if(!(Test-Path -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt"))
           { 
           Write-Host "Starting Data Archiving Process for $Year" -BackgroundColor Green        
           New-Item -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt" -ItemType File -Value "Archival Process Started at $(Get-Date)
==================================================================================================================================
"          
            if(!(Test-Path -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt")){[System.Windows.Forms.MessageBox]::Show("Log File could not created and exiting script")
               break}
            }
        
         try {

           if(Test-Path -Path "$DestinationFolder\$FileYear")
               {  
               Move-Item -LiteralPath $_.FullName -Destination "$DestinationFolder\$FileYear" -ErrorAction Ignore
               "Moved '$_' to $DestinationFolder\$FileYear successfully at $(Get-Date)" | add-content ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt"
               $i++
               }
            else
               {
               New-Item -Path "$DestinationFolder\$FileYear" -ItemType Directory -ErrorAction Ignore
               Move-Item -LiteralPath $_.FullName -Destination "$DestinationFolder\$FileYear"
               "Moved '$_' to $DestinationFolder\$FileYear successfully at $(Get-Date)" | add-content ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt"
               $i++
               }

           $Remaining=$DirCount-$i
           [int]$PercentageStat=(($i/$DirCount)*100)
           
           Write-Progress -Activity "Archival Document Process" -Status "Archiving Document $_  $i" -PercentComplete $PercentageStat
           #Start-Sleep -Seconds 2


            }
         Catch
            {
             "Error in moving object $_.FullName" | add-content ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt"
            }
          }

}


######Checking for existence of log file and appending comment in log file"########
if(Test-Path -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt")
{"===================================================================================================================================
Archival Processs Finished at $(Get-date)" | add-content ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt"

Write-Host "Data Archiving Process Finished, Total files/folders Archived $i" -BackgroundColor Green

Write-Host "Archival Processs Finished at $(Get-date), Please check the log file Archive $(($time).ToString("MM-dd-yyyy HH-MM")).Txt on Location $(Get-Item -Path ".\")" -BackgroundColor Green -ForegroundColor Blue

If(!(Test-Path -Path ".\Logs"))
     {
      New-Item -Path .\ -ItemType Directory -Name "Logs"
      Move-Item -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt" -Destination ".\Logs"
      Write-Host "Log File .\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt has been moved to $(Get-Item -Path ".\Logs")" -BackgroundColor Green -ForegroundColor White 
     }
else{
      Move-Item -Path ".\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt" -Destination ".\Logs"
      Write-Host "Log File .\Archive $(($time).ToString("MM-dd-yyyy hh-mm tt")).Txt has been moved to $(Get-Item -Path ".\Logs")" -BackgroundColor Green -ForegroundColor White 
     }
}

else
{
Write-Host "No files or folder found for $Year" -BackgroundColor Green -ForegroundColor White
}

The script can be run in PowerShell Console Admin mode as below:

./Archive_files.ps1 -Year 2016

Optional Parameter $Destination Folder can be ignored as it is hard-coded in the script. You can pass it if the Destination folder is different.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.