How to get server downtime report using powershell

Server downtime report using powershell.
I've report to query the uptime of server but is there any way to get downtime.
Suppose in a week the server was down for let's say 5mins on day one 15 mins on day three etc.
Total downtime here is 20mins.. sum of all downtime in a week and return the output.
Using PowerShell can this be achieved.. Thanks in advance
jack jonesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Shaun VermaakTechnical Specialist/DeveloperCommented:
To get downtime you won need to check on short intervals (as in minutes because you want values in minutes) if either the server is up/down or what the uptime value is.

I would rather write a Powershell etc. heartbeat that runs as a scheduled task etc. that reports to a database such as SQL similar to the scheduled task in
https://www.experts-exchange.com/articles/31687/Windows-Firewall-as-Code.html

This way you can get your report from the database and you do not need to poll devices constantly
1
Patrick CCommented:
You can try below code :
PowerShell Code
<#PSScriptInfo .VERSION 1.3 .GUID 2cb94e4f-1e85-4712-9441-91abcaea8572 .AUTHOR Mike Galvin twitter.com/digressive & Dan Price twitter.com/therezin, based on code by Bhavik Solanki. .COMPANYNAME .COPYRIGHT (C) Mike Galvin. All rights reserved. .TAGS Windows Server Status Report Monitor .LICENSEURI .PROJECTURI https://gal.vin/2017/07/28/windows-server-status/ .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #>
 
<# .SYNOPSIS Creates a status report of Windows Servers. .DESCRIPTION Creates a status report of Windows Servers. This script will: Generate a HTML status report from a configurable list of Windows servers. The report will highlight information is the alert threashold is exceeded. Please note: to send a log file using ssl and an SMTP password you must generate an encrypted password file. The password file is unique to both the user and machine. The command is as follows: $creds = Get-Credential $creds.Password | ConvertFrom-SecureString | Set-Content c:\foo\ps-script-pwd.txt .PARAMETER List The path to a text file with a list of server names to monitor. .PARAMETER O The path where the HTML report should be output to. The filename will be WinServ-Status-Report.htm. .PARAMETER DiskAlert The percentage of disk usage that should cause the disk space alert to be raised. .PARAMETER CpuAlert The percentage of CPU usage that should cause the CPU alert to be raised. .PARAMETER MemAlert The percentage of memory usage that should cause the memory alert to be raised. .PARAMETER Refresh The number of seconds that she script should wait before running again. If not configured the script will run once and then exit. .PARAMETER SendTo The e-mail address the log should be sent to. .PARAMETER From The from address the log should be sent from. .PARAMETER Smtp The DNS or IP address of the SMTP server. .PARAMETER User The user account to connect to the SMTP server. .PARAMETER Pwd The password for the user account. .PARAMETER UseSsl Connect to the SMTP server using SSL. .EXAMPLE WinServ-Status.ps1 -List C:\foo\servers.txt -O C:\foo -DiskAlert 90 -CpuAlert 95 -MemAlert 85 -Refresh 120 The script will execute using the list of servers and output a html report called WinServ-Status-Report.htm to C:\foo. The disk usage alert will highlight at 90% usage for any one drive, the CPU usage alert will highlight at 95% usage, and the memory usage alert will highlight at 85% usage. The script will re-run every 2 minutes. #>
 
## Set up command line switches and what variables they map to
[CmdletBinding()]
Param(
    [parameter(Mandatory=$True)]
    [alias("List")]
    $ServerFile,
    [parameter(Mandatory=$True)]
    [alias("O")]
    $OutputPath,
    [alias("DiskAlert")]
    $DiskAlertThreshold,
    [alias("CpuAlert")]
    $CpuAlertThreshold,
    [alias("MemAlert")]
    $MemAlertThreshold,
    [alias("Refresh")]
    $RefreshTime,
    [alias("SendTo")]
    $MailTo,
    [alias("From")]
    $MailFrom,
    [alias("Smtp")]
    $SmtpServer,
    [alias("User")]
    $SmtpUser,
    [alias("Pwd")]
    $SmtpPwd,
    [switch]$UseSsl)
 
## Function to get the up time from the server
Function Get-UpTime
{
    param([string] $LastBootTime)
    $Uptime = (Get-Date) - [System.Management.ManagementDateTimeconverter]::ToDateTime($LastBootTime)
    "$($Uptime.Days) days $($Uptime.Hours)h $($Uptime.Minutes)m"
}
 
