-
More PowerShell – a Cmdlet
This past weekend I spent some time reading up on and writing my first PowerShell cmdlet. The cmdlet is an easy one, but replaces a PS function I have copy/pasted into several scripts here and there to handle cleaning out directories of old backups or other types of files. One scenario is my RadioShark which I have setup to make daily radio recordings. The software doesn’t have any settings for how long to keep the files, so up until now I have just been manually deleting a couple dozen at a time every month or so.
Enter Remove-OldItems, named after the built-in Remove-Item.
Full Syntax: Remove-OldItems c:temp -pattern *.mp3 -KeepDays 7 -Leave 2 -Confirm -WhatIf
That will remove all mp3 files in c:temp which are older than 7 days. The Leave parameter is for when I use it for dealing with backup files and is a safeguard so that even if all of the files fall out of the date range, they won’t all be deleted.
I have put together 32-bit and 64-bit installers, feel free to download them. If you run it on a 64-bit system, the install will register with both the 32 and 64bit PowerShells. I can make the code available if anyone’s interested.
After installing the .msi, you can confirm the new Snapin is on the system by running get-pssnapin -registered. You should see EjiSnapin listed.

Now the Snapin containing the cmdlet(s) is there, but not loaded into the current PowerShell session. Since I’m going to be running this from a Scheduled Task, I don’t want to have to explicitly run Add-PSSnapin EjiSnapin every time I want to use it. One quick way around this is to add that command to the system-wide PowerShell Profile located at $pshomeprofile.ps1. That’s easy enough, in an elevated PS prompt, just run notepad $pshome/profile.ps1 and add a single line Add-PSSnapin EjiSnapin and save the file. Now every PS session will have the cmdlet ready to go.
Here’s the final result, a scheduled task with a simple command being run to clear out old files in my RadioShark directory.

Overall it was fairly easy, the most difficult part came with getting the installers to work correctly between 32 and 64-bit installations. Future enhancements, if I come into a situation where I need it, may be to add processing from the pipeline so a collection of files to be deleted could be passed to the cmdlet instead of a directory path. Might be useful, might not.
Here’s C# for doing the actual deletions.
DirectoryInfo rootDir = new DirectoryInfo(Path); // anything older than Today minus KeepDays may be deleted DateTime protectionDate = DateTime.UtcNow.AddDays(-KeepDays); List candidates = rootDir.GetFiles(string.IsNullOrEmpty(Pattern) ? "*.*" : Pattern, SearchOption.TopDirectoryOnly) .OrderBy(f => f.LastWriteTimeUtc).ToList(); if (Leave > 0) { // pop the last Leave files off the end (the most recent) candidates.RemoveRange(candidates.Count - Leave, Leave); } // now only keep those that are old enough candidates.RemoveAll(f => f.LastWriteTimeUtc >= protectionDate); // cycle and delete candidates.ForEach(f => { if (ShouldProcess(f.FullName, "delete")) { try { f.Delete(); } catch (UnauthorizedAccessException ex) { WriteWarning(String.Format("Unable to delete '{0}', UnauthorizedAccess", f.FullName)); // IOException can also occur, but I want that to be a termanating exception } } else { // Nothing to do, ShouldProcess provided any errors/warnings/etc. } });In the process of writing this I learned that PowerShell V2 allows you to script cmdlets. So this could have been greatly simplified (mostly on the deployment side), but that wouldn’t have been nearly as interesting, right?
That’s all folks. Thanks for reading.
-
Slides
We spent this past Sunday afternoon in the park enjoying the great weather. More photos available in the gallery.
-
David and Imagination Movers
Our little David gets pretty excited when he hears the theme song for Imagination Movers, so much so that it’s just fun to sit back and watch him dance and sing to it. This morning I grabbed my cameras and caught a toned-down version. Enjoy!
-
Swimming!
Springfield finally had weather warm enough for swimming, so we took advantage of it and headed over to Jay and Katherine’s pool for the afternoon. David took a while to relax in the water but ended up having fun and wearing himself out.
-
Tracking down a Blue Screen of Death
Since rebuilding my machine with a new motherboard and processor, I’ve gotten a few crashes in the middle of the night. I’ve come downstairs to a rebooted PC with an error message indicating the dreaded Blue Screen of Death has visited. So I decided to figure out what’s causing it, and maybe find a fix.
When a bluescreen happens, Windows will take a snapshot of what is in memory at the time of the crash and store them for analyzing later. “Mini” crash dumps are stored in c:windowsminidump and are trimmed down (for space reasons) versions of the full crash dumps. There’s a great tool called Windows Debugger that can be used to take a peek into these dump files to decipher what may be causing the problem.
First I downloaded the Windows Debugging Tools so that I could get the WinDbg (Windows Debugger).
After installing the tools, start up WinDbg and you’ll see a very plain looking interface that is essentially a console with tons of menu options/commands.
The next step is to open one of those crash dump files. So go to File -> Open Crash Dump and select one of the .dmp files. It’ll chug away for a few seconds as it opens, and then you’ll be presented with some messages that include:
***** Kernel symbols are WRONG. Please fix symbols to do analysis.
Symbols are files that contain debugging information for your system files. They are platform and version dependent – meaning symbol files for a 32-bit Windows XP machine won’t help figuring out a 64-bit Windows 7 problem as is the case here. Luckily, WinDbg will download the appropriate versions of symbols once you simply tell it where to get them and where to put them. Select File -> Symbol File Path and enter the following into the window to save the symbols to a path on your C::
SRV*c:debugsymbols*http://msdl.microsoft.com/download/symbols
Check the Reload box before closing so that the symbols will be downloaded right away:
When you click OK, the status bar on the main console will read BUSY as the necessary symbols are downloaded. Then the cursor will sit and blink, waiting for you to tell it what to do.
Now just type in:
!analyze -v
and you’ll be presented with lots of very technical technical text. In my case, I scanned through and saw a couple important bits of information:
PAGE_FAULT_IN_NONPAGED_AREA (50)
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0x50
PROCESS_NAME: Robocopy.exe
FAULTING_IP:
nt!MmCopyToCachedPage+215IMAGE_NAME: memory_corruption
So it sounds like it’s a bad memory pointer resulting in a fun access violation, happening in a kernel function MmCopyToCachedPage. And it doesn’t seem to have anything to do with power management, instead it was occurring during one of my nighly backups that uses Robocopy to pull files off of the network.
Now, what to do about it? I tossed MmCopyToCachedPage into Bing, and the very first hit was for someone running a similar processor on the exact same motherboard. (For the record, Google’s search results didn’t appear to be nearly as useful). Reading through the thread, a mentioned fix was to change a BIOS setting to accomodate the processor better (CPU Margin Enhancement, whatever the heck that is). Tonight we’ll see if this has any impact on the system crash, I’ll be crossing my fingers.
So there you have it, using WinDbg to get a look into what part of your machine is blowing up. Thanks for reading.








