Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Thought about it while answering this question.

How can you avoid the need to fully qualify every single type in a namespace?

It's really, really tedious to write System.Security.Cryptography.X509Certificates.X509Store instead of X509Store, or [System.Security.Cryptography.X509Certificates.StoreName]::My instead of [StoreName]::My.

In C# you have using directives... what about Powershell?


EDIT 1 - This works for types:

$ns = "System.Security.Cryptography.X509Certificates"
$store = New-Object "$ns.X509Store"(StoreName,StoreLocation)

New-Object takes a string literal as the type definition, so it can be built programmatically.


EDIT 2 - This works for enumeration members used as parametes:

$store = New-Object "$ns.X509Store"("My","LocalMachine")

Where "My" is [System.Security.Cryptography.X509Certificates.StoreName]::My and "LocalMachine" is [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine.
Literal names are automatically converted to enumeration members, if placed where an enumeration member is expected.

share|improve this question
    
Right there with you on this one. –  Joseph Kern Oct 15 '09 at 12:37

2 Answers 2

up vote 5 down vote accepted

For enumerations you don't have to specify the whole type name. For example:

You can do this:

New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::Domain)

or the much more simple version:

New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain')

You can use strings to identify the enumerations you want to use without having to use the fully decorated name. PowerShell handles the typecasting for you to convert the strings to the enumeration values. Using the specific example you showed above, that means you can do this:

[System.Security.Cryptography.X509Certificates.OpenFlags]'ReadWrite'

And Powershell will properly convert it (so passing 'ReadWrite' to a parameter that takes an OpenFlags enumeration value will work just fine). If you want to pass multiple values, you can do it like this:

[System.Security.Cryptography.X509Certificates.OpenFlags]@('ReadWrite','IncludeArchived')

Note that I'm prefixing these commands with the type name, but if you were passing them to a typed parameter you would simply leave that out.

That should get you one step closer to being able to write scripts that work with a specific namespace without having to decorate all of the names.

share|improve this answer
    
This works great, thanks. I just hope to never find an overloaded method that can take as a parameter two different enumerations that have a member with the same name :-) –  Massimo Oct 15 '09 at 19:23
    
Accepting this one because the tip is useful, but the issue is still quite far from resolved... :-/ –  Massimo Oct 19 '09 at 6:35

The right way?

$_m = [math]
$_m::sin((45*($_m::pi/180)))


And this seems to work:

[Reflection.Assembly]::Load("System.Security, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a")

$stoopidnamespace = 'System.Security.Cryptography.X509Certificates.X509Store'
New-Object $stoopidnamespace($null)

But it's ugly when you do this:

$stoopidnamespace = 'System.Security.Cryptography.X509Certificates'
New-Object $stoopidnamespace'.X509Store'($null)
share|improve this answer
1  
$something = [type] only works for a single type definition, not for a whole namespace. It works for "Math" because that's a class. –  Massimo Oct 15 '09 at 12:57
    
... I seriously need to study powershell more ... –  Joseph Kern Oct 15 '09 at 13:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.