$Disk query exports as SystemObject?

Welcome Forums General PowerShell Q&A $Disk query exports as SystemObject?

This topic contains 8 replies, has 4 voices, and was last updated by

 
Participant
2 weeks, 5 days ago.

  • Author
    Posts
  • #125813

    Participant
    Points: 46
    Rank: Member

    Hi guys, I have a starting script for system info, that needs to be exported to a csv.  If I export the $Disk info only, this saves correctly, but as part of the script (see below) just returns as SYSTEM Object? I need to record capacity, used space and %free per disk, and export as part of a wider script:

    
    $Disk = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" | Sort-Object -Property Name | Select-Object Name, `
    @{"Label"="DiskSize(GB)";"Expression"={"{0:N2}" -f ($_.Size/1GB) -as [float]}}, `
    @{"Label"="FreeSpace(GB)";"Expression"={"{0:N2}" -f ($_.FreeSpace/1GB) -as [float]}}, `
    @{"Label"="% Free";"Expression"={"{0:N}" -f ($_.FreeSpace/$_.Size*100) -as [float]}}
    
    $H = $Env:Computername
    $Path = "C:\Test"
    $OS = (Get-WMIObject win32_operatingsystem)
    $OSName = $OS.caption
    $Serial = (Get-WMIObject win32_Bios).Serialnumber
    
    $ipV4 = (Test-Connection -ComputerName ($H) -Count 1 | Select -ExpandProperty IPV4Address).IPAddressToString
    
    #Memory Info:
    
    $Mem = Get-WMIObject Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))}
    $PctFree = [math]::Round(($OS.FreePhysicalMemory/$OS.TotalVisibleMemorySize)*100,2)
    $PCTFree = $PctFree = " %"
    $Free = [math]::Round($OS.FreePhysicalMemory/1mb,2)
    $Used = ($Mem – $Free)
    $Mem = $Mem + " GB"
    $Page = (Get-Counter "\\$H\Memory\Pool Paged Bytes").Countersamples | Select-Object -ExpandProperty cookedvalue
    $Page = ("{0:N2}" -f ([math]::Round($Page/1mb)))
    $Page = "Page File Size : " +$Page + " Mb"
    
    #CPU Info:
    
    $CPUInfo = ((get-counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 10 |
    select -ExpandProperty countersamples | select -ExpandProperty cookedvalue | Measure-Object -Average).average)
    $CPU = ("{0:N2}" -f ($CPUInfo))
    $CPU = "CPU Used: " + $CPU + " %"
    
    $Output = [pscustomobject]@{
    
    ServerName = $H
    OperatingSystem = $OSName
    SerialNumber = $Serial
    Memory = $Mem
    Used = $Used
    PercentFree = $PctFree
    Paged = $Page
    CPU = $CPU
    Disks = $Disk
    }
    $Output | Export-CSV -Path $Path\$H.csv -NoTypeInformation
    
    

    Is there a better way to do this, and so it actually shows the information? If I run the following separately, this creates a csv with the relevant information:

     

    
    $DISK = "C:\Test\2-Disks.csv"
    Get-WmiObject -Class Win32_LogicalDisk |
    Where-Object {$_.DriveType -ne 5} |
    Sort-Object -Property Name |
    Select-Object Name, VolumeName, VolumeSerialNumber, FileSystem, Description, `
    @{"Label"="DiskSize(GB)";"Expression"={"{0:N}" -f ($_.Size/1GB) -as [float]}}, `
    @{"Label"="FreeSpace(GB)";"Expression"={"{0:N}" -f ($_.FreeSpace/1GB) -as [float]}}, `
    @{"Label"="%Free";"Expression"={"{0:N}" -f ($_.FreeSpace/$_.Size*100) -as [float]}} | Export-CSV $DISK -noTypeInformation
    
    

     

    I need to combine this with other information.

     

    Many thanks

    Jason

     

  • #125837

    Participant
    Points: 261
    Helping Hand
    Rank: Contributor

    Line 19 needs to be changed to

     $PCTFree = "$PctFree %" 

    Otherwise, when I run the top part, everything comes out okay. Which field is returning just a system object for you?

    https://imgur.com/ILHP71T

  • #125844

    Participant
    Points: 815
    Helping Hand
    Rank: Major Contributor

    $Disk inside a custom object will have its type in a csv. Because there is no way that in a column we can have another object in tabular view.
    Try below

    $Output = [pscustomobject]@{
    
    ServerName = $H
    OperatingSystem = $OSName
    SerialNumber = $Serial
    Memory = $Mem
    Used = $Used
    PercentFree = $PctFree
    Paged = $Page
    CPU = $CPU
    DiskSize(GB) = $Disk."DiskSize(GB)"
    "FreeSpace(GB)" = $Disk."FreeSpace(GB)"
    "% Free" = $Disk."% Free"
    }
    
    • #125853

      Participant
      Points: 261
      Helping Hand
      Rank: Contributor

      Ah yeah, that's probably it!

      I've only got a single disk over here, so didn't catch that.

  • #125868

    Participant
    Points: 305
    Helping Hand
    Rank: Contributor

    There should be a ton of examples of reports like this on the interwebs. Here are the problems at first glance:

    • WMI – You should really be using Get-CimInstance over Get-WmiObject, Get-WmiObject uses DCOM which is basically deprecated
    • ComputerName – You're referencing a computer in one command, but none of the others. All of the commands should be referencing -ComputerName if you intend on being able to run this against remote systems.
    • Error Handling – There is no error handling. Minimally, you want to use Test-Connection to validate you can reach a computer. If you can, then attempt to connect with WMI.
    • Disks – You are returning an object. This object is basically nested under your $Output object, which is why it is showing as an Object.
    • CSV – For a report like this, because of items like Disks, a CSV is a bad choice. You should consider utilizing HTML reporting with ConvertTo-HTML. There is a free eBook on the left under Free Resources about reporting that will most likely even have information on the a hardware inventory.
  • #125904

    Participant
    Points: 46
    Rank: Member

    thanks for all your help guys...will investigate Kvprasoon's suggestions...

  • #125907

    Participant
    Points: 46
    Rank: Member

    thanks guys – Kvprasoon's help didn't actually work, unfortunately (empty fields).  Rob, understand the -computername usage – was just using this as a test sofar (on 1 pc only).  The wmic is due to customer's setup only.  they want .csv then into excel as a report (ultimate goal).

     

  • #125999

    Participant
    Points: 815
    Helping Hand
    Rank: Major Contributor
    $Output = [pscustomobject]@{
    
    ServerName = $H
    OperatingSystem = $OSName
    SerialNumber = $Serial
    Memory = $Mem
    Used = $Used
    PercentFree = $PctFree
    Paged = $Page
    CPU = $CPU
    'DiskSize(GB)' = "{0:N2}" -f ($Disk.Size/1GB) -as [float]
    'FreeSpace(GB)' = "{0:N2}" -f ($Disk.FreeSpace/1GB) -as [float]
    '% Free' = "{0:N}" -f ($Disk.FreeSpace/$_.Size*100) -as [float]
    }
    

    You will still have issues if you have multiple logical disks. So you could some Excel output.

    Checkout ImportExcel module by Douge Finke, Its the best know module to create excel ouputs in PowerShell

  • #126078

    Participant
    Points: 305
    Helping Hand
    Rank: Contributor

    Think of how you will need to format this. I don't see a disk id or name in your disk results, so how would you know what partition you're reporting on? Lets say we have

    DiskId (e.g. C:\)
    DiskSpace
    DiskFree
    DiskPctFree

    You have disks 2 on the server, so your header row is going to be something like this to create unique header values:

    ServerName,OperatingSystem,...CPU,DiskId_0,DiskSpace_0,DiskFree_0,DiskPctFree_0,DiskId_1,DiskSpace_1,DiskFree_1,DiskPctFree_1

    In order to do that, we have to rip the object apart and rebuild it:

    $output = @()
    $output += [pscustomobject]@{
        ServerName = 'Server1'
        OperatingSystem = 'Windows Server 2016'
        SerialNumber = '312fef12'
        Memory = 16
        Disks = [pscustomobject]@{
                    'DiskId' = 'C:' 
                    'DiskSize(GB)' = '99'
                    'FreeSpace(GB)' = '28'
                    'PctFree' = '28'
                },
                [pscustomobject]@{
                    'DiskId' = 'D:' 
                    'DiskSize(GB)' = '500'
                    'FreeSpace(GB)' = '180'
                    'PctFree' = '36'
                }
    }
    
    $output += [pscustomobject]@{
        ServerName = 'Server2'
        OperatingSystem = 'Windows Server 2016'
        SerialNumber = '42rwrrg13g13'
        Memory = 32
        Disks = [pscustomobject]@{
                    'DiskId' = 'C:' 
                    'DiskSize(GB)' = '60'
                    'FreeSpace(GB)' = '32'
                    'PctFree' = '53'
                }
    }
    
    
    $myNewOutput = foreach ($srv in $output) {
        #Get the flat properties and start a hash table
        $newObjProps = @{
            ServerName = $srv.ServerName
            OperatingSystem = $srv.OperatingSystem
            SerialNumber = $srv.SerialNumber
            Memory = $srv.Memory
        } 
    
        #Loop thru the disks and sort them on Id (e.g. C:, D:, etc.)
        for ($d = 0;$d -lt (@($srv.Disks | Sort-Object -Property DiskId).Count);$d++) {
            #Now we need to rip apart the object and make it flat.  We loop through
            #each property and build a column on property name and append the index and
            #set the property value
            foreach ($prop in $srv.Disks[$d].PSObject.Properties) {
                $newObjProps.Add(('{0}_{1}' -f $prop.Name, $d), $prop.Value)
            }
        }
    
        #Generate our new ripped apart object
        [pscustomobject]$newObjProps
    }
    
    $myNewOutput
    

    Output:

    DiskId_0        : C:
    PctFree_1       : 36
    DiskId_1        : D:
    ServerName      : Server1
    SerialNumber    : 312fef12
    DiskSize(GB)_1  : 500
    DiskSize(GB)_0  : 99
    PctFree_0       : 28
    Memory          : 16
    FreeSpace(GB)_0 : 28
    FreeSpace(GB)_1 : 180
    OperatingSystem : Windows Server 2016
    
    DiskId_0        : C:
    ServerName      : Server2
    SerialNumber    : 42rwrrg13g13
    DiskSize(GB)_0  : 60
    PctFree_0       : 53
    Memory          : 32
    FreeSpace(GB)_0 : 32
    OperatingSystem : Windows Server 2016
    

You must be logged in to reply to this topic.