Welcome to MSDN Blogs Sign in | Join | Help

When NOT To Use "WHERE"

I've seen a number of scripts that look like this:

 GET-XXXX | Where {$_.name -eq "foo"} 

or

GET-XXXX | Where {$_.name -like "A*"}

Whenever you see code like this, it is a sign that the GET-XXXX is not designed correctly.   (NOTE:  GET-XXXX is NOT a porn retrieval cmdlet - it is a standin for any GET-<SOMETHING> cmdlet).

The whole point of a cmdlet is to think about the USER and deliver the correct experience.  As a GENERAL rule, we encourage cmdlet developers to leverage PowerShell utilities like WHERE, SORT, FORMAT, etc and NOT to put that function into their cmdlets.  The reason for this is that this makes the cmdlet more complicated and provides NEW semantics that the user has to learn.

There are a couple of exceptions to this general rule:

  1. GET cmdlets should support -NAME.  A VERY large percentage of the time people do a GET, they want a specific item or a set of NAMED items so you should hotrod this experience by directly supporting it.
    • NAME should take a multiple inputs and support wildcards. e.g.  "get-process -name *ss,a*"
  2. GET cmdlets should support -FILTER if your getter has native query capabilities.  Users can decide whether the perf advantage of your cmdlet is worth learning the new syntax [in most cases it will be].
    • e.g.  If/when there are a set of AD cmdlets, they should support -FILTER and take an LDAP query. 
    • The APIs that support Get-Process have no native filtering which is why it doesn't support it but the file system APIs do which is why "DIR -FILTER A*" works.

Cheers!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Published Tuesday, August 12, 2008 12:32 PM by PowerShellTeam
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: When NOT To Use "WHERE"

Have you considered translating the input

GET-XXXX | Where {$_.name -eq "foo"}

to GET-XXXX -Name "foo"

The | WHERE {...} syntax is the easiest to write and understand. This seems to be a simple mapping in which the where-object scriptblock is translated back to -name (in this case).

GET-XXXX | Where {$_.path -eq "foo"}

to GET-XXXX -include YYYY

The include translation probably needs some extra attribute(s) on the cmdlet to map the where-object scriptblock to include/exclude/etc string(s)...

The ultimate extension would map where-object scriptblock to a cmdlet's filter by using expression trees (where the cmdlet translates the expression tree to the provider specific filter expression) :)

Tuesday, August 12, 2008 4:44 PM by George Tsiokos

# re: When NOT To Use "WHERE"

Since most comdlets deal with sequences of items, filter seems being a common attribute. That is why it could be worth providing a special syntax rule for filtering. One could treat filtered query as a "protected statement" in some programming languages. The statement must be true if some condition was satisfied.

Providing special syntax could solve the problem of interaction between "where-object" and the preceeding get-* cmdlet. Cmdlet author could specify whether the code supports filtering on its own by implementing corresponding interface. If so PowerShell should pass the query text to the cmdlet via property or method. Else PowerShell calls "where-object".

This way we could eliminate feature and code duplication in the user's eyes. And more important is to eliminate the ambiguity.

Tuesday, August 12, 2008 11:16 PM by Aleksei Guzev

# re: When NOT To Use "WHERE"

Sometimes it's not the cmdlet, it's that the user just isn't aware :). I tell my students to "move filtering as far to the left of the command-line as possible," so they have a general rule to read up on the cmdlets they're using and see if they do support -filter or something.

Thursday, August 14, 2008 11:05 AM by Don Jones

# re: When NOT To Use "WHERE"

File System APIs have native filtering - How does one filter based on date without using where?

e.g.

get-childitem | where-object {$_.lastwritetime -ge [datetime]::Today}

Or, is is just by name that you can do this with the fs and get-childitem?

Friday, August 15, 2008 11:21 AM by Andrew

# re: When NOT To Use "WHERE"

Yes there are many ways to filter and select locally without using WHERE, but when dealing with remote systems and WMI WHERE is a necessity. Hopefully with a future release of powershell some of the cmdlets will have built in remoting capability.

Thursday, August 21, 2008 12:02 PM by Bryan Fairchild

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker