How to escape an asterisk? - powershell

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:\*

Related

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 do you use Get-Content with the exclude parameter?

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.

Test-Path -isValid with wildcards

I am trying to validate paths so I can provide meaningful error logging, and I am running into an issue with wildcards.
This returns False unless there is a folder and something in it, but it should return True.
Test-Path -isValid -path:"C:\Somefolder\*"
And like this doesn't work because -literalPath doesn't interpret wildcards.
Test-Path -isValid -literalPath:"C:\Somefolder\*"
My sense is that I am going to have to test for wildcards, and if found Test-Path -isValid on the parent folder. But then I run into issues with -like because I can't really test for a condition like *.EXT. Which has me thinking the only real answer is a RegEx, but this feels like something so basic I shouldn't really need to resort to a RegEx and I am probably missing something.
Note that for a variety of reasons I am limited to PS v2.
EDIT: To clarify, the actual path is variable. Users provide a path in an XML file, I then validate the path and do something with it. So, it might be that the user wants to delete all TXT files in a certain path. Or all files. Or even all files and subfolders. Thus C:\Somefolder\* needs to be supported. If they had C:\\Somefolder\* or C:Somefolder\* I would want to flag that as an invalid path. But C:\Somefolder\* when Somefolder doesn't exist is not an invalid path, it's a missing folder and I want to flag that as a different error.
Indeed you need a regular expression for validating a path specification. Something like this should work:
$re = '^[a-z]:[/\\][^{0}]*$' -f [regex]::Escape(([IO.Path]::InvalidPathChars -join ''))
'C:\something\*' -match $re # returns $true
The expression will match any string starting with a letter followed by a colon, a forward or backslash, and any number of valid path characters.
Note that consecutive path separators are valid in a path, so C:\\something\* -match $re will evaluate to $true as well, as it should.
If you want to validate actual (existing) paths instead of path specs you can use Get-ChildItem:
function Test-WildcardPath($Path) {
Get-ChildItem $Path -ErrorAction SilentlyContinue >$null
return $?
}
Again, C:\\something\* will evaluate to $true, since consecutive path separators are allowed in a path.
Can you try like this :
Test-Path -IsValid C:\Somefolder
Edit : then why don't you leave out the wildchars for test-path?
$test.Substring(0,($test.length-($test.Split("\")[-1]).length-1))

Passing a registry key with an asterisk to Test-Path

I want to run this registry path by Test-Path in PowerShell but it contains an asterisk, which is valid in the registry but not in Windows paths.
The problem is, when I pass it, Test-Path treats the asterisk as a wild card, so this takes a very, very long time because it checks all the sub paths of Classes and is not anything like what I want to test anyway.
Is there any way I can correctly pass that asterisk? Some escape mechanism?
Write-Host "Begin"
Test-Path "HKLM:\SOFTWARE\Classes\*\shell\Some shell extension"
Write-Host "End"
Use the -LiteralPath parameter to prevent globbing/wildcard matching.
-LiteralPath<String[]>
Specifies a path to be tested. Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any characters as escape sequences.
Write-Host "Begin"
Test-Path -LiteralPath "HKLM:\SOFTWARE\Classes\*\shell\Some shell extension"
Write-Host "End"