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.
When you add an action to a FinalBuilder project, you also add at least three script events:
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.
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.
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.)
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
Here are the complete script events: (download as project.)
# Create empty hash table for use in action (we need to store it in a Project Variable) $FBVariables["FrequencyTable"] = @{ }
# 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 }
# 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.)
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.
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
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.
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!