need assistance with a disk space alerting script

hello, i get the following error when running the attached script to check for disk space and alert on it:  [many of these servers are win2003]

any assistance would be much appreciated. thx

Attempted to divide by zero.
At C:\scripts\diskspacealerting.ps1:2 char:96
+     Add-Member -InputObject $_ -MemberType noteproperty -Name freepercent -Va
lue ($_.freespace/ <<<< $_.size*100) -PassThru
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException
Get-Content c:\scripts\serverlist.txt | ForEach-Object {Get-WmiObject -Class Win32_LogicalDisk -ComputerName $_ -Filter "drivetype=3"} | %{
    Add-Member -InputObject $_ -MemberType noteproperty -Name freepercent -Value ($_.freespace/$_.size*100) -PassThru
} | ?{$_.freepercent -lt 10} | ForEach-Object {
    $message = "Low disk space on server $($_.__server) on disk $($_.name), actual free size $([int] $_.freepercent)%"
    
    Send-MailMessage -Body $message -From E2010-diskspacealert@mydomain.com -To alerts@mydomain.com -SmtpServer 10.x.x.x -Subject "Low disk space notification"
}

Open in new window

siber1Asked:
Who is Participating?
 
chrismerrittCommented:
Hi siber1. I have tested this myself against Server 2003 Servers and found it works no problem. Please try this revised version which will tell you if it fails to return any disks. I can replicate your error if I put in an invalid server name or WMI doesn't work against the server in question.

$MasterArray = @()

$ServerList = Get-Content "C:\scripts\serverliste2010.txt"

foreach ($Server in $ServerList)
{
	Write-Host -ForeGroundColor "Yellow" "Server: $Server"
	
	$ServerDrives = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $Server -Filter "drivetype=3"
	if ($ServerDrives)
	{
		foreach ($ServerDrive in $ServerDrives)
		{
			$TempArray = @()
			$TempArray = "" | Select Server, DeviceID, FreeSpaceGB, SizeGB, PercentFree, VolumeName
			
			$ServerDriveFreeSpaceGB = ($ServerDrive.FreeSpace /1GB).ToString("N2").Replace(",","")
			$ServerDriveSizeGB = ($ServerDrive.Size /1GB).ToString("N2").Replace(",","")
			
			[string]$TempArray.Server = $Server
			[string]$TempArray.DeviceID = $ServerDrive.DeviceID
			[decimal]$TempArray.FreeSpaceGB = $ServerDriveFreeSpaceGB
			[decimal]$TempArray.SizeGB = $ServerDriveSizeGB
			[decimal]$TempArray.PercentFree = ($ServerDriveFreeSpaceGB / $ServerDriveSizeGB).ToString("P2").Replace(" %","")
			[string]$TempArray.VolumeName = $ServerDrive.VolumeName
			
			if ($TempArray.PercentFree -lt 20 -and $TempArray.DeviceID -eq "C:")
			{
				$Message = "Low disk space on server $($TempArray.Server) on disk $($TempArray.DeviceID), actual free size $($TempArray.FreeSpaceGB) GB / $($TempArray.SizeGB) GB - $($TempArray.PercentFree) %"
				write-host $Message
				#Send-MailMessage -Body $Message -From E2010-diskspacealert@mydomain.com -To alerts@mydomain.com -SmtpServer 10.x.x.x -Subject "Low disk space notification"
			}
			
			if ($TempArray.PercentFree -lt 50 -and $TempArray.DeviceID -ne "C:")
			{
				$Message = "Low disk space on server $($TempArray.Server) on disk $($TempArray.DeviceID), actual free size $($TempArray.FreeSpaceGB) GB / $($TempArray.SizeGB) GB - $($TempArray.PercentFree) %"
				write-host $Message
				#Send-MailMessage -Body $Message -From E2010-diskspacealert@mydomain.com -To alerts@mydomain.com -SmtpServer 10.x.x.x -Subject "Low disk space notification"		
			}
			
			$MasterArray += $TempArray
		}
	}
	else
	{
		Write-Host "No Drives found on Server $Server - Check the Server Name/Exception Message"
	}
}