## Begining of the loop. Lower down the loop is broken if the refresh option is not configured.
Do
{
    ## Change value of the following parameter as needed
    $OutputFile = "$OutputPath\WinServ-Status-Report.htm"
    $ServerList = Get-Content $ServerFile
    $Result = @()
 
    ## Look through the servers in the file provided
    ForEach ($ServerName in $ServerList)
    {
        $PingStatus = Test-Connection -ComputerName $ServerName -Count 1 -Quiet
 
        ## If server responds, get uptime and disk info
        If ($PingStatus)
        {
            $OperatingSystem = Get-WmiObject Win32_OperatingSystem -ComputerName $ServerName
            $CpuAlert = $false
            $CpuUsage = Get-WmiObject Win32_Processor -Computername $ServerName | Measure-Object -Property LoadPercentage -Average | ForEach-Object {$_.Average; If($_.Average -ge $CpuAlertThreshold){$CpuAlert = $True}; "%"}
            $Uptime = Get-Uptime($OperatingSystem.LastBootUpTime)
            $MemAlert = $false
            $MemUsage = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ServerName | ForEach-Object {“{0:N0}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) * 100)/ $_.TotalVisibleMemorySize); If((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) * 100)/ $_.TotalVisibleMemorySize -ge $MemAlertThreshold){$MemAlert = $True}; "%"}
            $DiskAlert = $false
            $DiskUsage = Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName | Where-Object {$_.DriveType -eq 3} | Foreach-Object {$_.DeviceID, [Math]::Round((($_.Size - $_.FreeSpace) * 100)/ $_.Size); If([Math]::Round((($_.Size - $_.FreeSpace) * 100)/ $_.Size) -ge $DiskAlertThreshold){$DiskAlert = $True}; "%"}
            $IPv4Address = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ServerName | Select-Object -Expand IPAddress | Where-Object { ([Net.IPAddress]$_).AddressFamily -eq "InterNetwork" }
        }
     
        ## Put the results together
        $Result += New-Object PSObject -Property @{
            ServerName = $ServerName
            IPV4Address = $IPv4Address
            Status = $PingStatus
            CpuUsage = $CpuUsage
            CpuAlert = $CpuAlert
            Uptime = $Uptime
            MemUsage = $MemUsage
            MemAlert = $MemAlert
            DiskUsage = $DiskUsage
            DiskAlert = $DiskAlert
        }
 
        ## Clear the variables after obtaining and storing the results so offline servers don't have duplicate info.
        Clear-Variable IPv4Address
        Clear-Variable Uptime
        Clear-Variable MemUsage
        Clear-Variable CpuUsage
        Clear-Variable DiskUsage
    }
 
    ## If there is a result put the HTML file together.
    If ($Result -ne $null)
    {
     ## HTML Code goes here! HTML doesn't format properly with PowerShell on WordPress. Download the script from TechNet or the PowerShell Gallery to see the complete code!
    }
        ## Output the HTML file
        $HTML | Out-File $OutputFile
 
        ## If email was configured, set the variables for the email subject and body
        If ($SmtpServer)
        {
            $MailSubject = "Server Status Report"
            $MailBody = Get-Content -Path $OutputFile | Out-String
 
            ## If an email password was configured, create a variable with the username and password
            If ($SmtpPwd)
            {
                $SmtpPwdEncrypt = Get-Content $SmtpPwd | ConvertTo-SecureString
                $SmtpCreds = New-Object System.Management.Automation.PSCredential -ArgumentList ($SmtpUser, $SmtpPwdEncrypt)
 
                ## If ssl was configured, send the email with ssl
                If ($UseSsl)
                {
                    Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -BodyAsHtml -SmtpServer $SmtpServer -UseSsl -Credential $SmtpCreds
                }
 
                ## If ssl wasn't configured, send the email without ssl
                Else
                {
                    Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -BodyAsHtml -SmtpServer $SmtpServer -Credential $SmtpCreds
                }
            }
 
            ## If an email username and password were not configured, send the email without authentication
            Else
            {
                Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -BodyAsHtml -SmtpServer $SmtpServer
            }
        }
 
        ## If the refresh time option is configured, wait the specifed number of seconds then loop.
        If ($RefreshTime -ne $null)
        {
            Start-Sleep -Seconds $RefreshTime
        }
    }
}
 
## If the refresh time option is not configured, stop the loop.
Until ($RefreshTime -eq $null)
 
## End

Open in new window

[Edited MASQ]
1
jack jonesAuthor Commented:
@Patrick thanks for this report.
However I'm looking to calculate the downtime of a server in a week.
Suppose if the server was down for 20 mins or an hour i wanted to return that downtime value using ps.
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

jack jonesAuthor Commented:
Thanks Shaun ..
I think from event log we can get the shutdown event and the next startup event..
Consecutively we can sum up the time interval between them and store in variable something & it will return the downtime in a week(-7 days).
1
Shaun VermaakTechnical Specialist/DeveloperCommented:
Downtime includes unavailability too which cannot be measured by startup and shutdown events
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jack jonesAuthor Commented:
Thanks shawn .. just for demo purpose lets consider only this parameter startup n shutdown for unavailability..
Is there any way to do it via ps. .Thanks
0
Shaun VermaakTechnical Specialist/DeveloperCommented:
1
Aaron GuilmetteTechnology Solutions ProfessionalCommented:
Trying to gather this data reliably on hosts is more of a monitoring solution.  I put together a quick script a few years ago (https://gallery.technet.microsoft.com/Computer-Uptime-Report-4a7cb338) that does uptime based on the last startup, the script posted above on idera calculates between the last shutdown and last startup, but depending on how long the polling interval is, how long the logs are kept, and such, you might not get the best data.  This is really the realm for a monitoring solution (SolarWinds, Microsoft Operations Manager, Big Brother, Kaseya, etc) that has built in processes and algorithms to periodically attempt connectivity (ICMP, event, SNMP) and graph availability.
0
Seth SimmonsSr. Systems AdministratorCommented:
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I have recommended this question be closed as follows:

Accept: Shaun Vermaak (https:#a42525944)

If you feel this question should be closed differently, post an objection and the moderators will review all objections and close it as they feel fit. If no one objects, this question will be closed automatically the way described above.

seth2740
Experts-Exchange Cleanup Volunteer
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

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.