|
[Flags()] Enum RoboCopyExitCodes{ |
|
NoChange = 0 |
|
OKCopy = 1 |
|
ExtraFiles = 2 |
|
MismatchedFilesFolders = 4 |
|
FailedCopyAttempts = 8 |
|
FatalError = 16 |
|
} |
|
|
|
Class RoboCopy{ |
|
[String]$Source |
|
[String]$Destination |
|
[String]$LogDir |
|
[String]$JobID |
|
[String]$Options |
|
[String[]]$WildCards |
|
[PSObject[]]$rcCMDs |
|
[PSObject[]]$rcExitCodes |
|
|
|
#default constructor |
|
RoboCopy(){} |
|
|
|
#constructor |
|
RoboCopy([String]$src,[String]$des,[String]$jid,[String]$ld,[string[]]$wc){ |
|
$this.Source = $src |
|
$this.Destination = $des |
|
$this.JobID = $jid |
|
$this.LogDir = $ld |
|
$this.WildCards = $wc |
|
} |
|
|
|
[PSCustomObject]VerifyPaths(){ |
|
|
|
return [PSCustomObject]@{ |
|
Source = $(Test-Path -Path $this.Source) |
|
Destination = $(Test-Path -Path $this.Destination) |
|
LogDirectory = $(Test-Path -Path $this.LogDir) |
|
} |
|
} |
|
|
|
StartRCProcess($source,$target,$params,$logFile,$tag){ |
|
#Save RoboCopy Command |
|
$MessageData = $('robocopy "{0}" "{1}" {2} {3}' -f $source,$target,$($params -join ' '),$logFile) |
|
$this.rcCMDs += Write-Information -MessageData $MessageData 6>&1 -Tags $tag | Select-Object * |
|
|
|
#Execute Process |
|
$rcArgs = "`"$($source)`" `"$($target)`" $params $logFile" |
|
$rcResult = Start-Process robocopy -ArgumentList $rcArgs -WindowStyle Hidden -PassThru -Wait |
|
|
|
#Save ExitCode |
|
$this.rcExitCodes += [PSCustomObject]@{ |
|
ExitCode = [RoboCopyExitCodes]$rcResult.ExitCode |
|
StartTime = $rcResult.StartTime |
|
ExitTime = $rcResult.ExitTime |
|
rcCMD = $MessageData |
|
} |
|
} |
|
|
|
ExecuteRCCMD($source,$target,$params,$logFile,$tag){ |
|
#Save RoboCopy Command |
|
$MessageData = $('robocopy "{0}" "{1}" {2} {3}' -f $source,$target,$($params -join ' '),$logFile) |
|
$this.rcCMDs += Write-Information -MessageData $MessageData 6>&1 -Tags $tag | Select-Object * |
|
|
|
#Execute Robocopy CMD |
|
$rcArgs = @("$($source)","$($target)",$params,$logFile) |
|
robocopy @rcArgs |
|
} |
|
|
|
Mirror(){ |
|
$tag = @('Mirror',$this.JobID) |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@('/MIR','/E','/BYTES','/NP','/NDL','/R:1','/W:1')) |
|
|
|
$logFile = '/LOG:{0}\mirror-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
$this.StartRCProcess($this.Source,$this.Destination,$params,$logFile,$tag) |
|
#$this.ExecuteRCCMD($this.Source,$this.Destination,$params,$logFile,$tag) |
|
} |
|
|
|
Move(){ |
|
$tag = @('Move',$this.JobID) |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@('/COPY:DATS','/DCOPY:T','/SECFIX','/BYTES','/S','/E','/NP','/NDL','/R:1','/W:1','/MOVE')) |
|
|
|
$logFile = '/LOG:{0}\move-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
#$this.StartRCProcess($this.Source,$this.Destination,$params,$logFile,$tag) |
|
$this.ExecuteRCCMD($this.Source,$this.Destination,$params,$logFile,$tag) |
|
} |
|
|
|
RollBack(){ |
|
$tag = @('RollBack',$this.JobID) |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@('/COPY:DATS','/DCOPY:T','/SECFIX','/BYTES','/S','/E','/NP','/NDL','/R:1','/W:1','/MOVE')) |
|
|
|
$logFile = '/LOG:{0}\rollback-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
#$this.StartRCProcess($$this.Source,$this.Destination,$params,$logFile,$tag) |
|
$this.ExecuteRCCMD($this.Destination,$this.Source,$params,$logFile,$tag) |
|
} |
|
|
|
Sync(){ |
|
$tag = @('Sync',$this.JobID) |
|
|
|
#Excluded Files & Directories |
|
$XF = @( |
|
'/XF' |
|
'thumbs.db' |
|
'~*.*' |
|
'*.pst' |
|
'desktop.ini' |
|
'*.lnk' |
|
) |
|
$XD = @( |
|
'/XD' |
|
"`$Recycle.bin" |
|
'Boot Recycler' |
|
'IECompatCache' |
|
'IEDownloadHistory' |
|
'Cookies' |
|
'WINDOWS' |
|
'PrivacIE' |
|
"`"System Volume Information`"" |
|
) |
|
|
|
$Excluded = "$($XF -join ' ') $($XD -join ' ')" |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@($($this.WildCards),'/COPY:DATS','/SECFIX','/BYTES','/S','/PURGE','/E','/NP','/NDL','/R:1','/W:1')) |
|
|
|
$logFile = '/LOG:{0}\sync-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
#Save RoboCopy Command |
|
$arrMessageDataInput = @( |
|
$this.Source |
|
$this.Destination |
|
$($params -join ' ') |
|
$($this.Options -join ' ') |
|
$Excluded |
|
$logFile |
|
) |
|
$MessageData = $('robocopy "{0}" "{1}" {2} {3} {4} {5}' -f $arrMessageDataInput ) |
|
$this.rcCMDs += Write-Information -MessageData $MessageData 6>&1 -Tags $tag | Select-Object * |
|
|
|
#Execute Robocopy CMD |
|
$rcArgs = @("$($this.Source)","$($this.Destination)",$params,$XF,$XD,$logFile) |
|
robocopy @rcArgs |
|
} |
|
|
|
GetListSource(){ |
|
$tag = @('ListSRC',$this.JobID) |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@($($this.WildCards),'/L','/S','/E', '/BYTES','/FP','/NC','/NDL','/TS','/R:0','/W:0')) |
|
|
|
$logFile = '/LOG:{0}\listSRC-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
$this.StartRCProcess($this.Source,'NULL',$params,$logFile,$tag) |
|
#$this.ExecuteRCCMD($this.Source,$this.Destination,$params,$logFile,$tag) |
|
} |
|
|
|
GetListDestination(){ |
|
$tag = 'ListDES' |
|
$params = New-Object System.Collections.Arraylist |
|
$params.AddRange(@($($this.WildCards),'/L','/S','/E','/BYTES','/FP','/NC','/NDL','/TS','/R:0','/W:0')) |
|
|
|
$logFile = '/LOG:{0}\listDES-{1}.log' -f $this.LogDir,$this.JobID |
|
|
|
#$this.StartRCProcess($this.Source,$this.Destination,$params,$logFile,$tag) |
|
$this.ExecuteRCCMD($this.Destination,'NULL',$params,$logFile,$tag) |
|
} |
|
|
|
static [PSCustomObject]GetLogSummary([String]$rcLogFile){ |
|
filter Get-CapacitySize { |
|
'{0:N2} {1}' -f $( |
|
if ($_ -lt 1kb) { $_, 'Bytes' } |
|
elseif ($_ -lt 1mb) { ($_/1kb), 'KB' } |
|
elseif ($_ -lt 1gb) { ($_/1mb), 'MB' } |
|
elseif ($_ -lt 1tb) { ($_/1gb), 'GB' } |
|
elseif ($_ -lt 1pb) { ($_/1tb), 'TB' } |
|
else { ($_/1pb), 'PB' } |
|
) |
|
} |
|
|
|
$rcLogSummary = [PSCustomObject]@{ |
|
Start = $null |
|
End = $null |
|
LogFile = $null |
|
Source = $null |
|
Destination = $null |
|
TotalDirs = $null |
|
CopiedDirs = $null |
|
FailedDirs = $null |
|
TotalFiles = $null |
|
CopiedFiles = $null |
|
FailedFiles = $null |
|
TotalBytes = $null |
|
CopiedBytes = $null |
|
FailedBytes = $null |
|
TotalTimes = $null |
|
Speed = $null |
|
} |
|
|
|
$rcLogSummary.LogFile = $rcLogFile.Split('\')[-1].ToLower() |
|
|
|
$logFileContent = Get-Content $rcLogFile -Raw |
|
|
|
[regex]$regex_Start = 'Started\s:\s+(?<StartTime>.+[^\n\r])' |
|
if ($logFileContent -match $regex_Start){ |
|
$rcLogSummary.Start = $Matches['StartTime'] |
|
} |
|
|
|
[regex]$regex_End = 'Ended\s:\s+(?<EndTime>.+[^\n\r])' |
|
if ($logFileContent -match $regex_End){ |
|
$rcLogSummary.End = $Matches['EndTime'] |
|
} |
|
[regex]$regex_Source = 'Source\s:\s+(?<Source>.+[^\n\r])' |
|
if($logFileContent -match $regex_Source){ |
|
$rcLogSummary.Source = $Matches['Source'].Tolower() |
|
} |
|
|
|
[regex]$regex_Target = 'Dest\s:\s+(?<Target>.+[^\n\r])' |
|
if($logFileContent -match $regex_Target){ |
|
$rcLogSummary.Destination = $Matches['Target'].ToLower() |
|
} |
|
|
|
[regex]$regex_Dirs = 'Dirs\s:\s+(?<TotalDirs>\d+)\s+(?<CopiedDirs>\d+)(?:\s+\d+){2}\s+(?<FailedDirs>\d+)\s+\d+' |
|
if ($logFileContent -match $regex_Dirs){ |
|
$rcLogSummary.TotalDirs = [int]$Matches['TotalDirs'] |
|
$rcLogSummary.CopiedDirs = [int]$Matches['CopiedDirs'] |
|
$rcLogSummary.FailedDirs = [int]$Matches['FailedDirs'] |
|
} |
|
|
|
[regex]$regex_Files = 'Files\s:\s+(?<TotalFiles>\d+)\s+(?<CopiedFiles>\d+)(?:\s+\d+){2}\s+(?<FailedFiles>\d+)\s+\d+' |
|
if ($logFileContent -match $regex_Files){ |
|
$rcLogSummary.TotalFiles = [int]$Matches['TotalFiles'] |
|
$rcLogSummary.CopiedFiles = [int]$Matches['CopiedFiles'] |
|
$rcLogSummary.FailedFiles = [int]$Matches['FailedFiles'] |
|
} |
|
|
|
[regex]$regex_Speed = 'Speed\s:\s+(?<Speed>.+\/min)' |
|
if ($logFileContent -match $regex_Speed){ |
|
$rcLogSummary.Speed = $Matches['Speed'] |
|
} |
|
|
|
$arrBytes = @( |
|
'Bytes\s:\s+(?<TotalBytes>(\d+\.\d+\s)[bmg]|\d+)\s+' #TotalBytes |
|
'(?<CopiedBytes>\d+.\d+\s[bmg]|\d+)\s+' #CopiedBytes |
|
'(?:(\d+.\d+\s[bmg]|\d+)\s+){2}' #Skip two |
|
'(?<FailedBytes>\d+.\d+\s[bmg]|\d+)' #FailedBytes |
|
) |
|
|
|
[regex]$regex_Bytes = -join $arrBytes |
|
if ($logFileContent -match $regex_Bytes){ |
|
$rcLogSummary.TotalBytes = [int64]$Matches['TotalBytes'] | Get-CapacitySize |
|
$rcLogSummary.CopiedBytes = [int64]$Matches['CopiedBytes'] | Get-CapacitySize |
|
$rcLogSummary.FailedBytes = [int64]$Matches['FailedBytes'] | Get-CapacitySize |
|
} |
|
|
|
[regex]$regex_Times = 'Times\s:\s+(?<TotalTimes>\d+:\d+:\d+)' |
|
if ($logFileContent -match $regex_Times){ |
|
$rcLogSummary.TotalTimes = $Matches['TotalTimes'] |
|
} |
|
|
|
return $rcLogSummary |
|
} |
|
|
|
[String]GetRoboCopyCMD(){ |
|
$paramRoboCopy = @( |
|
$this.Source |
|
$this.Destination |
|
$($this.WildCards -join ' ') |
|
$this.Options |
|
$('/LOG:{0}\{1}.log' -f $this.LogDir,$this.JobID) |
|
) |
|
|
|
return $('robocopy "{0}" "{1}" {2} {3} {4}' -f $paramRoboCopy) |
|
} |
|
} |