Search code examples
powershelldisk

disk check PowerShell with report


I made a PowerShell script to write a report and highlight any disk under 20% of space but the script keeps failing because the size value is not right. Can you please help me?

$Computers = Get-Content -Path C:\Users\gbekari\unbackup\Servers.txt

$results = foreach ($Computer in $Computers){
    Get-WmiObject Win32_Volume -Filter "DriveType='3'" -ComputerName $Computer | ForEach {
           New-Object PSObject -Property @{

           Computername = $computer
           date         = (Get-Date -format "dd.MM.yy HH:mm")
           size         = ([Math]::Round($_.Size /1GB,2))
           freeSpace    = ([Math]::Round($_.FreeSpace /1GB,2))
           Status       = if ([Math]::Round(100 * $db.FreeSpace / $db.Size) -gt 19 ) {'NONE'} else {'Warning'}
           empty        = "Diskcheck"
           }
        }
}

$results | ConvertTo-Csv -NoTypeInformation -Delimiter "|" | % {$_-replace'"',''} | Set-Content -Path C:\Users\gbekari\unbackup\Sers.txt

Solution

  • Lance U. Matthews is on point with his comment, you're trying to reference a property (Size) that does not exist in the Win32_Volume Class and you're referencing a variable that is not defined ($db).

    As aside, if you're running PowerShell 3.0 or above, you can construct objects by casting [pscustomobject] instead of using New-Object, this way is more direct and efficient.

    Get-WmiObject does not longer exist in newer versions of PowerShell and as stated in the docs:

    Starting in PowerShell 3.0, this cmdlet has been superseded by Get-CimInstance

    You can also query all computers in parallel, -ComputerName accepts an array of computers.

    $Computers = Get-Content -Path C:\Users\gbekari\unbackup\Servers.txt
    $results = Get-CimInstance -ClassName Win32_Volume -Filter "DriveType='3'" -ComputerName $Computers | ForEach-Object {
        $status = if ([Math]::Round(100 * $_.FreeSpace / $_.Capacity) -gt 19 ) {
            'NONE'
        }
        else {
            'Warning'
        }
    
        [pscustomobject]@{
            Date         = Get-Date -format "dd.MM.yy HH:mm"
            Size         = [Math]::Round($_.Capacity / 1GB, 2)
            FreeSpace    = [Math]::Round($_.FreeSpace / 1GB, 2)
            Status       = $status
            Empty        = "Diskcheck"
        }
    }
    
    ($results | ConvertTo-Csv -NoTypeInformation -Delimiter "|") -replace '"', '' |
        Set-Content -Path C:\Users\gbekari\unbackup\Sers.txt
    

    If you don't mind having the computer names in a column named PSComputerName, leave the code as-is, if instead you want to change the column name you can use Select-Object:

    ($results | Select-Object @{N='ComputerName'; E={ $_.PSComputerName }}, * |
        ConvertTo-Csv -NoTypeInformation -Delimiter "|") -replace '"', '' |
            Set-Content -Path C:\Users\gbekari\unbackup\Sers.txt