Open in new window

0
 
Krzysztof PytkoSenior Active Directory EngineerCommented:
Some time ago I found something in the Internet (PowerShell Function) and I'm using it. Maybe you would be interested with that solution.

Please chech the code below

 
Function Get-FreeDiskSpace($drive,$server)
{
 $driveData = Get-WmiObject -class win32_LogicalDisk -ComputerName $server -filter "Name = '$drive'" 
"$server free disk space on drive $drive"
"{0:n2}" -f ($driveData.FreeSpace/1GB) + "GB free of " + "{0:n2}" -f ($driveData.Size/1GB) + "GB total"

}

Clear-Host

Get-FreeDiskSpace -drive "<DriveLetter:" -server "<Server-DNS-Name"

Open in new window


Regards,
Krzysztof
0
 
siber1Author Commented:
thx iSiek, is there a way to reference a .txt file with a list of servers to query?
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

 
chrismerrittCommented:
0
 
Krzysztof PytkoSenior Active Directory EngineerCommented:
Yes, you can. Using Get-Content you can import flat text file with server names and check one drive C or D or whatever. See this code below

 
Function Get-FreeDiskSpace($drive,$server)
{
 $driveData = Get-WmiObject -class win32_LogicalDisk -ComputerName $server -filter "Name = '$drive'" 
"$server free disk space on drive $drive"
"{0:n2}" -f ($driveData.FreeSpace/1GB) + "GB free of " + "{0:n2}" -f ($driveData.Size/1GB) + "GB total"

}

Clear-Host

Get-Content c:\FileName.txt | %{ Get-FreeDiskSpace -drive "C:" -server $_
Write-Host "" }

Open in new window


If you want to use more advanced servers query, use CSV file for that in this format. Create two columns in Excel sheet named

ServerName  ServerDrive

and put there apporpriate names and drives

ServerName  ServerDrive
server1             c:
server1             e:
server2             c:
server3             d:

and save this file as CSV. Edit it with notepad and check what separator is used between values (by default it's semicolon ;)

and use this code below

 
Function Get-FreeDiskSpace($drive,$server)
{
 $driveData = Get-WmiObject -class win32_LogicalDisk -ComputerName $server -filter "Name = '$drive'" 
"$server free disk space on drive $drive"
"{0:n2}" -f ($driveData.FreeSpace/1GB) + "GB free of " + "{0:n2}" -f ($driveData.Size/1GB) + "GB total"

}

Clear-Host

Import-CSV c:\output\test-srv.csv -Delimiter ";" | %{ Get-FreeDiskSpace -drive $_.ServerDrive -server $_.ServerName
Write-Host "" }

Open in new window


If you have more questions, do not hesitate to ask

Krzysztof
0
 
siber1Author Commented:
Hi Chris, when i try running your script against win2003 servers i get this error:

Cannot convert value "NaN" to type "System.Decimal". Error: "Input string was not in a correct format."
At C:\scripts\test\diskalertingtest.ps1:20 char:23
+         [decimal]$TempArray. <<<< PercentFree = ($ServerDriveFreeSpaceGB / $ServerDriveSizeGB).ToString("P2").Replace
(" %","")
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException
0
 
siber1Author Commented:
Hi Chris, can you modify this so that it only reports on the actual disks present on the servers? this version runs though all letters of the alphabet and sends me 26 emails per server.  sigh  ; )
0
 
siber1Author Commented:
Chris, just re-tested and i think i've found the issue. your original script works perfectly on all servers except exchange 2003 cluster nodes. this may be because of the single copy share storage design. not sure if you have a way around that? i.e. each SCC node has access to all volumes, with drive letters spread between the nodes.

otherwise it works perfectly against standalone [non-clustered servers]

thx in advance.
0
 
siber1Author Commented:
thx again!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.