One of the strengths of PowerShell is the easy access to WMI it provides at the command line. Before PowerShell, accessing WMI involved doing all the work from within VBScript and processing the results using the facilities available in the scripting language. PowerShell on the other hand is a built on top of the .Net framework so the manipulation of the results is far easier. I now find myself stepping away from the desktop and opening the console for a lot more tasks, I always believe that you should tell the machine what you want it to do rather than doing it yourself.
To demonstrate this the code example below will
Query the application event log of a remote server
Order the log entries by the date they occurred
Return the first 5 results from the set
The cmdlet Get-WmiObject is the gateway to WMI and allowed me to complete the first step with this simple command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As the results from the WMI query are stored in an array, I’m now free to manipulate the result set further using the commands available in PowerShell. Completing items two and three on my list only requires this command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The big win here is being able to run a query on a remote server but manipulate the result set on my local machine. WMI has a large set of providers which are now only a query away from my console.
Sometimes errors occur that really have me scratching my head and they are usually occur when I move from my machine to the test environment.
While running through some changes I’d made to a form the behaviour of HttpSessionState became erratic, randomly returning either null or the value I had set. I fired up DebugView and captured this trace:
Here, three different threads are shown serving the page requests and, as I would expect, only one thread is returning the value I had set.
This sounded like a configuration issue so I had a look in IIS Manager and found the application pool was configured to be a Web Garden
This now made sense as my form was using InProc sessions handling and Web Gardens behave like a single machine Web Farm, requiring a StateServer for session handling.
The solution to my problem was simple, set the value to 1 as I don’t need the resilience of a Web Garden. If you do though Nicholas Piasecki, has a great write up here.
I found the amount of time I spent manually testing forms as part of my development process painful and thought there must be a better way of doing this task. The forms are tightly coupled to the database so any refactoring becomes a risky process due to the lack of unit tests. One answer I found that helped me is the http://seleniumhq.org/ web testing framework from ThoughtWorks.
The framework is built around a language called Selenese which executes actions in a web browser. There is a client library available for .Net, so the tests can be run in NUnit or any similar tool. For the NUnit integration to work you have to be running the Selenium RC web server to host the test and a web server for the ASP.Net page being tested.
This could be a lot of work upfront just to run some tests. So I have written some helpers to configure the environment automatically.
Web server
The development web server which ships with Visual Studio (once called Cassini) is a perfect tool for hosting the ASP.Net page under test. An instance is started for the test suite with a hard coded port of 8085 and the URL is set to localhost. As all the projects live at the same level in my project tree I am able to hard code the path as well.
Selenium RC
The process that hosts the tests is a Java based application called Selenium RC. When a test is run in NUnit, the Selenium client library sends Selenese commands to this process over HTTP. When the test suite first runs, I start a Java process and point it to the Selenium RC jar file, this will only get closed when all the tests are finished.
Selenium Runner
The helpers are combined by an abstract class which starts the Web Server and Selenium RC process so any test class that derives from this will automatically have the testing environment configured. The only data required by implementors is the name of the project under test:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I have been using this for a week now. At first just as a means to run through the forms quickly. However, I have found other uses for it. I have started adding asserts for common scenarios. One Selenium command that is proving useful to me is selenium.GetHtmlSource() which returns a string of the full source code. This is enabling me to run a test and see the source appear in the Output window and then to check for the presence of certain items. I have used this method the check that certain Omniture tags are being generated:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I am happy with the addition of UI testing to my development process. Here it helps to deal with legacy code which requires some work. It is now possible for me to start refactoring which is something that can only be done with this kind of test coverage.
One problem I have always encountered with RedDot is debugging the pre-executed script blocks. Fortunately Gavin Cope came up with this superb solution which also has the benefit of moving the pre-executed files out of the main RedDot folder.
Modifications
I have added to Gavin's work by:
Writing the error to a HTML file so it can be viewed easily in the browser
Adding a page with a list of all the error files in the logs folder
To create a HTML file for the error change the call to WriteToFile with the code below. Note, I have also changed the path for the PreExecute folder.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For the list of errors create a new file in the PreExecute folder called ErrorList.asp and paste in the following script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a handy PowerShell snippet. The first line creates a list of files containing a specified string, while the second line will delete each item in the list. For a sanity check, put -whatif after the rm command to see what will happen.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For my first attempt I tried to do the whole operation in one go but PowerShell threw an error. It took a little while for me to realise that the select-string command still had the file open which caused the delete to fail. Putting the list of files in to a variable fixed this quickly.
I wish to learn PowerShell as Windows finally has a great shell making it possibile to automate tasks that are long winded using the GUI.
Here are three very simple task which were hard to achieve using the MS-DOS shell.
Connect to UNC paths
To browse a network share in cmd.exe you first had to map a drive. With PowerShell you can navigate to server shares as you would a local drive.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
While it is possible to recursively delete files in cmd.exe, PowerShell has built in support for the ** operator making operations on sets of files very simple. For an example, the following will delete all files with the extension .bak from the C:\temp and all folders within it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Often I have to administer a service on a remote machine, a recent example is starting the W3SVC on a server which kept failing. As PowerShell has access to the Windows Management Interface API I can run this command instead of using IIS manager over Remote Desktop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In fact PowerShell finally provides a useful wrapper around those rich but hard to get at WMI APIs. The following script will enumerate all websites and display the path to their log file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I have a Mac Mini running as a small home server. So small in fact it runs headless, no keyboard, no mouse and no screen. This is fine as I can control it using VNC but every now and then it reboots and the VNC Server doesn't start at boot time.
So this script can be run from and SSH connection to get the server backup and running.
I use ReSharper, an amazing extension to Visual Studio and one which seems to be on most developers default tool list. I have now started using Subversion and Tortoise for some personal projects which means I have to manage my own file exclusion lists, specifically ReSharper which quickly turns a 100KB project in to a 4MB one.
So here is my TortoiseSVN global ignore pattern:rn:
While writing some tests for the following method I had a strange problem. When the test ran it threw a NullReferenceExceptions for my stubbed User object.
The method under test is simple enough
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The mocking Framework is Rhino Mocks and this was the solution to the problem.
With Rhino a call to a stub (or mock) is expected only once while my method is checking the user object a number of times. Eventually the test will just check that the cookie has been set so I can change the User stub to:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Back when I wrote a lot of ASP my best debugging tool was Response.Write and like most people I had functions to help me handle all the information. Back to the present day and the .Net framework moved on from echoing information to the response stream but every now this method still has its uses. Take my recent example of writing a HttpModule, this code runs inside the .Net pipepline and fires various events. When I deployed it to a test server I wanted to find out when events fired and what isntances were initiated. To help me .Net has the System.Diagnostics namespace so I can write:
Debug.WriteLine("Post Authorize event has fired");
Great, but how do I view all this debugging? I could have logged it, but I wanted a nice simple solution so I used DebugView, part of the SysInternals suite.
This clever program will display anything written to the DefaultTraceListener, plus it can connect to a remote computer.
I watched Glen Blocks PDC demo for the Managed Extensibility Framework (MEF) last year and thought it would be a great tool to use if I ever created a client application that had to provide a plug-in mechanism. As I write web based business applications I didn’t think this would be any time soon. Added to this I am using the Castle Windsor Inversion of Control container so I didn’t think I had a need for another container.
Background
I’m currently working on a project that has a central application for user authentication. Each client application calls a webservice to check the user’s credentials and, if all is well, a principal is added to the HttpContext. This process is all wrapped up in a HttpModule. My task is to create a variety of cookies to authenticate users with 3rd party or legacy systems once they are authenticated. The best place to do this is within the HttpModule but this is used by a variety of applications. To solve this I used MEF to create a pluggable PostAuthorization mechanism.
MEF and the HttpModule
My goal is to be able to write a component that can set a client cookie. As it is dealing with user information is will also have to access the user stored in the HttpContext. I created this interface to start with
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MEF creates dependencies at runtime whereas an IoC usually has a configuration process which defines the concrete instance to be created for the abstract services. In my httpModule I created a list of CookieSetters that MEF could populate:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
By attributing the collection with [Import] I'm telling MEF to wire up all assemblies it discovers that implement ISetCookies. Now this is in place it is time to start up MEF, and this being a HttpModule the place to do the work is in the Init method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The creation of the container, which I lifted from the CodePlex site, creates:
A catalog of all the assemblies in the bin folder, anything attributed with an Export will be added to the catalog.
A composition batch that will consume the exported assemblies, anything attributed with Import will be added to the batch.
A container to hold it all and orchestrate the magic.
Now I can create my PostAuthroization event to kick off any CookieSetters MEF has found:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here I first check that the list has been created and then call the SetCookie method on each one. Below is a trivial example of a CookieSetter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When working with different teams being able to provide simple extension points is great and I can see MEF being the tool for the job. It will also be a good tool to have alongside an IoC as the two are complimentry.
As for the code above it solves a problem for me but still needs some work as the container will be built everytime the module is loaded causing a nasty performance hit. Putting in the HttApplicationState as described by Michael Puleio will be the best solution.