DSCResources/MSFT_xRobocopy/MSFT_xRobocopy.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $Source, [parameter(Mandatory = $true)] [System.String] $Destination, [System.String] $Files, [System.UInt32] $Retry, [System.UInt32] $Wait, [System.Boolean] $SubdirectoriesIncludingEmpty = $False, [System.Boolean] $Restartable = $False, [System.Boolean] $MultiThreaded = $False, [System.String] $ExcludeFiles, [System.String] $LogOutput, [System.Boolean] $AppendLog = $False, [System.String[]] $AdditionalArgs ) $result = Test-TargetResource $Source $Destination $Files $Retry $Wait $SubdirectoriesIncludingEmpty $Restartable $MultiThreaded $ExcludeFiles $LogOutput $AppendLog $AdditionalArgs $ensure = 'Absent' if($result -eq $true) { $ensure = 'Present' } $returnValue = @{ Source = $Source Destination = $Destination Files = $Files Retry = $Retry Wait = $Wait SubdirectoriesIncludingEmpty = $SubdirectoriesIncludingEmpty Restartable = $Restartable MultiThreaded = $MultiThreaded ExcludeFiles = $ExcludeFiles LogOutput = $LogOutput AppendLog = $AppendLog AdditionalArgs = $AdditionalArgs Ensure = $ensure } return $returnValue } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $Source, [parameter(Mandatory = $true)] [System.String] $Destination, [System.String] $Files, [System.UInt32] $Retry, [System.UInt32] $Wait, [System.Boolean] $SubdirectoriesIncludingEmpty = $False, [System.Boolean] $Restartable = $False, [System.Boolean] $MultiThreaded = $False, [System.String] $ExcludeFiles, [System.String] $LogOutput, [System.Boolean] $AppendLog = $False, [System.String[]] $AdditionalArgs ) $arguments = Get-RobocopyArguments $Source $Destination $Files $Retry $Wait $SubdirectoriesIncludingEmpty $Restartable $MultiThreaded $ExcludeFiles $LogOutput $AppendLog $AdditionalArgs Write-Verbose "Executing robocopy.exe with: $arguments" &robocopy $arguments | Out-Null if($LASTEXITCODE -ge 8) { throw "robocopy returned with errors! Exit code: $LASTEXITCODE! More info here:https://support.microsoft.com/en-us/kb/954404" } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.String] $Source, [parameter(Mandatory = $true)] [System.String] $Destination, [System.String] $Files, [System.UInt32] $Retry, [System.UInt32] $Wait, [System.Boolean] $SubdirectoriesIncludingEmpty = $False, [System.Boolean] $Restartable = $False, [System.Boolean] $MultiThreaded = $False, [System.String] $ExcludeFiles, [System.String] $LogOutput, [System.Boolean] $AppendLog = $False, [System.String[]] $AdditionalArgs ) $arguments = Get-RobocopyArguments $Source $Destination $Files $Retry $Wait $SubdirectoriesIncludingEmpty $Restartable $MultiThreaded $ExcludeFiles $LogOutput $AppendLog $AdditionalArgs if(!$arguments.Contains('/L') -and !$arguments.Contains('/l')) { $arguments += '/L' } &robocopy $arguments | Out-Null # https://support.microsoft.com/en-us/kb/954404 # ROBOCOPY $LASTEXITCODE is a bitflag: # 0: Source and destination are completely synchronized # 1: One or more files were copied successfully (new files present) # 2: extra files/directories detected # 4: mismatched files/directories # 8: copy errors and retries exceeded # 16: serious error if ($LASTEXITCODE -ge 1 -and $LASTEXITCODE -lt 8) { Write-Verbose "Source and destination are out of sync" $result = $false } elseif ($LASTEXITCODE -eq 0) { Write-Verbose "Source and destination are completely synchronized" $result = $true } else { throw "robocopy returned with errors! Exit code: $result! More info here:https://support.microsoft.com/en-us/kb/954404" } return $result } # Helper Functions function Get-RobocopyArguments { [CmdletBinding()] [OutputType([System.String[]])] param ( [parameter(Mandatory = $true)] [System.String] $Source, [parameter(Mandatory = $true)] [System.String] $Destination, [System.String] $Files, [System.UInt32] $Retry, [System.UInt32] $Wait, [System.Boolean] $SubdirectoriesIncludingEmpty, [System.Boolean] $Restartable, [System.Boolean] $MultiThreaded, [System.String] $ExcludeFiles, [System.String] $LogOutput, [System.Boolean] $AppendLog, [System.String[]] $AdditionalArgs ) [System.String[]]$arguments = @($Source, $Destination) if($Files) { $arguments += $Files } if ($Retry) { $arguments += "/R:$Retry" } if ($Wait) { $arguments += "/W:$Wait" } if ($SubdirectoriesIncludingEmpty) { $arguments += '/E' } if ($Restartable) { $arguments += '/Z' } if ($MultiThreaded) { $arguments += '/MT' } if ($ExcludeFiles) { $arguments += @('/XF', $ExcludeFiles) } if ($ExcludeDirs) { $arguments += @('/XD', $ExcludeDirs) } if ($LogOutput -AND $AppendLog) { $arguments += "/LOG+:$LogOutput" } if ($LogOutput -AND !$AppendLog) { $arguments += "/LOG:$LogOutput" } if ($AdditionalArgs) { $arguments += $AdditionalArgs } return $arguments } Export-ModuleMember -Function *-TargetResource |