Handling Array With Multiple Object Types

Hi again, another curious question.

I’m trying to handle an array of users in local groups by doing the following:

$groupuser = Get-CimInstance -Query "SELECT * FROM Win32_GroupUser WHERE GroupComponent=""Win32_Group.Domain='$computername',Name='$group'"""

$groupuser

GroupComponent                         PartComponent                          PSComputerName                        
--------------                         -------------                          --------------                        
Win32_Group (Name = "Administrators... Win32_UserAccount (Name = "Administ...                                       
Win32_Group (Name = "Administrators... Win32_UserAccount (Name = "AUser", D...                                       
Win32_Group (Name = "Administrators... Win32_Group (Name = "Group1"...                                       
Win32_Group (Name = "Administrators... Win32_Group (Name = "Group2", D...                                       
Win32_Group (Name = "Administrators... Win32_Group (Name = "Group3",...       

This retrieves a list of members in the group wonderfully if I narrow it down further by doing $groupuser.PartComponent.Name.

Now here’s where it gets ugly. I want to shove the results into another array variable (or further refine the $groupuser var) by reducing this list to just a list of users in the array, not groups. However, as you can probably already tell, this array is made up of objects of multiple types:

PS H:\> $groupuser.PartComponent | gm


   TypeName: Microsoft.Management.Infrastructure.CimInstance#ROOT/cimv2/Win32_UserAccount

Name                      MemberType  Definition                                                                    
----                      ----------  ----------                                                                    
Clone                     Method      System.Object ICloneable.Clone()                                              
Dispose                   Method      void Dispose(), void IDisposable.Dispose()                                    
Equals                    Method      bool Equals(System.Object obj)                                                
GetCimSessionComputerName Method      string GetCimSessionComputerName()                                            
GetCimSessionInstanceId   Method      guid GetCimSessionInstanceId()                                                
GetHashCode               Method      int GetHashCode()                                                             
GetObjectData             Method      void GetObjectData(System.Runtime.Serialization.SerializationInfo info, Sys...
GetType                   Method      type GetType()                                                                
ToString                  Method      string ToString()                                                             
AccountType               Property    uint32 AccountType {get;}                                                     
Caption                   Property    string Caption {get;}                                                         
Description               Property    string Description {get;}                                                     
Disabled                  Property    bool Disabled {get;set;}                                                      
Domain                    Property    string Domain {get;}                                                          
FullName                  Property    string FullName {get;set;}                                                    
InstallDate               Property    CimInstance#DateTime InstallDate {get;}                                       
LocalAccount              Property    bool LocalAccount {get;set;}                                                  
Lockout                   Property    bool Lockout {get;set;}                                                       
Name                      Property    string Name {get;}                                                            
PasswordChangeable        Property    bool PasswordChangeable {get;set;}                                            
PasswordExpires           Property    bool PasswordExpires {get;set;}                                               
PasswordRequired          Property    bool PasswordRequired {get;set;}                                              
PSComputerName            Property    string PSComputerName {get;}                                                  
SID                       Property    string SID {get;}                                                             
SIDType                   Property    byte SIDType {get;}                                                           
Status                    Property    string Status {get;}                                                          
PSStatus                  PropertySet PSStatus {Status, Caption, PasswordExpires}                                   


   TypeName: Microsoft.Management.Infrastructure.CimInstance#ROOT/cimv2/Win32_Group

Name                      MemberType  Definition                                                                    
----                      ----------  ----------                                                                    
Clone                     Method      System.Object ICloneable.Clone()                                              
Dispose                   Method      void Dispose(), void IDisposable.Dispose()                                    
Equals                    Method      bool Equals(System.Object obj)                                                
GetCimSessionComputerName Method      string GetCimSessionComputerName()                                            
GetCimSessionInstanceId   Method      guid GetCimSessionInstanceId()                                                
GetHashCode               Method      int GetHashCode()                                                             
GetObjectData             Method      void GetObjectData(System.Runtime.Serialization.SerializationInfo info, Sys...
GetType                   Method      type GetType()                                                                
ToString                  Method      string ToString()                                                             
Caption                   Property    string Caption {get;}                                                         
Description               Property    string Description {get;}                                                     
Domain                    Property    string Domain {get;}                                                          
InstallDate               Property    CimInstance#DateTime InstallDate {get;}                                       
LocalAccount              Property    bool LocalAccount {get;set;}                                                  
Name                      Property    string Name {get;}                                                            
PSComputerName            Property    string PSComputerName {get;}                                                  
SID                       Property    string SID {get;}                                                             
SIDType                   Property    byte SIDType {get;}                                                           
Status                    Property    string Status {get;}                                                          
PSStatus                  PropertySet PSStatus {Status, Name} 

So is there a way of simply focusing on just the one type of objects in the array? I figured if I can just narrow it to the Win32_UserAccount type, I can get just users.

Even if this isn’t the best solution for this particular goal, I’m still curious if it’s possible to distinguish objects in an object array via type.

This should do the trick:

$users = $groupuser.PartComponent | Where-Object { $_.CimClass.CimClassName -eq 'Win32_UserAccount' }
$users

Beautiful! I will definitely need to peruse namespaces more for valuable items like this.