Blogroll

Search

Where-in and Where-Property-in

November 15th, 2010 by Karl

I’m back again in my quest for general purpose functions slicing and dicing objects and keeping it all in the pipeline.

So in PowerShell you often use the pattern in the pipeline of get-something | where { $_.property -eq $null }

However often you need something more complex. In one case you want to do something similar to to a SQL in.. like select * from mytable where mycolumn in (1,2,3) or such.

in powershell you can do this relatively easily with -CONTAINS but the semantics can be confusing as it seems backwards to us. Here is an example

get-process | where { ("svchost","outlook","powershell" ) -contains $_.processname }

but what if you want to express this differently, and you also want to be able to apply expressions

where-in and where-propertyin are filters that allow to pass through pipeline object that are in a specified array/collection, or that have a property that is in an array or collection. They also can take a scriptblock that can be used to implement a comparision when the relationship isn’t exact. in that scriptblock the variable $__ is created to represent the item in the collection being compared with the pipeline $_ object.

here are some examples

$a = (1..10) , (1..10) | % { $_ } #create some sample data
$a | Where-in (3,4,8)

and with properties

gps | where-propertyin ("powershell","svchost") processname

in hindsight the following would syntax would be a little more intuitive (but its not implemented in this function but could be )

gps | where-property processname -in ("powershell","svchost")

and if you want to graduate to actual expressions with scriptblocks, in adition to the usual PIPELINE object $_ , i added $__ which is the object from the IN list to compare with. Here are some examples.

gps | where-in  ("power","s")  { $_.processname.startswith($__) }

and with properties

gps | where-propertyin ("power","s") processname { $_.startswith($__) }

I also like to use ?. for the alias for this..

and now for the functions themselves

function where-in {
[cmdletbinding()]
param (
[parameter(mandatory = $true,position = 1)]
[system.Collections.IEnumerable]$collection,
[parameter(position = 2)]
[scriptblock]$predicate ,
[parameter(valuefrompipeline = $true)]
$pipelineobject
)
    process {
        if ($predicate) {
            foreach ($__ in $collection) {
                if(&$predicate) {
                    write-Output $pipelineobject
                    break;
                }
            }
        }
        else {
            if ($collection -contains $pipelineobject) {
            write-Output $pipelineobject }
        }
    }
}
set-alias ?in where-in

function where-propertyin {
[cmdletbinding()]
param (
[parameter(mandatory = $true,position = 1)]
[system.Collections.IEnumerable]$collection,
[parameter(mandatory = $true,position = 2)]
[string] $propertyname,
[parameter(position = 3)]
[scriptblock]$predicate ,
[parameter(valuefrompipeline = $true)]
$pipelineobject
)
    process {
        if ($predicate) {
            foreach ($__ in $collection) {
                $_ = $pipelineobject.$propertyname
                if(&$predicate) {
                    write-Output $pipelineobject
                    break;
                }
            }
        }
        else {
            if ($collection -contains $pipelineobject.$propertyname) {
            write-Output $pipelineobject }
        }
    }
}
set-alias ?.in where-propertyin

Posted in Powershell | No Comments »

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.