Why can "find" not be used in PowerShell?

4

1

What does find.exe find objectionable about the parameters when it is used in a PowerShell console shell?

These commands work as expected in a cmd.exe shell:

PS C:\Windows\System32\WindowsPowerShell\v1.0> find /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> find /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> C:\Windows\System32\find.exe /i "System.Diagnostics.Process" *.ps1xml
FIND: Parameter format not correct
PS C:\Windows\System32\WindowsPowerShell\v1.0> C:\Windows\System32\find.exe /i "System.Diagnostics.Process" .\DotNetTypes.format.ps1xml
FIND: Parameter format not correct

lit

Posted 2017-05-14T02:10:07.213

Reputation: 515

It isn't a Powershell command? Don't get confused between a executable ipconfig and a command shell command – Ramhound – 2017-05-14T02:29:39.300

What is it using other than C:\Windows\SYSTEM32\find.EXE? – lit – 2017-05-14T02:44:41.207

What exactly are you trying to do? Your third example uses invalid syntax – Ramhound – 2017-05-14T02:53:21.973

indeed I tried exactly the same command and it fails in PowerShell while gives proper output in cmd. Moreover where find works in cmd but doesn't in PowerShell – phuclv – 2017-05-14T02:54:34.883

I am in a PowerShell console. I want to search files for a string. find.exe does that. Yes, I know that PowerShell can also do that with Get-Content... etc. I am just trying to do something simple. Is that not possible in PowerShell? I have written a grep-like PowerShell script, but it is not on this system and I did not want to chase it down tonight. – lit – 2017-05-14T02:56:53.103

cross-site duplicate: PowerShell pipe into find.exe command

– phuclv – 2018-04-02T01:24:36.203

Answers

5

Try:

find /i "`"System.Diagnostics.Process`"" *.ps1xml

I used Sysmon.exe to compare the executions in PowerShell.exe and cmd.exe:

For cmd.exe:

 Image: C:\Windows\System32\find.exe
 CommandLine: find  /i "System.Diagnostics.Process" *.ps1xml
 ParentImage: C:\Windows\System32\cmd.exe

For PowerShell:

 Image: C:\Windows\System32\find.exe
 CommandLine: "C:\Windows\system32\find.exe" /i System.Diagnostics.Process *.ps1xml
 ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

we can see that in PowerShell, the quotes around the search-term are missing, so by adding another set of double-quotes it should work.

Peter Hahndorf

Posted 2017-05-14T02:10:07.213

Reputation: 10 677

1

That's because You must enclose string in quotation marks in find

– phuclv – 2017-05-14T03:28:18.910

1So, PowerShell strips the quotes from the command line parameter. Sneaky. Thanks. – lit – 2017-05-14T23:56:09.927

Well, most shells strip quotes from their own arguments; it would be surprising if PowerShell didn't do that. The unusual nonstandard behavior here is that FIND.EXE requires double quotes around the target string to look for, even though the double quotes themselves are not part of the target. – Ti Strga – 2020-01-16T17:01:59.057

4

As Peter Hahndorf said, PowerShell is stripping the outer quotes. See PowerShell stripping double quotes from command line arguments. You can check it by echoing or writing the string directly in command line

PS C:\> echo C:\Windows\System32\find.exe /i "System.Diagnostics.Process" *.ps1xml
C:\Windows\System32\find.exe
/i
System.Diagnostics.Process
*.ps1xml
PS C:\> "System.Diagnostics.Process"
System.Diagnostics.Process

IMHO it's a good thing because now you can use single quotes to wrap strings. You also have a standardized way to pass special characters in parameters similar to bash, unlike in cmd where embedded double quotes are a pain

According to PowerShell quoting rule you must escape the quote by either `backticks` or the double quote itself, or simply put it in single quotes

find.exe /i "`"System.Diagnostics.Process`"" *.ps1xml
find.exe /i """System.Diagnostics.Process""" *.ps1xml
find.exe /i '"System.Diagnostics.Process"' *.ps1xml

In simple cases like this when there's no space in the parameter you can also escape the double quotes directly without putting it inside another pair of quotes

find.exe /i `"System.Diagnostics.Process`" *.ps1xml

However there's an easier way with Verbatim arguments --%

In PowerShell 3.0 the special marker --% is a signal to PowerShell to stop interpreting any remaining characters on the line. This can be used to call a non-PowerShell utility and pass along some quoted parameters exactly as is.

As a result you can use it like this

find.exe --% "System.Diagnostics.Process" *.ps1xml

Or if you don't need Unicode support then you can simply find with findstr which doesn't need the quotes

PS C:\Users> help | findstr command
    topics at the command line.
    The Get-Help cmdlet displays help at the command line from content in

But if PowerShell is available then you can use its Select-String cmdlet directly. It's much more powerful than find and findstr

phuclv

Posted 2017-05-14T02:10:07.213

Reputation: 14 930