Uptime Script

rated by 0 users
This post has 9 Replies | 2 Followers

Not Ranked
Posts 3
aochoar Coffee [C] Posted: 10-31-2011 11:29 AM

Hello everyone, I'm trying to retrieve some information from Event ID 1074. I need the following information Domain\User and Comment. I alread have the servername and uptime output to html.

I have added the an example of the html output and a sample of the script, hope you can help.

Example of event ID,

Event Type:      Information
Event Source:      USER32
Event Category:      None
Event ID:      1074
Date:            10/30/2011
Time:            12:31:47 PM
User:            Domain\User
Computer:      Server Name
Description:
The process winlogon.exe has initiated the restart of computer SERVER on behalf of user Domain\User for the following reason: No title for this reason could be found
 Reason Code: 0x800000ff
 Shutdown Type: restart
 Comment: Maintenance Reboot

HTMP Output Example
Machine Name   Last Reboot TimeStamp    User                       Comment
ServerName      10/23/2011 1:05:46 PM    DomainName/Kevin  Maintenance Reboot

$ErrorActionPreference = "SilentlyContinue"
Remove-Item C:\Scripts\Output -Recurse
$InputFile = Get-Content MachineList.txt
$LastReboot = @()
foreach ($computer in $InputFile)
 {
 $x = "" | Select-Object 'Machine Name','Last Reboot TimeStamp','Reboot Initiator','Reboot Reason Code'
 $x.'Machine Name' = $computer
 $x.'Last Reboot TimeStamp' = [Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject -class Win32_OperatingSystem -computername $computer -namespace "root\CIMV2").LastBootUpTime)
 $LastReboot += $x
 }
New-Item C:\Scripts\Output -ItemType directory

$LastReboot | Sort-Object 'Last Reboot TimeStamp' -Descending | ConvertTo-Html | Out-File C:\Scripts\Output\LastReboot.htm
Invoke-Expression C:\Scripts\Output\LastReboot.htm

 

Top 500 Contributor
Posts 6

Apologies to the Forum MODs for raising such an old post, thought that it was useful as I have needed this info and have been asked for it many times by clients.

Code Only:

    if (test-path c:\test) {} else {New-Item -Path c:\test -ItemType Directory}
    foreach ($i in (Get-WinEvent -FilterHashtable @{logname='System'; id=1074}))
        {
            $Sid = $i.userID
            $objSID = New-Object System.Security.Principal.SecurityIdentifier("$Sid")
            $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
            $i.message | Out-File c:\test\comment.txt
            $evtCmt = GC c:\test\comment.txt | select -last 1
            Write-Host "Reboot initiated by: $objUser with the following"$evtCmt.Substring(1)
        }

With Comments:

# [VOID][System.Reflection.Assembly]::LoadWithPartialName("System.Security.Principal.SecurityIdentifier")

# loop through each Windows system Log and identify entries that are EventID 1074
    foreach ($i in (Get-WinEvent -FilterHashtable @{logname='System'; id=1074}))
        {
# Store the SSID as a variable by taking the IserID property from the for loop
        $Sid = $i.userID
# Create a new instance of the following System.Security..., then pass the SSID variable to the class object
        $objSID = New-Object System.Security.Principal.SecurityIdentifier("$Sid")
# Trnaslate the SSID back to a user real username Format = Domain\User
        $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
# ugly way of displaying only the "Comment: " value. It does not appear that the
# Reason Code, Shutdown Type, or Comment can't be called as objects, they appear to be just text
        if (test-path c:\test) {} else {New-Item -Path c:\test -ItemType Directory}
# this obtains the value of the "message" filed from each eventlog entry and outputs it to a text file (gets clobbered at each pass)
        $i.message | Out-File c:\test\comment.txt
# Gets the last line from the textfile
        $evtCmt = GC c:\test\comment.txt | select -last 1
# Writes to the console (.Substring(1) removes the indent format from the log entry)
        Write-Host "Reboot initiated by: $objUser with the following"$evtCmt.Substring(1)
        }

 $objUser and $evtCmt are the variables that need to be piped to your HTML. 
