Thursday, December 28, 2006

UPDATE NUMBER 2:

Kevin commented about a flaw in my script wherein it would keep files open until the PowerShell process was closed - a scenario I should've tested but, in all of the excitement (ha), I missed. You won't believe what the problem was, either. I forgot parentheses on my $inStream.Close() method (it looked like $inStream.Close instead of $inStream.Close() ). The reason the trap { } script block didn't catch it is because the statement was still valid... it would just display the MethodInfo like below:

MemberType          : Method
OverloadDefinitions : {System.Void Close()}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.Void Close()
Name                : Close
IsInstance          : True

The [void] statement before it prevented the output from displaying, hence me not catching the bug. The script has now been fixed (hopefully). Thanks for the catch Kevin!

UPDATE:

Ignore my script. Go download the PowerShell Community Extensions instead. It has a great Get-Hash script that does everything that my script does and more. I wish I had downloaded it sooner :-)

 

Jeffrey Snover posted a suggestion on the PowerShell blog recently to post automation scripts people have written in PowerShell that they use. Well, here is a script I wrote that I also submitted for the PowerShell Scripting Contest a few weeks back. The script is quite basic and is based on other code I found, but I added a little bit to it to handle some of my own needs. It calculates file hashes based on a specified hash algorithm (i.e. SHA1, MD5, etc). I like to use it to determine if a large file I've downloaded (like an ISO from MSDN) is a good file or if it was corrupted during the download.

Here is Calc-Hash.ps1:

param (
	[string] $inFile = $(throw "Usage: Calc-Hash.ps1 file.txt [sha1|md5] "),
	[string] $hashType = "sha1"
)

function Main
{
	if ($hashType -eq "")
	{
		throw "Usage: Calc-Hash.ps1 file.txt [sha1|md5] "
	}
	
	if ($hashType -eq "sha1")
	{
		$provider = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider
	}
	elseif ($hashType -eq "md5")
	{
		$provider = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
	}
	else
	{
		throw "Unsupported hash type $hashType"
	}
		
	$inFileInfo = New-Object System.IO.FileInfo($inFile)
	if (-not $inFileInfo.Exists)
	{
		# If the file can't be found, try looking for it in the current directory.
		$inFileInfo = New-Object System.IO.FileInfo("$pwd\$inFile")
		if (-not $inFileInfo.Exists)
		{
			throw "Can't find $inFileInfo"
		}
	}

	$inStream = $inFileInfo.OpenRead()
	$hashBytes = $provider.ComputeHash($inStream)
	[void] $inStream.Close()
	
	trap
	{
		if ($inStream -ne $null)
		{
			[void] $inStream.Close()
		}
		break
	}
	
	foreach ($byte in $hashBytes)
	{
		Write-Host -NoNewLine $byte.ToString("X2")
	}
	
	Write-Host
}

. Main
posted on Thursday, December 28, 2006 7:55:57 AM (Central Standard Time, UTC-06:00)  #    Comments [4]

This Christmas, my wife got me one of those awesome Logitech Harmony remotes (the Harmony 880 for those who are curious, and at a great price, too). I spent the better part of last night attempting to get it set up.

The out-of-box experience is great. The remote looks and feels excellent and the docking station for it is really cool. Of course, you should charge it prior to use. I got the thing charged and then began the installation process... on my Windows Vista box. Like so many things, it doesn't officially support Vista yet. What this means practically is that it doesn't yet support things like Aero Glass (I think because of WDDM support). It kicks the whole thing down to Aero Basic while the program runs. I also had some fun with Logitech's website because of some errors their server was having related to creating some COM objects.

At this point, it doesn't look all that good. Well, to be honest, I was feeling a little upset about the whole thing, but I WAS using the remote on an unsupported OS still and everybody has server issues once in a while. I was willing to give them the benefit of the doubt so I tried their website a few hours later. The thing worked great - even with the new security settings that Internet Explorer has. The website works by downloading a special file that the Harmony Remote Client opens so that all the settings are customized on their website and then loaded to the remote. I had a few extra security dialogs, but the thing still worked great.

Once I had the remote customized to my liking, I went into the living room to try it out.

POWER!

...

POWER!

...

POWER! POWER! TURN ON! TURN ON!

What is going on?!?

My TV came on, my receiver came on, but my satellite receiver just sat there.

For those who may have read the title of this blog post, you may have already figured out what my problem was. My satellite receiver's remote uses UHF instead of IR. My Harmony remote only uses IR (AFAIK). In other words, my remote cannot talk to my satellite receiver.

*sigh*

I am happy to report that I'm planning on investigating digital cable again anyway, because my satellite company likes new sign-ups better than existing customers. They'll give you an HD receiver without any questions if you're a new customer, but if you want to upgrade your receiver later, they want to charge you $800+ for a new receiver. Yeahhh, I think I'd rather go another route, thank you.

Hopefully, the digital cable box uses an IR signal instead of a UHF signal.

For those who may be scared away from the Harmony remotes, don't be. The thing works great with everything else. I entered in the model numbers for my receiver, TV, XBox 360, and PlayStation 2 and it talks with all of them without any problems. I'd been lazy and not using my receiver for sound before because I had to get out 2+ remotes everytime, but now, I'll be enjoying some surround sound when I play games on my 360 now.

posted on Thursday, December 28, 2006 7:21:19 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, December 14, 2006

Ahhh, JavaScript error messages.

<sarcasm>
They are the epitome of the user friendly error message. Developers love them, because they always tell you exactly where the problem is. Absolute error message perfection.
</sarcasm>

Below is an example of one of these messages that a friend sent:

Nice, eh?

