Issues with multiple pscustom objects and multiple for each loops

Welcome Forums General PowerShell Q&A Issues with multiple pscustom objects and multiple for each loops

This topic contains 9 replies, has 3 voices, and was last updated by

 
Participant
3 weeks ago.

  • Author
    Posts
  • #146240

    Participant
    Points: 94
    Rank: Member

    Good afternoon experts
    Attempting to get the following script to work with multiple computers. If I set $serverlist to one computer the script works but when i set to $serverlist to multiple computers the script fails and not sure how to get it work. Don't know how to combine the two for each loops together, had enough of a headache just getting the script to work with one computer.
    Any suggestions as to how I can get this work for multiple computers?

    thank you for any and all input

    Norm

    
    $ServerList = Get-ADComputer -Filter "OperatingSystem -like '*2012*'" -properties * | select-object -ExpandProperty Name
    #$ServerList = $env:COMPUTERNAME
    
    foreach ($ComputerName in $ServerList) {
    $Session = New-CimSession -ComputerName $ComputerName
    $System = Get-CimInstance -CimSession $Session -ClassName CIM_ComputerSystem
    $OS = Get-CimInstance -CimSession $Session -ClassName CIM_OperatingSystem
    $memalloc = [math]::round($System.TotalPhysicalMemory/1GB, 0)
    
    
    [PSCustomObject]@{
    ComputerName = $System.Name
    RAM = $memalloc
    Manufacturer = $System.Manufacturer
    OS = $OS.Caption
    OSVersion = $OS.Version
    LastBootUpTime = $OS.LastBootUpTime
    
    }
    
    }
    
    $Disks = get-wmiobject -class "Win32_LogicalDisk" -namespace "root\CIMV2" -ComputerName $ComputerName
    foreach ($Disk in $Disks) {
    
    if ($Disk.size -gt 0)
    {
    
    $size = [math]::round($disk.Size/1GB, 0)
    $free = [math]::round($disk.FreeSpace/1GB, 0)
    [PSCustomObject]@{
    Drive = $disk.Name
    "Total Disk Size" = $size
    "Free Disk Size" = "{0:N0} ({1:P0})" -f $free, ($free/$size)
    }
    }
    }
    
  • #146264

    Participant
    Points: 315
    Helping Hand
    Rank: Contributor

    Your disk loop is outside the main computerlist loop.

    This is one way of doing it:

    $ServerList = Get-ADComputer -Filter "OperatingSystem -like '*2012*'" -properties * | select-object -ExpandProperty Name
    #$ServerList = $env:COMPUTERNAME
    
    foreach ($ComputerName in $ServerList) {
        $Session = New-CimSession -ComputerName $ComputerName
        $System = Get-CimInstance -CimSession $Session -ClassName CIM_ComputerSystem
        $OS = Get-CimInstance -CimSession $Session -ClassName CIM_OperatingSystem
        $memalloc = [math]::round($System.TotalPhysicalMemory/1GB, 0)
    
        $Disks = get-wmiobject -class "Win32_LogicalDisk" -namespace "root\CIMV2" -ComputerName $ComputerName
        $DiskObjects = foreach ($Disk in $Disks) {
            if ($Disk.size -gt 0) {
                $size = [math]::round($disk.Size/1GB, 0)
                $free = [math]::round($disk.FreeSpace/1GB, 0)
                [PSCustomObject]@{
                    Drive = $disk.Name
                    "Total Disk Size" = $size
                    "Free Disk Size" = "{0:N0} ({1:P0})" -f $free, ($free/$size)
                }
            }
        }
    
        [PSCustomObject]@{
            ComputerName = $System.Name
            RAM = $memalloc
            Manufacturer = $System.Manufacturer
            OS = $OS.Caption
            OSVersion = $OS.Version
            LastBootUpTime = $OS.LastBootUpTime
            DiskInformation = $DiskObjects
        }
    }
    
    

    This uses a DiskInformation object under the main computer object

  • #146558

    Participant
    Points: 94
    Rank: Member

    Hello Sam,
    Thank you for your input, looks like we still have a issue with the output

    ComputerName    : FWAPP171
    RAM             : 12
    Manufacturer    : VMware, Inc.
    OS              : Microsoft Windows Server 2012 R2 Datacenter
    OSVersion       : 6.3.9600
    LastBootUpTime  : 3/21/2019 3:12:31 AM
    DiskInformation : {@{Drive=C:; Total Disk Size=80; Free Disk Size=43 (54 %)}, @{Drive=D:; Total Disk Size=350; Free Disk Size=269 (77 %)}, @{Drive=E:; Total Disk Size=1000; Free Disk Size=717 (72 %)}, @{Drive=P:; Total Disk 
                      Size=8; Free Disk Size=4 (50 %)}}
    

    Have not come across this type of issue before.

    Again thanks for your input

    Norm

  • #146565

    Participant
    Points: 94
    Rank: Member

    Hello Sam;
    Looks like I need to expand the contents of $DiskObjects. Did the following change and was able to get the drive id's to display:
    "$($DiskObjects.drive)"

    Don't know how to expand the contents of $Diskobjects to display Total Disk Size and Free Disk Size.

    Thanks again for your input

    Norm

  • #147035

    Participant
    Points: 94
    Rank: Member

    Good afternoon experts
    Would greatly appreciate some help with this script. Sam's response was very helpful but have not been able to figure out how to fix the hash table output for $Diskobjects. Been working off and on for a couple of days trying to alter the pscustom object to deal with the hash table output but have failed to fix the problem. If someone could assist would greatly appreciate it!!!!

    
    $ServerList = Get-ADComputer -Filter "OperatingSystem -like '*2012*'" -properties * | select-object -ExpandProperty Name
    #$ServerList = $env:COMPUTERNAME
    
    foreach ($ComputerName in $ServerList) {
        $Session = New-CimSession -ComputerName $ComputerName
        $System = Get-CimInstance -CimSession $Session -ClassName CIM_ComputerSystem
        $OS = Get-CimInstance -CimSession $Session -ClassName CIM_OperatingSystem
        $memalloc = [math]::round($System.TotalPhysicalMemory/1GB, 0)
    
        $Disks = get-wmiobject -class "Win32_LogicalDisk" -namespace "root\CIMV2" -ComputerName $ComputerName
        $DiskObjects = foreach ($Disk in $Disks) {
            if ($Disk.size -gt 0) {
                $size = [math]::round($disk.Size/1GB, 0)
                $free = [math]::round($disk.FreeSpace/1GB, 0)
                [PSCustomObject][ordered]@{
                     Drive = $disk.Name
                    "Total Disk Size" = $size
                    "Free Disk Size" = "{0:N0} ({1:P0})" -f $free, ($free/$size)
                } 
            }
        }
    
        [PSCustomObject][ordered]@{
            ComputerName = $System.Name
            RAM = $memalloc
            Manufacturer = $System.Manufacturer
            OS = $OS.Caption
            OSVersion = $OS.Version
            LastBootUpTime = $OS.LastBootUpTime
            DiskInformation = $DiskObjects
        } 
    } 
    

    Thank you for help!!

    Norm

  • #147242

    Participant
    Points: 94
    Rank: Member

    Hello experts
    Need some help with the output from this script, note the following output:

    DiskInformation : {@{Drive=C:; Total Disk Size=80; Free Disk Size=43 (54 %)}, @{Drive=D:; Total Disk Size=350; Free Disk Size=269 (77 %)}, @{Drive=E:; Total Disk Size=1000; Free Disk Size=717 (72 %)}, @{Drive=P:; Total Disk Size=8; Free Disk Size=4 (50 %)}}
    

    The output makes more sense found out pscustomobjects are effectively a superset of hashtables. Need some help converting $DiskObjects from a hashtable to for lack of better words to a normal output.

    Hope this makes sense, appreciate any and all instance.

  • #147258

    Participant
    Points: 34
    Rank: Member

    There are different ways to output the contents of a hashtable. Also, because the default output format for $DiskObjects is a table, and the hashtable is a list, you're essentially trying to combine two different output formats as one output and this can make things messy.

    The correct approach depends on what your goal is: is this just for console output, reporting, email notifications, etc?

    Based on your code, the quick and dirty way would be to move DiskInformation outside the hashtable and pipe $DiskObjects to Out-String:

    [PSCustomObject][ordered]@{
        ComputerName = $System.Name
        RAM = $memalloc
        Manufacturer = $System.Manufacturer
        OS = $OS.Caption
        OSVersion = $OS.Version
        LastBootUpTime = $OS.LastBootUpTime
    }
    
    Write-Output "Disk Information"
    
    $DiskObjects | Out-String

    or even better:

    $DiskObjects.GetEnumerator()

    The above would output disks in a table after the computer info output.

    Output as a list:

    $DiskObjects | Format-List

    Keep in mind that you can't append the individual objects from $DiskObjects to the hashtable because the hashtable keys have to be unique.

    My personal preference is to throw everything into psobjects, wrap in a function, and make calls to that function and format output as necessary (for reporting, etc).

    Edit: Sorry for multiple submits – formatting issues.

  • #147284

    Participant
    Points: 94
    Rank: Member

    Hello Aaron,
    For now simply looking for console output, played around with your suggestions made the following change

    [PSCustomObject][ordered]@{
            ComputerName = $System.Name
            RAM = $memalloc
            Manufacturer = $System.Manufacturer
            OS = $OS.Caption
            OSVersion = $OS.Version
            LastBootUpTime = $OS.LastBootUpTime
            DiskInformation = $DiskObjects | Out-String 
    

    and the change produced this:

    ComputerName    : XXXXX01
    RAM             : 16
    Manufacturer    : Dell Inc.
    OS              : Microsoft Windows Server 2012 R2 Standard
    OSVersion       : 6.3.9600
    LastBootUpTime  : 3/20/2019 10:16:49 PM
    DiskInformation : 
                      Drive Total Disk Size Free Disk Size
                      ----- --------------- --------------
                      C:                100 73 (73 %)     
                      D:                200 200 (100 %)   
                      E:                398 396 (99 %)    
                      F:               1000 805 (81 %)    
                      G:                863 863 (100 %)
    

    Ideally would have liked the output to be formatted as follows:

    Computername   : XXXXX077
    RAMGB          : 16
    Manufacturer   : VMware, Inc.
    OS             : Microsoft Windows Server 2012 R2 Datacenter
    OSVersion      : 6.3.9600
    LastBootUpTime : 3/28/2019 3:15:41 AM
    Drive          : P
    FileSystem     : NTFS
    SizeGB         : 20
    FreeGB         : 11.96
    PctFree        : 59.8
    

    Not sure my format desire is possible, never hurts to ask.

    Thank you for responding been waiting for a response for days now.

    Norm

  • #147296

    Participant
    Points: 34
    Rank: Member

    Norm,

    The ideal output you mentioned would only work if you had to report only one disk (and you would have to specify which one), but in reality that wouldn't happen. When output contains more than one object (more than one disk), PowerShell wraps them all into a collection, a hashtable in this case. At this point, you'd have to pull everything back out by using .GetEnumerator() or some other means, depending on what you're doing.

    Glad to offer a workaround!

  • #147306

    Participant
    Points: 94
    Rank: Member

    Aaron,
    I'm content with the output/workaround.

    Thanks again

    Norm

You must be logged in to reply to this topic.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort