<######################################################################
Uptime Report
This Script gathers the report of system boot time using WMI query to remote servers and generates HTML output.
.NOTES
Name: Uptime_Report.ps1
Version : 1.2
Update : Check on Address Resolution Status
: Check on WMI Query Status
Date : 04-Oct-2018
Version : 1.1
Date : 24-Jan-2018
.ServerList
Add List of Servers in RADWS.txt file and keep on same directory
.EXAMPLE
Uptime_Report.ps1
######################################################################>
<#------------------
Get server status code
--------------------#>
$Now = Get-Date
Function GetStatusCode
{
Param([int] $StatusCode)
switch($StatusCode)
{
0 {"ONLINE"}
11001 {"Buffer Too Small"}
11002 {"Destination Net Unreachable"}
11003 {"Destination Host Unreachable"}
11004 {"Destination Protocol Unreachable"}
11005 {"Destination Port Unreachable"}
11006 {"No Resources"}
11007 {"Bad Option"}
11008 {"Hardware Error"}
11009 {"Packet Too Big"}
11010 {"Request Timed Out"}
11011 {"Bad Request"}
11012 {"Bad Route"}
11013 {"TTL Expired Transit"}
11014 {"TimeToLive Expired Reassembly"}
11015 {"Parameter Problem"}
11016 {"Source Quench"}
11017 {"Option Too Big"}
11018 {"Bad Destination"}
11032 {"Negotiating IPSEC"}
11050 {"General Failure"}
default {"Failed"}
}
}
<#------------------
Get Up time and Up days
--------------------#>
Function GetUpTime
{
param([string] $LastBootTime)
$Now = Get-Date
$Uptime = (Get-Date) - [System.Management.ManagementDateTimeconverter]::ToDateTime($LastBootTime)
"$($Uptime.Days) Days; $($Uptime.Hours) Hrs; $($Uptime.Minutes) Mins; $($Uptime.Seconds) Secs"
"$($Uptime.Days)"
}
$ServerList = Get-Content "C:\wamp64\apps\uptime\RADWS.txt"
$SlNo = 0
$Result = @()
Foreach($ServerName in $ServerList)
{
$SlNo = $SlNo + 1
#$pingStatus.StatusCode = $null
$pingStatus = Get-WmiObject -Query "Select * from win32_PingStatus where Address='$ServerName'"
$Uptime = $null
$OS = $null
$LastPatch = $null
$LastBoot = $null
$SerialNumber = $null
if($pingStatus.StatusCode -eq 0)
{
try {
$OperatingSystem = Get-WmiObject Win32_OperatingSystem -ComputerName $ServerName -ErrorAction Stop
$Uptime = GetUptime( $OperatingSystem.LastBootUpTime )
$LastBoot = [System.Management.ManagementDateTimeconverter]::ToDateTime( $OperatingSystem.LastBootUpTime )
$OS = $OperatingSystem | select -Expand Caption
##$LastPatch = (Get-HotFix -ComputerName $ServerName | sort installedon).InstalledOn[-1].ToShortdatestring()
$LastPatch = (Get-HotFix -ComputerName $ServerName | sort installedon).InstalledOn[-1]
$SerialNumber = (Get-WmiObject -Class Win32_Bios -ComputerName $ServerName | sort SerialNumber).SerialNumber
}
catch {
$OS = "NA"
$Uptime = @("NA", "NA")
$LastBoot = "NA"
$LastPatch = "NA"
$SerialNumber = "NA"
}
$Result += New-Object PSObject -Property @{
SlNo = $SlNo
ServerName = $ServerName
SerialNumber = $SerialNumber
OpertaingSystem = $OS
IPV4Address = $pingStatus.IPV4Address
Status = GetStatusCode( $pingStatus.StatusCode )
Uptime = $Uptime[0]
UpDays = $Uptime[1]
LastPatch = $LastPatch
LastBoot = $LastBoot
}
}
else {
$Result += New-Object PSObject -Property @{
SlNo = $SlNo
ServerName = $ServerName
SerialNumber = "NA"
OpertaingSystem = "NA"
IPV4Address = $pingStatus.IPV4Address
Status = "NA"
Uptime = "NA"
UpDays = "NA"
LastBoot = "NA"
LastPatch = "NA"
}
}
}
<#---------------------
Generate HTML report page
------------------------#>
if($Result -ne $null)
{
<#$HTML = "<div class="'content'">"#>
$HTML = "<p>
Time : $($Now) <br>
</p>"
$HTML += "<div class="script-name"><p><u>RADIOLOGY RAD WORKSTATIONS STATUS REPORT</u></p></div>"
$HTML += "<div class="back-btn"><button class='button' onclick='goBack()'>HOME</button></div>"
$HTML += "<br><br>"
$HTML += "<div>"
$HTML += "<Table class="'sortable'">
<TR>
<TH><B>Sl No.</B></TH>
<TH><B>Server Name</B></TH>
<TH><B>Serial Number</B></TH>
<TH><B>IP Address</B></TH>
<TH><B>OS</B></TD>
<TH><B>Ping Status</B></TH>
<TH><B>Last Patched</B></TH>
<TH><B>Last Reboot</B></TH>
<TH><B>Uptime</B></TH>
<TH><B>UpDays</B></TH>
</TR>"
Foreach($Entry in $Result)
{
$HTML += "
<TD>$($Entry.SlNo)</TD>
<TD><a href="/uptime/patch_lst.php?m=$($Entry.ServerName)">$($Entry.ServerName)</a></TD>
<TD>$($Entry.SerialNumber)</TD>
<TD>$($Entry.IPV4Address)</TD>"
if($Entry.OpertaingSystem -clike '*Microsoft *'){
$Entry.OpertaingSystem = $Entry.OpertaingSystem.Substring(10)
}
if($Entry.OpertaingSystem -clike '*2008*' -or $Entry.OpertaingSystem -clike '*Windows 7*')
{
$HTML += "<TD style="color:">"
}
else
{
$HTML += "<TD>"
}
$HTML += "$($Entry.OpertaingSystem)</TD>
<TD>$($Entry.Status)</TD>
<TD>$($Entry.LastPatch)</TD>
<TD>$($Entry.LastBoot)</TD>
<TD>$($Entry.Uptime)</TD>"
if($Entry.UpDays -ne "NA")
{
$Days = [int]$Entry.UpDays
if($Days -gt 20)
{
$HTML += "<TD style="color:">"
}
else
{
$HTML += "<TD>"
}
}
else
{
$HTML += "<TD>"
}
$HTML += "
$($Entry.UpDays)</TD>
</TR>"
}
$HTML += "</Table></div></br></br></br>"
Write-Output $HTML
}
The above code can be invoked by a simple Php script on a web server.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SERVER STATUS REPORT</title>
<style type="text/css">
.content {
max-width:100%;
margin:auto;font-family:"Cambria", Arial, Helvetica, sans-serif;}
#disp-tbl {
max-width: 1600px;
font-size: 15px;
margin:auto;
font-family:"Cambria", Arial, Helvetica, sans-serif; margin-left: auto; margin-right: auto;
}
.script-name {
font-family: Cambria;
color: #ed8484;
font-size: 34px;
text-align: center;
margin-top: 50px;
margin-bottom: 50px;
}
.back-btn {
font-family:Cambria;
color:#ed8484;
font-size:34px;
text-align:right;
margin-right:300px;
}
.button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 25px;
text-align: center;
font-size: 16px;
cursor: pointer;
}
.button:hover {
background-color: green;
}
table.sortable thead {
background-color:#ccc;
color:#666666;
font-weight: bold;
cursor: default;
}
table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {
content: " \25B4\25BE"
}
table.sortable tbody tr:hover{
background: #ccc;
}
table.sortable tbody tr:nth-child(2n) td {
background: #eee;
}
table.sortable tbody tr:nth-child(2n+1) td {
background: #fff;
}
header {
background-color: #666;
padding: 10px;
text-align: center;
font-size: 35px;
color: white;
}
nav {
float: left;
width: 10%;
/*height: 300px; only for demonstration, should be removed */
background: #ccc;
padding: 20px;
}
nav ul {
list-style-type: none;
padding: 0;
}
article {
padding: 20px;
width: 90%;
/*//float: left;
//background-color: #f1f1f1;
//height: 300px; only for demonstration, should be removed */
}
/* Clear floats after the columns */
section:after {
content: "";
display: table;
clear: both;
}
/* Style the footer */
footer {
background-color: #777;
padding: 10px;
text-align: center;
color: white;
}
/* Responsive layout - makes the two columns/boxes stack on top of each other instead of next to each other, on small screens */
@media (max-width: 600px) {
nav, article {
width: 100%;
height: auto;
}
}
</Style>
<script>
function goBack() {
window.history.back();
}
</script>
<script src="sorttable.js"></script>
</head>
<body>
<div class="'content'">
<?php
ini_set('max_execution_time', 6000);
// If there was no submit variable passed to the script (i.e. user has visited the page without clicking submit), display the form:
if(!isset($_POST["submit"]))
{
?>
<div>
<form name="testForm" id="testForm" action="index.php" method="post" />
<table>
<tr>
<td>PACS SERVER</td>
<td><input type="submit" name="submit" id="submit" value="SERVERS" /></br></td>
</tr>
<tr>
<td>PACS WORKSTATIONS</td>
<td><input type="submit" name="submit" id="submit" value="RAD WRKSTATIONS" /></br></td>
</tr>
<tr>
<td>CPACS TECH WORKSTATIONS</td>
<td><input type="submit" name="submit" id="submit" value="TECH WRKSTATIONS" /></br></td>
</tr>
<tr>
<td>PACS TECH WORKSTATIONS</td>
<td><input type="submit" name="submit" id="submit" value="TECH WRKSTATIONS" /></br></td>
</tr>
<tr>
<td>SSL CERTIFICATES</td>
<td><input type="submit" name="submit" id="submit" value="SERVER SSL CERT" /></br></td>
</tr>
</table>
</form>
</div>
<?php
}
// Else if submit was pressed, check if all of the required variables have a value:
elseif((isset($_POST["submit"])))
{
if($_POST["submit"] == "PACS SERVERS")
{
$psScriptPath = "C:\wamp64\apps\uptime\get-uptime-SERVERS.ps1";
}
if($_POST["submit"] == "PACS RAD WRKSTATIONS")
{
$psScriptPath = "C:\wamp64\apps\uptime\get-uptime-RADWRKSTNS.ps1";
}
if($_POST["submit"] == "PACS TECH WRKSTATIONS")
{
$psScriptPath = "C:\wamp64\apps\uptime\get-uptime-TECHWRKSTNS.ps1";
}
if($_POST["submit"] == "CPACS TECH WRKSTATIONS")
{
$psScriptPath = "C:\wamp64\apps\uptime\get-uptime-CPACSWRKSTNS.ps1";
}
if($_POST["submit"] == "SERVER SSL CERT")
{
$psScriptPath = "C:\wamp64\apps\uptime\get-cert-date-SERVERS.ps1";
}
// Get the variables submitted by POST in order to pass them to the PowerShell script:
//$username = $_POST["username"];
// Best practice tip: We run out POST data through a custom regex function to clean any unwanted characters, e.g.:
// $username = cleanData($_POST["username"]);
// Path to the PowerShell script. Remember double backslashes:
//$psScriptPath = "C:\wamp64\apps\uptime\get-process.ps1";
//$psScriptPath = "C:\wamp64\apps\uptime\get-uptime-SERVERS.ps1";
// Execute the PowerShell script, passing the parameters:
$query = shell_exec("powershell -command $psScriptPath < NUL");
echo $query;
}
// Else the user hit submit without all required fields being filled out:
else
{
$msg = "Sorry, you did not complete all required fields. Please go back and try again.";
echo $msg;
}
?>
</div>
</body>
</html>