locked
Exchange 2007 CCR/SCR web health dashboard. RRS feed

  • Question

  • Hi

    here is my powershell script to create a Exchange 2007 CCR/SCR web health dashboard - modify it with your server names and webserver directory location. Then run it on your CCR passive node.

    web page requires some jpg's and I cannot upload them here so email me brendon @ fnb.co.za and I will send them to you.

    I am not a developer so I am sure this can be improved so if you have questions or improvements please let me know

    thanks

    Brendon

    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
    
    #SET WEBSERVER HTML FILE LOCATION
    $Monfile = “Y:\web\monitor\monitor.htm”
    
    #SET HTML ALERT JPEG IMAGES
    $noalerton = '"noalerton.jpg"'
    $noalertoff = '"noalertoff.jpg"'
    $redalerton = '"redalerton.jpg"'
    $redalertoff = '"redalertoff.jpg"'
    $warnalerton = '"warnalerton.jpg"'
    $warnalertoff = '"warnalertoff.jpg"'
    
    #SET HTML ALERT TABLE FORMATTING
    $noalert = "<td BGCOLOR=white><font color=black>"
    $redalert = "<td BGCOLOR=red><font color=white>"
    $warnalert = "<td BGCOLOR=orange><font color=black>"
    
    #START MAIN SCRIPT LOOP
    Do 
    {
    #GET THE CURRENT TIME
    $time = get-date -format g
    
    #RUN EXCHANGE HEALTH CHECKS
    $queues = Get-ExchangeServer | Where { $_.isHubTransportServer -eq $true } | get-queue 
    $queueshtml = $queues | select @{Expression={$_.Identity};Name=”Queue Identity"}, @{Expression={$_.NextHopDomain};Name="Destination"}, @{Expression={$_.Status};Name=”Status”}, @{Expression={$_.MessageCount};Name=”Queue Count”}, @{Expression={$_.LastError};Name="Last Error"} |ConvertTo-Html -fragment
    $queues | foreach -begin {$total=0} -process {$total+=$_.messageCount}
    if ($total -gt 100) {$Queuealerton=$redalerton;$Queuealertoff=$redalertoff;$A14=$redalert} else {$Queuealerton=$noalerton;$Queuealertoff=$noalertoff;$A14=$noalert}
    
    $services = Get-ExchangeServer | Test-ServiceHealth 
    $serviceshtml = $services | Select @{Expression={$_.Role};Name=”Role"}, @{Expression={$_.RequiredServicesRunning};Name=”Required Services Running"}, @{Expression={$_.ServicesNotRunning};Name=”Services Not Running"}, @{Expression={$_.ServicesRunning};Name=”Services Running"} | ConvertTo-Html -fragment
    $Servalerton=$noalerton;$Servalertoff=$noalertoff
    $services | foreach {if ($_.RequiredServicesRunning.ToString() -ne "True") {$Servalerton=$redalerton;$Servalertoff=$redalertoff}}
    
    $Cluster = Test-ReplicationHealth 
    $Clusterhtml = $Cluster | ConvertTo-Html -Fragment
    $Clusalerton=$noalerton;$Clusalertoff=$noalertoff
    $Cluster | foreach {if ($_.result.tostring() -ne "Passed") {$Clusalerton=$redalerton;$Clusalertoff=$redalertoff}}
    
    $MAPI = Test-MAPIConnectivity -server your_CCR_CMSname
    $MAPIhtml = $MAPI | select @{Expression={$_.Server};Name="Server"}, @{Expression={$_.Database};Name="Database"}, @{Expression={$_.Result};Name="Result"}, @{Expression={$_.Latency.milliseconds};Name="Latency ms"} | ConvertTo-Html -Fragment
    $latencytotal = $MAPI | foreach -begin {$latency=0} -process {$latency+=$_.Latency.milliseconds} -end {[math]::round(($latency/35), 2)}
    if ($latencytotal -gt 20) {$MAPIalerton=$redalerton;$MAPIalertoff=$redalertoff;$A13=$redalert} else {$MAPIalerton=$noalerton;$MAPIalertoff=$noalertoff;$A13=$noalert}
    
    $CCR = Get-StorageGroupCopyStatus -Server your_CCR_CMSname 
    $CCRhtml = $CCR | Select @{Expression={$_.StorageGroupName};Name=”Storage Group”}, @{Expression={$_.SummaryCopyStatus};Name=”Status”}, @{Expression={$_.CopyQueueLength};Name=”Copy Queue”}, @{Expression={$_.ReplayQueueLength};Name=”Replay Queue”}, @{Expression={$_.LatestFullBackupTime};Name=”Last Full Backup”} | ConvertTo-Html -Fragment
    $CCRalerton=$noalerton;$CCRalertoff=$noalertoff
    $CCR | foreach {if ($_.SummaryCopyStatus.ToString() -ne "Healthy") {$CCRalerton=$redalerton;$CCRalertoff=$redalertoff}}
    
    $SCR = Get-StorageGroupCopyStatus -Server your_CCR_CMSname -StandbyMachine FRGRBGSCR01 
    $SCRhtml = $SCR | Select @{Expression={$_.StorageGroupName};Name=”Storage Group”}, @{Expression={$_.SummaryCopyStatus};Name=”Status”}, @{Expression={$_.CopyQueueLength};Name=”Copy Queue”}, @{Expression={$_.ReplayQueueLength};Name=”Replay Queue”}, @{Expression={$_.LatestFullBackupTime};Name=”Last Full Backup”} | ConvertTo-Html -Fragment
    $SCRalerton=$noalerton;$SCRalertoff=$noalertoff
    $SCR | foreach {if ($_.SummaryCopyStatus.ToString() -ne "Healthy") {$SCRalerton=$redalerton;$SCRalertoff=$redalertoff}}
    
    $POPIMAP = Get-ClientAccessServer frgstn* | Test-popConnectivity | select @{Expression={$_.ClientAccessServer};Name="CAS Server"}, @{Expression={$_.Scenario};Name="Test Scenario"}, @{Expression={$_.ScenarioDescription};Name="Test Description"}, @{Expression={$_.Result};Name="Result"}, @{Expression={$_.Latency.milliseconds};Name="Latency"}, @{Expression={$_.Port};Name="Port"}, @{Expression={$_.Connectiontype};Name="Type"}
    $POPIMAP += Get-ClientAccessServer frgstn* | Test-ImapConnectivity | select @{Expression={$_.ClientAccessServer};Name="CAS Server"}, @{Expression={$_.Scenario};Name="Test Scenario"}, @{Expression={$_.ScenarioDescription};Name="Test Description"}, @{Expression={$_.Result};Name="Result"}, @{Expression={$_.Latency.milliseconds};Name="Latency"}, @{Expression={$_.Port};Name="Port"}, @{Expression={$_.Connectiontype};Name="Type"}
    $POPIMAP += Get-ClientAccessServer frgstn* | Test-OwaConnectivity | select @{Expression={$_.ClientAccessServer};Name="CAS Server"}, @{Expression={$_.Scenario};Name="Test Scenario"}, @{Expression={$_.ScenarioDescription};Name="Test Description"}, @{Expression={$_.Result};Name="Result"}, @{Expression={$_.Latency.milliseconds};Name="Latency"}, @{Expression={$_.Port};Name="Port"}, @{Expression={$_.Connectiontype};Name="Type"}
    $POPIMAPhtml = $POPIMAP | ConvertTo-Html -fragment
    $POPIMAPalerton=$noalerton;$POPIMAPalertoff=$noalertoff
    $POPIMAP | foreach {if ($_.Result.ToString() -ne "Success") {$POPIMAPalerton=$redalerton;$POPIMAPalertoff=$redalertoff}}
    
    #RUN PERFORMANCE COUNTER CHECKS
    $CPUused = Get-Counter "\\FRGSTNMX02\Processor(_total)\% Processor Time" -sampleinterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue, 2)}
    if ($CPUused -gt 75) {$A1 = $redalert} elseif ($CPUused -gt 50) {$A1 = $warnalert} else {$A1 = $noalert}
    $MEMavail = Get-Counter "\\FRGSTNMX02\Memory\Available Mbytes" | Foreach { $_.CounterSamples[0].CookedValue }
    if ($MEMavail -lt 100) {$A2 = $redalert} elseif ($MEMavail -lt 200) {$A1 = $warnalert} else {$A2 = $noalert}
    $MEMread = Get-Counter "\\FRGSTNMX02\Memory\Page Reads/sec" -SampleInterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue, 2)}
    if ($MEMread -gt 100) {$A3 = $redalert} elseif ($MEMread -gt 75) {$A3 = $warnalert} else {$A3 = $noalert}
    $DISKread = Get-Counter "\\FRGSTNMX02\LogicalDisk(_total)\Avg. Disk sec/Read" -sampleinterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue, 4)}
    if ($DISKread -gt 20) {$A4 = $redalert} elseif ($DISKread -gt 10) {$A4 = $warnalert} else {$A4 = $noalert}
    $DISKwrite = Get-Counter "\\FRGSTNMX02\LogicalDisk(_total)\Avg. Disk sec/Write" -sampleinterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue, 4)}
    if ($DISKwrite -gt 20) {$A5 = $redalert} elseif ($DISKwrite -gt 10) {$A5 = $warnalert} else {$A5 = $noalert}
    $traffic = Get-Counter "\\FRGSTNMX02\Network Interface(broadcom bcm5709c netxtreme ii gige [ndis vbd client])\Bytes Total/sec" -sampleinterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue /1MB, 2)}
    if ($traffic -gt 65) {$A6 = $redalert} elseif ($traffic -gt 40) {$A6 = $warnalert} else {$A6 = $noalert}
    $emails = Get-Counter "\\FRGSTNMX02\MSExchangeIS Mailbox(_total)\Messages Delivered/sec" -SampleInterval 5| Foreach {[math]::round($_.CounterSamples[0].CookedValue, 2)}
    if ($emails -gt 50) {$A8 = $redalert} elseif ($emails -gt 20) {$A8 = $warnalert} else {$A8 = $noalert}
    $RPCReq = Get-Counter "\\FRGSTNMX02\MSExchangeIS\RPC Requests" -sampleinterval 5 | Foreach { $_.CounterSamples[0].CookedValue }
    if ($RPCReq -gt 69) {$A9 = $redalert} elseif ($RPCReq -gt 39) {$A9 = $warnalert} else {$A9 = $noalert}
    $RPClat = Get-Counter "\\FRGSTNMX02\MSExchangeIS\RPC Averaged Latency" | Foreach { $_.CounterSamples[0].CookedValue }
    if ($RPClat -gt 25) {$A10 = $redalert} elseif ($RPCLat -gt 15) {$A10 = $warnalert} else {$A10 = $noalert}
    $RPCOps = Get-Counter "\\FRGSTNMX02\MSExchangeIS\RPC Operations/sec" -sampleinterval 5 | Foreach {[math]::round($_.CounterSamples[0].CookedValue, 2)}
    if ($RPCOps -gt 7000) {$A11 = $redalert} elseif ($RPCOps -gt 5000) {$A11 = $warnalert} else {$A11 = $noalert}
    $RPCOpsout = Get-Counter "\\FRGSTNMX02\MSExchange Store Interface(_total)\RPC Requests Outstanding" -sampleinterval 5 | Foreach { $_.CounterSamples[0].CookedValue }
    if ($RPCOpsout -gt 5) {$A12 = $redalert} elseif ($RPCOpsout -gt 3) {$A12 = $warnalert} else {$A12 = $noalert}
    if ($A1,$A2,$A3,$A4,$A5,$A6,$A8,$A9,$A10,$A11,$A12 -eq $redalert) {$Perfalerton=$redalerton;$Perfalertoff=$redalertoff} elseif ($A1,$A2,$A3,$A4,$A5,$A6,$A8,$A9,$A10,$A11,$A12 -eq $warnalert) {$Perfalerton=$warnalerton;$Perfalertoff=$warnalertoff} else {$Perfalerton=$noalerton;$Perfalertoff=$noalertoff}
    
    #BUILD PERFORMANCE COUNTER TABLE
    $Performance = "
         <table>
         <colgroup> <col/> <col/> <col/> </colgroup>
         <tr><th>Performance Counter</th><th><b>Current Value</th><th><b>Expected Value - hover for info</th></tr>
         <tr><td align=left>your_CCR_CMSname CPU Processor Time </td>" + $A1 + $CPUused + "%</td><td title='5 Sec Sample. Shows the percentage of time that the processor is executing application or operating system processes. This is when the processor is not idle.'> Should be less than 75% on average.</td></tr>
         <tr><td align=left>your_CCR_CMSname MEM Available MB's </td>" + $A2 + $MEMavail + "MB</td><td title='Shows the amount of physical memory, in megabytes (MB), immediately available for allocation to a process or for system use. It is equal to the sum of memory assigned to the standby (cached), free, and zero page lists.'> Should not be less than 100MB.</td></tr>
         <tr><td align=left>your_CCR_CMSname MEM Page Read/sec </td>" + $A3 + $MEMread + "</td><td title='Indicates data must be read from the disk instead of memory. Indicates there is not enough memory and paging is beginning. A value of more than 30 per second means the server is no longer keeping up with the load.'> Should be less than 100.</td></tr>
         <tr><td align=left>your_CCR_CMSname DISK Avg Reads</td>" + $A4 + $DISKread + "ms</td><td title='5 Sec Sample. For servers with more than 1,000 users, 20-ms disk times may not be fast enough to return responses to the client to accommodate user load. Check remote procedure call (RPC) averaged latencies to ensure these are within recommended values.'> Should be less than 20ms.</td></tr>
         <tr><td align=left>your_CCR_CMSname DISK Avg Writes</td>" + $A5 + $DISKwrite + "ms</td><td title='5 sec Sample. Should be below 100 ms at all times on average. If disk writes are high, it is possible that read latencies are also affected as a direct correlation with high write times.'> Should be less than 20ms.</td></tr>
         <tr><td align=left>your_CCR_CMSname NIC Traffic</td>" + $A6 + $traffic + "Mb/sec</td><td title='Indicates the rate at which the NIC is processing data'> 1Gb NIC should be less than 60Mb</td></tr>
         <tr><td align=left>your_CCR_CMSname Emails Del/sec </td>" + $A8 + $emails + "</td><td title='Shows the average rate that messages are delivered to all recipients. Indicates current message delivery rate to the store.'> Should closely correspond to norm.</td></tr> 
         <tr><td align=left>your_CCR_CMSname MAPI RPC Requests</td>" + $A9 + $RPCReq + "</td><td title='Indicates the overall RPC requests that are currently executing within the information store process. The maximum value in Exchange 2007 is 500 RPC requests that can execute at any designated time before the information store starts rejecting any new connections from clients'> Should be below 70 at all times.</td></tr>
         <tr><td align=left>your_CCR_CMSname MAPI RPC Avg Latency</td>" + $A10 + $RPClat + "ms</td><td title='Indicates the RPC latency, in milliseconds, averaged for all operations in the last 1,024 packets.'> Should be less than 50ms on average.</td></tr> 
         <tr><td align=left>your_CCR_CMSname MAPI RPC Ops/sec </td>" + $A11 + $RPCOps + "</td><td title='Should closely correspond to historical baselines. Values much higher than expected indicate that the workload has changed, while values much lower than expected indicate a bottleneck preventing client requests from reaching the server.'> Should closely correspond to norm.</td></tr>
         <tr><td align=left>your_CCR_CMSname RPC Requests Outstanding </td>" + $A12 + $RPCOpsout + "</td><td title='Shows the current number of outstanding RPC requests. Useful in identifying issues involving the interface between the Microsoft Exchange Information Store service on the Mailbox server and Hub Transport servers'> Should be close to 0 at all times </td></tr>
         </table>"
    
    #BUILD HTML CONTENT
    $HTML = "
    <HTML>
    <HEAD>
    <META HTTP-EQUIV=refresh CONTENT=60>
    <style type=text/css>
     body {font: 8pt verdana; background: lightgrey;}
     table {font: 8pt verdana; border-width:3px;border-style:double;border-color:grey;border-collapse:collapse;text-align:center} 
     table TH{font: 8pt verdana; font-weight:bold; color:white; border-width: 2px;border-style: solid;border-color:slategray;background-color:midnightblue} 
     table TR{font: 8pt verdana; background-color:white} 
     table TD{font: 8pt verdana; border-width: 2px;border-style: solid;border-color:slategray}
    table.main {border-width: 0px; border-spacing: 0px; border-collapse: collapse} 
     table.main TR {border-width: 0px; padding: 0px;}
     table.main TD {font: 10pt verdana; border-width: 0px; padding: 0px;}
    </style>
    
    <script>
     function roll_over(img_name,img_src){document[img_name].src=img_src;}
    </script>
    
    <script>
     function doMenu(item){obj=document.getElementById(item);col=document.getElementById('x'+item);if(obj.style.display=='none'){obj.style.display='block';col.innerHTML='[-]';}else{obj.style.display='none';col.innerHTML='[+]';}}
    </script> 
    </head>
    
    
    <body>
    <div style=text-align:center>
    <div>
    <table class=main>
    <tr height=61>
     <td background=left.jpg>&nbsp</td>
     <td width=354 background=main.jpg align=center><b>FRG EXCHANGE 2007 HEALTH DASHBOARD</b></td>
     <td background=right.jpg>&nbsp</td>
    </tr>
    </table>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE Mail Queues</td>
     <td background=" + $Queuealertoff + "><A HREF=JavaScript:doMenu('queues'); onmouseover=roll_over('queuepic'," + $Queuealerton + ") onmouseout=roll_over('queuepic'," + $Queuealertoff + ")><IMG SRC=" + $Queuealertoff + " NAME=queuepic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=queues style=display:none>
    <table><td><b>&nbspLast Updated : " + $time + "&nbsp</b></td>" + $A14 + "<b>&nbsp Queue Total :&nbsp" + $total + "&nbsp</td></table>
    " + $Queueshtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE Performance Counters</td>
     <td background=" + $Perfalertoff + "><A HREF=JavaScript:doMenu('Performance'); onmouseover=roll_over('Perfpic'," + $Perfalerton + ") onmouseout=roll_over('Perfpic'," + $Perfalertoff + ")><IMG SRC=" + $Perfalertoff + " NAME=Perfpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=Performance style=display:none>
    <table><td><b>Last Updated : " + $time + "</td></table>
    " + $Performance + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE Service Health</td>
     <td background=" + $Servalertoff + "><A HREF=JavaScript:doMenu('Services'); onmouseover=roll_over('Servpic'," + $Servalerton + ") onmouseout=roll_over('Servpic'," + $Servalertoff + ")><IMG SRC=" + $Servalertoff + " NAME=Servpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=Services style=display:none>
    <table><td><b>Last Updated : " + $time + "</td></table>
    " + $serviceshtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE Cluster Status</td>
     <td background=" + $Clusalertoff + "><A HREF=JavaScript:doMenu('Cluster'); onmouseover=roll_over('Cluspic'," + $Clusalerton + ") onmouseout=roll_over('Cluspic'," + $Clusalertoff + ")><IMG SRC=" + $Clusalertoff + " NAME=Cluspic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id='Cluster' style=display:none>
    <table><td><b>Last Updated : " + $time + "</td></table>
    " + $Clusterhtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE MAPI Connectivity</td>
     <td background=" + $MAPIalertoff + "><A HREF=JavaScript:doMenu('MAPI'); onmouseover=roll_over('MAPIpic'," + $MAPIalerton + ") onmouseout=roll_over('MAPIpic'," + $MAPIalertoff + ")><IMG SRC=" + $MAPIalertoff + " NAME=MAPIpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=MAPI style=display:none>
    <table><td><b>Last Updated : " + $time + "&nbsp</td>" + $A13 + "<b>&nbspLatency Average :&nbsp" + $latencytotal + "ms.</td></table>
    " + $MAPIhtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE CCR Health</td>
     <td background=" + $CCRalertoff + "><A HREF=JavaScript:doMenu('CCR'); onmouseover=roll_over('CCRpic'," + $CCRalerton + ") onmouseout=roll_over('CCRpic'," + $CCRalertoff + ")><IMG SRC=" + $CCRalertoff + " NAME=CCRpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=CCR style=display:none>
    <table><td><b>Last Updated : " + $time + "</td></table>
    " + $CCRhtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE SCR Health</td>
     <td background=" + $SCRalertoff + "><A HREF=JavaScript:doMenu('SCR'); onmouseover=roll_over('SCRpic'," + $SCRalerton + ") onmouseout=roll_over('SCRpic'," + $SCRalertoff + ")><IMG SRC=" + $SCRalertoff + " NAME=SCRpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=SCR style=display:none>
    <table>
    <td><b>Last Updated : " + $time + "</td>
    </table>
    <table class=sub>
    " + $SCRhtml + "
    </div>
    
    <table class=main>
    <tr>
     <td background=left.jpg>&nbsp</td>
     <td width=300 background=main.jpg>EXCHANGE POP3 IMAP OWA Health</td>
     <td background=goodoff.jpg><A HREF=JavaScript:doMenu('POPIMAP'); onmouseover=roll_over('POPIMAPpic'," + $POPIMAPalerton + ") onmouseout=roll_over('POPIMAPpic'," + $POPIMAPalertoff + ")><IMG SRC=" + $POPIMAPalertoff + " NAME=POPIMAPpic BORDER=0></A></td>
    </tr>
    </table>
    
    <div id=POPIMAP style=display:none>
    <table>
    <td><b>Last Updated : " + $time + "</td>
    </table>
    <table class=sub>
    " + $POPIMAPhtml + "
    </div>
    <table><td><b>Last Updated : " + $time + "</td></table>
    </div>
    </body>
    </html>"
    
    #WRITE HTML WEBPAGE TO WEBSERVER
    $HTML | out-file $Monfile
    }
    #LOOP
    until (1 -eq 2)
    
    Thursday, October 28, 2010 7:54 AM

Answers

  • For the question about script please use the “Development” forum which would be the best place for you to find the useful advice


    James Luo
    TechNet Subscriber Support (http://technet.microsoft.com/en-us/subscriptions/ms788697.aspx)
    If you have any feedback on our support, please contact tngfb@microsoft.com
    • Proposed as answer by Alan.Gim Thursday, November 4, 2010 6:06 AM
    • Marked as answer by Alan.Gim Friday, November 5, 2010 7:26 AM
    Monday, November 1, 2010 8:16 AM

All replies

  • For the question about script please use the “Development” forum which would be the best place for you to find the useful advice


    James Luo
    TechNet Subscriber Support (http://technet.microsoft.com/en-us/subscriptions/ms788697.aspx)
    If you have any feedback on our support, please contact tngfb@microsoft.com
    • Proposed as answer by Alan.Gim Thursday, November 4, 2010 6:06 AM
    • Marked as answer by Alan.Gim Friday, November 5, 2010 7:26 AM
    Monday, November 1, 2010 8:16 AM
  • many thanks for sharing your script man !
    /* Server Support Specialist */
    Thursday, May 26, 2011 1:13 AM