Creating Windows Event Log Sources from PowerShell

To help out with some logging in a recent project we needed to organise the Windows logs with multiple sources. A bit of research later and I found a nice and easy way to create these log sources from PowerShell using the New-EventLog cmdlet.

After a few iterations I also put in checks to make sure the event source did not exist before trying to create it and give the appropriate feedback to the user.

function Create-LoggingSources($loggingSources){
Write-HostIndent "Creating logging sources" 1
foreach($loggingSource in $loggingSources.LoggingSource){
$eventLog = [System.Diagnostics.EventLog]::SourceExists($loggingSource)

if($eventLog)
{
Write-HostIndent "Logging Source '$loggingSource' exists" 2
}
else
{
Write-HostIndent "Creating Logging Source '$loggingSource'" 2
New-EventLog -LogName "Sauces" -Source $loggingSource
}

Limit-EventLog -OverflowAction OverWriteAsNeeded -MaximumSize 10240KB -LogName "Sauces"
}
Write-HostIndent "Logging sources created" 1
}

The logging sources are provided in an XML configuration file. $loggingSources is in the following structure.

<LoggingSources>
<LoggingSource>Apple</LoggingSource>
<LoggingSource>Orange</LoggingSource>
</LoggingSources>

I've put together a self contained example of this script you can play with. It will create two new event log sources called Apple and Orange in the log of Sauce. CreateEventLogs.ps1

Remembering where you've been in Powershell with pushd and popd

The other day I discovered a long existing pair of commands in Powershell that allows one to navigate to a directory and then back to the previous one without having to manually maintain a stack of directories. The two commands are pushd and popd.

A quick bit of searching shows that these commands have existed in Unix shells for many years as well as Powershell since version 2. Wikipedia -- Pushd and popd

Where I have found this really useful recently is in deployment scripts where I need to change the current directory in the script but for usability I want to go back to where the script was first called from should any errors occur or even if the script finishes successfully. By using a try/catch/finally pattern this allows me to put the user back where they started with confidence whenever they execute the script.

try
{
pushd DIRECTORYPATH
# Logic goes here
}
catch
{
# Make sure any exceptions are bubbled up
throw $_
}
finally
{
popd
}

TechNet -- Push-Location
TechNet -- Pop-Location

Good comments instead of bad

One of the refrains that we all hear when the topic of code comments comes up is the refrain “My code is self-documenting.” On the surface this refrain makes sense, why write more than you have to. Unfortunately the way this is usually implemented results in the baby being thrown out with the bathwater. Leaving us in a worse off position than we were with too many comments.

I’ve never met someone who would argue that the code we create should be difficult to understand. That the how the code executes should be hidden or where the flow of control goes. Our code needs to be easy to understand so that as we maintain it in the future we do not have to rewrite entire classes just to add a bit of functionality.

So, what is a good code comment?

Comments should explain WHY” to paraphrase the colleague of mine who gave me this pointer.

Code Comments

How often have you come across some code that works but does something in a crazy way when a much more simple option is clear to you? Only when you implement your simple solution suddenly bugs appear and you finally understand why those lines existed.

An example of a superflorus comment can be found in the .NET Framework Reference Source of the String class. Range check everything. Yes, I can see that’s being done. You’ve obviously thought it important enough to point out but why? Why is it important to note that you are doing all range checks? A comment like this only results in more questions while answering none.

This sort of situation is where code comments become invaluable and will save you and your colleague’s hours in the future. Spend the time to explain why you made the design decisions you did. When you apply a workaround that is strange explain why you did this instead of the more ‘obvious’ solution.

A good example can also be found in the .NET Framework Reference Source. But this time in the DateTime class. That DateTime adjustment underneath the code is not clear at first glance why you would want to add double the day remainder in milliseconds when the time is negative. However when we read the comment above it explains why we would want to do such a thing and even uses a clear example to demonstrate the way.

Commit Comments

This concept of explaining why finds even more value when it comes to commit comments.

How often do you see an odd design decision but when you look into the history of that file the comment is “Added files.” A comment like that is less than worthless because not only does it tell you nothing new but you get irritated or angry and it sits with you as you try to fix whatever is wrong. Again, explain WHY you have made the changes you have. Explain why you chose a pattern or design over another. When writing these comments imagine that 12 months from now you will be coming back to this. When we can barely remember why we made choices a few weeks ago how can we expect to remember why we made choices 52 weeks later?

