【问题标题】:Copy-Item and exclude folders复制项目和排除文件夹
【发布时间】:2021-11-15 01:35:48
【问题描述】:

我需要将我的所有 c:\inetpub 目录复制到新位置,但不包括以下文件夹及其子文件夹:

c:\inetpub\custerr
c:\inetpub\history
c:\inetpub\logs
c:\inetpub\temp
c:\inetpub\wwwroot

到目前为止,我正在这样做:

# Directory name is created with a format string
$dirName = "\\servername\folder1 _ {0}\inetpub" -f (get-date).ToString("yyyy-MM-dd-hh-mm-ss")
$dirName # Check the output

# Create dir if needed
if(-not (test-path $dirName)) {
    md $dirName | out-null
} else {
    write-host "$dirName already exists!"
}

#Copy Backup File to Dir
Copy-Item "\\servername\c$\inetpub\*" $dirName -recurse

【问题讨论】:

  • 嗯?解读文字内容真的有那么难吗?
  • 我是唯一一个认为现在更好的人? :)
  • 好多了!我鄙视在这个网站上发帖,它总是给我带来格式问题!

标签: powershell


【解决方案1】:

这是一个您可以做的简单示例。构建要排除的父文件夹数组。由于您是通过 UNC 路径访问它们,因此我们不能真正使用 c:\ 路径(我们可以解决这个问题,但我将要展示的内容应该足够好了。

然后使用Get-ChildItem 获取inetpub 目录下的所有文件夹。使用-notin 过滤掉排除项并将其余部分传递给Copy-Item

$excludes = "custerr","history","logs","temp","wwwroot"
Get-ChildItem "c:\temp\test" -Directory | 
    Where-Object{$_.Name -notin $excludes} | 
    Copy-Item -Destination $dirName -Recurse -Force

您至少需要 PowerShell 3.0 才能使其工作。

【讨论】:

  • 我出错了,我的PS主版本是3。 copy-Item : 输入对象不能绑定到命令的任何参数,因为命令不接受管道输入或输入并且它的属性与任何接受管道输入的参数都不匹配。在 line:15 char:93 + ... n $excludes} |复制项目 $dirName -recurse + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (Webservices:PSObject) [复制项目] , ParameterBindingException + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.CopyItemCommand
  • 不知道为什么我之前没有解决这个问题。我省略了参数名称-Destination。没有它,绑定就搞砸了。如果重要的话,它现在已经修复了。 @MJJM
  • 警告:如果$dirName 尚不存在,则会创建它,不会复制源中的第一个子目录。相反,它的内容将被直接复制到$dirName,从而消除了一层深度。由于这会创建 $dirName,因此将按预期复制第二个子目录。
  • @MSalters 这就是为什么我现在和现在都非常依赖 robocopy。
【解决方案2】:
Copy-Item -Path (Get-Item -Path "$path\*" -Exclude ('Folder1', 'File.cmd', 'File.exe', 'Folder2')).FullName -Destination $destination -Recurse -Force

替换:

$path 通过您的源文件夹

('Folder1', 'File.cmd', 'File.exe', 'Folder2') 由您要排除的特定文件/文件夹

$destination 您的目标文件夹

【讨论】:

  • 这看起来很棒!干净简单。但是,排除项似乎不适用于子文件夹。
  • 黄金答案!我浪费了大量时间在 Copy-Item 本身上使用 -Include 参数,但我想知道为什么根本不工作。在 Get-Item 上使用 -Include 解决了!完美!
  • 这只适用于Folder1在$path中,它不适用于$path\sub1\sub2\Folder1
【解决方案3】:

哦,答案很简单,但似乎我们都是 PowerShell 菜鸟。

New-Item -ItemType Directory -Force -Path $outDir # directory must exist
Copy-Item $inDir\* $outDir -Exclude @("node_modules",".yarn") -Recurse

\* 使它起作用。

PowerShell 很棒,但是...

【讨论】:

    【解决方案4】:

    我写这个是为了日常使用,并打包在脚本模块中,它维护了所有的目录结构并支持通配符:

    function Copy-Folder {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory)]
            [String]$FromPath,
    
            [Parameter(Mandatory)]
            [String]$ToPath,
    
            [string[]] $Exclude
        )
    
        if (Test-Path $FromPath -PathType Container) {
            New-Item $ToPath -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
            Get-ChildItem $FromPath -Force | ForEach-Object {
                # avoid the nested pipeline variable
                $item = $_
                $target_path = Join-Path $ToPath $item.Name
                if (($Exclude | ForEach-Object { $item.Name -like $_ }) -notcontains $true) {
                    if (Test-Path $target_path) { Remove-Item $target_path -Recurse -Force }
                    Copy-Item $item.FullName $target_path
                    Copy-Folder -FromPath $item.FullName $target_path $Exclude
                }
            }
        }
    }
    

    只需拨打Copy-Folder -FromPath inetpub -ToPath new-inetpub -Exclude custerr,history,logs,temp,wwwroot

    -FromPath-ToPath 可以省略,

    Copy-Folder inetpub new-inetpub -Exclude custerr,history,logs,temp,wwwroot

    【讨论】:

      【解决方案5】:

      您可以按照以下方式做一些事情:

        ?{$_.fullname -notmatch '\\old\\'}
      

      在您获取所有文件夹以过滤它们之后。

      此示例将排除名称中包含“旧”的任何内容。您可以对要排除的目录执行此操作。

      一个完整的例子:

      C:\Example*" -include "*.txt -Recurse |
        ?{$_.fullname -notmatch '\\old\\'}|
          % {Copy-Item $_.fullname "C:\Destination\"}
      

      对于多个排除,您可以使用-And

      C:\Example*" -include "*.txt -Recurse |
        ?{$_.fullname -notmatch '\\old\\' -And $_.fullname -notmatch '\\old2\\'}|
          % {Copy-Item $_.fullname "C:\Destination\"}
      

      【讨论】:

      • 如果想要的子文件夹之一包含该名称怎么办?此外,您应该展示您将如何解释 OP 正在寻找的多个文件夹。
      • 我开始怀疑是否值得只运行副本,然后在删除 \\server\foldername\logs 之后执行单独的删除命令,因为做一些我认为会做的事情似乎是一项艰巨的任务比较容易
      猜你喜欢
      • 1970-01-01
      • 2018-12-05
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 2012-05-15
      相关资源
      最近更新 更多