powershell - 如何直接通过管道传输到 Copy-Item 而不是在 ForEach-Object 中

标签 powershell pipeline copy-item foreach-object

因为 Get-ChildItem 的 -Exclude 参数在使用 -Recurse 标志时不过滤子文件夹,请参阅其他 unable-to-exclude-directory-using-get-childitem-exclude-parameter-in- powershell

但是-Exclude参数可以用来过滤掉根级别的文件夹

我写了自己的递归函数:

function Get-ChildItem-Recurse() {
    [cmdletbinding()]
    Param(
      [parameter(ValueFromPipelineByPropertyName = $true)]
      [alias('FullName')]
      [string[]] $Path,
      [string] $Filter,
      [string[]] $Exclude,
      [string[]] $Include,
      [switch] $Recurse = $true,
      [switch] $File = $false
    )

    Process {
      ForEach ( $P in $Path ) {
        Get-ChildItem -Path $P -Filter $Filter -Include $Include -Exclude $Exclude | ForEach-Object {
        if ( -not ( $File -and $_.PSIsContainer ) ) {
          $_
        }
        if ( $Recurse -and $_.PSIsContainer ) {
          $_ | Get-ChildItem-Recurse -Filter $Filter -Exclude $Exclude -Include $Include -Recurse:$Recurse
        }
      }
    }
  }
}

当我将结果通过管道传递给 ForEach-Object 以将结果复制到不同的目的地时,一切正常,除了与排除参数匹配的项目之外的项目都被复制

$source = 'D:\Temp\'
$destination = 'D:\Temp_Copy\'

Get-ChildItem-Recurse -Path $source -Exclude @( '*NotThis*', '*NotThat*' ) | ForEach-Object {
  $_ | Copy-Item -Destination ( "$($destination)$($_.FullName.Substring($source.Length))" ) -Force 
}

当我将它直接传送到 Copy-Item commandlet 时,我得到一个空值错误,因为 .Substring() 是在显然为空的 $_.FullName 上调用的

Get-ChildItem-Recurse -Path $source -Exclude @( '*NotThis*', '*NotThat*' ) |
  Copy-Item -Destination ( "$($destination)$($_.FullName.Substring($source.Length))" ) -Force

因为 native 命令行开关 Get-ChildItem 确实允许我将其结果通过管道传递给 Copy-Item,我喜欢我自己的自定义函数也能够做到这一点。但我不明白为什么它不起作用。

最佳答案

使用脚本 block 将管道输入值动态绑定(bind)到参数:

Get-ChildItem ... |Copy-Item -Destination { "$($destination)$($_.FullName.Substring($source.Length))" }

mklement0 的以下回答详细介绍了这种动态绑定(bind)(追溯命名为 "delay-bind scriptblocks" ,或通俗地称为“管道绑定(bind)脚本 block ”):
For PowerShell cmdlets, can I always pass a script block to a string parameter?

关于powershell - 如何直接通过管道传输到 Copy-Item 而不是在 ForEach-Object 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70275254/

相关文章:

powershell - 在 Powershell 中创建文件夹时禁用继承并手动应用权限

powershell - 如何删除azure sql db的长期保留并删除保管库

python - 为什么 sklearn Pipeline 调用 transform() 的次数比 fit() 多很多?

pipeline - Sagemaker 管道 |将字符串列表作为参数传递

google-chrome-extension - 如何将成功的 TFS 构建自动上传到 Chrome 网上应用店?

windows - Powershell相当于cp -n,即复制文件而不覆盖

c# - PowerShell 使用 PSSession 删除项目

powershell - 如何使用变量导出Csv?

powershell - 复制项目不包括 PowerShell 中源目录的子文件夹文件

使用递归复制文件期间的 powershell 错误检查