none
Combine two arrays of objects for one continuous display RRS feed

  • Question

  • I'm trying to combine certain properties of the WMI classes PageFileSetting and PageFileUsage into one collection of some sort that will allow me to output the entire collection on the display, as follows:

    [array]$PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server |
      Select-Object -Property `
      @{L = 'Name'; E = {$_.Name}},
      @{L = 'Size'; E = {$_.MaximumSize}}
     
    [array]$PFUsage = gwmi -Class win32_PageFileUsage -ComputerName $server |
      Select-Object -Property `
     @{L = 'Current Usage(gb)'; E = {$_.CurrentUsage}},
     @{L = 'Peak Usage(gb)'; E = {$_.PeakUsage}}

    The result I'm looking for would be this:

    Name                 Size      Current Usage    Peak Usage
    ----                    ----       -------------        ----------
    c:\pagefile.sys    16                      15                 15
    d:\pagefile.sys    12288            1365             1365
    e:\pagefile.sys    4096              1140             1386
    f:\pagefile.sys     4096              1096             1358
    h:\pagefile.sys    6144              1132             1377

    However, I have been unable to figure out how to combine them, or exactly what object or otherwise 'entity' to combine them into, that would allow them to be displayed together across the screen as shown. Can anyone help please?


    Tony Auby

    Sunday, July 5, 2015 2:27 AM

Answers

  • How about something like this?

    $PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server |
        Select-Object Name, MaximumSize
     
    $PFUsage = gwmi -Class win32_PageFileUsage -ComputerName $server |
        Select-Object Name, CurrentUsage, PeakUsage
    
    $PFSummary = @()
    foreach ($PF in $PageFiles) {
        $PFSummary += [pscustomobject]@{
            Name = $PF.Name
            Size = $PF.MaximumSize
            Current = ($PFUsage | where Name -eq $PF.Name).CurrentUsage
            Peak = ($PFUsage | where Name -eq $PF.Name).PeakUsage
        }
    }
            
    $PFSummary

    Sunday, July 5, 2015 8:44 AM

All replies

  • How about something like this?

    $PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server |
        Select-Object Name, MaximumSize
     
    $PFUsage = gwmi -Class win32_PageFileUsage -ComputerName $server |
        Select-Object Name, CurrentUsage, PeakUsage
    
    $PFSummary = @()
    foreach ($PF in $PageFiles) {
        $PFSummary += [pscustomobject]@{
            Name = $PF.Name
            Size = $PF.MaximumSize
            Current = ($PFUsage | where Name -eq $PF.Name).CurrentUsage
            Peak = ($PFUsage | where Name -eq $PF.Name).PeakUsage
        }
    }
            
    $PFSummary

    Sunday, July 5, 2015 8:44 AM
  • Thanks so much-- a concise elegant solution, and VERY instructive! However, at first I was getting an error. It refers to line2,char1, the initial $pageFiles gwmi object retrieval. For some reason, I had to cast that variable to an [array] to resolve.

    Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Collections.Hashtable".
    At D:\AUBYT001\Scripts\PFDisplay.ps1:2 char:1
    + $PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server | Select Na ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
        + FullyQualifiedErrorId : RuntimeException

    Name                         Size                         Current                     Peak                      
    ----                         ----                         -------                     ----                      

    $server = "computer01"
    [array]$PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server |
         Select Name, MaximumSize
    [array]$PFUsage = gwmi -Class win32_PageFileUsage -ComputerName $server |
         Select Name, CurrentUsage, PeakUsage
    $PFSummary = @()
    foreach ($PF in $PageFiles) {
        $PFSummary += [pscustomobject]@{
            Name = $PF.Name
            Size = $PF.MaximumSize
            Current = ($PFUsage | where Name -eq $PF.Name).CurrentUsage
            Peak = ($PFUsage | where Name -eq $PF.Name).PeakUsage
        }
    }
    $PFSummary | Format-Table -autosize

    Name               Size          Current Peak
    ----                  -------       -------   ------
    c:\pagefile.sys    16          15         15
    d:\pagefile.sys   12288     1007      1365
    e:\pagefile.sys   4096       1033      1386
    f:\pagefile.sys    4096        997      1358
    h:\pagefile.sys   6144      1019       1377

    Thanks again!!


    Tony Auby

    Sunday, July 5, 2015 4:19 PM
  • You're welcome. I ran the script on a Windows Server 2003 and it worked for me without casting to array. Not sure why you got an error. Perhaps someone else can come up with an explanation.
    Sunday, July 5, 2015 8:13 PM
  • If WMI returns a singleton it will not be wrapped as an array.

    Example:

    PS C:\scripts> $b=gwmi Win32_Bios
    PS C:\scripts> $b.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     ManagementObject                         System.Management.ManagementBaseObject
    

    Now we get an obviously multi result:

    PS C:\scripts> $na=gwmi win32_networkadapter
    PS C:\scripts> $na.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS C:\scripts>

    Now we force that to a singleton:

    PS C:\scripts> $na=gwmi win32_networkadapter -filter 'DeviceId=1'
    PS C:\scripts> $na.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     ManagementObject                         System.Management.ManagementBaseObject
    
    
    PS C:\scripts>
    

    Now we wrap it:

    PS C:\scripts> [array]$na=gwmi win32_networkadapter -filter 'DeviceId=1'
    PS C:\scripts> $na.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    

    N'est-ce pas?


    \_(ツ)_/

    Sunday, July 5, 2015 8:23 PM
  • So if gwmi -Class win32_PageFileSetting returns only one object it will not be wrapped in an array? If that is the case I don't understand why I did not get an error as my query returned only a single object, and judging by Tony's output his query returned 5 objects.
    Sunday, July 5, 2015 8:39 PM
  • Thanks for continuing to help.

    But since, in our example here, the line is returning 5 'page file' objects, so not a singleton (as you called it), shouldn't PS have created $pagefiles as an array in the first place, making it unnecessary to cast it?

    $PageFiles = gwmi -Class win32_PageFileSetting -ComputerName $server | Select Name, MaximumSize


    Tony Auby


    • Edited by TonyAuby Sunday, July 5, 2015 8:48 PM
    Sunday, July 5, 2015 8:45 PM
  • With select:

    PS C:\> $p = gwmi -Class win32_PageFileSetting -Comp $server -Cred $cred | Select Name, MaximumSize
    PS C:\> $p.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    PSCustomObject                           System.Object

    Without select:

    PS C:\> $p = gwmi -Class win32_PageFileSetting -Comp $server -Cred $cred
    PS C:\> $p.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     ManagementObject                         System.Management.ManagementBaseObject

    As you can see, no arrays and no errors.

    Sunday, July 5, 2015 9:13 PM
  • Point is that OP did not use your code.  He used an array approach and apparently hasn't posted it.

    Just look at the error:

    Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Collections.Hashtable".

    My answer was in response to the question and not to the error.

    The real issue is, what code caused that error?


    \_(ツ)_/

    Sunday, July 5, 2015 10:07 PM
  • Hmmm. I can't re-generate the error now-- without the [array] casting. It may have been the IDE I'm using, maybe something retained in the session after multiple test executions, alterations, etc.

    So, sorry for the extra trouble. Thanks again, both of you for your help here. The world of PSCustomObject is now open to me!


    Tony Auby

    Monday, July 6, 2015 12:25 AM