The Difference between your Current Directory and your Current Location

§ February 27, 2013 11:45 by beefarino |

35479106It’s time for another entry in the trying-to-keep-myself-from-making-this-mistake-all-the-time series.

PowerShell has a notion of your current location.  You can see this using the $pwd automatic variable or the get-location cmdlet:

PS C:\Users\Jim\Documents> $pwd


PS C:\Users\Jim\Documents> get-location


This location is also displayed in the default prompt.  This path is used by PowerShell to resolve relative paths at the level of the PowerShell API.

Applications have a notion of the current directory.  This is the directory used to resolve relative paths at the level of the Windows API.

How you Get Burned

Your current location may or may not be the same as your current directory.

Allow me to elaborate…

If you write a file using a PowerShell cmdlet like out-file, the relative path you specify will be resolved using the current location:

PS C:\Users\Jim\Documents> 'hello world' | out-file foo.txt
PS C:\Users\Jim\Documents> ls foo.txt

    Directory: C:\Users\Jim\Documents

Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
-a---         2/27/2013  10:50 AM         28 foo.txt                                                                   

I told the out-file cmdlet to write the file foo.txt, and it create that file in my current location – c:\users\jim\documents.  Make sense? 

Now, let’s try the same thing using the .NET Framework directly:

PS C:\Users\Jim\Documents> [io.file]::writealltext( 'bar.txt', 'hello world' )
PS C:\Users\Jim\Documents> dir bar*
PS C:\Users\Jim\Documents> dir ../bar*

    Directory: C:\Users\Jim

Mode                LastWriteTime     Length Name                                                                      
----                -------------     ------ ----                                                                      
-a---         2/27/2013  11:04 AM         11 bar.txt                                                                   

This time I used the System.IO.File.WriteAllText static method, specifying the relative path bar.txt.  But the file was written into another directory! 

Why?  Because the WriteAllText method uses paths relative to my current directory, not my current location.  In this case, they’re different:

PS C:\Users\Jim\Documents> [environment]::currentdirectory
PS C:\Users\Jim\Documents> get-location


The fact is, PowerShell doesn’t actively move the [environment]::currentdirectory as you navigate around the drive:

PS C:\Users\Jim\Documents> cd .\project
PS C:\Users\Jim\Documents\project> [environment]::currentdirectory
PS C:\Users\Jim\Documents\project> cd /
PS C:\> [environment]::currentdirectory

This becomes a problem when you use PowerShell to run an application or invoke parts of the .NET framework – the output doesn’t go where you’d expect it to go.  Generally speaking, these things will work off of the current directory and have no concept of your current location in PowerShell.

Things You Can Do

First, you can force PowerShell to update the current directory each time the current location changes.  Just customize your prompt function so it sets [environment]::currentDirectory to the current filesystem location:

   1:  function prompt {
   2:      $p = get-location -PSProvider filesystem | select -exp path;
   3:      [environment]::CurrentDirectory = $p;
   4:      return "Jim is Awesome!!!1 $pwd> ";
   5:  }

Line 2 gets the current location for the FileSystem PowerShell Provider.  We have to specify the FileSystem provider because PowerShell lets you do crazy things like set the current location to the registry, and we can’t very well set the current directory to such a path.  Line 3 updates the current directory so it matches the current location.  This happens each time each time the prompt is written by the current host, so the current directory will be updated after each command.  That means when you change location, the current directory will immediately follow suit.

Second, if you author cmdlets that rely on paths, and you end up using these paths in .NET framework calls, I would strongly recommend that you resolve the PowerShell paths into full file system paths before passing them on to the framework:

// ...
[Parameter(Mandatory = true)]
public string FilePath { get; set; }

protected override void ProcessRecord()
    var fullPath = this.GetUnresolvedProviderPathFromPSPath(FilePath);
    Bitmap bitmap = CreateBitmap();
    bitmap.Save( fullPath );
// ...

Finally, if you find your self expecting a file to appear in your current location and it doesn’t, check the current directory before you start throwing things:

PS C:\Users\Jim\Documents> test-path bar.txt
PS C:\Users\Jim\Documents> test-path ( join-path ([environment]::currentdirectory) bar.txt)

Day of Warehousing to Benefit the Cloverleaf School

§ February 25, 2013 12:50 by beefarino |

