PowerShell: Синхронизация с помощью robocopy

Про замечательную утилу robocopy я уже писал в заметке Перенос MDaemon на другой сервер, но тогда я использовал консоль, сейчас же мне потребовалось использовать PoerShell. Что бы не изобретать велосипед я полез искать, т. к. решения просто обязаны быть.
Был найден скрипт за авторством NIKLAS JUMLIN. Скрипт запускает robocopy с параметрами и ведет логи.

## This Script Mirrors a directory tree from source to destination with the Windows builtin command robocopy.
## Exit codes from robocopy are logged to Windows Eventlog.
## Author: NIKLAS JUMLIN

## Usage: Run with administrative rights in Windows Task Scheduler or Administrator:PowerShell
## If not executed with administrative privileges the script will not write to eventlog.

## Change these parameters
## ================================================================

## Name of the job, name of source in Windows Event Log and name of robocopy Logfile.
$JOB = "DB Backup"

## Source directory
$SOURCE = "C:\Base"

## Destination directory. Files in this directory will mirror the source directory. Extra files will be deleted!
$DESTINATION = "E:\Backup"

## Path to robocopy logfile
$LOGFILE = "E:\Backup\LOGS\$JOB"

## Log events from the script to this location
$SCRIPTLOG = "E:\Backup\LOGS\$JOB.log"

## Mirror a direcotory tree
$WHAT = @("/MIR")
## /COPY:DATS: Copy Data, Attributes, Timestamps, Security
## /SECFIX : FIX file SECurity on all files, even skipped files.

## Retry open files 3 times wait 30 seconds between tries. 
$OPTIONS = @("/R:3","/W:30","/NDL","/NFL")
## /NFL : No File List - don't log file names.
## /NDL : No Directory List - don't log directory names.
## /L   : List only - don't copy, timestamp or delete any files.

## This will create a timestamp like yyyy-mm-yy
$TIMESTAMP = get-date -uformat "%Y-%m%-%d"

## This will get the time like HH:MM:SS
$TIME = get-date -uformat "%T"

## Append to robocopy logfile with timestamp
$ROBOCOPYLOG = "/LOG+:$LOGFILE`-$TIMESTAMP.log"

## Wrap all above arguments
$cmdArgs = @("$SOURCE","$DESTINATION",$WHAT,$ROBOCOPYLOG,$OPTIONS)

## ================================================================

## Start the robocopy with above parameters and log errors in Windows Eventlog.
& C:\Windows\System32\Robocopy.exe @cmdArgs

## Get LastExitCode and store in variable
$ExitCode = $LastExitCode

$MSGType=@{
"16"="Errror"
"8"="Error"
"4"="Warning"
"2"="Information"
"1"="Information"
"0"="Information"
}

## Message descriptions for each ExitCode.
$MSG=@{
"16"="Serious error. robocopy did not copy any files.`n
Examine the output log: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"8"="Some files or directories could not be copied (copy errors occurred and the retry limit was exceeded).`n
Check these errors further: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"4"="Some Mismatched files or directories were detected.`n
Examine the output log: $LOGFILE`-Robocopy`-$TIMESTAMP.log.`
Housekeeping is probably necessary."
"2"="Some Extra files or directories were detected and removed in $DESTINATION.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"1"="New files from $SOURCE copied to $DESTINATION.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"0"="$SOURCE and $DESTINATION in sync. No files copied.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
}

## Function to see if running with administrator privileges
function Test-Administrator  
{  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

## If running with administrator privileges
If (Test-Administrator -eq $True) {
	"Has administrator privileges"

	## Create EventLog Source if not already exists
	if ([System.Diagnostics.EventLog]::SourceExists("$JOB") -eq $false) {
	"Creating EventLog Source `"$JOB`""
    [System.Diagnostics.EventLog]::CreateEventSource("$JOB", "Application")
	}

	## Write known ExitCodes to EventLog
	if ($MSG."$ExitCode" -gt $null) {
		Write-EventLog -LogName Application -Source $JOB -EventID $ExitCode -EntryType $MSGType."$ExitCode" -Message $MSG."$ExitCode"
	}
	## Write unknown ExitCodes to EventLog
	else {
		Write-EventLog -LogName Application -Source $JOB -EventID $ExitCode -EntryType Warning -Message "Unknown ExitCode. EventID equals ExitCode"
	}
}
## If not running with administrator privileges
else {
	## Write to screen and logfile
	Add-content $SCRIPTLOG "$TIMESTAMP $TIME No administrator privileges" -PassThru
	Add-content $SCRIPTLOG "$TIMESTAMP $TIME Cannot write to EventLog" -PassThru

	## Write known ExitCodes to screen and logfile
	if ($MSG."$ExitCode" -gt $null) {
		Add-content $SCRIPTLOG "$TIMESTAMP $TIME Printing message to logfile:" -PassThru
		Add-content $SCRIPTLOG ($TIMESTAMP + ' ' + $TIME + ' ' + $MSG."$ExitCode") -PassThru
		Add-content $SCRIPTLOG "$TIMESTAMP $TIME ExitCode`=$ExitCode" -PassThru
	}
	## Write unknown ExitCodes to screen and logfile
	else {
		Add-content $SCRIPTLOG "$TIMESTAMP $TIME ExitCode`=$ExitCode (UNKNOWN)" -PassThru
	}
	Add-content $SCRIPTLOG ""
	Return
}
Поделиться
Отправить
2013   windows