$from = \"\\\\something\\1 XLS\\2010_04_22\\*\"
$to = \"c:\\out\\1 XLS\\2010_04_22\\\"
copy-item $from $to -Recurse
This works if c:\\out\\
function Copy-File ([System.String] $sourceFile, [System.String] $destinationFile, [Switch] $overWrite) {
if ($sourceFile -notlike "filesystem::*") {
$sourceFile = "filesystem::$sourceFile"
}
if ($destinationFile -notlike "filesystem::*") {
$destinationFile = "filesystem::$destinationFile"
}
$destinationFolder = $destinationFile.Replace($destinationFile.Split("\")[-1],"")
if (!(Test-Path -path $destinationFolder)) {
New-Item $destinationFolder -Type Directory
}
try {
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch [System.IO.IOException] {
# If overwrite enabled, then delete the item from the destination, and try again:
if ($overWrite) {
try {
Remove-Item -Path $destinationFile -Recurse -Force
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch {
Write-Error -Message "[Copy-File] Overwrite error occurred!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} else {
Write-Error -Message "[Copy-File] File already exists!" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} catch {
Write-Error -Message "[Copy-File] File move failed!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
}
In PowerShell 2.0, it is still not possible to get the Copy-Item cmdlet to create the destination folder, you'll need code like this:
$destinationFolder = "C:\My Stuff\Subdir"
if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory}
Copy-Item "\\server1\Upgrade.exe" -Destination $destinationFolder
If you use -Recurse in the Copy-Item it will create all the subfolders of the source structure in the destination but it won't create the actual destination folder, even with -Force.
My favorite is to use the .Net [IO.DirectoryInfo] class, which takes care of some of the logic. I actually use this for a lot of similar scripting challenges. It has a .Create() method that creates directories that don't exist, without errors if they do.
Since this is still a two step problem, I use the foreach alias to keep it simple. For single files:
[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}
As far as your multi file/directory match, I would use RoboCopy over xcopy. Remove the "*" from your from and just use:
RoboCopy.exe $from $to *
You can still add the /r (Recurse), /e (Recurse including Empty), and there are 50 other useful switches.
Edit: Looking back at this it is terse, but not very readable if you are not using the code often. Usually I have it split into two, like so:
([IO.DirectoryInfo]$to).Create()
cp $from $to
Also, DirectoryInfo is the type of the Parent property of FileInfo, so if your $to is a file, you can use them together:
([IO.FileInfo]$to).Parent.Create()
cp $from $to