So to conclude. “Self-documenting code” should be applied to only the how something works. In no way can it show the why changes were made of designs chosen. When you come back months or years later the why is more valuable than any amount of how or what comments.

Connecting an iOS device to a mixed 802.11b/n WiFi network

In a recent visit to home I was presented with an old problem that had become a real annoyance. The iOS devices owned by the family (minus the iPad) including my iPhone would not connect to the house WiFi network. They would happily detect them but the moment they tried to connect they would time out.

It took a bit of pecking around and trial and error but I found a single change that then allowed all the devices to connect.

It boils down to only allowing 802.11b to operate on the 2.4GHz band instead of the default dual b/n. It see,ms the iPhone and iPod Touch devices do not play nicely with dual use of that band by the b and n standards.

Playing with Regex on OSX

RegExhibit

If you've ever been stuck with the problem of trying to build anything but a simple regular expression you know how painful it can be getting it to match just what you want.

When developing for .NET on Windows I was introduced to a brilliant free tool called Rad Software Regex Designer that gave you the ability to provide an example of the text you wanted to match and an area to slowly build up your regular expression while getting instant feedback on what it was doing. It even has dialogs to add specific regular expression commands in case your proficiency with regular expressions isn't high or you just forgot how to create a non matching group. After moving to OSX for work I went looking for a similar tool for the Mac. And after a while I found it.

RegExhibit is a GUI tool of OSX that uses the Perl regular expression library to help you build regular expressions. This should be fine for any other languages that use a PCRE library but make sure you check before deploying. The core part of the program are two text areas. you place an example of the text you want to match into the lower area and build up your regular expression in the top are. There are even tabs for doing matches and splits but you'll likely find yourself in the match tab for most of time. However it doesn't offer the same built in dialogs like the Rad Software Regex Designer so make sure you've got a regular expression reference handy.

This is a great tool that has saved my sanity several times already and I do recommend to anyone that has to play with regular expressions and is developing on the Mac.

Adding Attachments with ActionMailer

Well recently I had the fun task of using Ruby on Rails' ActionMailer to create some automated emails to send out to users. At some point it was decided to attach the original email we received from the user to the notification email we were sending out to the user.

Now you would think that using the attachments method provided by ActionMailer would make it a easy as just giving it the file you wanted to add. Turns out it's like that for Ruby on Rails 3, not for 2.

The most infuriating thing was that if you use the attachments method then the method you called attachments from will not render the default view template it would normally. This means you have to explicitly call the render method.

Instead of putting it out all nicely I'll just link to a blog post from ELCtech.com that explains it well. http://www.elctech.com/ -- [ActionMailer] Multipart emails with attachments

My Borderlands Troubles

Being a Good Consumer

Last week I purchased the Borderlands DLC, Zombie Island of Dr Ned, for my PC Retail version of Borderlands. After purchasing it I was informed I would also have to install the 1.1 update so that was downloaded as well.

We've Got a Problem

My first attempt to update Borderlands resulted in a catch-all error dialog informing me that the update had failed. After looking on the Gearbox forums I got pointed at running the update from the command prompt using the "msiexec" program. http://gbxforums.gearboxsoftware.com/showthread.php?t=87233 - (FIX) Fatal Error:Installation ended prematurely because of an error. This resulted in the patch doing the same "Gathering information about your computer" routine as the original patch attempt and silently exiting without doing anything. A quick check on the "msiexec" program's help dialog showed a logging flag which I set and posted the output of that and the dxdiag output on the Gearbox forums. http://gbxforums.gearboxsoftware.com/showthread.php?p=1721935 - Unable to Install Patch or Zombie DLC - Windows 7 - Error 1603

You Didn't. Did You?

This is when things got interesting. Soon after I read a new post of someone having a similar problem as me and posted a suggestion to run the "msiexec" program with the logging flag set. A reply post by another member to mine said that would be pointless as "we know where the patch is try to write to" This gave me an idea which prompted me to look through the "msiexec" log to try and answer. A quick search for the drive that I installed Borderlands to (E:) found nothing. A search for the 32 and 64 bit Program Files directories on the C drive found both. Now my question was a pretty simple one, did the patch and DLC require that the game be installed in the Program Files directory on the C drive? A question in the FIX thread brought no answer after several days so I decided to give it a go and reinstalled Borderlands to my "C:\Program Files(x86)\" folder.

You Did

And guess what, the patch and DLC installed without a hitch.

For a game developer to not allow the patch to be installed to wherever the program has been installed is just unacceptable when every other game I have patched has never required it.