0

I am checking my servers Disk Space Usage and generate a text file as a report. I want to sort the output file in an ascending order of FreePercentage Free%.

I am stuck at this stage. It just does not sort. Is it a delimiter issue? Where is my mistake?

# files to be used
$FileName0 = "C:\MONITORING\WINDOWS-SPACE\SCRIPT\SPACE0.txt"
$FileName1 = "C:\MONITORING\WINDOWS-SPACE\SCRIPT\SPACE1.txt"
$FileName2 = "C:\MONITORING\WINDOWS-SPACE\SCRIPT\SPACE2.txt"

# file containing servers list
#$ServerName = Get-Content "C:\MONITORING\WINDOWS-SPACE\SCRIPT\COMPUTERS.txt"

# use 2 servers only for coding test, will be replaced by a file containing all
# servers
$ServerName = "SERVER1","SERVER2"

# loop and process drive-id and calculations and populate filename-0
foreach ($_ in $ServerName) {
  Get-WmiObject -Query "Select * from win32_logicaldisk"  -ComputerName $_ |
    Select PSComputername, DeviceID,
      @{Name="TotalGB"; Expression={"{0:N0}" -F ($_.Size/1GB)}}, 
      @{Name="UsedGB" ; Expression={"{0:N0}" -F (($_.Size/1GB)-($_.Freespace/1GB))}},
      @{Name="FreeGB" ; Expression={"{0:N0}" -F ($_.Freespace/1GB)}}, 
      @{Name="Free%"  ; Expression={"{0:N0}" -F (($_.Freespace/$_.Size)*100)}} |
    Format-Table -AutoSize >> $FileName0
}

# remove unwanted drives ('A'&'Z') and duplicate lines and empty lines and
# populate filename-1
Get-Content $FileName0 | Select-Object -Unique |
  Where {$_ -notmatch "A:"} |
  Where {$_ -notmatch "Z:"} |
  Where { $_ -notmatch "^-" } |
  Where {$_ -ne ""} |
  Format-Table -AutoSize > $FileName1   

# input final result into a CSV file filename-2
Import-Csv $FileName1 -Header PSComputername, TotalGB, UsedGB, FreeGB, Free%  |
  sort [int]Free% |
  Format-Table -AutoSize >> $FileName2

Actual output file:

PSComputerName DeviceID TotalGB UsedGB FreeGB Free%
SERVER1        C:       60      33     27     45
SERVER1        D:       20      2      18     88
SERVER2        C:       40      27     13     33
SERVER2        D:       50      6      44     87

Desired output file:

PSComputerName DeviceID TotalGB UsedGB FreeGB Free%
SERVER2        C:       40      27     13     33
SERVER1        C:       60      33     27     45
SERVER2        D:       50      6      44     87
SERVER1        D:       20      2      18     88
0

2 Answers 2

2

Get-WmiObject accepts a list of computernames, so you don't need a loop. Your main issue, though, is that you pipe your WMI result through Format-Table, write it to a file, and then try to read it again with Import-Csv when the format of your intermediate file isn't CSV at all. Sort the data right after Get-WmiObject before writing it to a file.

Get-WmiObject -Query 'SELECT * FROM Win32_LogicalDisk' -ComputerName $ServerName |
  Select PSComputername, DeviceID,
    @{Name="TotalGB"; Expression={"{0:N0}" -f ($_.Size/1GB)}}, 
    @{Name="UsedGB" ; Expression={"{0:N0}" -f (($_.Size/1GB)-($_.Freespace/1GB))}},
    @{Name="FreeGB" ; Expression={"{0:N0}" -f ($_.Freespace/1GB)}}, 
    @{Name="Free%"  ; Expression={"{0:N0}" -f (($_.Freespace/$_.Size)*100)}} |
  Sort-Object {[int]$_.'Free%'} |
  Format-Table -AutoSize |
  Set-Content $FileName2

Use Export-Csv instead of Format-Table | Set-Content if you want actual CSV output:

... | Sort-Object [int]$_.Free% | Export-Csv $FileName2 -NoType
Sign up to request clarification or add additional context in comments.

Comments

1

Here's a shorter way to do what you are asking:

$computerList = "server1","server2"
$computerList | ForEach-Object {
  $computerName = $_
  $params = @{
    "Class" = "Win32_LogicalDisk"
    "ComputerName" = $computerName
    "Filter" = "DriveType=3"
  }
  Get-WmiObject @params | Select-Object `
    @{Name = "ComputerName"; Expression = {$_.__SERVER}},
    @{Name = "Drive";        Expression = {$_.DeviceID}},
    @{Name = "TotalGB";      Expression = {[Int] ("{0:N0}" -f ($_.Size / 1gb)                         )}},
    @{Name = "UsedGB";       Expression = {[Int] ("{0:N0}" -f (($_.Size / 1gb) - ($_.FreeSpace / 1gb)))}},
    @{Name = "FreeGB";       Expression = {[Int] ("{0:N0}" -f ($_.FreeSpace / 1gb)                    )}},
    @{Name = "FreePercent";  Expression = {[Int] ("{0:N0}" -f (($_.FreeSpace / $_.Size) * 100)        )}}
} | Sort-Object FreePercent

The problem you have is trying to use formatting and sorting before you're done creating output. Make sure you output everything before you try to format or sort.

3 Comments

FreePercent are string values, so you need Sort-Object {[int]$_.FreePercent} to get the results in the correct order.
Correct, I noticed that after I posted and updated to cast all of the values to [Int].
*cough* [int]($_.Size / 1gb) *cough*

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.