Extremely Serious Database Developers.I think my favorite aspect of the MVP summit is the chance to reconnect with friends from all over the world and hear about the things they’re doing.  The professional stuff is great, but I also love to hear how MVPs are using their skills to improve their communities.

As it turns out, two of my friends from the Atlanta SQL community are putting together an all-day data warehousing training, with all proceeds going to the Cloverleaf School of AtlantaJulie Smith and Audrey Hammonds are generously donating their time and expertise to dispel your data warehousing ignorance on March 14, 2013 in Duluth, GA. 

This is a rare chance to learn from two experts in the area while doing something grand for the community at the same time.  For more information about this event – including the opportunity to donate to the school directly if you cannot attend – check out A Day of Warehousing with the DataChix to Benefit the Cloverleaf School.

StudioShell 1.5 is Available

§ February 6, 2013 14:07 by beefarino |

I’m happy to say that a new release of StudioShell is up, along with a new version of the StudioShell.Beta nuget package!

The big things in this release:

  1. Support for Visual Studio 2012
  2. Support for PowerShell 3.0
  3. Support for use in the ISE

In addition there are tons of itty bitty bug fixes and incremental improvements. 

This release is still classified as a beta.  I want to collect usage information from VS2012 and/or PowerShell 3 users before marking the release as stable, and there are some documentation gaps that need to be filled.  That said, the 1.5 release is still preferred over the existing 1.2 and 1.3.1 packages for stability and features.

Oh, and I went ahead and started pushing the StudioShell.Contrib project.  There isn’t must up there - at the moment it contains a few “helper functions” that I commonly use, and I will shortly push some Psake-related functions along with some contribution guidelines.  My hope is that others will fork the project and contribute their own pieces.


Spam Male

§ February 6, 2013 11:33 by beefarino |

spammaleI was walking my dog this morning, mulling over the kerfuffle on the interwebs lately about the overly sexual behavior of men at tech conferences, and I came to a realization.

These guys are spammers.  They’re Spam Male.

There is no better description – think about it:

  • their goal is singular and self-serving;
  • their lack of creativity and intellect makes it statistically improbable that they will achieve their goal;
  • ergo, they must throw themselves on as many instances as possible in the hopes that someone, some day, will prove the exception and help them achieve their goal.

Spam Male has a lot in common with Spam Mail.  No one really wants it around, it gets marginalized and ignored, and eventually, it’ll get rooted out and sent to a special place where no one will ever pay any attention to it again.  I’m working on that last piece, by the way – and not just for Spam Males, but any community spammer who takes it upon themselves to ruin a good thing for everyone.  A proof of concept is in the works, and with some support I think I’ll have something working in short order.

And truth be told it isn’t just the men – I know women who act completely inappropriate at these things too.  But mostly it’s men.

The Sex Part

All humor aside, let me put something out there that will probably not go over well with my fellow men:

Sex isn’t that important to me.  I have better things to do and better ways to form relationships.  Because I’m a fucking adult.

Sure I love sex – it’s fun and helps me feel close to my spouse and relieves stress, but it’s not something I live for.  I don’t put it on the calendar or keep a tally to make sure I’m getting it.  And it’s certainly not something I’ve ever wanted to do with someone on a whim.

I’m sure part of this is age – I turn the big 4-0 in a month – but to be perfectly honest sex hasn’t been an all-the-time-on-the-brain thing with me. since I was … what … 16?  Guys supposedly think about sex every few seconds; I can’t say that isn’t true, but I can also attest that it doesn’t take much to get past those thoughts and act like a decent human being. 

Yeah, it really isn’t difficult to not act like a booby-coveting 16-year-old mouth-breather around my female peers.  In fact, I’m doing it now.  See?  Easy.

The People Part

As I write this my brain is throwing back memories of my own juvenile behavior – much of it as recent as last summer.  The difference between me and Spam Male?  My behavior is focused squarely at me.  I might make myself look like an ass, but I would be mortified if I made someone else uncomfortable.  In any fashion.

And of course I have done so in the past – more times than I care to admit or remember - and I’ve apologized.

Because I’m a decent person.  And that’s what people do.  They make mistakes and make amends and learn and move on and get forgiven and do the forgiving.

The thing about people – they’re people, first and foremost.