Copy-Item 不复制到正确的目标目录
Copy-Item does not copy to correct target directory
我正在尝试使用 PowerShell 脚本复制目录结构。我想排除某个目录。
我的目录结构是这样的:
C:\
└───murks
├───murks_source
│ │ test1.txt
│ │ test2.txt
│ │
│ ├───sub
│ │ subtest1.txt
│ │ subtest2.txt
│ │ subtest3.txt
│ │
│ └───sub2
│ sub2test.txt
│
└───murks_target
现在,当我 运行 脚本时,它不会创建包含从属文件的子目录 "sub2"。相反,它会将所有文件(包括 "sub2" 子目录中的文件)直接复制到 murks_target_directory 中。我不明白这种行为,因为 "Select -ExpandProperty FullName"-part 到目前为止看起来不错。
非常感谢任何帮助或提示。
提前致谢!
到目前为止,我的脚本如下所示:
$rootFolderPath = 'C:\murks\murks_source'
$excludeDirectories = ("sub");
function Exclude-Directories
{
process
{
$allowThrough = $true
foreach ($directoryToExclude in $excludeDirectories)
{
$directoryText = "*\" + $directoryToExclude
$childText = "*\" + $directoryToExclude + "\*"
if (($_.FullName -Like $directoryText -And $_.PsIsContainer) `
-Or $_.FullName -Like $childText)
{
$allowThrough = $false
break
}
}
if ($allowThrough)
{
return $_
}
}
}
Get-ChildItem $rootFolderPath -Recurse | Exclude-Directories | Select -ExpandProperty FullName | Copy-Item -Destination C:\murks\murks_target -Force
我几乎找到了一个答案,它提供了您不满意的功能。
$from = "C:\murks\murks_source"
$to = "C:\murks\murks_target"
$exclude = Get-ChildItem -Path C:\murks\murks_source\sub2\ -Depth 10
Copy-Item $from -Exclude $exclude -Destination $to -Recurse
它将忽略除文件夹结构之外的所有文件。
文件夹结构将被复制但为空。
希望对您有所帮助。
下面的自定义函数应该可以满足您的需求:
function Copy-Path {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[ValidateScript({Test-Path -Path $_ -PathType Container})]
[string]$Source,
[Parameter(Position = 1)]
[string]$Destination,
[string[]]$ExcludeFolders = $null,
[switch]$IncludeEmptyFolders
)
$Source = $Source.TrimEnd("\")
$Destination = $Destination.TrimEnd("\")
Get-ChildItem -Path $Source -Recurse | ForEach-Object {
if ($_.PSIsContainer) {
# it's a folder
if ($ExcludeFolders.Count) {
if ($ExcludeFolders -notcontains $_.Name -and $IncludeEmptyFolders) {
# create the destination folder, even if it is empty
$target = Join-Path -Path $Destination -ChildPath $_.FullName.Substring($Source.Length)
if (!(Test-Path $target -PathType Container)) {
Write-Verbose "Create folder $target"
New-Item -ItemType Directory -Path $target | Out-Null
}
}
}
}
else {
# it's a file
$copy = $true
if ($ExcludeFolders.Count) {
# get all subdirectories in the current file path as array
$subs = $_.DirectoryName.Replace($Source,"").Trim("\").Split("\")
# check each sub folder name against the $ExcludeFolders array
foreach ($folderName in $subs) {
if ($ExcludeFolders -contains $folderName) { $copy = $false; break }
}
}
if ($copy) {
# create the destination folder if it does not exist yet
$target = Join-Path -Path $Destination -ChildPath $_.DirectoryName.Substring($Source.Length)
if (!(Test-Path $target -PathType Container)) {
Write-Verbose "Create folder $target"
New-Item -ItemType Directory -Path $target | Out-Null
}
Write-Verbose "Copy file $($_.FullName) to $target"
$_ | Copy-Item -Destination $target -Force
}
}
}
}
到位后,像这样使用它:
Copy-Path -Source 'C:\murks\murks_source' -Destination 'C:\murks\murks_target' -ExcludeFolders 'sub' -Verbose
其中参数 -ExcludeFolders
可以是要跳过的文件夹名称数组。
添加开关参数 IncludeEmptyFolders
也会在目的地创建空文件夹。如果省略,将不会复制空文件夹。
使用您的示例文件结构,结果是
C:\murks\murks_target
| test1.txt
| test2.txt
|
\---sub2
sub2test.txt
这些都可以用one-liners实现。
$source = 'C:\murks\murks_source'
$dest = 'C:\murks\murks_target'
复制除 'Sub' 文件夹及其内容之外的所有内容:
Get-ChildItem -Path $source -Recurse | ? {$_.Name -notmatch 'sub'} | Copy-Item -Destination $dest
保留包括所有文件的文件夹结构:
Get-ChildItem -Path $source | Copy-Item -Destination $dest -Recurse -Container
复制文件夹结构但没有文件...
Get-ChildItem -Path $source | ? {$_.PSIsContainer} | Copy-Item -Destination $dest -Recurse -Exclude '*.*'
您显然可以结合示例 1 和示例 2 来保留 folder/file 结构,并通过名称、通配符等排除您想要的任何目录。
我正在尝试使用 PowerShell 脚本复制目录结构。我想排除某个目录。
我的目录结构是这样的:
C:\
└───murks
├───murks_source
│ │ test1.txt
│ │ test2.txt
│ │
│ ├───sub
│ │ subtest1.txt
│ │ subtest2.txt
│ │ subtest3.txt
│ │
│ └───sub2
│ sub2test.txt
│
└───murks_target
现在,当我 运行 脚本时,它不会创建包含从属文件的子目录 "sub2"。相反,它会将所有文件(包括 "sub2" 子目录中的文件)直接复制到 murks_target_directory 中。我不明白这种行为,因为 "Select -ExpandProperty FullName"-part 到目前为止看起来不错。
非常感谢任何帮助或提示。 提前致谢!
到目前为止,我的脚本如下所示:
$rootFolderPath = 'C:\murks\murks_source'
$excludeDirectories = ("sub");
function Exclude-Directories
{
process
{
$allowThrough = $true
foreach ($directoryToExclude in $excludeDirectories)
{
$directoryText = "*\" + $directoryToExclude
$childText = "*\" + $directoryToExclude + "\*"
if (($_.FullName -Like $directoryText -And $_.PsIsContainer) `
-Or $_.FullName -Like $childText)
{
$allowThrough = $false
break
}
}
if ($allowThrough)
{
return $_
}
}
}
Get-ChildItem $rootFolderPath -Recurse | Exclude-Directories | Select -ExpandProperty FullName | Copy-Item -Destination C:\murks\murks_target -Force
我几乎找到了一个答案,它提供了您不满意的功能。
$from = "C:\murks\murks_source"
$to = "C:\murks\murks_target"
$exclude = Get-ChildItem -Path C:\murks\murks_source\sub2\ -Depth 10
Copy-Item $from -Exclude $exclude -Destination $to -Recurse
它将忽略除文件夹结构之外的所有文件。 文件夹结构将被复制但为空。
希望对您有所帮助。
下面的自定义函数应该可以满足您的需求:
function Copy-Path {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[ValidateScript({Test-Path -Path $_ -PathType Container})]
[string]$Source,
[Parameter(Position = 1)]
[string]$Destination,
[string[]]$ExcludeFolders = $null,
[switch]$IncludeEmptyFolders
)
$Source = $Source.TrimEnd("\")
$Destination = $Destination.TrimEnd("\")
Get-ChildItem -Path $Source -Recurse | ForEach-Object {
if ($_.PSIsContainer) {
# it's a folder
if ($ExcludeFolders.Count) {
if ($ExcludeFolders -notcontains $_.Name -and $IncludeEmptyFolders) {
# create the destination folder, even if it is empty
$target = Join-Path -Path $Destination -ChildPath $_.FullName.Substring($Source.Length)
if (!(Test-Path $target -PathType Container)) {
Write-Verbose "Create folder $target"
New-Item -ItemType Directory -Path $target | Out-Null
}
}
}
}
else {
# it's a file
$copy = $true
if ($ExcludeFolders.Count) {
# get all subdirectories in the current file path as array
$subs = $_.DirectoryName.Replace($Source,"").Trim("\").Split("\")
# check each sub folder name against the $ExcludeFolders array
foreach ($folderName in $subs) {
if ($ExcludeFolders -contains $folderName) { $copy = $false; break }
}
}
if ($copy) {
# create the destination folder if it does not exist yet
$target = Join-Path -Path $Destination -ChildPath $_.DirectoryName.Substring($Source.Length)
if (!(Test-Path $target -PathType Container)) {
Write-Verbose "Create folder $target"
New-Item -ItemType Directory -Path $target | Out-Null
}
Write-Verbose "Copy file $($_.FullName) to $target"
$_ | Copy-Item -Destination $target -Force
}
}
}
}
到位后,像这样使用它:
Copy-Path -Source 'C:\murks\murks_source' -Destination 'C:\murks\murks_target' -ExcludeFolders 'sub' -Verbose
其中参数 -ExcludeFolders
可以是要跳过的文件夹名称数组。
添加开关参数 IncludeEmptyFolders
也会在目的地创建空文件夹。如果省略,将不会复制空文件夹。
使用您的示例文件结构,结果是
C:\murks\murks_target | test1.txt | test2.txt | \---sub2 sub2test.txt
这些都可以用one-liners实现。
$source = 'C:\murks\murks_source'
$dest = 'C:\murks\murks_target'
复制除 'Sub' 文件夹及其内容之外的所有内容:
Get-ChildItem -Path $source -Recurse | ? {$_.Name -notmatch 'sub'} | Copy-Item -Destination $dest
保留包括所有文件的文件夹结构:
Get-ChildItem -Path $source | Copy-Item -Destination $dest -Recurse -Container
复制文件夹结构但没有文件...
Get-ChildItem -Path $source | ? {$_.PSIsContainer} | Copy-Item -Destination $dest -Recurse -Exclude '*.*'
您显然可以结合示例 1 和示例 2 来保留 folder/file 结构,并通过名称、通配符等排除您想要的任何目录。