Использование пространств имен в Powershell

9

Думал об этом, отвечая на этот вопрос .

Как вы можете избежать необходимости полностью квалифицировать каждый тип в пространстве имен?

Это действительно очень утомительно писать System.Security.Cryptography.X509Certificates.X509Storeвместо X509Storeили [System.Security.Cryptography.X509Certificates.StoreName]::Myвместо [StoreName]::My.

В C # у вас есть usingдирективы ... как насчет Powershell?


РЕДАКТИРОВАТЬ 1 - Это работает для типов:

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

New-Object принимает строковый литерал в качестве определения типа, поэтому он может быть построен программно.


РЕДАКТИРОВАТЬ 2 - Это работает для членов перечисления, используемых в качестве параметров:

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

Где «Мой» [System.Security.Cryptography.X509Certificates.StoreName]::Myи «LocalMachine» [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine.
Литеральные имена автоматически преобразуются в члены перечисления, если они размещены там, где ожидается член перечисления.

Massimo
источник
Прямо с тобой на этом.
Джозеф Керн

Ответы:

11

Я знаю, уже немного поздно, но PowerShell v5 добавляет массу интересных языковых вещей. Одним из них является «использование пространства имен».

PS> using namespace System.Security.Cryptography.X509Certificates; [X509Store]


IsPublic IsSerial Name                                     BaseType                                     
-------- -------- ----                                     --------                                     
True     False    X509Store                                System.Object                                
xvorsx
источник
6

Для перечислений вам не нужно указывать полное имя типа. Например:

Ты можешь сделать это:

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

или гораздо более простая версия:

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

Вы можете использовать строки, чтобы идентифицировать перечисления, которые вы хотите использовать, не используя полностью оформленное имя. PowerShell обрабатывает преобразование типов, чтобы преобразовать строки в значения перечисления. Используя конкретный пример, который вы показали выше, это означает, что вы можете сделать это:

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

И Powershell будет правильно конвертировать его (поэтому передача ReadWrite в параметр, который принимает значение перечисления OpenFlags, будет работать нормально). Если вы хотите передать несколько значений, вы можете сделать это следующим образом:

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

Обратите внимание, что я добавляю эти команды к имени типа, но если бы вы передавали их типизированному параметру, вы бы просто пропустили это.

Это должно сделать вас на один шаг ближе к возможности писать сценарии, которые работают с определенным пространством имен, без необходимости декорировать все имена.

Poshoholic
источник
Это прекрасно работает, спасибо. Я просто надеюсь, что никогда не найду перегруженный метод, который может принимать в качестве параметра два разных перечисления с одним и тем же членом :-)
Massimo
Принятие этого, потому что совет полезен, но проблема все еще довольно далека от решения ...: - /
Massimo
0

Правильный путь?

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

И это похоже на работу:

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

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

Но это уродливо, когда вы делаете это:

$stoopidnamespace = 'System.Security.Cryptography.X509Certificates'
New-Object $stoopidnamespace'.X509Store'($null)
Джозеф Керн
источник
3
$ нечто = [тип] работает только для одного определения типа, но не для всего пространства имен. Это работает для "Math", потому что это класс.
Массимо
... Мне серьезно нужно больше изучать PowerShell ...
Джозеф Керн