Why are you mixing a PowerShell alias with a DOS executable (find.exe)?
DOS/cmd.exe commands have requirements. It is why you are getting the issue you are seeing. Many cmd.exe/DOS commands do fin without quotes at all, some don't.
In PowerShell proper, you don't need double quotes for simple strings. You need them for variable expansion when a variable is included in a string and a few other formatting instances, but not what you are doing.
You are in Powershell, so, best to do this the PowerShell way. If this is throw-away code, or interactive console, stuff, using aliases is fine, but don't use aliases in functions, scripts, modules, aka production code.
As per Microsoft:
• Best Practices for aliases Best Practice for Using Aliases in
PowerShell Scripts
https://devblogs.microsoft.com/scripting/best-practice-for-using-aliases-in-powershell-scripts
https://devblogs.microsoft.com/scripting/using-powershell-aliases-best-practices
Why worry about aliases in the first place?
What is the big deal about using aliases anyway? If they make the code
easier to type, what is the harm in using them in scripts? There are
two things at work when it comes to a script. The first is that no
alias is guaranteed to exist—even aliases that are created by Windows
PowerShell.
So, this ...
echo abc | find "a"
... should be this...
Get-Alias -Name echo |
Format-Table -AutoSize
# Results
<#
CommandType Name Version Source
----------- ---- ------- ------
Alias echo -> Write-Output
#>
Write-Output -Object 'abc' | Select-Object 'a'
or this...
Write-Output -Object 'abc' | Select-String -Pattern 'a'
or this...
Select-String -Pattern 'a' -InputObject 'abc'
Results
<#
abc
#>
Get-Alias -Name echo | Format-Table -AutoSize
Results
<#
CommandType Name Version Source
Alias echo -> Write-Output
#>
Get-Alias -Name xcopy | Format-Table -AutoSize
Results
<#
Get-Alias : This command cannot find a matching alias because an alias with the name 'xcopy' does not exist.
At line:1 char:1
#>
As you can see the above is using cmd.exe/DOS executable, not an alias
So, change to this.
Get specifics for a module, cmdlet, or function
(Get-Command -Name Copy-Item).Parameters
(Get-Command -Name Copy-Item).Parameters.Keys
Get-help -Name Copy-Item -Examples
Get-help -Name Copy-Item -Full
Get-help -Name Copy-Item -Online
'.txt', '.xls' |
ForEach-Object {
Copy-Item -Path "d:\temp$PSItem" -Destination 'D:\Temp\ChildFolder' -WhatIf
}
Results
<#
What if: Performing the operation "Copy File" on target "Item: D:\temp\abc.txt Destination: D:\Temp\ChildFolder\abc.txt".
What if: Performing the operation "Copy File" on target "Item: D:\temp\account.txt Destination: D:\Temp\ChildFolder\account.txt".
...
#>
about_Command_Precedence
If you do not specify a path, PowerShell uses the following precedence
order when it runs commands for all items loaded in the current
session:
1 - Alias
2 - Function
3 - Cmdlet
4 - External executable files
(programs and non-PowerShell scripts)
Therefore, if you type "help", PowerShell first looks for an alias
named help, then a function named Help, and finally, a cmdlet named
Help. It runs the first help item that it finds.
For example, if your session contains a cmdlet and a function, both
named Get-Map, when you type Get-Map, PowerShell runs the function.
Yes, you can use cmd.exe/DOS executable in a PowerShell command or script, but when you do, they must conform to cmd.exe/DOS particulars. Calling external executables from Powershell is a well-documented thing.
• PowerShell: Running Executables
https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx
Try to avoid mixing cmd.exe/DOS executables in PowerShell scripts and use the PowerShell equivalents instead. Note: There are times this cannot be avoided, but not in your use case as posted.
Update
As per your comment
write-host abc | select-string -pattern "a" shows the result expected
- abc. But This unfortunately also shows abc. write-host abc | select-string -pattern "z"
That should have been Write-Output, not Write-Host, Corrected the above.
No need for the Write-Host or Write-Output thing at all for what you are doing. Output to the screen is the PoweShelll default unless you tell it otherwise. If you are saying, you only want the letter 'a' of the string, then you need to pass it as an array, not a single string
'a','b','c' |
Select-String -Pattern 'a'
# Results
<#
a
#>
'a','b','c' |
Select-String -Pattern 'z'
Results
<#
#>
Here is another way to split a single string into an array.
('abc').ToCharArray() |
Select-String -Pattern 'a'
You could also use the .Net namespace directly
[regex]::Match('abc','a').Value
# Results
<#
a
#>
Results
<#
#>
PowerShell is an Object-Oriented language and expects and emits objects by default, not strings.
You can convert things to strings or pass in strings in several different ways for comparison, matching, reporting needs.