Search code examples
powershelldirectorycompressionget-childitem

Exclude one folder and a filetype from Get-childitem


I have a website that needs frequent backup hence I would like to write a script to compress all the files in the screenshot. Except:

  1. All the contents in the image folder (See Highlighted)
  2. Any *.log files in the entire directory

enter image description here

I tried to get a list of files and always end up having the image folders contents:

$WebAppFolder = 'C:\ReleaseBackupScript\MyWebSite'
$filteredList = Get-childitem -path $WebAppFolder -exclude $WebAppFolder"\image",*.log -Name -recurse -force
Out-File -FilePath FilteredList.txt -InputObject $filteredList 

Solution

  • As Theo notes, as of PowerShell 7.4.x:

    • -Exclude, as well as -Include and -Filter, operate on file and directory names only, not on paths.

    • Similarly, -Exclude doesn't support excluding entire directory subtrees (a directory and all its content).

    Overcoming these limitations in a future PowerShell version for -Include and -Exclude is being discussed in GitHub issue #15159.

    Therefore, you'll have to perform your own post-filtering yourself:

    $WebAppFolder = 'C:\ReleaseBackupScript\MyWebSite'
    $filteredList = 
      Get-ChildItem -Recurse -Force -File -Name -LiteralPath $WebAppFolder -Exclude *.log |
        Where-Object { $_ -notlike 'image\*' } > FilteredList.txt
    

    Note: Since you're using Get-ChildItem's -Name parameter, the output objects are strings, namely relative paths, which is why each input object to the Where-Object script block (reflected in automatic $_ variable) is matched as whole against a wildcard expression that matches strings that start with image\.

    Without -Name, System.IO.FileInfo instances would be output, in which case you'd have to use the following filter command:
    Where-Object { $_.FullName -notlike '*\image\*' } or - using Where-Object's simplified syntax:
    Where-Object FullName -notlike *\image\*

    Note that, as of PowerShell 7.4.x, simplified syntax is currently not available for operations performed on the input object as a whole, because the name of a property to operate on is required. That is,
    Where-Object -notlike *\image\* - with the LHS operand implicitly being the whole input object ($_) - does not work, though supporting that is being discussed in GitHub issue #8357.