Saturday, June 28, 2008

This little bit of usefulness in powershell is also available in various guides and books, but I often find that technical documentation is written to be more complete than practical.  I will scan a long document full of reference data to assemble what I need to do which can really be communicated in a simple example.  So here's a few easy ways to check to see if a registry entry exists or to look up a value.  These are really handy for testing and auto configuring machines on your network.

# The Test-Path cmdlet is handy for detecting not only if files exist in the file system, 
# but reg key entries as well
#
# $QuickLog will get a $true or $false
#
$QuickLog=(Test-Path 'HKCU:\Software\JQL - www.jql.co.uk\Quick Log')
 
# This returns an array of all the values at this key
$regObj = get-item 'HKCU:\Software\JQL - www.jql.co.uk\Quick Log'
 
# This is a path for using with set-ItemProperty
$path = 'HKCU:\Software\JQL - www.jql.co.uk\Quick Log'
 
# Notice we use the object here
$keys = $regObj.GetValueNames()
foreach($key in $keys)
{
    # Do what you will with your reg keys
    if($key.Contains("Hints"))
    {
        # Set the execution policy so we can write here
        set-itemproperty -Path $path -Name ExecutionPolicy -Value unrestricted
        
        # This assumes you have a String property
        # Notice that we use the path and not the object here
        set-itemproperty -path $path -name $key -value 0
    }
}
Saturday, June 28, 2008 1:26:11 PM (Central Standard Time, UTC-06:00)
Oh this is hilarious.  I'm playing with Google AdSense on my blog and it being a new generator, it has decided to place ads for black singles based on my last name.  Now that's entertaining.  I'm curious to see if they will hone in on something more appropriate, so bear with my experimentation here.

Saturday, June 28, 2008 12:35:58 PM (Central Standard Time, UTC-06:00)
 Monday, June 16, 2008

I've been looking all over trying to find a smart way to create nested XML in powershell, and after combining a few sources I have come up with something that works pretty well.  Now I don't recommend actually doing it this way unless you have to.  This is a fairly laborious process that I'm undertaking only because my particular situation requires that I do not use compiled code.  A C# object model using the Linq XML serializer is far easier, consistent, and less prone to bugs than this.  However sometime you just have to write a hack.

