简体   繁体   中英

Get-ChildItem -File -Exclude issue

Issue

I wrapped Get-ChildItem in a generic function to add checks and be able to re-use it. When combining -File with -Exclude , the function seems to break even though the same call to Get-ChildItem outside of it does work as expected.

Question

What is going wrong? How can I fix it?

Related

Get-ChildItem Exclude and File parameters don't work together

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"

Output

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: Any constructive criticism on syntax/best practices is welcome.

This seems to be a known problem as per this issue on the PowerShell GIT repository.

Solution

There appear to be a conflict while using -Filter , -Exclude , and -File all at the same time. By removing one or adding -Recurse , the function works as expected.

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

Obviously this is not optimal and should be considered as a workaround until the issue is fixed.

Full working example

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"

Output

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM