<# FPS:Containers:Make:Public:Sync-FileCabinet:ACTIVE
#>
function Sync-FileCabinet {
<#
.DESCRIPTION
Module: Make
Public CmdLet:
Sync-FileCabinet.ps1
Dependencies: Get-Folder.ps1, Update-Log.ps1,
Remove-DirTree.ps1, Move-SingleFile.ps1, (Get-Answer.ps1)
This function performs a sync operation from a cloud file
cabinet tranistional location to a current
location. Designed to only be used via
shortcut, it can be used to keep directories sync'd in
other places also if run interactively.
Called when updates may be needed. If called without the -Sync switch the
process only outputs the results without performing the actions.
files.
.EXAMPLE
if (Push-NeededFor Sync-FileCabinet)
{ . (Get-ActiveFileNm -PS1
Sync-FileCabinet) }
$pSource = '[source]'
$pTarget = '[target]'
$pSync = $true
if ($global:Pro_CI.CI
-ne 'DESKTOP-A9GTPL1') {
Write-Host
("This process can only run on "+$makLoc_FileCabinetCurrentCI+".")
return
} else {
if ($pSync) {
Sync-FileCabinet -Source $pSource
-Target $pTarget -Sync
} else {
Sync-FileCabinet -Source $pSource
-Target $pTarget
}
}
.CC
[2025.03.16 JD] Original code release
.NOTES
If the -Sync option was sent, then the source will be
removed after copying over to the target.
If you want to keep a file in the source, just
copy the target file back to the source and since they
have the same timestamp it will not get removed from the source.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)] [string]$Source,
[Parameter(Mandatory=$false)] [string]$Target,
[Parameter(Mandatory=$false)] [switch]$Sync
)
#region Initialization
$testCmdLet, $overrideTestSnippet, $overrideSnippet = "", "", "" # Initialize override variables
. (Get-ActiveFileNm -PS1 Initialize-Make-Locations)
. (Get-ActiveFileNm -PS1 Load-Make-Dependencies)
#endregion
if ($global:Pro_CI.CI -ne $makLoc_FileCabinetCurrentCI) {
Write-Host ("This process can only run on "+$makLoc_FileCabinetCurrentCI+".")
return
} else {
$sfpBuffer = "Info*Process starting ... copy $Source to $Target."
#Organize the directories.
if ($Source -gt "") {
$SourceContainer = $Source } else { $SourceContainer = Get-Answer "Enter the FileCabinet
source container location: " }
if ($Target -gt "") {
$TargetContainer = $Target } else { $TargetContainer = Get-Answer "Enter the FileCabinet
target container location: " }
# First, Check for new folders
that will be necessary in the target
$srcFiles = Get-Folder $SourceContainer
$srcPaths = Get-ChildItem -Path $SourceContainer -Recurse -Directory -Force -ErrorAction SilentlyContinue | Select-Object FullName
foreach ($srcPath in $srcPaths) {
$tgtPath = $srcPath.FullName.Replace($SourceContainer,$TargetContainer)
if (-not (Test-Path $tgtPath)) {
# If Sync has been specified, create the
directory - otherwise just print it out.
if ($PSBoundParameters.Sync -eq $true) {
mkdir $tgtPath | Out-Null
$sfpBuffer += "|Info*Missing Directory on target
created - $tgtPath"
} else {
$sfpBuffer += "|Info*Missing Directory on target
would have been created - $tgtPath"
}
}
}
$tgtFileSet = $tgtFiles | Select LastWriteTime, FullName, Name
$srcFileSet = $srcFiles | Select LastWriteTime, FullName, Name
# Dates, when matched, have to both be converted to UTC
so they are in alignment with their timezone.
function local:getLastWriteTimeUtc([string]$path) {
try {
Get-Date -Date (Get-Item $path).LastWriteTimeUtc.ToString('yyyy-MM-dd HH:mm:ss')
} catch { }
}
# Now that the directories are sync'd, make sure the
files are sync'd. Check for missing and
updated files (timestamp mismatch)
foreach ($srcFile in $srcFileSet) {
$tgtFile = Get-ChildItem -Path ($srcFile.Fullname.replace($Source,$Target)) -Force -ErrorAction SilentlyContinue | Select-Object LastWriteTime, FullName, Name
if ($tgtFile.FullName -gt "") {
$utcSrc = getLastWriteTimeUtc $srcFile.FullName
$utcTgt = getLastWriteTimeUtc $tgtFile.FullName
if ($utcSrc -ne $utcTgt) {
if ($PSBoundParameters.Sync -eq $true) {
[string]$sfpBufferCast = "Source/Target timestamp mismatch for
"+$tgtFile.FullName+" and will be replaced and removed from source -
"+$utcSrc.toString()+"-"+$utcTgt.toString()
$sfpBuffer += "|Info*"+$sfpBufferCast
Move-SingleFile -SourceFile $srcFile.FullName -TargetFile $tgtFile.FullName -KeepSource 'NO' -KeepTarget 'NO'
} else {
[string]$sfpBufferCast = "Source/Target timestamp mismatch for
"+$tgtFile.FullName+" and would have been replaced and removed from
source - "+$utcSrc.toString()+"-"+$utcTgt.toString()
$sfpBuffer += "|Info*"+$sfpBufferCast
}
} else {
[string]$sfpBufferCast = "Source/Target timestamp match for
"+$tgtFile.FullName+" and will not be replaced or removed."
$sfpBuffer += "|Info*"+$sfpBufferCast
}
} else {
$tgtFile = $srcFile.Fullname.replace($Source,$Target)
if ($PSBoundParameters.Sync -eq $true) {
# First make sure the path exists
$sink = Mount-Path (Split-Path -Path $srcFile.FullName -Parent)
[string]$sfpBufferCast = "Target file missing and will be added
and removed from source - "+$tgtFile
$sfpBuffer += "|Info*"+$sfpBufferCast
Move-SingleFile -SourceFile $srcFile.FullName -TargetFile $tgtFile -KeepSource 'NO' -KeepTarget 'NO'
} else {
[string]$sfpBufferCast = "Target file missing and would have
been added - "+$tgtFile
$sfpBuffer += "|Info*"+$sfpBufferCast
}
}
}
# Write the completion message
$sfpBuffer += "|Info*Process complete ... copy $Source to $Target."
Update-Log -Sev "Buffered" -Module "Make" -Element "Sync-FileCabinet" -Buffer $sfpBuffer -LogFile $makLoc_Logs -Buffered
}
}