# Create the results file
$output = $args[0] + "\results.xml"
$outxml = New-Object "System.Xml.XmlDocument"
$outxml.LoadXml("<?xml version=`"1.0`" encoding=`"utf-8`"?><Results xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`" xmlns:xsd=`"http://www.w3.org/2001/XMLSchema`"></Results>")
 
# Tests
$elem = $outxml.CreateElement("Tests")
$outxml.get_ChildNodes().Item(1).AppendChild($elem)
 
# Test
$elem = $outxml.CreateElement("Test")
$elem.SetAttribute("xsi:type","MemoryTest")
$outxml.SelectSingleNode("Results/Tests").AppendChild($elem)
 
# Name
$elem = $outxml.CreateElement("Name")
$elem.PSBase.InnerText = "Video"
$nsMgr = New-Object System.Xml.XmlNamespaceManager($outxml.get_NameTable())
$nsMgr.AddNamespace("type", "MemoryTest")
$outxml.SelectSingleNode("Results/Tests/Test", $nsMgr).AppendChild($elem)

 

Notice the use of the XmlNamespaceManager.  This allows you to have multiple Test nodes within Tests each with a different type.  This makes sure you can add elements to the right trees. 

Again, this is the grunt work of XML serialization that lots of programmers end up doing, but really shouldn't have to.  Go use the Linq serializer.

Monday, June 16, 2008 10:01:53 PM (Central Standard Time, UTC-06:00)
 Friday, May 23, 2008
This is a nice and short talk on the emergence of open source information, not just software, and how it is reshaping economies.  Even though everyone is pretty well used to the internet, at least in rich industrial nations, we are still in the very early stages of its development.  It's only been commercially available for 15 years.  There are some great ideas in this talk about where it might go and how it may impact industry.

Friday, May 23, 2008 1:14:05 AM (Central Standard Time, UTC-06:00)
 Wednesday, May 21, 2008

I just found this great new blog for efficient and power concious living.  Check it out.

http://www.metaefficient.com/

Wednesday, May 21, 2008 12:11:02 PM (Central Standard Time, UTC-06:00)
 Wednesday, May 14, 2008

So I've recently had the task of fetching some information out of system.nfo files to translate cryptic IDs numbers into human readable friendly names.  This is the thing that XML is supposed to excel at right?  Well you would think that task would be simple enough, and as it turns out it is.  However searching for this solution online proved to be difficult, so I'm going to retell my experience here in hopes that it might help anyone else with this problem out.

I started with what I thought was a nice elegant powershell script that would query the XML like a SQL DB and return my value.  Seems simple enough right?

$friendlyName = $sysinfo.MsInfo.Category.Category.Category.Data.DeviceName | where {$sysinfo.MsInfo.Category.Category.Category.Data.Device_ID -eq $global:deviceName}

 

This would work with normal XML where your content is inside the XML tags.  However the system.nfo file uses CDATA objects and many nests of categories so you have to go one step further.  Since I don't know which Category sub-tree my offending device or data might be in, I ended up grabbing all of the data objects that met my criteria and doing a breadth first search.  Sounds ugly compared to the one liner up there, but it actually works and don't take that long.  The following code is in powershell.  The key here is that handy get_innertext() method.  Your standard .Value or .Text won't cut it with CDATA.

# Open the associated .nfo file
$sysinfo_file = $global:computer_name + ".nfo"
$sysinfo_path = $global:computer_name + "\" + $sysinfo_file
[xml]$sysinfo = get-content $sysinfo_path
 
$nodeList1 = @($sysinfo.GetElementsByTagName("Device_Name"))
$nodeList2 = @($sysinfo.GetElementsByTagName("Device_ID"))
$nodeList3 = @($sysinfo.GetElementsByTagName("Manufacturer"))
 
$i = 0
foreach($node in $nodeList2)
{
    $deviceID = $nodeList2[$i].get_innertext()
    if($deviceID -eq $global:device_name)
    {
        $friendlyName = $nodeList1[$i].get_innertext()
        $deviceManuf = $nodeList3[$i].get_innertext()
    }
    $i++
}

The purpose of this handy little script is to look up a cryptic device ID and return a friendly manufacturers name.

Wednesday, May 14, 2008 11:20:06 AM (Central Standard Time, UTC-06:00)
 Thursday, April 17, 2008
Last night I actually sat down and watched part of the Democratic debate.  I was hoping for some engaging discussion about how to differentiate Hillary from Obama.  Instead it was a tabloid hash out.  The Washington Post was dead on with their assessment.  Instead of probing the candidates about how they would handle large issues that affect the future of the country like health care, the budget, Iraq, the falling dollar, immigration, and legislative gridlock, ABC decided to pander to the Enquirer crowd.  Most of what I could stand to watch was arguing over sound bites, who said what about whom, who was electable, and which friend of yours said something nasty about the other side.  All of it useless and mostly irrelevant to how each potential leader would handle the future of this country.

However, there is a ray of hope, at least spoken about by some.  Tim Robbins' speech at the National Association of Broadcasters meeting in Las Vegas this month offers a compelling vision, which is at the heart of why networks run debates like a high school lunch room instead of a forum for deciding the future of the American nation.  The speech was considered highly controversial.  After listening to it, the fact that it was considered controversial is at the root of the problem.

So instead of complaining, create, make something good for others to be inspired by.  The above is certainly my share of complaint, and Tim's speech is in my opinion something to be inspired by.

Thursday, April 17, 2008 8:40:36 AM (Central Standard Time, UTC-06:00)
 Saturday, April 12, 2008

Got this off the Drudge Report this morning.  It's more writing on the wall, but it sets the context very well for what is coming.  There's no need to fight it, so we'd better get used to embracing China as the world's next super power.  Let's just hope it's a peaceful transition.  Their rise is affecting manufacturing job markets the most right now.  Software and IT services still hold an edge in experience because kids getting out of Chinese universities just haven't shipped software yet.  This will change though.  Right now most companies have a hard time getting the value out of overseas development houses that cost less.  I suspect the US and Silicon Valley have maybe 15 to 20 years before anyone working in those markets can be easily outsourced to very reliable, highly experienced developers in China or India.  So save up now, and start looking for property in less expensive regions where your VISA is valid, and the money you save now will go further, as income pressure for American IT workers will force real wages lower.

Saturday, April 12, 2008 12:18:23 PM (Central Standard Time, UTC-06:00)
 Thursday, April 10, 2008

Today I had the opportunity to practice some more test driven development with a resident expert in the field, Scott Bellware.  Scott is a really excited and engaging guy to be around.  He's really taken on Domain Driven Design, he believes in it, and he can teach it like you would teach someone to tie their shoes.  It's simply second nature for him.  I consider myself a relatively accomplish IT professional.  I know my way around all flavors of C code, object oriented design, and implementation.  Typically I come from the school of thought that you plan what you are going to build before building it.  Write it all down, figure out the hard problems, chop them into smaller, more manageable ones.  Show your solution to someone else, let them tear it up, and before you start writing any code you have a pretty good idea of how version 1.0 of what you are creating will look like.  Now this is an abbreviated summary of development, but that being said you can push it into waterfall with milestones, or agile with a backlog and sprints. 

Milestones and sprints are both organizational process.  They have very little to do with actual development.  Domain Driven Design is the bible for this style of development, and we got to experience a little piece of it implementing just a few straightforward rules in part of a hypothetical system.  I have not read the book, although it is now on the top of my list. 

The paradigm as experienced in an afternoon is code to the test, and isolate your functionality into 'domains.'  Coding to the test is essentially writing your tests first, simple ones.  Write a test, then write the code to get just that test to work.  As you make more tests work, you add more functionality without adding anything extra.  It goes against my grain because you see extensibilities and optimizations you want to make for future expansion or features you 'know' are coming simply because you've seen them done that way so many times before.  This is a lot like taking your past out of your coding future, and only writing what is necessary even if it feels incomplete.  If you come to a new feature, write it down, present it to the client, or whoever is writing the check before writing something no one may want.

The domain side of the coin revolves around setting rules for what to and not to write for given domains.  At the core of this is interoperability.  Make no piece of code dependent upon another.  If you add an include or a using, that is all it should take.  Everyone who has written software has gone through a project where they tried to get one little API or feature to work which required just one include.  That one begat another, which begat another, and another until you've written a state machine for Judges in the Old Testament.  Adhering to strict domains eliminates this.

Now I am not about to call myself an expert on DDD, but I did like what I saw.  For the purposes of our example, it worked very well and I can envision it to work well for large projects.  One thing is for sure, I will definitely be giving this new approach a few more cycles.  I'll just need the discipline to stick to it and not jump into coding before testing which is oh so tempting.

Thursday, April 10, 2008 12:52:50 AM (Central Standard Time, UTC-06:00)