#Get a list of all servers then go through that list and get all local drives and email a report with
#a summary of the most critical drives and errors and attach the full list
IF (Get-PSSnapin | where {$_.name -eq "quest.activeroles.admanagement"})
{write-host "Quest Active Roles snapin already loaded"}
Else
{add-PSSnapin quest.activeroles.admanagement}
$CriticalFreeSpaceGB = .5
$WarningFreeSpacePercent = 5
$smtpServer = "mail.blah.com"
#$To = "Kevin Curran <kcurran@blah.com>"
$From = "AD Reporting <ADReporting@blah.com>"
$OutputFile = "c:\Temp\ServerDriveUsage.csv"
$Counter = $null
Function check-even ($num) {[bool]!($num%2)}
$WindowsServers = Get-QADComputer -SizeLimit 0 -OSName "*windows*server*" | select Name, OperatingSystem
#Testing
#$WindowsServers = Get-QADComputer -SizeLimit 0 -OSName "*windows*server*" | select Name, OperatingSystem -First 30
#$WindowsServers | Group-Object -Property operatingsystem | select count, name
$DriveReport =@()
foreach ($Server in $WindowsServers)
{
$DNS = $null
$pingable = $null
$WMIError = $null
$ErrorString = $null
$ErrorMessage = ""
$Counter ++
Write-Host $Counter $Server.Name
$DNS = [System.Net.Dns]::GetHostByName($Server.Name)
If ($DNS)
{
$pingable=$(Test-Connection -Quiet -count 2 -ComputerName $Server.Name)
If ($pingable)
{
#Add a where filter to exclude drives in the non active cluster node
$DriveReport += Get-WmiObject -ErrorVariable WMIError -ErrorAction SilentlyContinue Win32_LogicalDisk -Filter "DriveType='3'" -ComputerName $Server.Name |
Where {$_.Size -ne $null} |
select @{Name='Machine';Expression={$Server.Name}},
@{Name='Drive';Expression={$_.DeviceID}},
@{Name='SizeGB';Expression={[Math]::Round($($_.Size / 1GB),1)}},
@{Name='FreespaceGB';Expression={[Math]::Round($($_.FreeSpace / 1GB ),1)}},
@{Name='PercentFree';Expression={[Math]::Round($($_.FreeSpace /$_.Size * 100),1)}},
@{Name='ErrorMessage';Expression={""}}
$ErrorMessage = If ($WMIError)
{
$ErrorString = "$WMIError"
If($ErrorString -like '*Access is denied*'){"WMI Error - Access is denied"}
ElseIf($ErrorString -like '*OutOfMemoryException*'){"WMI Error - OutOfMemoryException"}
ElseIf($ErrorString -like '*Server execution failed*'){"WMI Error - Server execution failed"}
ElseIf($ErrorString -like '*RPC server is unavailable*'){"WMI Error - RPC server is unavailable"}
ElseIf($ErrorString -like '*Not Found*'){"WMI Error - Not Found"}
Else
{
#return the errorstring to ErrorMessage variable and write the new WMI error to a log file
$ErrorString
#$WMIError | Out-File .\$($Server.Name)_error.txt
}
}
}
Else
{
#Write Error unable to ping server
$ErrorMessage = "Error unable to ping Server $($Server.Name)"
}
}
Else
{
#Write Error no DNS entry found
$ErrorMessage = "Error unable to find DNS entry for $($Server.Name)"
}
IF ($ErrorMessage)
{
$DriveReport += $Server.Name | select @{Name='Machine';Expression={$Server.Name}},
@{Name='Drive';Expression={""}},
@{Name='SizeGB';Expression={""}},
@{Name='FreespaceGB';Expression={""}},
@{Name='PercentFree';Expression={""}},
@{Name='ErrorMessage';Expression={$ErrorMessage}}
}
}
$DriveReport | Export-Csv -NoTypeInformation -Path $OutputFile
$CriticalDrives = $DriveReport | where {$_.ErrorMessage -eq "" -and $_.FreespaceGB -le $CriticalFreeSpaceGB} | Sort-Object -Property FreespaceGB
$WarningDrives = $DriveReport | where {$_.ErrorMessage -eq "" -and $_.FreespaceGB -gt $CriticalFreeSpaceGB -and $_.PercentFree -le $WarningFreeSpacePercent} | Sort-Object -Property PercentFree
$ErrorDrives = $DriveReport | where {$_.ErrorMessage -ne ""}
$Message = $CriticalDrives | ConvertTo-Html -Fragment -Property Machine, Drive, SizeGB, FreespaceGB, PercentFree -PreContent "<b>Critical Drives (less than $CriticalFreeSpaceGB GB freespace) </b>" | ForEach-Object {$_}
$Message += $WarningDrives | ConvertTo-Html -Fragment -Property Machine, Drive, SizeGB, FreespaceGB, PercentFree -PreContent "<br><b>Warning Drives (less than $WarningFreeSpacePercent Percent freespace)</b>" | ForEach-Object {$_}
$Message += $ErrorDrives | ConvertTo-Html -Fragment -Property Machine, ErrorMessage -PreContent "<br><b>Errors</b> <br>If these machines do not exist please decommission them and remove from Active Directory" | ForEach-Object {$_}
$Counter = $null
#Modify HTML alternate row color
$ModifiedHTML=ForEach ($line in $Message)
{
$counter++
if (check-even $counter)
{$line.replace('<tr><td>','<tr class="d0"><td>')}
Else
{$line.replace('<tr><td>','<tr class="d1"><td>')}
}
$PreMessage = @"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
<style>
BODY{background-color:white;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 5px;border-style: solid;border-color: black;background-color:MidnightBlue; color:Yellow}
TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;background-color:PaleGoldenrod}
TR.D0 TD {background-color: White; color: black;}
TR.D1 TD {background-color: LawnGreen; color: black;}
TR.Crit TD {background-color: Red; color: black;}
</style>
</head><body>
"@
$PostMessage = "<br>This script was run by " + $env:username + " on " + $env:COMPUTERNAME
$PostMessage += "<br>ScriptName: $($MyInvocation.MyCommand) "
$PostMessage += "<br>Script path: $(Split-Path -Parent $MyInvocation.MyCommand.Path)"
$PostMessage += "</body></html>"
$HTML = $PreMessage + $($ModifiedHTML | out-string) + $PostMessage
Send-MailMessage -From $From -To $To -SmtpServer $smtpServer -Attachments $OutputFile `
-Subject "$Env:userdomain Domain Server Drive Usage Report" -BodyAsHtml $HTML