Forum Discussion

Susan_Griffiths's avatar
Susan_Griffiths
Copper Contributor
Apr 15, 2020

Need TOTAL (all disks added together) disk size for multiple servers

I can use the get-wmiobject Win32_LogicalDisk to get size by drive -

But I need the total space (all drives added together) per multiple servers.

What would be the best way just pull the total disk space per server?

I used PS a while ago, but not in the last couple of years, so a bit rusty.

Any help would be appreciated.

 

4 Replies

  • leonsv's avatar
    leonsv
    Brass Contributor
    $servers = "server1","server2"
    foreach ($server in $servers) {
    $total=0;
    Get-WmiObject Win32_Volume -Filter "DriveType='3'" -ComputerName $server | ForEach-Object {$total += [Math]::Round((($_.Capacity)/1GB),2)};
    Write-Output "ServerName: $server, TotalUsedSpace_GB: $total"}
    • LainRobertson's avatar
      LainRobertson
      Silver Contributor

      leonsv 

       

      This thread is positively ancient, but if you want an efficient version that you can run as a single line (though I've chosen to indent this example to improve readability):

       

      Example

       

       

      (Invoke-Command -UseSSL -ComputerName (Get-Content -Path ".\forum.csv") -ScriptBlock {
          [PSCustomObject] @{
              "Capacity (GB)" = [math]::Round((Get-CimInstance -ClassName Win32_Volume -Filter "DriveType=3" | Measure-Object -Sum -Property Capacity).Sum / 1GB, 2);
          }
      }) |
          Select-Object -Property PSComputerName, "Capacity (GB)";

       

       

       

      Output

      I've deliberately included a server to which I don't have access to illustrate how an error can be thrown, and that it doesn't preclude getting results back from the other servers. You could suppress these errors or handle them as you see fit.

       

       

       

      Get-CimInstance can actually query multiple computers in parallel, however, that brings unnecessary summation processing back to the querying client to perform.

       

      Instead, we let each remote computer handle its own summation and pull the end result back to the client, which is a task better suited to Invoke-Command.

       

      Using a foreach loop is inefficient and doesn't scale well since each computer is processed synchronously (i.e. one has to finish before the next can be queried).

       

      Note: You will likely need to leave the -UseSSL parameter off unless you've enabled secure WinRM (WinRM over TLS).

       

      Edited to add a pure WMI example, as while it'd be surprising, it occurred to me that people still possibly aren't enabling WinRM remoting.

       

      WMI alternative

      This handles the aggregation client-side. It still leverages parallel processing through passing an array of strings to -ComputerName.

       

       

      Get-CimInstance -ComputerName (Get-Content -Path ".\forum.csv") -ClassName Win32_Volume -Filter "DriveType=3" |
          Select-Object -Property PSComputerName, Capacity |
              Group-Object -Property PSComputerName |
                  Select-Object -Property Name, @{
                      n="Capacity (GB)"; e = { [math]::Round((($_.Group.Capacity | Measure-Object -Sum).Sum / 1GB), 2); }
                  };

       

       

      Output

       

       

      Cheers,

      Lain

    • Animesh Joshi's avatar
      Animesh Joshi
      Brass Contributor
      Assuming you have list of server names one per line in a .txt file
      $svTbl = @{}
      $servers = get-content -path c:\temp\server-names.txt
      foreach($srvr in $server) {
      $totalSpc = 0
      $svTbl.add($srvr,$totalSpc)
      get-wmiobject -class win32_logicalDisk | where-object {$_.driveType -eq 3 -and `
      !($_.volumeName -eq $null)} | foreach-object {$totalSpc = $totalSpc + $_.size}
      $svTbl[$srvr] = $totalSpc
      }
      $svTbl

Resources