functions/Copy-ItemFiltered.ps1
function Copy-ItemFiltered { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] $SourceDir, [Parameter(Mandatory=$true)] [string] $TargetDir, [switch] $Force, [string[]] $Excludes, $message = "Copying items...", [switch][bool]$ClearDest = $false ) $SourceDir = (get-item $SourceDir).FullName #$activity = "$message $sourcedir => $targetDir" try { import-module pathutils $Excludes = $Excludes | % { $_.replace("\","/") } $Excludes = $Excludes | % { if ($_.StartsWith("/")) { $_.substring(1) } else { $_ } } #$excludedDirs = $Excludes | where { $_ -match "\\*\\" } | foreach { $_.Replace("\","\\") } Write-Verbose "excludes: $excludes" if (!(test-path $targetdir)) { $null = New-Item -ItemType Directory $targetdir } #Write-Progress $activity -Status "getting list of directories" #get directories (recursively) to copy $dirs = @(pathutils\Get-Listing -Path $SourceDir -Recursive -Excludes $excludes -Dirs) #Write-Progress $activity -Status "preparing... ($($dirs.length) dirs)" Write-Verbose "dirs: $dirs" write-host 'test 1' #create matching direcctory structure foreach( $d in $dirs ) { if ($d -eq $null) { continue } $fullname = $d.FullName if ($fullname -eq $null) { $fullname = $d.Name } Write-Verbose "d.name=$($d.Name) fullname=$fullname tmpPath=$tmpPath" $tmpPath = Join-Path $targetdir (Get-RelativePath $SourceDir $fullname) if (!(test-path $tmpPath)) { $null = New-Item -ItemType Directory -Path $tmpPath } } write-host 'test 2' $items = $dirs $items += get-item $sourcedir -Force <# #get top-level dirs $items += Get-Listing $SourceDir -Exclude $excludes -Recursive:$false -Dirs Write-Verbose "items: $items" foreach( $d in $dirs ) { if ($d -eq $null) { continue } Write-Progress $activity -Status "preparing... listing '$($d.name)'" $curItems = Get-Listing $($d.FullName) -Exclude $excludes -Recursive:$false -Dirs if ($curItems -ne $null) { $items += $curItems } } #> if($ClearDest){ write-host "removing $dest" remove-item -path "$dest\*" -Recurse -Force -Exclude $Excludes } #$i = 0 $items | foreach { #$i++ #Write-Progress -Activity $activity -Status " directory '$_' ($i/$($items.Length))" -PercentComplete ($i/[float]$($items.Length) * 100) $dir = $_ try { $dest = Join-Path $targetdir (Get-RelativePath $SourceDir $_.fullname) $files = get-childitem $($_.fullname) -File -Recurse:$false #$j = 0 $files | % { #$j++ #Write-Progress -Activity $activity -Status " directory '$dir' ($i/$($items.Length)) | file $_ ($j/$($files.length)) ($($_.length)B)" -PercentComplete ($i/[float]$($items.Length) * 100) try { Copy-Item "$($_.fullname)" -Force:$Force -Destination $dest -Verbose } catch { # replace exceptions with errors, so ErrorAction could take effect write-error $_ } } } catch [System.Exception] { write-host "failed to copy dir $dir : $($_.Exception)" } } } finally { #write-progress -Activity $activity -completed } } |