Disk free space powershell report showing wrong results. Pl help.

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of M1981 M1981 3 weeks, 5 days ago.

  • Author
    Posts
  • #74039
    Profile photo of M1981
    M1981
    Participant

    Hi Experts,

    Need some powershell help.

    Issue Descrition: I work as SQL Server DBA and we monitor servers using powershell scripts. So, we have one such script to monitor disk free space of multiple servers. We are running powershell 4.0 and using below powershell script which takes Servers_test.txt file as input file. i.e. We put the list of servers and read the content inside the powershell script to loop thru each server , get all disk/drive space details and if the freespacepercent< 10% we show the drive entry in RED color indicating it is CRITICAL and we are running of space and if freespacepercent $PSVersionTable Name Value —- —– PSVersion 5.1.14393.1358 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.14393.1358 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 SQL Server Details : SQL server 2016 Enterprise Edition SP Sql agent Job as only 1 step and choosen Powershell subsystem and then invoking powershell script as below powershell.exe E:\diskspace\DiskspaceV2.ps1 Script source code (E:\diskspace\DiskspaceV2.ps1) ====================== # Continue even if there are errors- $ErrorActionPreference = "Continue"; # Set your warning and critical thresholds $percentWarning = 15; $percentCritcal = 10; # EMAIL PROPERTIES i.e Tolist # Set the recipients Emails $users = "testguy@cnz.com" #—- change this later # REPORT PROPERTIES # Path to the report $reportPath = "E:\DiskSpace\"; # Report name #$reportName = "DiskSpaceRpt_$(get-date -format ddMMyyyy).html"; $reportName = "DiskSpaceRpt_$(get-date -format ddMMyyyyHHmmss).html"; # Path and Report name together $diskReport = $reportPath + $reportName #Set colors for table cell backgrounds $redColor = "#FF0000" $orangeColor = "#FBB917" $whiteColor = "#FFFFFF" # Count if any computers have low disk space. Do not send report if less than 1. $i = 0; $computers = Get-Content "E:\DiskSpace\servers_test.txt"; #–testing $datetime = Get-Date -Format "MM-dd-yyyy_HHmmss"; Write-host $diskReport # Create and write HTML Header of report $titleDate = get-date -uformat "%m-%d-%Y – %A" $header = " DiskSpace Report

    Disk Usage Report for $titledate

    "
    Add-Content $diskReport $header

    # Create and write Table header for report
    $tableHeader = "

    Server
    Drive
    Drive Label
    Total Capacity(GB)
    Used Capacity(GB)
    Free Space(GB)
    Freespace %

    "
    Add-Content $diskReport $tableHeader

    # Start processing disk space reports against a list of servers
    foreach($computer in $computers)
    {
    $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3"
    $computer = $computer.toupper()
    # Write-host "Computer : "$computer
    $dataRow="";

    foreach($disk in $disks)
    {
    $deviceID = $disk.DeviceID;

    $volName = $disk.VolumeName;
    [float]$size = $disk.Size;
    [float]$freespace = $disk.FreeSpace;
    $percentFree = [Math]::Round(($freespace / $size) * 100, 2);
    $sizeGB = [Math]::Round($size / 1073741824, 2);
    $freeSpaceGB = [Math]::Round($freespace / 1073741824, 2);
    $usedSpaceGB = $sizeGB – $freeSpaceGB;
    $color = $whiteColor;

    Write-host "Computer : "$computer
    Write-host "Deviceid : "$deviceID
    Write-host "Volumne name : "$volName
    Write-host "Size : "$size
    Write-host "FreeSpace : "$freespace
    Write-host "PercentFree : "$percentFree
    Write-host "SizeGB : "$sizeGB
    Write-host "UsedGb : "$usedSpaceGB
    Write-host "FreespaceGB : "$freeSpaceGB
    Write-host " "

    # Set background color to Orange if just a warning
    if($percentFree -lt $percentWarning)
    {
    $color = $orangeColor

    # Set background color to Orange if space is Critical
    if($percentFree -lt $percentCritcal)
    {
    $color = $redColor
    }

    # Create table data rows
    $dataRow = "

    $computer
    $deviceID
    $deviceID
    $sizeGB
    $usedSpaceGB
    $freeSpaceGB
    $percentFree

    "
    Add-Content $diskReport $dataRow;

    #Write-Host -ForegroundColor DarkYellow "$computer $deviceID percentage free space = $percentFree";
    $i++
    }
    }
    }

    # Create table at end of report showing legend of colors for the critical and warning
    $tableDescription = "

    Warning less than 15% free space
    Critical less than 10% free space

    "
    Add-Content $diskReport $tableDescription
    Add-Content $diskReport ""

    # Send Notification if alert $i is greater then 0
    if ($i -gt 0)
    {
    #Write-host "*** 1 ***"
    foreach ($user in $users)
    {
    #Write-host "*** 2 ***"
    Write-Host "Sending Email notification to $user"

    $smtpServer = "smtphost.xxxxx.xxx.xxxx.com" #—- change this later
    $smtp = New-Object Net.Mail.SmtpClient($smtpServer)
    $msg = New-Object Net.Mail.MailMessage
    $msg.To.Add($user)
    $msg.From = "abc@hall.com" #—- change this later

    $msg.Subject = "Disk Usage Report for $titledate"
    $msg.IsBodyHTML = $true
    $msg.Body = get-content $diskReport
    Invoke-Expression $diskReport
    Write-Host $msg.Body

    $smtp.UseDefaultCredentials = $true
    $smtp.Send($msg)
    #$body = ""
    }
    }

    I am unable to attach screenshots here. not sure how to do it. 🙁

  • #74051
    Profile photo of Olaf Soyk
    Olaf Soyk
    Participant

    M,

    why do you still refuse after about 8 month posting questions here to format your code as code and even your text is really badly formatted so it's almost unreadable. ... and you even managed it once to use the right code formatting tags!? Don't you read your own post when you're finished?

    Ok, now your problem: Why don't you start with something small and pure so it is better to understand and to debug. With the following function you can get the most basic information about the disks sizes of a given computer (or a list of computers):

    function Get-DisksSPaceReport {
    	[CmdletBinding()]
    	param(
    		[Parameter(ValueFromPipeline=$true)]
    		[ValidateNotNullOrEmpty()]
    		[System.String[]]
    		$ComputerName = $env:COMPUTERNAME
    	)
    	process {
            $diskList = get-wmiobject Win32_LogicalDisk -computername $ComputerName -Filter "DriveType = 3"
            foreach ($disk in $diskList){
                [PSCustomObject]@{
                    ComputerName = $disk.PSComputerName
                    DriveLetter = $disk.DeviceID
                    VolumeName = $disk.VolumeName
                    Size = $disk.Size
                    FreeSpace = $disk.FreeSpace
                }
            }
    	}
    }

    Now you can store these information in a variable ....

    $Result = Get-DisksSPaceReport

    .... or simply pipe it to whatever you need ... par example like this:

    $Result | 
        Select-Object -Property ComputerName, 
            DriveLetter, 
            VolumeName,
            @{Name='SizeInGB';Expression={[math]::round($_.Size / 1GB,2)}},
            @{Name='FreeSpaceInGB';Expression={[math]::round($_.FreeSpace / 1GB,2)}},
            @{Name='FreeSpaceIn%';Expression={[math]::round($_.FreeSpace / $_.Size * 100,2)}},
            @{Name='FreeSpaceLessThan10%';Expression={If(($_.FreeSpace / $_.Size * 100) -lt 10){$true}Else{$false}}}|
                Format-Table -AutoSize

    ... now you have something you can overlook. That's much easier to debug if needed.

  • #74053
    Profile photo of M1981
    M1981
    Participant

    Hi Olaf Soyk, Sorry for the formatting part. That's my bad.
    Coming to my problem. I did try to debug the code line – by – line using Write-host so that to check what values are getting into variables and what values are getting assigned inside each in the HTML table. I am also checking the final html which is assigned to the body of smtp message which is sent as an email. Everything is perfect while I am running Powershell commandline.

    But once I am calling the powershell script inside SQL Server Agent Job, thats when it is excluding one row.
    Not able to figure out if it is a security issue or it is picking from some cache. I know its pretty hard to repro such issue but if any pointers on troubleshooting such issue?

    Thanks for the inputs though.

You must be logged in to reply to this topic.