<# 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

 

    }

 

}