Where-in and Where-Property-in
November 15th, 2010 by KarlI’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 »
