Knowledge.ToString()

Powershell Script to Copy Files at Multiple Destinations Using Regex

Here is a parameterized Powershell script to copy the files from one location to multiple destinations. You can also rename the files and use various date formats to put the files in yearly/monthly folder. Once the files are successfully copied, you have an option to delete the file from source location.

Usage

<# Explanation - Source Excel file name contains 4 digit store number (example: "Report_Store_0278.xlsx"). We want to copy those files to "business" folder with only store number (i.e. "0278.xlsx") and also archive the same file in a folder with today's date (i.e. "archive\20180215\0278.xlsx"). Once copied, we want to delete the files from source folder.
#>
CopyFiles.ps1 -SourcePath '\\networklocation\source\' -SourceFilePattern 'Report_Store_\[([0-9]{4})\].*.xlsx' -CopyFiles '\\networklocation\business\${1}.xlsx','\\networklocation\archive\%date{yyyyMMdd}\${1}.xlsx' -DeleteSource 1

Source Code

# Copy the following code into a file called CopyFiles.ps1
param(
     
    [string]$SourcePath = $(throw "SourcePath param required"),
    [string]$SourceFilePattern = $(throw "$SourceFilePattern param required"),
    [string[]] $CopyFiles = $(throw "CopyFiles param required"),
    [int] $DeleteSource = 0
)
 
<#
$SourceFile = "C:\Temp\Opterus\Source\S([0-9]+).*.xls"
$CopyFiles = @("C:\Temp\Opterus\Destination\*.*", "C:\Temp\Opterus\Archive\%date{yyyyMMdd}\S`${1} Merchandise Report.xls")
$DeleteSource = $true
#>
 
$DateEvaluator = 
{  
  param($m) 
  $date = [DateTime]::Now
    $date.ToString($m.Groups[1].Value)
}
 
Write-Host "[Source:]" $SourcePath$SourceFilePattern
Write-Host "[Copy To:]" $CopyFiles
Write-Host "[Delete?:]" $DeleteSource
 
# replace date token in source path if any
$SourcePath = [Regex]::Replace($SourcePath, '%date{(.+?)}', $DateEvaluator)
$SourceFilePattern = [Regex]::Replace($SourceFilePattern, '%date{(.+?)}', $DateEvaluator)
 
$matchedFiles = Get-ChildItem -Path $SourcePath | Where-Object {($_.Name -match $SourceFilePattern)}
# Check if the files found
if (($matchedFiles -eq $null) -or ($matchedFiles.Count -eq 0))
{
    # Files not found so exit the script
    Write-Host "No files found"
    Exit
}
 
foreach($CopyFile in $CopyFiles)
{
    $CopyFile = [Regex]::Replace($CopyFile, '%date{(.+?)}', $DateEvaluator)
    $DestPath = Split-Path $CopyFile -Parent
    $DestFilePattern = Split-Path $CopyFile -Leaf
     
    # Loop through each files
    foreach ($file in $matchedFiles) {
        $destFileName = ""
        if($DestFilePattern -and $DestFilePattern -ne '*.*')
        {
            $destFileName = $file.Name -ireplace $SourceFilePattern, $DestFilePattern
        }
        else
        {
            $destFileName = $file.Name;
        }
         
        Write-Host "[Source File] ["$file.FullName"]"
     
        # If the directory does not exists, create one
        if ((Test-Path $DestPath) -eq $false)
        {
            New-Item -ItemType Directory -Force -Path $DestPath
        }
         
        # Copy file
        Copy-Item -LiteralPath $file.FullName -Destination ($DestPath + "\\" + $destFileName)
        Write-Host "[Copy File] ["$DestPath\$destFileName"]"
    }
}
 
if($DeleteSource -eq 1)
{
    foreach ($file in $matchedFiles) {
        Write-Host "[Delete File] ["$file.FullName"]"
        Remove-Item  -LiteralPath $file.FullName
    }
}

Share

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *