I work with a lot of time-stamped CSV files generated automatically by a system we have. I’d like to write scripts to manipulate these files to compare system status from one moment to the next, but first I want to copy them as a backup in case I want to revert changes.
I’ve decided to create a Backup-File function in my $profile to call in all my scripts, I hope that’s the right move. I would like to create a function that works for any filetype, not just CSVs. In theory it would take all the files in the working directory and copy them into a subfolder therein, adding a " (Copy #)" to the end of the filename …before the extension… to preserve all copies. I spent all damn day working on this and I’ve come up with a nice chunk of code that just doesn’t seem to work.
I can select parts of it and walk through the script in parts, without getting an error, and I see the files being created properly. But when I run the whole thing, it doesn’t do anything!
I’ve even gone so far as to start putting in Write-Debug lines but those don’t work either unless I select those smaller blocks individually.
To test this script, create a temp folder with some files of any type, run the script in that directory, and see if the files you created were copied to a new subfolder under your temp folder. Run it again, to see if a 2nd set is created with different names.
function Backup-File ([string]$BkpFolder = "Backup", [string]$FileType = "*")
{
$DebugPreference = "Continue"
# Create target path if it doesn't exist
{
if (-not (Test-Path $BkpFolder))
{
New-Item -Path $BkpFolder -ItemType directory |out-null
}
} # END ... path if it doesn't exist
# Master object to variable
{
$FileObjects = Get-ChildItem ("*." + [string]$FileType) | Sort-Object Length -Descending
} # END ... to variable
# Introduce variables for backup file copy operation, so the destination can be different if needed.
{
[int]$i = $FileObjects.Count - 1
While ($i -gt -1) {
Write-Debug 'While $i > -1 ... Setting 3 variables'
Set-Variable -Name ("SourceFileObject" + [string]$i) -Value $FileObjects[$i]
Set-Variable -Name ("DestinationFilename" + [string]$i) -Value $FileObjects[$i].Name
Set-Variable -Name ("DestinationFilePath" + [string]$i) -Value (".\" + ($BkpFolder) + "\" + ($FileObjects[$i]).Name)
# Incrementally rename the file instead of overwriting any existing.
{
# Check to see if the dest filename matches the path filename of the source
If (Test-Path -Path ((Get-Variable -Name ("DestinationFilePath" + [string]$i)).Value))
{
Write-Debug 'If $DestinationFilename# exists in target ... find a new name'
# Iterate until you have a unique filename
$j = 2
While (Test-Path -Path ((Get-Variable -Name ("DestinationFilePath" + [string]$i)).Value))
{
Write-Debug 'While $DestinationFilename# exists in target ... change name'
$copyJ = (" (Copy " + [string]$j + ")")
Set-Variable -Name ("DestinationFilePath" + [string]$i) `
-Value (".\" + ($BkpFolder) + "\" `
+ ($FileObjects[$i].Name).TrimEnd($FileObjects[$i].Extension) `
+ $copyJ + $FileObjects[$i].Extension)
$j += 1
}
}
Write-Debug 'Copying file to target'
Copy-Item -Path $FileObjects[$i] `
-Destination ((Get-Variable -Name ("DestinationFilePath" + [string]$i)).Value) `
-Force
} # END rename the file instead of overwriting any existing.
Write-Debug 'Done copying ... Subtract 1 from $i and loop. '
$i -= 1
}
} # END variables for backup file copy operation, so the destination can be different if needed.
Write-Debug "End of function"
} # END Function
Also, It’s been a long day for my brain and I may not be choosing the best implementation do accomplish my goals.
Also wondering if I should I have used a cmdlet instead of a function?
Thanks. ![]()