Advertisement
Guest User

Initialize-RobocopyJob

a guest
Jul 16th, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Function Initialize-RobocopyJob {
  2.     <#
  3.         .SYNOPSIS
  4.             Executes Robocopy to recursively copy a specified directory to any location.
  5.         .DESCRIPTION
  6.             Launches Robocopy.exe (assumed to be included with the OS) with parameters supplied via arguments or optionally in batch mode reading data from a CSV or XLSX file.
  7.             Current default options are to recursively copy data while preserving security ACLs, Ownership, and Timestamps information.
  8.             Log files are created in a LOGS directory at the current path of execution. If the LOGS directory does not exist it will be created.
  9.         .PARAMETER JobName
  10.             Optional field used in naming the transcript and copy job log files.
  11.         .PARAMETER SrcPath
  12.             The path of the folder to be copied as a string. Be sure to enclose in double quotes if the path contains a space in it.
  13.         .PARAMETER DestPath
  14.             The destination path the files should be copied to. If the -MIR switch is included then files in the destination path which are not in the source will be purged.
  15.         .PARAMETER DirExclusions
  16.             Partial or full folder names to be excluded. (see the Robocopy docs for the /XD parameter.)
  17.             Multiple entries should be passed in the form of an array. e.g. -DirExclusions ('Dir1','Dir2')
  18.         .PARAMETER FileExclusions
  19.             Partial or full file names to be excluded. (see the Robocopy docs for the /XF parameter.)
  20.             Multiple entries should be passed in the form of an array. e.g. -FileExclusions ('desktop.ini','*.exe')
  21.         .PARAMETER MIR
  22.             Optional switch specifying that Robocopy should be run the /MIR parameter which purges files from the destination that are not found in the source.
  23.             See Robocopy docs on /MIR for more info.  If not specified /E is ued instead which copies all subdirectories (including empty ones) but does not purge.
  24.         .PARAMETER DataMap
  25.             Instead of specifying -SrcPath and -DestPath you can provide the path to a CSV or XLSX file which will be parsed.
  26.             Each row of the datamap sheet will be a separate robocopy job. They will be run serially (not simultaneously) and will share a common transcript
  27.             log but have distinct Robocopy Job logs. The CSV or XLSX must contain the following headers as the first row of the file:
  28.             SourcePath, DestinationPath, DirExclusions, FileExclusions
  29.             SourcePath and DestinationPath must be filled out. Any lines missing one of those will be ignored.
  30.         .PARAMETER MonitorCopy
  31.             Optional switch that when specified will spawn a new PowerShell window which tails the Robocopy job log.
  32.             Nice for monitoring long jobs. Closing the spawned windows will not affect the job itself. The windows do not auto-close on job completion.
  33.         .PARAMETER NoTranscript
  34.             Optional parameter which disables the transcript logging.  Robocopy job logs are still created for each job.
  35.  
  36.         .NOTES
  37.             Name: Initialize-RoboCopyJob
  38.             Author: mOjO_mOjO
  39.             Version History:
  40.                  1.0 - Ported this over from another script.
  41.         .EXAMPLE
  42.             Initialize-RobocopyJob -JobName Dir1Copy -SrcPath "C:\Dir1" -DestPath "\\SERVER\SHARE\Dir1"
  43.  
  44.             Initiates a job to copy "Dir1".
  45.  
  46.         .EXAMPLE
  47.             Initialize-RobocopyJob -JobName "Dir1Copy" -SrcPath "C:\Dir1" -DestPath "\\SERVER\SHARE\Dir1" -MIR -FileExclusions ('*.lnk','desktop.ini') -MonitorCopy
  48.  
  49.             Initiates the same copy job but excluding .lnk files and files named "desktop.ini". Also uses the mirror option which purges any files from the destination
  50.             which are not in the source.
  51.     #>
  52.     [cmdletBinding(SupportsShouldProcess,ConfirmImpact="High")]
  53.     Param(
  54.         [String]$JobName,
  55.         [string][Alias('Path','SourcePath')]$SrcPath,
  56.         [string][Alias('Destination','DestinationPath')]$DestPath,
  57.         [array][Alias('XD')]$DirExclusions= @(),
  58.         [array][Alias('XF')]$FileExclusions= @(),
  59.         [switch][Alias('Mirror')]$MIR,
  60.         [string]$DataMap,
  61.         [switch]$MonitorCopy,
  62.         [string]$LogDir = $($pwd.Path + "\LOGS"),
  63.         [switch]$NoTranscript
  64.     )
  65.  
  66.     $StartTime = Get-Date
  67.     $DateString = (get-date -UFormat %Y%m%d%H%M)
  68.  
  69.     If (!$(Test-Path -PathType Container -Path $LogDir)) { New-Item -ItemType Directory -path $LogDir }
  70.     If (!$(Test-Path -PathType Container -Path $LogDir)) { Write-Host "Invalid log directory or unable to create $($LogDir). Exiting." -f Red; Return "ERROR" }
  71.  
  72.     If ($JobName) {
  73.         $LogPath = $LogDir + "\RoboCopy_" + $DateString + "_" + $($JobName | Remove-InvalidFileNameChars) + "_Log.txt"
  74.     } else {
  75.         $LogPath = $LogDir + "\RoboCopy_" + $DateString + "_Log.txt"
  76.     }
  77.  
  78.  
  79.     If (!$NoTranscript) {
  80.         try { stop-transcript | out-null } catch {}
  81.         start-transcript -Path $LogPath
  82.     }
  83.  
  84.     [array]$DataMigrationMap = @()
  85.  
  86.     if ($DataMap) {
  87.         $DataMapObj = Get-Item $DataMap -ErrorAction SilentlyContinue
  88.         If (!$DataMapObj) { Write-Host "`nInvalid or missing data mapping file specified. Check the path and try again." -f Red; try {Stop-Transcript} catch {}; Return "ERROR"}
  89.         If ($DataMapObj.Extension -notmatch '.csv|.xlsx') { Write-Host "`nInvalid mapping file type specified. Must be .xlsx or .csv file." -f Red; try {Stop-Transcript} catch {}; Return "ERROR"}
  90.         If ($Matches[0] -eq '.xlsx') {
  91.             $DataMigrationMap = Import-Excel -Path $DataMapObj.FullName
  92.             $DataMigrationMap = $DataMigrationMap | ?{$_.SourcePath -and $_.DestinationPath}
  93.             If (!$DataMigrationMap) { Write-Host "No valid data found in datamap file. Headers must be `"SourcePath`", `"DestinationPath`", and optional `"Exclusions`"" -f Red; try {Stop-Transcript} catch {}; Return "ERROR" }
  94.         } elseif ($Matches[0] -eq '.csv') {
  95.             $DataMigrationMap = Import-CSV -Path $DataMapObj.FullName
  96.             $DataMigrationMap = $DataMigrationMap | ?{$_.SourcePath -and $_.DestinationPath}
  97.             If (!$DataMigrationMap) { Write-Host "No valid data found in datamap file. Headers must be `"SourcePath`", `"DestinationPath`", and optional `"Exclusions`"" -f Red; try {Stop-Transcript} catch {}; Return "ERROR" }
  98.         }
  99.     } elseif ($SrcPath -and $DestPath) {
  100.         [array]$DataMigrationMap = [PSCustomObject]@{
  101.             SourcePath = $SrcPath
  102.             DestinationPath = $DestPath
  103.             DirExclusions = [array]$DirExclusions
  104.             FileExclusions = [array]$FileExclusions
  105.         }
  106.     }
  107.    
  108.     if ($DataMigrationMap) {
  109.         ForEach ($Entry in $DataMigrationMap) {
  110.             $EntryNum = "{0:00}" -f $($DataMigrationMap.IndexOf($Entry) + 1)
  111.             If ($JobName) {
  112.                 $CopyLog = $LogDir + "\RoboCopy_" + $DateString + "_" + $($JobName | Remove-InvalidFileNameChars) + "_" + $EntryNum + "_JobLog.txt"
  113.             } else {
  114.                 $CopyLog = $LogDir + "\RoboCopy_" + $DateString + "_" + $EntryNum + "_JobLog.txt"
  115.             }
  116.             $FullSrcPath = $Entry.SourcePath
  117.             $FullDestPath = $Entry.DestinationPath
  118.             [string]$exclSTR = $null
  119.             If ($Entry.DirExclusions) {
  120.                 $exclSTR += $Entry.DirExclusions | %{ "/XD " + '"' + $_ + '"' }
  121.             }
  122.             If ($Entry.FileExclusions) {
  123.                 $exclSTR += $Entry.FileExclusions | %{ "/XF " + '"' + $_ + '"' }
  124.             }
  125.  
  126.             If (!(Test-Path $FullSrcPath)) { Write-Host "`nInvalid source path specified." -f Red; if (!$NoTranscript) { try {Stop-Transcript} catch {} }; Return "ERROR"}
  127.             If (!(Test-Path $FullDestPath)) {
  128.                 [array]$DestPathArr = $FullDestPath.Split('\')
  129.                 If ($DestPathArr.Count -gt 1) {
  130.                     If (Test-Path $($DestPathArr[0..$($DestPathArr.Count - 2)] -join("\"))) {
  131.                         Write-Warning "Destination path $($FullDestPath) does not exist.  It will be created."
  132.                     } else {  Write-Host "`nInvalid destination path specified." -f Red; if (!$NoTranscript) { try {Stop-Transcript} catch {} }; Return "ERROR" }
  133.                 }
  134.             }
  135.             # Write-Host "`tStart Time: $(Get-Date)"
  136.  
  137.             $RoboCopyCore = "robocopy `"$($FullSrcPath)`" `"$($FullDestPath)`" /LOG:`"$($CopyLog)`""
  138.             $RoboCopyArgs = "/R:0 /W:0 /COPY:DATSO /DCOPY:DAT /MT /NP"
  139.             If ($MIR) { $RoboCopyArgs = $RoboCopyArgs + " /MIR" } else { $RoboCopyArgs = $RoboCopyArgs + " /E" }
  140.             If ($exclSTR) { $RoboCopyArgs = $RoboCopyArgs + " " + $($exclSTR) }
  141.             $RoboCopyCMD = $RoboCopyCore + " " + $RoboCopyArgs
  142.  
  143.             Write-Verbose "Robocopy Command: $($RoboCopyCMD)"
  144.             write-host "`nStarting Robocopy Entry `#$($EntryNum)"
  145.             write-host "`tSource:`t`t$($FullSrcPath)"
  146.             write-host "`tDestination:`t$($FullDestPath)"
  147.             If ($Entry.DirExclusions) { write-host "`tDirExclusions: $($Entry.DirExclusions -Join(', '))" -f Yellow }
  148.             If ($Entry.FileExclusions) { write-host "`tFileExclusions: $($Entry.FileExclusions -Join(', '))" -f Yellow }
  149.             write-host "`tRobocopy Args:`t$($RoboCopyArgs)"
  150.             Write-Host
  151.  
  152.             if ($pscmdlet.ShouldProcess("Robocopy entry `#$($EntryNum)")) {
  153.                 if ($MonitorCopy) {
  154.                     Write-Host "`tOpening copy job log file for monitoring in a new window:`n`t`t$($CopyLog)" -f Cyan
  155.                     Write-Host "`tNote: Closing the monitoring windows will not affect the copy jobs.`n" -f Yellow
  156.                     $ArgList = "-command `"start-sleep 1; Get-Content -Wait `"$($CopyLog)`"`""
  157.                     Start-Process -FilePath "PowerShell.exe" -ArgumentList $ArgList
  158.                 } else {
  159.                     Write-Host "`nRobocopy job is running. To monitor the copy job paste the below command into a new powershell window:" -f Cyan
  160.                     write-host "`t`tGet-Content -Wait `"$($CopyLog)`"`n" -F Magenta
  161.                 }
  162.                 write-verbose "Executing $($RoboCopyCMD)"
  163.                 $a = Invoke-Expression $RoboCopyCMD
  164.                 $CopyLogResultsHead = Get-Content -Head 30 -Path $CopyLog
  165.                 Write-Host "`tRoboCopy Header:"
  166.                 for ($i = 5; ($($CopyLogResultsHead[$i]) -notmatch "----------") -and $i -lt 30; $i++) { write "`t$($CopyLogResultsHead[$i])" }
  167.                 # Write-Host "`tEnd Time: $(Get-Date)"
  168.                 Write-Host "`tRoboCopy Results:"
  169.                 $CopyLogResultsTail = Get-Content -Tail 16 -Path $CopyLog
  170.                 for ($i = 0; $i -lt $CopyLogResultsTail.Count; $i++) { if ( $CopyLogResultsTail[$i] -match "----------") { [int]$iStart = $i + 2 } }
  171.                 if (!$iStart) { $iStart = 0 }
  172.                 for ($i = $iStart; $i -lt $CopyLogResultsTail.Count; $i++) { Write "`t$($CopyLogResultsTail[$i])" }
  173.             }
  174.         } # End ForEach Loop
  175.     } else {
  176.         write-host "No valid DataMigrationMap entries found. Data migration will be skipped." -F Red; if (!$NoTranscript) { try {Stop-Transcript} catch {} }; Return "ERROR"
  177.     }
  178.     write-Host "`nAll jobs complete @ $(Get-Date). Total time elapsed: $($StartTime - (get-date))"
  179.     if (!$NoTranscript) { try {Stop-Transcript} catch {} }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement