Utilisation d'espaces de noms dans Powershell

9

J'y ai réfléchi en répondant à cette question .

Comment pouvez-vous éviter d'avoir à qualifier entièrement chaque type dans un espace de noms?

C'est vraiment, vraiment fastidieux d'écrire System.Security.Cryptography.X509Certificates.X509Storeau lieu de X509Store, ou [System.Security.Cryptography.X509Certificates.StoreName]::Myau lieu de [StoreName]::My.

En C #, vous avez des usingdirectives ... et Powershell?


EDIT 1 - Cela fonctionne pour les types:

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

New-Object prend un littéral de chaîne comme définition de type, il peut donc être construit par programme.


EDIT 2 - Cela fonctionne pour les membres d'énumération utilisés comme paramètres:

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

Où "My" est [System.Security.Cryptography.X509Certificates.StoreName]::Myet "LocalMachine" [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine.
Les noms littéraux sont automatiquement convertis en membres d'énumération, s'ils sont placés là où un membre d'énumération est attendu.

Massimo
la source
Juste là avec toi sur celui-ci.
Joseph Kern

Réponses:

11

Je sais, c'est un peu tard, mais PowerShell v5 ajoute des tonnes de trucs de langage sympas. L'un d'eux est «l'utilisation de l'espace de noms».

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


IsPublic IsSerial Name                                     BaseType                                     
-------- -------- ----                                     --------                                     
True     False    X509Store                                System.Object                                
xvorsx
la source
6

Pour les énumérations, vous n'avez pas besoin de spécifier le nom complet du type. Par exemple:

Tu peux le faire:

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

ou la version beaucoup plus simple:

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

Vous pouvez utiliser des chaînes pour identifier les énumérations que vous souhaitez utiliser sans avoir à utiliser le nom entièrement décoré. PowerShell gère le transtypage pour que vous convertissiez les chaînes en valeurs d'énumération. En utilisant l'exemple spécifique que vous avez montré ci-dessus, cela signifie que vous pouvez le faire:

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

Et Powershell le convertira correctement (donc passer 'ReadWrite' à un paramètre qui prend une valeur d'énumération OpenFlags fonctionnera très bien). Si vous voulez passer plusieurs valeurs, vous pouvez le faire comme ceci:

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

Notez que je préfixe ces commandes avec le nom du type, mais si vous les passiez à un paramètre tapé, vous laisseriez simplement cela de côté.

Cela devrait vous rapprocher de la possibilité d'écrire des scripts qui fonctionnent avec un espace de noms spécifique sans avoir à décorer tous les noms.

Poshoholic
la source
Cela fonctionne très bien, merci. J'espère juste de ne jamais trouver une méthode surchargée qui peut prendre en paramètre deux énumérations différentes qui ont un membre du même nom :-)
Massimo
Accepter celui-ci car l'astuce est utile, mais le problème est encore assez loin d'être résolu ...: - /
Massimo
0

Le droit chemin?

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

Et cela semble fonctionner:

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

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

Mais c'est moche quand tu fais ça:

$stoopidnamespace = 'System.Security.Cryptography.X509Certificates'
New-Object $stoopidnamespace'.X509Store'($null)
Joseph Kern
la source
3
$ something = [type] ne fonctionne que pour une seule définition de type, pas pour un espace de noms entier. Cela fonctionne pour "Math" parce que c'est une classe.
Massimo
... J'ai sérieusement besoin d'étudier PowerShell plus ...
Joseph Kern