You can tell EXACTLY what the problem is. That... thing... is null or not an object! And we've even got a line number, too!

NOTE: The above message was generated by a script I wrote a while back that is kicked off by the window.onerror event that fires when JavaScript exceptions are thrown. It posts to an application which then emails the developers in question.

posted on Thursday, December 14, 2006 11:05:47 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, December 11, 2006

I'll tell you what it looks like.

It looks like -1.#IND.

That's what it looks like. At least if the code is using the Double.NaN constant. I sure didn't know that before I saw it and, I can tell you, it sure freaked me out when I saw that in the immediate window in Visual Studio. I was working on speeding up another dev's code here and apparently they were using NaN to signify the difference between 0 and "not yet initialized." It works pretty well for them in that case, but as I said, if you're not expecting that, it very well may throw you off.

And PowerShell is smart enough to just say NaN instead of this -1.#IND stuff.

Along the same lines, -1.#INF is apparently how Infinity is represented.

(IND would be indefinite whereas INF is infinite... makes sense I guess.)

posted on Monday, December 11, 2006 2:34:15 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, November 29, 2006

A few weeks ago I posted a way to use PowerShell to find in files. This is just an extension of that post to show how you might open the results of your find in a program.

Try this out:

dir -include *.vb -recurse | select-string "text to search for" | % { notepad $_.Path }

If you've got a lot of Visual Basic files that contain "text to search for", you may end up with a lot of instances of notepad open. At work, I use UltraEdit, so I typically would open my files using uedit32 so that all of the results get opened in tabs. You could do the same with Notepad++ or any other program.

I haven't really used PowerShell for much production work, but it has already made me for more productive than I used to be.

While I'm at it, I'll share another nice one-liner that Kerry shared with me to ngen all assemblies in a directory:

dir *.dll | % { C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ngen.exe $_.fullname}

posted on Wednesday, November 29, 2006 1:21:49 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, November 07, 2006

The web has been busy with news about .NET 3.0 going RTM, along with Office 2007, Vista, etc. But some other news that hasn't received quite as much publicity is news regarding Sysinternals at Microsoft. There were a couple of posts today that I thought were very interesting.

The first post is about the move from the original Sysinternals site over to Microsoft. I think the best part of the announcement is the focus on letting the "community demand help drive [their] priorities." A few of the comments have been negative regarding the decision to not post the source code to the tools, but that is the only negative thing that I can see in the post. Besides, if people want the source enough, maybe Microsoft will put it back out again. They listened when people complained about the Vista EULA didn't they?

The second post is even better news. In addition to some new releases of some great tools from Sysinternals (mostly to support Vista), a new tool has been released called Process Monitor! Process Monitor takes all of the functionality provided by RegMon and FileMon and combines them with even more information such as information about threads! If you're worried that it will put too much into one place because it was nice to focus only on registry or file access, don't because with the click of a button, you can tell it to only display registry changes, file changes, or thread changes. If you want to get straight to the main Process Monitor page, it is here.

Here's a screenshot of Process Monitor in action:

Unrelated to this post, but I used the Snipping Tool in Vista to get this screenshot. It works pretty well.

posted on Tuesday, November 07, 2006 6:58:17 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, November 06, 2006

I haven't posted anything on PowerShell in a while so here's something that's useful.

Get-ChildItem -Recurse -Include *.* | Select-String "text to search for"

Or, if you like things a little more abbreviated, try this:

dir -r -i *.* | Select-String "text to search for"

Select-String is a cmdlet that will search files or strings, sort of like grep in Unix or findstr in cmd.exe. If you use the Get-ChildItem cmdlet, you can specify the -Recurse switch to retrieve subdirectories and the -Include switch will only include the file types that you specify. Then you can pipe it over to Select-String.

Pretty nifty if you're wanting to do some quick file searches.

Check out this PowerShell in Action book excerpt. It gives a good overview on file manipulation from PowerShell and also introduced me to using the Get-ChildItem command and piping the output to Select-String.

Before I began using PowerShell, I had been using a small cmd file called ff.cmd that used the following:

findstr /p /s /i /c:%1 %2

Then I could type things like:

ff "text to search for" .\*.*

But PowerShell is so much cooler now :-)

posted on Monday, November 06, 2006 1:12:11 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, October 31, 2006

Colin has raved about the joys of middle clicking for a while now, but I was never able to enjoy it because clicking my mouse's middle button never seemed to do all of the cool things that his did. Mine brought up a really weird multi-directional arrow thing that was supposed to let me scroll in any direction I wanted - except that it rarely worked the way I wanted it to.

Well, I finally decided it was time to fix it once and for all so that I could enjoy middle clicking like the rest of the world.

The mouse in question that I'm using is the Logitech MX700 *.

Here's what my mouse settings dialog looked like when it didn't work:

Now that it does work, it looks like this:

The difference is subtle, but all I did was change the functionality for the middle button from "Universal Scroll" to "Middle Button." That was way too easy for me to have missed it for this long, but I'm glad I finally found it. If you're having a similar problem getting your MX700 (or other similar Logitech mouse) doing middle clicks the way you want, check out what your setting is.

* - The Logitech MX700 is a great mouse that has a recharging dock so you don't have to buy batteries all of time... I've been using mine for almost 3 years without any new batteries. I can also highly recommend the Logitech MX1000, which I use at home. I plan on sticking with Logitech mice unless Microsoft ever releases a wireless mouse with a rechargeable dock. That rechargeable dock makes all of the difference.

posted on Tuesday, October 31, 2006 1:13:17 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, October 30, 2006

I'm having my first 9 minutes of fame... ever!

Check it out here!

(from Jon Galloway)

posted on Monday, October 30, 2006 12:58:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0]