Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - Testing object arrays using Compare-Object and -contains

Reply
 
Old 08-31-2006   #1 (permalink)
Alex K. Angelopoulos [MVP]


 
 

Testing object arrays using Compare-Object and -contains

I'm having trouble finding a simple scheme for getting all objects which are
members of a set B but not also members of another set A.

The specific real problem is a tool for loading all registered snapins
automatically, but only attempting to do so if they are not already loaded.
I could of course do this:
Get-PsSnapin -Registered | Add-PSSnapin -ea SilentlyContinue
for quiet output, but that would be cheating (and would kill errors due to
reasons other than the snapin being already loaded).

We can get all loaded snapins like this:
$Loaded = Get-PSSnapin
and we can get all registered snapins like this:
$Registered = Get-PSSnapin -Registered
but $Loaded will contain any registered snapins that are already loaded.

I initially tried to test for containment, but the -contains operator does
not appear to work correctly for objects; it apparently compares members by
identity, and the PSSnapInInfo objects never test as identical; e.g., even
if all of the registered snapins are already loaded,
Get-PSSnapin -Registered | ?{$Loaded -notcontains $_}
passes through all of the objects.

Trying to do a Select-Object Name on each set doesn't correctly filter
identical items either.

Since -notcontains works fine on a simple array, my current approach is
this:

$Loaded = Get-PSSnapin | ForEach-Object {$_.Name}
Get-PSSnapin -Registered | ForEach-Object {
Where-Object {$Loaded -notcontains $_.Name}
} | Add-PSSnapin



I also checked into using Compare-Object. I like the way it works in terms
of the thinking behind it, but it takes some low-level unboxing to work
right. The shorthand is pretty lengthy:

diff (gsnp) (gsnp -r) | ?{$_.SideIndicator -eq "=>"} | %{
$_.InputObject} | asnp

and a fully-described comparison is very long:
Compare-Object (Get-PSSnapin) (Get-PSSnapin -Registered) |
Where-Object {$_.SideIndicator -eq "=>"} |
ForEach-Object {$_.InputObject} |
Add-PSSnapin

Compare-Object also takes a while to run; this is not really the kind of
thing it was specifically designed to do.

Does anyone have any better ideas on how to approach this?



My System SpecsSystem Spec
Old 08-31-2006   #2 (permalink)
Jouko Kynsijärvi


 
 

Re: Testing object arrays using Compare-Object and -contains

Alex K. Angelopoulos [MVP] wrote:
> I'm having trouble finding a simple scheme for getting all objects
> which are members of a set B but not also members of another set A.


> I also checked into using Compare-Object. I like the way it works in
> terms of the thinking behind it, but it takes some low-level unboxing
> to work right. The shorthand is pretty lengthy:
>
> diff (gsnp) (gsnp -r) | ?{$_.SideIndicator -eq "=>"} | %{
> $_.InputObject} | asnp


Here is another approach:

$a=@(gsnp | ?{ !$_.isdefault }); $a+=@(gsnp -r)
$a | group name | ?{ $_.count -eq 1} | asnp

> Compare-Object also takes a while to run; this is not really the kind
> of thing it was specifically designed to do.


In my testing Get-PSSnapin without -r is the slow one:
[~] (measure-command { get-pssnapin }).milliseconds
714
[~] (measure-command { get-pssnapin -r}).milliseconds
7

....Compare-Object on the other hand is quite fast:
[~] $a = 1..500; $b = 5..505
[~] (measure-command { compare-object $a $b }).milliseconds
61


My System SpecsSystem Spec
Old 08-31-2006   #3 (permalink)
Alex K. Angelopoulos [MVP]


 
 

Re: Testing object arrays using Compare-Object and -contains


"Jouko Kynsijärvi" <jouko.kynsijarvi@nospam.nospam> wrote in message
news:ujV822TzGHA.4232@TK2MSFTNGP05.phx.gbl...
> Alex K. Angelopoulos [MVP] wrote:
>> I'm having trouble finding a simple scheme for getting all objects
>> which are members of a set B but not also members of another set A.


> Here is another approach:
>
> $a=@(gsnp | ?{ !$_.isdefault }); $a+=@(gsnp -r)
> $a | group name | ?{ $_.count -eq 1} | asnp
>
>> Compare-Object also takes a while to run; this is not really the kind
>> of thing it was specifically designed to do.

>
> In my testing Get-PSSnapin without -r is the slow one:
> [~] (measure-command { get-pssnapin }).milliseconds
> 714
> [~] (measure-command { get-pssnapin -r}).milliseconds
> 7
>
> ...Compare-Object on the other hand is quite fast:
> [~] $a = 1..500; $b = 5..505
> [~] (measure-command { compare-object $a $b }).milliseconds
> 61


Whoops.
I had a spin-up pause because my Compare-Object had to evaluate Get-PSSnapin
before executing. Duh! :|


My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
compare-object PowerShell
compare object PowerShell
Compare-Object and Get the name of object/File? PowerShell
Compare-object doesn't seem to work with Arrays PowerShell
Adding canonical aliases for Compare-Object, Measure-Object, New-Object PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46