首页 > 解决方案 > Get-ChildItem -File -Exclude 问题

问题描述

问题

我包装Get-ChildItem了一个通用函数来添加检查并能够重用它。与结合-File使用时-Exclude,即使对Get-ChildItem外部的相同调用确实按预期工作,该函数似乎也会中断。

问题

出了什么问题?我该如何解决?

有关的

Get-ChildItem Exclude 和 File 参数不能一起使用

MWE

function Get-Object {
  [CmdletBinding ()]
  param (
    [Parameter (
      Position    = 1,
      Mandatory   = $true,
      HelpMessage = "Path to the object"
    )]
    [String]
    $Path,
    [Parameter (
      Position    = 2,
      Mandatory   = $false,
      HelpMessage = "Type of object"
    )]
    [ValidateSet ("All", "File", "Folder")]
    [String]
    $Type = "All",
    [Parameter (
      Position    = 3,
      Mandatory   = $false,
      HelpMessage = "Filter to apply"
    )]
    [String]
    $Filter = "*",
    [Parameter (
      Position    = 4,
      Mandatory   = $false,
      HelpMessage = "Pattern to exclude"
    )]
    [String]
    $Exclude = $null
  )
  begin {
    if (-Not (Test-Path -Path $Path)) {
      Write-Host "$Path does not exists."
      exit 1
    }
    $ObjectType = [ordered]@{
      "All"     = "items"
      "File"    = "files"
      "Folder"  = "folders"
    }
  }
  process {
    # Get files
    switch ($Type) {
      "File"    {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude -File
      }
      "Folder"  {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude -Directory
      }
      default   {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude
      }
    }
    # If no files are found, print hints
    if ($Files.Count -eq 0) {
      if ($Filter -ne "*") {
        Write-Host "No $($ObjectType[$Type]) were found in $Path matching the filter ""$Filter""."
      } elseif ($Exclude) {
        Write-Host "No $($ObjectType[$Type]) corresponding to the criterias were found in $Path."
      } else {
        Write-Host "No $($ObjectType[$Type]) were found in $Path."
      }
      # exit 1
    } else {
      return $Files
    }
  }
}

$Path         = Split-Path -Path $MyInvocation.MyCommand.Definition
$RelativePath = "\test"
$AbsolutePath = Join-Path -Path $Path -ChildPath $RelativePath
$Filter       = "*"
$Exclude      = $null

Get-ChildItem -Path $RelativePath -Filter $Filter -Exclude $Exclude -File

Get-ChildItem -Path $AbsolutePath -Filter $Filter -Exclude $Exclude -File

Get-Object -Path $RelativePath -Filter $Filter -Exclude $Exclude -Type "File"

Get-Object -Path $AbsolutePath -Filter $Filter -Exclude $Exclude -Type "File"

输出

PS C:\> .\test.ps1


    Directory: C:\test


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       21/09/2018     18:42              0 text.txt
-a----       21/09/2018     18:42              0 text.txt
No files were found in \test.
No files were found in C:\test.

PS:欢迎对语法/最佳实践提出任何建设性的批评。

标签: powershellget-childitem

解决方案


根据 PowerShell GIT 存储库上的这个问题,这似乎是一个已知问题。

解决方案

-Filter同时使用,-Exclude-Fileall 时似乎存在冲突。通过删除一个或添加-Recurse,该功能按预期工作。

  1. Get-ChildItem -Path $Path -Filter $Filter -File
  2. Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude -File -Recurse

显然,这不是最优的,在问题得到解决之前,应将其视为一种解决方法。

完整的工作示例

function Get-Object {
  [CmdletBinding ()]
  param (
    [Parameter (
      Position    = 1,
      Mandatory   = $true,
      HelpMessage = "Path to the items"
    )]
    [String]
    $Path,
    [Parameter (
      Position    = 2,
      Mandatory   = $false,
      HelpMessage = "Type of object"
    )]
    [ValidateSet ("All", "File", "Folder")]
    [String]
    $Type = "All",
    [Parameter (
      Position    = 3,
      Mandatory   = $false,
      HelpMessage = "Filter to apply"
    )]
    [String]
    $Filter = "*",
    [Parameter (
      Position    = 4,
      Mandatory   = $false,
      HelpMessage = "Pattern to exclude"
    )]
    [String]
    $Exclude = $null
  )
  begin {
    if (-Not (Test-Path -Path $Path)) {
      Write-Host "$Path does not exists."
      exit 1
    }
    $ObjectType = [ordered]@{
      "All"     = "items"
      "File"    = "files"
      "Folder"  = "folders"
    }
  }
  process {
    # Get files
    switch ($Type) {
      "File"    {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude -File -Recurse
      }
      "Folder"  {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude -Directory
      }
      default   {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Exclude $Exclude
      }
    }
    # If no files are found, print hints
    if ($Files.Count -eq 0) {
      if ($Filter -ne "*") {
        Write-Host "No $($ObjectType[$Type]) were found in $Path matching the filter ""$Filter""."
      } elseif ($Exclude) {
        Write-Host "No $($ObjectType[$Type]) corresponding to the criterias were found in $Path."
      } else {
        Write-Host "No $($ObjectType[$Type]) were found in $Path."
      }
      # exit 1
    } else {
      return $Files
    }
  }
}

$Path         = Split-Path -Path $MyInvocation.MyCommand.Definition
$RelativePath = "\test"
$AbsolutePath = Join-Path -Path $Path -ChildPath $RelativePath
$Filter       = "*"
$Exclude      = $null

Get-ChildItem -Path $RelativePath -Filter $Filter -Exclude $Exclude -File

Get-ChildItem -Path $AbsolutePath -Filter $Filter -Exclude $Exclude -File

Get-Object -Path $RelativePath -Filter $Filter -Exclude $Exclude -Type "File"

Get-Object -Path $AbsolutePath -Filter $Filter -Exclude $Exclude -Type "File"

输出

PS C:\> .\test.ps1


    Directory: C:\test


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       21/09/2018     18:42              0 text.txt
-a----       21/09/2018     18:42              0 text.txt
-a----       21/09/2018     18:42              0 text.txt
-a----       21/09/2018     18:42              0 text.txt

推荐阅读