Help with a powershell script that generates server drive space data

Greetings Powershell Gurus,

Quite some time ago, I (with a significant amount of help from all of you) created a powershell script that basically reported the drive space for each of my servers.  The data was generated, dropped into an html report and emailed to me each morning.  I have tweaked the script and now all I get is a blank email.  I originally thought I may have messed up the code to pull the drive space data.  However, I have tested that code and it returns the appropriate drive space information.  That code is as follows:

  add-PSSnapin quest.activeroles.admanagement -ea SilentlyContinue

# Declare $OnlineServers as an array
$OnlineServers = @()

# Find all servers managed by CCIT and check to see if they respond to a ping
Get-QADComputer -managedby ccit | Sort-Object | foreach{
  $PingResult = Get-WmiObject -Query "SELECT * FROM win32_PingStatus WHERE address='$($_.Name)'"
  If ($PingResult.StatusCode -eq 0) {
 
    # If server responded to a ping , then it's current name is added to the array
    $OnlineServers += "$($_.Name)"
  }
}
## Execute Get-WMIObject for every element in the $OnlineServers array
## Added the filter to the WMI query rather than using Where-Object. No point in returning more than we must.
Get-WmiObject Win32_LogicalDisk -ComputerName $OnlineServers -Filter "DriveType='3'" | `
  Select-Object `
    @{n="Server";e={$_.SystemName}},`
    @{n="Drive Letter";e={$_.DeviceID}},`
    @{n="Volume Name";e={$_.VolumeName}},`
    @{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
    @{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
    @{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
    @{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}}

When we originally made the script, I understood how Powershell generated the drive space data and how it emailed the report.  However, the conversion to HTML and the formatting of the report was confusing to me.  Since I have tested the data generation portion of the script and that is working, I think my issue is in the formatting of the HTML report.  I was hoping some of you could take a look at the code and help me find the issue that is causing my report to be blank.  The code of the entire script is given below.

add-PSSnapin quest.activeroles.admanagement -ea SilentlyContinue

#
### HEADER SECTION ###
 
$Header = "<style type='text/css'>`n" + `
  "td { width: 200px }`n" + `
  "th { text-align: left }`n" + `
  "</style>"


# Declare $OnlineServers as an array
$OnlineServers = @()

# Find all servers managed by MCIT and check to see if they respond to a ping
Get-QADComputer -managedby ccit | Sort-Object | foreach{
  $PingResult = Get-WmiObject -Query "SELECT * FROM win32_PingStatus WHERE address='$($_.Name)'"
  If ($PingResult.StatusCode -eq 0) {
 
    # If server responded to a ping , then it's current name is added to the array
    $OnlineServers += "$($_.Name)"
  }
}
# Execute Get-WMIObject for every element in the $OnlineServers array
# Added the filter to the WMI query rather than using Where-Object. No point in returning more than we must.
$Body = Get-WmiObject Win32_LogicalDisk -ComputerName $OnlineServers -Filter "DriveType='3'" | `
  Select-Object `
    @{n="Server";e={$_.SystemName}},`
    @{n="Drive Letter";e={$_.DeviceID}},`
    @{n="Volume Name";e={$_.VolumeName}},`
    @{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
    @{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
    @{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
    @{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}} | `
  ConvertTo-HTML -Title "Server Disk Report" -Head $Header
 
 
### EMAIL REPORT SECTION ###
 
$Mail = New-Object System.Net.Mail.MailMessage( `
  "ServerAdmin@coconino.az.gov", `
  "nick@mycompany.com", `
  "Server Drive Space Report", `
  $Body)
 
$Mail.IsBodyHTML = $True
 
$Smtp = New-Object System.Net.Mail.SmtpClient("exchange.mycompany.internal")
$Smtp.Send($Mail)

Thanks in advance.
Regards,
Nick Dalmolin
LVL 1
ndalmolin_13Asked:
Who is Participating?
 
chrismerrittConnect With a Mentor Commented:
This works for me, hope you don't mind made some changes:

#Add QAD Snapin if needed
Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction "SilentlyContinue"

#Ping Status collection for all servers
$PingStatuses = @()

#Find all servers managed by MCIT and check to see if they respond to a ping
[array]$Computers = Get-QADComputer | Sort Name

