BaseName for FileInfo objects

<Edited to add categories>
In our active, responsive, and useful newsgroup Microsoft.Public.Windows.PowerShell (SELL SELL SELL :-) ),  MVP Alex Angelopoulos recented posted the following:



Although file extension changing is a common technique in administrative
tasks, the System.IO.FileInfo class does not provide a direct Basename
property and neither does PowerShell.

This is useful enough that I believe it should be added to PS typedata. It
can  be done with a simple ScriptProperty, as shown below:

  <Type>
   <Name>System.IO.FileInfo</Name>
   <Members>
    <ScriptProperty>
     <Name>Basename</Name>
     <GetScriptBlock>
      $this.Name.Remove($this.Name.Length – $this.Extension.Length);
     </GetScriptBlock>
    </ScriptProperty>
   </Members>
  </Type>


Alex posted this as a feature request and asked people to comment & vote on it at: https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=145875&SiteID=99


Alex’s point is very timely in that we were just discussing this yesterday (Actually Alex tends to do that a lot, I wonder if my office is bugged.  Hmmmm.).  Anyway, we were talking about the possibility of adding this as an operator and then maybe having user-define operators.  Of course my initial reaction was – let’s get this into V1.0 but we at a point in the project where we need to stop making changes to ensure the stability of the codebase.  (I suspect that our GPM Hilal has secretly purchased a roll of duct-tape for use the next time someone suggests adding a feature to V1.0. )


So what is great is that this is EXACTLY the situation we designed Windows PowerShell to address.  I’ve always HATED the conversation where a customer tells me what they need and then I have to say, “Got it, we’ll add that.  Just hang in there a couple more years and we’ll get you what you need.”  We designed the system to address this (As you can see from the mention of user-defined operators, we continue to think about how to do a better job of this).  You can take the XML that Alex provided above and include it into your own My.Types.ps1xml (this process is describe reasonably well in http://blogs.msdn.com/powershell/archive/2006/06/24/644987.aspx ). 


I did this and now I can do the following:


PS> dir m* |ft name,basename -auto


Name                          Basename
—-                          ——–
mines.ps1                     mines
MonadScripting-HandsOnLab.doc MonadScripting-HandsOnLab
mow.types.ps1xml              mow.types
msh.msc                       msh
MSH.xshd                      MSH
MSH.xshd.1                    MSH.xshd
MSH.xshd.orig                 MSH.xshd
MSNSearchService.cs           MSNSearchService
MSNSearchService.dll          MSNSearchService
my.format.ps1xml              my.format
my.TaskTypes.ps1xml           my.TaskTypes
my.types.ps1xml               my.types
my.types2.ps1xml              my.types2
my1.format.ps1xml             my1.format
MyKnowledge.ps1               MyKnowledge
MyTabExpansion.ps1            MyTabExpansion


 So – we’ll almost certainly do something similar to this in V2.0 (maybe V1.1) but you don’t have to wait for us – you can have this function today.  Now just be aware of one thing – name collisions.  If you think about it, when we get around to it, if we decide to add this function to the type (as opposed to creating an operator for it), we’ll almost certainly call it “BASENAME”.  If you’ve already define your own property called BASENAME, there will be a collision (we use Casino rules on name collision [House wins on a tie]).  So you might consider calling it something unique. 


We should probably promulgate a naming convention for user-defined extensions.  I’d love to get input on that topic so please post that as comments to this blog. 


Enjoy!
Jeffrey Snover
Windows PowerShell Architect

PSMDTAG:PHILOSOPHY: Provide mechanisms that the community can solve problems without waiting till the next release cycle.
PSMDTAG:TYPEEXTENSION: BaseName on FileInfo