Powershell script to copy files at multiple destinations using regex

By | February 15, 2018

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

[code language=”powershell”]
<# 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
[/code]

Source Code

[code language=”powershell”]
# 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
}
}

[/code]

Vishal Monpara is a full stack Solution Developer/Architect with 13 years of experience primarily using Microsoft stack. He is currently working in Retail industry and moving 1’s and 0’s from geographically dispersed hard disks to geographically dispersed user leveraging geographically dispersed team members.

Leave a Reply

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