Eggins.com
Powershell, .Net, Visual Studio, Team Foundation Server, Windows Communication Foundation

Powershell function to locate a type

My earlier posts on loading assemblies into Powershell gave me an idea for a useful Powershell function. I cannot remember the namespace for every type in the .Net framework, and all of our own custom business types. I have always wanted to have the functionality to locate a type, and get the namespace where it resides. We can write a Powershell cmdlet to do just that. I have listed out the full discovery path to create this function. If you just want to skip to the function, it is at the bottom of this blog post.

So we already know that we can get a list of loaded assemlies using the command
    $LoadedAssemblies = [System.Threading.Thread]::GetDomain().GetAssemblies()

Then we can look at the available members on these "Assembly" objects using the following command line
    $LoadedAssemblies | gm

You will notice that there is a "GetTypes" function. This is just what wee need. So the following command will list every type within every assembly currently loaded into Powershell
    $LoadedAssemblies | foreach-object {$_.GetTypes()}
   
And the following command tells me that there are currently 8285 types within the default assemblies loaded into Powershell 1.0 after installing Powershell Community Extensions. No wonder I cannot remember which namespace that type resides in! :-)
     $LoadedAssemblies |
    Foreach-Object {$_.GetTypes()} |
      Foreach-Object {$Count++}; $Count

So lets add a filter to just show the types containing a particular set of characters. In this case, I will look for any types that contain the letters "ftp".
    $LoadedAssemblies |
    Foreach-Object {$_.GetTypes()} |
      Where-Object {$_.Name -like "*ftp*"}

Not bad. Now lets format the results so that they can be used as a using statement within a c# app. We will also keep the fullname so you can chose which using statement to grab, based on the type you are after.
    $LoadedAssemblies |
    Foreach-Object {$_.GetTypes()} |
      Where-Object {$_.Name -like "*ftp*"} |
        Format-Table FullName, @{Label = "Using Statement"; Expression={"using " + $_.Namespace}}

This is the result of running the command above.
    FullName                                         Using Statement
    --------                                         ---------------
    System.FtpStyleUriParser                         using System
    System.Net.FtpStatusCode                         using System.Net
    System.Net.WebRequestMethods+Ftp                 using System.Net
    System.Net.FtpOperation                          using System.Net
    System.Net.FtpMethodFlags                        using System.Net
    System.Net.FtpMethodInfo                         using System.Net
    System.Net.FtpWebRequest                         using System.Net
    System.Net.FtpWebRequestCreator                  using System.Net
    System.Net.FtpWebResponse                        using System.Net
    System.Net.FtpPrimitive                          using System.Net
    System.Net.FtpLoginState                         using System.Net
    System.Net.FtpControlStream                      using System.Net
    System.Net.FtpDataStream                         using System.Net
    System.Net.Cache.FtpRequestCacheValidator        using System.Net.Cache
    System.Net.Configuration.FtpCachePolicyElement   using System.Net.Configuration
 

Now lets make this into a nice neat function.
    function Find-Type ([string]$FindString) {
      [System.Threading.Thread]::GetDomain().GetAssemblies() |
        Foreach-Object {$_.GetTypes()} |
          Where-Object {$_.Name -like "*${FindString}*"} |
            Format-table FullName, @{Label = "UsingStatement"; Expression={"using " + $_.Namespace}}
    }

You will need to put this function inside your profile file, or a ps1 file dot-sourced from your profile file so that you can run the function from the Powershell command line. You may even look at creating an alias to shorten the function name.

The last piece of the puzzle is to load all of your own custom assemblies into powershell before calling this function so that you can find types within your own custom assemblies. I shall leave that task to you.


Posted May 29 2007, 11:17 PM by David
Filed under:

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Copyright eggins.com, 1998 - 2008
Powered by Community Server (Non-Commercial Edition), by Telligent Systems