Home > Software engineering >  PowerShell unable to use two -Like comparison operators together
PowerShell unable to use two -Like comparison operators together

Time:07-26

I m learning PowerShell and one of the task I did is to filter a Csv file records.

Based on this link: https://4sysops.com/archives/create-sort-and-filter-csv-files-in-powershell/ I tried something similar to: Import-Csv -Path '.\sample.csv' | Select-Object EmailAddress,UniqueName,LastLoginDate | ? EmailAddress -like *gmail.com -Or ? EmailAddress -like *outlook.com | Export-Csv -Path $fileOut -NoTypeInformation

But the above gives me the error mentioned in the title. Based on this link: https://www.computerperformance.co.uk/powershell/match/ I addressed the error by using Where-Object instead after the Select-Object line as follows: Where-Object {$_.EmailAddress -Like "*gmail.com" -Or $_.EmailAddress -Like "*outlook.com"}

Why does the first example give me error but not the second example?

CodePudding user response:

tl;dr

  • Both your commands use the Where-Object cmdlet; ? is simply a built-in alias for it.

  • However, your commands use different syntax forms: your first command uses the simpler and more concise, but feature-limited individual argument-based simplified syntax, whereas your second one uses the verbose, but fully featured script-block syntax - see next section.

  • Because you need to combine multiple -like operations, you must use script-block syntax - simplified syntax limits you to a single operation.


Regular, script block-based syntax:

Example:

# You're free to add additional expressions inside { ... }
Where-Object { $_.EmailAddress -like '*gmail.com' }

uses a single argument that is a script block ({ ... }), inside of which the condition to test is formulated based on the automatic $_ variable that represents the input object at hand.

This syntax:

  • Places no constraints on the complexity of the expression - the whole PowerShell language is at your disposal inside a script block.

  • However, it is somewhat verbose.


Simplified, multi-argument syntax:

Example:

# Equivalent of the above.
# Note the absence of { ... }, $_, and "..." 
Where-Object EmailAddress -like *gmail.com

Simplified syntax is an alternative syntax that may be used with Where-Object as well as ForEach-Object, which:

  • as the name implies, is simpler and less verbose.
  • but is limited to a single conditional / operation based on a single property, or, in the case of method calls with ForEach-Object, the input object itself.

With simplified syntax the parts that make up a conditional / method call are passed as separate arguments, which therefore bind to distinct parameters that are specifically designed to work with this syntax:

  • Because separate arguments are used, there is no { ... } enclosure (no script block is used).

  • $_ need not be referenced, because its use is implied; e.g. EmailAddress is the equivalent of $_.EmailAddress in the script block-syntax.

    • A notable limitation as of PowerShell 7.2.x is that with Where-Object you cannot operate on the input object itself - you must specify a property. GitHub issue #8357 discusses overcoming this limitation in the future, but there hasn't been any activity in a long time.
  • As usual in argument-mode parsing, quoting around string values is optional, assuming they don't contain metacharacters such as spaces; e.g., *.gmail.com - without "..." or '...' - works with simplified syntax, whereas the expression-mode parsing inside the equivalent script block requires quoting, e.g. '*gmail.com'

  • Related