Translate a VBScript Event Log Script to PowerShell, Dude...

Translate a VBScript Event Log Script to PowerShell, Dude...

  • Comments 2
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about translating a VBScript script that queries the Windows Event logs directly into Windows PowerShell.  

Hey, Scripting Guy! Question Hey, Scripting Guy! Dude! I have this way cool VBScript script that I use every day to query the event logs on our servers. It receives all of the events and displays it to the screen. I look at the events as they scroll past; and in this way, I get a good overview of what’s happening on the servers. I am thinking of translating it to Windows PowerShell because I hear that Windows PowerShell is the way of the future. Is this cool or what? 

—SW

Hey, Scripting Guy! Answer Hello SW,

Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I are busy getting ready for the Atlanta TechStravaganza. We leave Thursday afternoon, and we get back late Friday night. Then leave on Saturday for TechEd Europe 2013 in Madrid. So things are really hopping around here. 

SW, if you like your Event Log VBScript script, then by all means keep using it. But whatever you do, please do not translate it directly into Windows PowerShell. Here is why… 

Retrieving event log events: the VBScript way

Back in the VBScript days, it was not uncommon to use WMI to connect to a local computer or a remote server to retrieve event log events. The way I generally did it was to use WMI. Here is an example VBScript script of performing this very task (this script appears in the Script Center Repository).

List events from a Specific Event Log

VBScript 

 

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

 

Set colLoggedEvents = objWMIService.ExecQuery _

    ("Select * from Win32_NTLogEvent Where Logfile = 'Application'")

 

For Each objEvent in colLoggedEvents

    Wscript.Echo "Category: " & objEvent.Category

    Wscript.Echo "Computer Name: " & objEvent.ComputerName

    Wscript.Echo "Event Code: " & objEvent.EventCode

    Wscript.Echo "Message: " & objEvent.Message

    Wscript.Echo "Record Number: " & objEvent.RecordNumber

    Wscript.Echo "Source Name: " & objEvent.SourceName

    Wscript.Echo "Time Written: " & objEvent.TimeWritten

    Wscript.Echo "Event Type: " & objEvent.Type

    Wscript.Echo "User: " & objEvent.User 

Next

The above script is 19 lines of code—not too bad really. As you can see, it contains a great deal of repetition, which means much of it is simple cut, paste, and edit. Certainly it is easier to use this script than to open the Event Viewer and connect to a bunch of servers.

Translating the Event Log events script to PowerShell

Certainly it is possible to translate the event log script to Windows PowerShell. This is because Windows PowerShell does WMI very well. However, a direct translation does not take advantage of the way that Windows PowerShell works. Here is a translated script of the above VBScript script (you can find the script in the Script Center Repository; it makes a great bad example).

List events from Event Logs

Windows PowerShell

 

$strComputer = "."

$colItems = get-wmiobject -class "Win32_NTLogEvent" -namespace "root\CIMV2" ` 

-computername $strComputer -Filter 'logfile = "application"'

 

foreach ($objItem in $colItems) {

      write-host "Category: " $objItem.Category

      write-host "Category String: " $objItem.CategoryString

      write-host "Compute rName: " $objItem.ComputerName

      write-host "Data: " $objItem.Data

      write-host "Event Code: " $objItem.EventCode

      write-host "Event Identifier: " $objItem.EventIdentifier

      write-host "Event Type: " $objItem.EventType

      write-host "Insertion Strings: " $objItem.InsertionStrings

      write-host "Logfile: " $objItem.Logfile

      write-host "Message: " $objItem.Message

      write-host "Record Number: " $objItem.RecordNumber

      write-host "Source Name: " $objItem.SourceName

      write-host "Time Generated: " $objItem.TimeGenerated

      write-host "Time Written: " $objItem.TimeWritten

      write-host "Type: " $objItem.Type

      write-host "User: " $objItem.User

      write-host

}

As you can see, the translated script follows the syntax of the VBScript original with little variation. So the script works, and “now you are doing Windows PowerShell,” but there is no Windows PowerShell advantage. If you understand your previous VBScript, you can certainly understand the Windows PowerShell version of that script—but it is still a decent amount of copy, paste, and edit to create the script.

A better way to do this sort of thing… 

A better way to do this is to at least take advantage of the way that Windows PowerShell works. The following code accomplishes this. 

Get-WmiObject win32_ntlogevent -Filter 'logfile = "application"'

Yep, you have got that right. It is a single line of code—65 characters instead of 25 lines of code. Now we are beginning to take advantage of Windows PowerShell.

But it gets better

OK, so if you are familiar with the previous VBScript script, and the bad version of the Windows PowerShell script, using the Get-WmiObject approach is probably understandable. But in reality, it is still too much typing, and it does not really make sense. The common question that I used to get all the time with WMI was, “So how did I know that class was there?” Well, Windows PowerShell has great discoverability, but to be honest I never use WMI to query the event logs. The reason? There is a cmdlet that does this for me. The command is shown here:

Get-EventLog -LogName application

The nice thing about this cmdlet, is that it makes sense. The code is very readable. Anyone looking at it will know immediately what it is doing. If I need to connect remotely, I just add the –ComputerName parameter as shown here:

Get-EventLog -LogName application -ComputerName dc1

If I need to connect to multiple computers, I can do this:

Get-EventLog -LogName application -ComputerName dc1, dc2, dc3

Again, the syntax is really clean and easy to read. This is the Windows PowerShell advantage.

SW, that is all there is to using Windows PowerShell to query a specific event log. Join me tomorrow when I will talk some more about translating VBScript to PowerShell.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • to help SW withdraw from VBScript addiction

    this will do the same thing the vbs did only better (because its in PoSh)

    gwmi win32_Ntlogevent | ?{$_.logfile -match "Application"} | select category, ComputerName, EventCode, message,RecordNumber, SourceName,@{name="TimeWritten";expression={$_.converttodatetime($_.TimeWritten)}}, type, user | fl

    NOTE. fl is Format-list (side note i tried ft aka format-table and no dice)

             @{name="";expression={ } } is a hash table

             ? is a default alias for where

             $_  is current item

  • @Krunch thank you for sharing this ... I like it, to help with withdraw from VBScript :-)