VSoft Technologies Blogs

rss

VSoft Staff Blogs


FinalBuilder 6 : PowerShell (Part Two, Script Events)


 PowerShell Script Events

This is Part Two in a series about the new PowerShell support in FinalBuilder 6. In Part One, we learned how to create an action Execute Condition using PowerShell.

In this article we will show how to use PowerShell as a scripting language in the FinalBuilder IDE, in order to customize the behaviour of a built-in FinalBuilder action. We'll also showcase some of the powerful string processing features in PowerShell.

Script Events

When you add an action to a FinalBuilder project, you also add at least three script events:

  • BeforeAction - This script event is called before the action runs.
  • OnStatusMessage - This script event is called each time the action outputs something to the log.
  • AfterAction - This script event is called after the action has finished running.

You can access the script events by clicking on the "Script Editor" tab in FinalBuilder. For this blog post, we're going to use PowerShell to create an implementation for each of these script events.

 

PsLogList

I'm going use scripting to extend the built-in FinalBuilder action for the PsLogList tool. PsLogList is part of the PsTools suite from SysInternals/Microsoft. It dumps the contents of the event log on a local or remote machine.

We're going to customize the action so it parses the list of log entries to automatically extract data about the frequency of events from different sources.

Output format

Here's an example log entry, as output from PsLogList:

[16664] Service Control Manager
Type: INFORMATION
Computer: DYNAMO
Time: 3/03/2008 3:09:18 PM ID: 7035
User: NT AUTHORITY\SYSTEM
The IMAPI CD-Burning COM Service service was successfully sent a start control.

 

For our example, the piece of data want to extract would be "Service Control Manager" in the expression above. To extract this, we can use the following Regular Expression:

^\[\d+\] (.+)$

Regular expressions are supported directly in PowerShell. You can create a regular expression using a code snippet like this:

$headerExpr = [regex] "\[\d+\] (.+)"

(If you ever need help remembering Regular Expression syntax, I recommend www.regular-expressions.info.)

 

Hash tables

The other piece of PowerShell functionality that we're going to make use of is the hash table. We're going to create an empty PowerShell hash table, and then use it as a dictionary to store event source names along with the frequency that each source appears.

Here's the script used to create a new empty hashtable:

$hashTable = ${}

To increment the frequency of an item in the table, we can use the increment operation += on the hashtable entry. If there is no entry, PowerShell returns $null, but ($null + 1) == 1 so it will work properly.

$hashTable[$name] += 1

 

Scripting it up

Here are the complete script events: (download as project.)

BeforeAction Script Event

# Create empty hash table for use in action (we need to store it in a Project Variable)
$FBVariables["FrequencyTable"] = @{ } 

OnStatusMessage Script Event

# When output comes from the action, check if it is an Event header line

$headerPattern = "^\[\d+\] (.+)$"
$RegexOptions = [System.Text.RegularExpressions.RegexOptions]

foreach ( $match in [regex]::Matches( $StatusMessage.MessageText, $headerPattern, $RegexOptions::MultiLine ) )
{
  $appName = $match.Groups[1].Value.Trim()
  $freqTable = $FBVariables["FrequencyTable"]
  $freqTable[$appName] += 1
}

 

AfterAction Script Event

# Log the frequencies, sorted by value
"Frequencies for different sources"
$FBVariables["FrequencyTable"].GetEnumerator() | sort -descending Value | ft Value, Name -autosize -wrap
#
# (the .GetEnumerator() call in the expression above is a trick which allows us to sort the contents of the hashtable.)

Download the Project

Click here to download a sample project with this action.

The downloaded project has one more feature: it suppresses the normal output from PsLogList. Only our custom information is shown in the log.

Action output

Here's the log output from when the action is run normally:

Frequencies for different sources
Value Name
----- ----
29 Service Control Manager
3 Application Popup
2 W32Time
2 IPSec
2 EventLog
2 WinHttpAutoProxySvc
1 DCOM
1 AeLookupSvc
1 Tcpip6
1 Tcpip
1 redbook

Why this is Useful

OK, so this example isn't particularly relevant for automated builds. However, this technique (or one like it) can be used to parse information from any tool which is run by FinalBuilder.

Notes

  • Having a script event run every time data is logged decreases the performance of the action. For actions which log very large amounts of data, it's better to use Log To Variable and then process the output all-at-once in a separate action.
  • You'll note that the actual regular expression call used in the script event is different to the example  expression showed at the beginning. We have to call the .NET RegularExpression class directly in order to use MultiLine mode. (If anyone from the PowerShell Team is reading this, please try and find a way to set the expression mode with simpler syntax!)
  • You can actually do everything shown in the example with JavaScript instead of PowerShell, using a Regexp object and an associative array. However, some steps (like automatically printing the results) are much more complex to do with JavaScript.
  • You could also get the same results from a PowerShell action by using get-wmi and the Win32_NTLogEvent class. That will be the subject of upcoming blog post Part Three: Custom actions.




Comments are closed.
Showing 1 Comment
Avatar  angus 6 years ago

For anyone who read this post before the final release of FB 6, I just tidied up some of the syntax to reflect a better way of accessing $FBVariables, and a better way of incrementing hash table entries.<br><br>If you didn't see the old version, don't worry - you're not missing much!