1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
| <# .SYNOPSIS Simple HTML report generator for server status, free RAM, and Disk capacity. The report info is injected into a web page. If anything is in the red it'll yell at you via email. .NOTES Original script from Martin Pugh (@TheSurlyAdm1n), greatly hacked/rewritten/made worse by Tobin Bradley (@fuzzytolerance). #>
[CmdletBinding()] Param ( [Parameter(ValueFromPipeline=$true, ValueFromPipelinebyPropertyName=$true)] [Alias("Servers")] [string[]]$Name = (Get-Content ".\servers.txt"), [int]$DriveAlertThreshold = 10, [int]$RAMAlertThreshold = 512, [string]$Credential = "domain\username", [string]$PathToCred = ".\", [string]$smtpServer = "servername", [string]$publishPath = "\\where\to\put\it\index.html", [string]$toMail = "hottub@fun.com" )
Begin { $path = split-path -parent $MyInvocation.MyCommand.Definition Set-Location -Path $Path
Function Get-Credentials { Param ( [String]$AuthUser = $env:USERNAME ) $Key = [byte]29,36,18,74,72,75,85,52,73,44,0,21,98,76,99,27
#Build the path to the credential file $CredFile = $AuthUser.Replace("\","~") $File = $PathToCred + "\Credentials-$CredFile.crd" #And find out if it's there, if not create it If (-not (Test-Path $File)) { (Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File } #Load the credential file $Password = Get-Content $File | ConvertTo-SecureString -Key $Key $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\") $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4) $Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password) Return $Credential }
Function Send-Mail { param($To, $From, $Subject, $Body, $mailServer) $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($mailServer) $msg.From = $From $msg.To.Add($To) $msg.Subject = $Subject $msg.IsBodyHtml = 1 $msg.Body = $Body $smtp.Send($msg) }
Write-Verbose "$(Get-Date): Script begins!" $AllComputers = @() }
Process { #Gather all computer names before processing $Name = $Name | Sort ForEach ($Computer in $Name) { $AllComputers += $Computer } }
End { #Sort the servers by name, then start getting information Write-Verbose "Sort server names and gather Credential information"
$DiskData = @() $date = Get-Date $thedate = "<p>Last Ran " + $date + "</p>" $errors = $null
If ($Credential) { $Cred = Get-Credentials $Credential }
ForEach ($Computer in $AllComputers) { Write-Verbose "Testing $Computer..." $ErrorReport = $null $DriveReport = $null If (Test-Connection $Computer -Quiet) { #Set parameters for splat, determine if checking local $CredParameter = @{ ComputerName = $Computer ErrorAction = "Stop" } If ($Computer.ToUpper() -notlike "*$($env:COMPUTERNAME.ToUpper())*" -and $Cred) { $CredParameter.Add("Credential",$Cred) }
#Get uptime and memory information Try { $WMI = Get-WmiObject Win32_OperatingSystem @CredParameter If ($WMI) { $Uptime = New-TimeSpan -Start $($WMI.ConvertToDateTime($WMI.LastBootUpTime)) -End (Get-Date) $UpText = "<td>Up for $($Uptime.Days)d, $($Uptime.Hours)h, $($Uptime.Minutes)m</td>" } Else { $UpText = "<td class=""up"">Up</td>" } #Get disk information and pretty up the data $Disks = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" @CredParameter | Select ` @{LABEL="Server";EXPRESSION={$Computer}}, @{LABEL="DriveLetter";EXPRESSION={$_.DeviceID}}, @{LABEL="Size";EXPRESSION={[int]("{0:N0}" -f ($_.Size/1gb))}}, @{LABEL="FreeSize";EXPRESSION={[int]("{0:N0}" -f ($_.FreeSpace/1gb))}}, @{LABEL="perUsed";EXPRESSION={[int]("{0:N0}" -f ((($_.Size - $_.FreeSpace)/$_.Size)*100))}}, @{LABEL="perFree";EXPRESSION={[int]("{0:N0}" -f (100-(($_.Size - $_.FreeSpace)/$_.Size)*100))}}, VolumeName $DiskData += $Disks
# check the ram $theram = ([math]::round($WMI.FreePhysicalMemory / 1024)) if ($theram -ge $RAMAlertThreshold) { $FreeRAM = "<td class=""text-right"">$theram MB</td>" } else { $FreeRAM = "<td class=""down text-right"">$theram MB</td>" $errors += "Low free RAM on $Computer.<br>" } } Catch { Write-Verbose "Error encountered gathering information for $Computer" $ErrorReport = $Error[0] $Error.Clear | Out-Null }
#Create the simple Status table If ($ErrorReport) { $UpText = "<td class=""down"">WMI Error</td>" $DiskHTML = "<div class=""red"">$($Error[0])</div>" } ElseIf ($Disks) { $DiskHTML = $null ForEach ($Disk in $Disks) { If ($Disk.perFree -le $DriveAlertThreshold) { $FreeClass = "red" $errors += "$Computer has less than 10% free space on drive $($Disk.DriveLetter) <br>" } Else { $FreeClass = "free" } $DiskHTML += "<div class=""green"" style=""width:$($Disk.perUsed)%"">$($Disk.DriveLetter) $($Disk.Size)gb</div><div class=""$FreeClass"" style=""width:$($Disk.perFree)%"">$($Disk.FreeSize)gb ($($Disk.perFree)%)</div>`n<div style=""clear:both""></div>" } } Else { $DiskHTML = "" } $DetailHTML += "<tr><td>$Computer</td>$UpText $FreeRAM<td>$DiskHTML</td></tr>`n" } Else { $DetailHTML += "<tr><td>$Computer</td><td class=""down"">DOWN</td><td class=""down""></td><td class=""down""></td></tr>`n" $errors += "$Computer is down.<br>" } }
# Insert Stuff into index.html (Get-Content .\index.html) -join "" | foreach{$_ -replace "<!-- Server Report -->(.*?)<!-- End Server Report -->","<!-- Server Report -->$DetailHTML<!-- End Server Report -->"} | Set-Content ./index.html (Get-Content .\index.html) -join "" | foreach{$_ -replace "<!-- Updated -->(.*?)<!-- End Updated -->","<!-- Updated -->$date<!-- End Updated -->"} | Set-Content ./index.html
# Copy index.html to web server Copy-Item -Path .\index.html -Destination $publishPath
#Send email if shit went bad if ($errors) { Send-Mail -To $toMail -From "noreply@noreply.com" -Subject "He's dead Jim!" -Body "<h1>Oh shit.</h1> <p> $errors </p> <p>Head to http://maps.co.mecklenburg.nc.us/bones for more information.</p>" -mailServer $smtpServer }
Write-Verbose "$(Get-Date): Script completed!" }
|