How do you use Get-Content with the exclude parameter? - powershell

I'm learning PowerShell and going through the parameters for Get-Content. I'm not sure how to use -Exclude with Get-Content.
I'm assuming it's supposed to be something like this:
Get-Content myfile.txt -Exclude "some string"
Am I using it wrong because it's not excluding some string in myfile.txt.

The -Exclude parameter does not apply to the content of files.
From the documentation:
-Exclude
Omits the specified items. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as "*.txt". Wildcards are permitted.

Related

How to escape an asterisk?

When I try to do anything with the path HKCR:\* it just takes forever. So I assume it takes the asterisk as wildcard.
Test-Path -Path HKCR:\*
What I've tried
HKCR:\\*
HKCR:\`*
'HKCR:\*'
Use the LiteralPath parameter rather than the Path parameter to prevent characters from being interpreted as wildcards.
Test-Path -LiteralPath HKCR:\*

How do I use square brackets in a wildcard pattern in PowerShell Get-ChildItem?

I want to list all files ending with some text in square brackets.
But neither Get-ChildItem *[* nor Get-ChildItem *`[* nor Get-ChildItem *``[* work.
How can I make this work without much ado (i.e. by creating variables, running additional commands through the pipe etc.)
The following, which includes one of the things you tried, should work, but currently[1] doesn't work due to a bug:
# SHOULD work, but CURRENTLY BROKEN:
Get-ChildItem *``[* # 1st ` is for string parsing, 2nd ` for wildcard escaping
Get-ChildItem "*``[*" # ditto, with double quotes
Get-ChildItem '*`[*' # single-quoted alternative, requires only 1 `
Note that the use of a (the first) positional argument implicitly binds to Get-ChildItem's -Path parameter.
The intent is for Get-ChildItem to see the following literal after argument parsing: *`[*, which correctly escapes [ with ` in order to treat it as a literal.
As an aside: unquoted *`[* is equivalent to double-quoted "*`[*", which results in literal *[*, because PowerShell's string parsing interprets the ` and effectively removes it.
Workarounds:
Instead of escaping the [ character, enclose it in [...], a character-set expression, which causes it to be matched literally:
Get-ChildItem *[[]* # OK
Interestingly, performing the filtering via -Include does not exhibit the bug:
Get-ChildItem * -Include '*`[*' # OK
Another option is to use -Filter instead of (implied) -Path, as demonstrated in Paxz's answer, but note that -Filter's wildcard language is not the same as PowerShell's (as supported by the -Path and -Include / -Exclude parameters); the -Filter argument is passed to the Windows API, whose wildcard language differs as follows:
It supports fewer constructs, notably no character sets or ranges ([...]).
It has legacy quirks - see this answer.
On the plus side, use of Filter, due to filtering at the source, performs better than letting PowerShell do the filtering via (implied) -Path or -Include.
Yet another option would be to add another layer of escaping, but that is ill-advised, because it will stop working once the bug is fixed:
# NOT RECOMMENDED: will stop working once the bug is fixed.
Get-ChildItem '*``[*'
[1] As of Windows PowerShell v5.1 / PowerShell Core 6.2.0-preview.3
You have to use the -Filter Parameter correct.
When you don't specify the Parameter, like you did in your examples, it will assume you want to use the first Parameter (in this case -Path, Ref. Get-ChildItem Doc).
Try this instead:
Get-ChildItem -Filter "*`[*"
This found the file ad.a[s] for me.
You can also change the filter to this:
Get-ChildItem -Filter "*`[*`]"
to expand it for the closing bracket.

PowerShell Test-Path -exclude

I need to perform a check on a target folder, and check if the file is from today and has more than 5kb
The below command provide a bool value based on the existence of the file using the today date, but I would like to add also an exclusion like -gt5kb
I tried to use -Exlcude but I'm not sure on how it work.
$integration = Test-Path 'C:\Users\EA\Desktop\CATS HTML*' -NewerThan (Get-Date -UFormat "%d/%m/%Y")
Do you have any advice on how can I include also the size check in the same statement?
This is not possible with the Test-Path cmdlet.
The exclude parameter is defined as follow:
Specifies items that this cmdlet omits. The value of this parameter
qualifies the Path parameter. Enter a path element or pattern, such as
"*.txt". Wildcard characters are permitted.
You will need a second method to perform the check. Here an example using the Get-Item cmdlet:
if (Get-Item 'yourfile.html'| Where-Object Length -gt 5kb) {
# do something
}

How to -Include using a variable with multiple criteria

I am trying to copy files with names that fulfills a given set of criteria from one folder to another. From this answer, I found that the -Include statement could be used for this.
My issue is that I need the criteria to be user-specified (through a variable), with the possibility of containing multiple criteria. That is, I try to do the following:
# THIS WORKS FINE
$includeFiles = "*tests.jar"
Copy-Item "from/path" "to/path" -Include $includeFiles
# THIS RETURNS NOTHING
$includeFiles = "*tests.jar, other.jar"
Copy-Item "from/path" "to/path" -Include $includeFiles
How do I work around this issue? Is it somehow possible to "destring" the variable, use another syntax or similar?
# THIS WORKS FINE
$copyPattern = "*tests.jar", "other.jar"
Copy-Item "from/path" "to/path" -Include $copyPattern
The point is that the argument to -Include is an array of strings, each string is a pattern to include. The way you wrote it would require a comma and space in the file name. So, unless you have such files, nothing would be included.
If you are positive that the pattern will never include commas and you'd rather just have a single string, you can of course convert it to an array:
$copyPatterns = "*tests.jar, other.jar" -split ', '
Note that parsing works differently in arguments to commands, which is why the following does work as well:
Copy-Item from/path to/path -Include *tests.jar,other.jar

In function repeat an action for each entered parameter

My main script run once gci on a specified drive via -path parameter , then it does multiple different tables from this output. Here below is a part of my script which does a specific table from an directory specified via -folder parameter, for example :
my-globalfunction -path d:\ -folder d:\folder
It work fine, but only for one entered folder path, the goal of this script is that user can enter multiple folders path and get a tables for each entered -folder parameter value, like this :
This clause in your Where-Object would be the issue:
$_.FullName.StartsWith($folder, [System.StringComparison]::OrdinalIgnoreCase)
The array of folders passed are most likely being cast as one long string which would never match. I had a regex solution posted but remembered a simpler way after looking at what your logic was trying to do.
Simpler Way
Even easier way is to put this information right into Get-ChildItem since it accepts string arrays for -Path. This way I don't think you even need to have 2 parameters since you never again use the results from $fol anyway. Based on the assumption that you were looking for all subfolders of $folder
$gdfolders = Get-ChildItem -Path $folder -Recurse -Force | Where-Object{$_.psiscontainer}
That would return all subfolders of the paths provided. If you have PowerShell 3.0 or higher this would even be easier.
$gdfolders = Get-ChildItem -Path $folder -Recurse -Force -Directory
Update from comments
The code you have displayed is incomplete which is what lead me to the solution that you see above. If you do use the variable $fol somewhere else that you do not show lets go back to my earlier regex solution which would work better in place with what you already have.
$regex = "^($(($folder | ForEach-Object{[regex]::Escape($_)}) -join "|")).+"
....
$gdfolders = $fol | Where-Object{($_.Attributes -eq "Directory") -and ($_.FullName -match $regex)}
What this will do is build a regex compare string with what I will assume is the logic of locate folders that begin with either of paths passed.
Using your example input of "d:\folder1", "d:\folder2" the variable $regex would work out to ^(d:\\folder1|d:\\folder2). The proper characters, like \, are escaped automatically by the static method [regex]::Escape which is applied to each element. We then use -join to place a pipe which, in this regex capture group means match whats on the left OR on the right. For completeness sake we state that the match has to occur at the beginning of the path with the caret ^ although this is most likely redundant. It would match paths that start with either "d:\folder1" or "d:\folder2". At the end of the regex string we have .+ which means match 1 to more characters. This should ensure we dont match the actual folder "d:\folder1" but meerly its children
Side Note
The quotes in the line with ’Size (MB)’ are not the proper ones which are '. If you have issues around that code consider changing the quotes.