8

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
7
  • It isn't a Powershell command? Don't get confused between a executable ipconfig and a command shell command
    – Ramhound
    May 14 '17 at 2:29
  • What is it using other than C:\Windows\SYSTEM32\find.EXE?
    – lit
    May 14 '17 at 2:44
  • What exactly are you trying to do? Your third example uses invalid syntax
    – Ramhound
    May 14 '17 at 2:53
  • 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
    May 14 '17 at 2:54
  • 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
    May 14 '17 at 2:56
8

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.

3
  • 2
    That's because You must enclose string in quotation marks in find
    – phuclv
    May 14 '17 at 3:28
  • 1
    So, PowerShell strips the quotes from the command line parameter. Sneaky. Thanks.
    – lit
    May 14 '17 at 23:56
  • 1
    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
    Jan 16 '20 at 17:01
5

TL;DR:

Escape the double quotes or put the string inside single quotes

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

or use verbatim arguments

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

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 like above

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

0

It works fine in PowerShell if you use the single-double-quote format like this:

find '"whateveryouarelookingfor"'
find /v '"whateveryouareremoving"'

That is, single-quotes before the double-quotes on the string you are searching for.

I imagine this has to do with PowerShell stripping the quotes off otherwise before passing the command to the function/exe. I am not an expert in PowerShell, however I do know batch. With the /v command you can remove an entire unwanted line with a keyword.

1
  • how does this add any new information compared to the current answers?
    – phuclv
    Nov 21 '20 at 9:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.