Use the -Exclude parameter, which allows you to specify an array of exclusion wildcard patterns - but see the caveats below:
Get-ChildItem -Exclude *.xml, *.txt, *.log -Path $target_cis -Recurse -File |
Remove-Item -WhatIf
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.
Post-filtering solution, building on your own attempt:
While it is generally preferable to solve a problem directly with a given cmdlet's parameter - both for concision and performance - as of PowerShell 7.2.2, there are good reasons to perform the filtering separately, applying it after Get-ChildItem has returned its (unfiltered) results (which is what you attempted):
While -Include / -Exclude work as expected with Get-ChildItem -Recurse, they don't without it, and it's not easy to remember this fact - see the bottom section.
Combining -Include / -Exclude with Get-ChildItem -Recurse is unexpectedly slow - even slower than a post-filtering solution: see GitHub issue #8662
Get-ChildItem -Path $target_cis -Recurse -File |
Where-Object { $_.Extension -notin '.xml', '.txt', '.log' } |
Remove-Item -WhatIf
That is, switching from the -ne operator in your attempt ($_.Extension -ne ".xml") to the
-notin operator allows placing an array of strings on the RHS to test the the LHS string against:
$_.Extension -notin '.xml', '.txt', '.log' returns $true if the value of $_.Extension is not present in the RHS array (using implicit -eq testing against each element).
Caveats as of PowerShell 7.2.2:
It is solely because your commands use -Recurse for recursive traversal with Get-ChildItem that -Exclude and -Include work as one would expect; without -Recurse, these parameters exhibit counter-intuitive behavior - see this answer.
With Copy-Item, even -Recurse wouldn't make -Include work, though -Exclude would mostly work as expected:
That is, while you should be able to use -Include with multiple wildcard patterns for inclusionary matching directly with Copy-Item -Recurse in order to limit what is copied to begin with, it doesn't work.
-Include is mistakenly applied to the immediate target directory and only to it:
- If none of the specified patterns match its name, nothing is copied.
- If any specified pattern does match its name, the whole directory subtree is copied without filtering.
-Exclude, by contrast, mostly works as expected: it applies the exclusion patterns on each level of the directory subtree hierarchy.
- If any exclusion pattern happens to match the name of the immediate target directory, nothing is copied.
See this answer for a detailed discussion, including a problem with how -Destination arguments are interpreted.