You may or may not need load System.Security.Principal.SecurityIdentifier

Sample output from running locally:
Reboot initiated by: CD\DeleteMe with the following Comment: This is a test of the event log comment parsing
Reboot initiated by: CD\DeleteMe with the following Comment: This is another test of the event log comment parsing
Reboot initiated by: CD\DeleteMe with the following Comment: testing
Reboot initiated by: CD\DeleteMe with the following Comment: more testing
Reboot initiated by: CD|DeleteMe with the following Comment: testing lakjdfljsldfjsjf

Top 10 Contributor
Posts 597
Microsoft MVP
Top Contributor

You don't need to convert SIDs, and the pieces of information you are after are available as separate sets of information :-). Here is a sample:

Get-WinEvent -FilterHashtable @{logname='System'; id=1074} |
  ForEach-Object {
    $rv = New-Object PSObject | Select-Object Date, User, Action, process, Reason, ReasonCode, Comment
    $rv.Date = $_.TimeCreated
    $rv.User = $_.Properties[6].Value
    $rv.Process = $_.Properties[0].Value
    $rv.Action = $_.Properties[4].Value
    $rv.Reason = $_.Properties[2].Value
    $rv.ReasonCode = $_.Properties[3].Value
    $rv.Comment = $_.Properties[5].Value
    $rv
   
  } | Select-Object User, Action, Reason, Date

Cheerio,

Tobias

 

Top 500 Contributor
Posts 6

Ahhh, nice. Thanks for that!  

Not Ranked
Posts 3

Please confirm if this code will work with PS Ver. 1. I currently get no output using PS Ver. 1. Thank you....

Not Ranked
Posts 3

Can we get this code to work with powershell ver 1....

Top 10 Contributor
Posts 296
Microsoft MVP
Top Contributor

In PowerShell v1 Get-WinEvent doesn't exist so we need to use Get-EventLog and modify the code slightly.  I don't have a v1 set up to test on but this should work

Get-EventLog  -LogName System |
where {$_.EventId -eq 1074} |
  ForEach-Object {
       
    $rv = New-Object PSObject | Select-Object Date, User, Action, process, Reason, ReasonCode, Comment
    $rv.Date = $_.TimeGenerated
    $rv.User = $_.ReplacementStrings[6]
    $rv.Process = $_.ReplacementStrings[0]
    $rv.Action = $_.ReplacementStrings[4]
    $rv.Reason = $_.ReplacementStrings[2]
    $rv.ReasonCode = $_.ReplacementStrings[3]
    $rv.Comment = $_.ReplacementStrings[5]
    $rv
   
  } | Select-Object User, Action, Reason, Date

Top 10 Contributor
Posts 597
Microsoft MVP
Top Contributor

Thanks Richard.

Which raises the question: why are you still using PSv1? There is no good reason I know of to not update to PSv2... ;-)

Top 50 Contributor
Posts 41

This Commandlet "Get-WinEvent" only works with Windows VISTA an higher versions

 

 

When i try it in Windows XP enviroment i get an error:

 

Get-WinEvent : Dieses Cmdlet kann nur unter Microsoft Windows Vista und höheren Versionen von Windows ausgeführt werden.
Bei Zeile:1 Zeichen:13
+ Get-WinEvent <<<<  -FilterHashtable @{logname='System'; id=1074} |
    + CategoryInfo          : NotImplemented: (:) [Get-WinEvent], Exception
    + FullyQualifiedErrorId : GetEventVistaPlusRequired,Microsoft.PowerShell.Commands.GetWinEventCommand

 

 

Top 10 Contributor
Posts 597
Microsoft MVP
Top Contributor

ah, that makes sense!

Page 1 of 1 (10 items) | RSS
Copyright 2012 PowerShell.com. All rights reserved.