#If one or more results are returned
if ($Computers.Count -gt 0)
{
	#Loop through all machine names
	foreach ($Computer in $Computers)
	{
		#Uses the DNSName to ensure correct DNS resolution
		$PingResult = Get-WmiObject -Query "SELECT * FROM Win32_PingStatus WHERE address='$($Computer.DNSName)'"
		#Add the current machines PingResult into the PingStatuses array
		$PingStatuses += $PingResult
	}
}
else
{
	Write-Host "no machines found, exiting"
	Start-Sleep 3
	exit
}

#Returns machines from the PingStatuses array where the StatusCode is 0 for ping status. i.e. all machines that are alive.
$OnlineServers = @()
$PingStatuses | ? {$_.StatusCode -eq 0} | % {$OnlineServers += $_.Address}

#Checks to see if any online servers in the array
if ($OnlineServers.Count -gt 0)
{
	### HEADER SECTION ###
	 
	$Header = "<style type='text/css'>`n" + `
	  "td { width: 200px }`n" + `
	  "th { text-align: left }`n" + `
	  "</style>"

	#Execute Get-WMIObject for every element in the $OnlineServers array
	#Added the filter to the WMI query rather than using Where-Object. No point in returning more than we must.
	$Body = Get-WmiObject Win32_LogicalDisk -ComputerName $OnlineServers -Filter "DriveType='3'" | `
	  Select-Object `
		@{n="Server";e={$_.SystemName}},`
		@{n="Drive Letter";e={$_.DeviceID}},`
		@{n="Volume Name";e={$_.VolumeName}},`
		@{n="Total Size (GB)";e={"{0:n2}" -f($_.size/1GB)}},`
		@{n="Free Space (GB)";e={"{0:n2}" -f($_.FreeSpace/1GB)}},`
		@{n="Used Space (GB)";e={"{0:n2}" -f(([Int64]$_.size/1gb) - ([Int64]$_.FreeSpace/1gb))}},`
		@{n="Percentage Used";e={"{0:P2}" -f((1-[Int64]$_.FreeSpace/[Int64]$_.Size))}} | `
	  ConvertTo-HTML -Title "Server Disk Report" -Head $Header
	 
	 
	### EMAIL REPORT SECTION ###
	 
	$Mail = New-Object System.Net.Mail.MailMessage( `
	  "sender@domain.com", `
	  "recipient@domain.com", `
	  "Server Drive Space Report", `
	  $Body)

	#This sets the body type to HTML
	$Mail.IsBodyHTML = $True
	 
	$Smtp = New-Object System.Net.Mail.SmtpClient("Server Address Here")
	$Smtp.Send($Mail)
}
else
{
	Write-Host "No Online machines found, exiting"
	Start-Sleep 3
	exit
}

Open in new window

0
 
chrismerrittCommented:
You will want to change Line 8 to this, I had the filter off for testing.

[array]$Computers = Get-QADComputer -managedby ccit | Sort Name
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
chrismerritt,
any reason for not using Test-Connection instead of WMI Win32_PingStatus? WMI is costly in general.
0
Worried about phishing attacks?

90% of attacks start with a phish. It’s critical that IT admins and MSSPs have the right security in place to protect their end users from these phishing attacks. Check out our latest feature brief for tips and tricks to keep your employees off a hackers line!

 
chrismerrittCommented:
Test-Connection works in a similar way to be honest (It actually uses WMI Win32_PingStatus anyway). I just used the logic from the OP's script.

"Unlike the traditional "ping" command, Test-Connection returns a Win32_PingStatus object that you can investigate in Windows PowerShell, but you can use the Quiet parameter to force it to return only a Boolean value."

Test-Connection, like a lot of the built in PowerShell commands is simpler to write out and control but they will both get the job done.

Speed should be a bigger concern if there are a lot of servers to process, if the OP only has like 5 servers to check then it probably will make little to no difference.



0
 
ndalmolin_13Author Commented:
Hello All,

I've been out sick until this morning.  Sorry about that.  I've tried the changes that Chris made in his post above, but my email is still showing up blank.  When I break the script out into sections, the data is being pulled corrrectly, so I think my issue is in the formatting.
0
 
chrismerrittCommented:
Is it possible your mail server is stripping out the content? as I am 100% sure my code worked when I ran it and I got an email with the right content in it as well!
0
 
ndalmolin_13Author Commented:
I will check.  Thanks
0
 
ndalmolin_13Author Commented:
I think I found the issue.  Thanks for your help
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.