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