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] $LogOutput ) $returnValue = @{ Source = if (Test-Path $Source){$Source}; Destination = if (Test-Path $Destination){$Destination}; LogOutput = if ($LogOutput){ if(Test-Path $LogOutput){$LogOutput} } } $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 ) [string]$Arguments = '' if ($Retry -ne '') {$Arguments += " /R:$Retry"} if ($Wait -ne '') {$Arguments += " /W:$Wait"} if ($SubdirectoriesIncludingEmpty) {$Arguments += ' /E'} if ($Restartable) {$Arguments += ' /Z'} if ($MultiThreaded) {$Arguments += ' /MT'} if ($ExcludeFiles -ne '') {$Arguments += " /XF $ExcludeFiles"} if ($ExcludeDirs -ne '') {$Arguments += " /XD $ExcludeDirs"} if ($LogOutput -ne '' -AND $AppendLog) { $Arguments += " /LOG+:$LogOutput" } if ($LogOutput -ne '' -AND -not $AppendLog) { $Arguments += " /LOG:$LogOutput" } if ($AdditionalArgs -ne $null) {$Arguments += " $AdditionalArgs"} try { Write-Verbose "Executing: Robocopy.exe `"$($Source)`" `"$($Destination)`" $($Arguments)" Invoke-Robocopy $Source $Destination $Arguments } catch { Write-Warning "An error occured executing Robocopy.exe. ERROR: $_" } } 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, [System.Boolean] $Restartable, [System.Boolean] $MultiThreaded, [System.String] $ExcludeFiles, [System.String] $LogOutput, [System.Boolean] $AppendLog, [System.String] $AdditionalArgs ) try { $result = Invoke-RobocopyTest $Source $Destination } catch { Write-Warning "An error occured while getting the file list from Robocopy.exe. ERROR: $_" } # 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 ($result -ge 0 -and $result -lt 8) {[system.boolean]$result = $true} else {[system.boolean]$result = $false} $result } # Helper Functions function Invoke-RobocopyTest { param ( [parameter(Mandatory = $true)] [System.String] $source, [parameter(Mandatory = $true)] [System.String] $destination ) $output = & robocopy.exe /L $source $destination $LASTEXITCODE } # Invoke-RobocopyTest C:\DSCTestMOF C:\DSCTestMOF2 function Invoke-Robocopy { param ( [parameter(Mandatory = $true)] [System.String] $source, [parameter(Mandatory = $true)] [System.String] $destination, [System.String] $Arguments ) # This is a safe use of invoke-expression. Input is only passed as parameters to Robocopy.exe, it cannot be executed directly $output = Invoke-Expression "Robocopy.exe `"$Source`" `"$Destination`" $Arguments" $LASTEXITCODE } # Invoke-Robocopy -source C:\DSCTestMOF -destination C:\DSCTestMOF2 -Arguments '/E /MT' Export-ModuleMember -Function *-TargetResource |