6
votes

Initialisation du module PowerShell

Est-ce que PowerShell appelle tout code d'initialisation lorsqu'un module est chargé?

Je cherche quelque chose comme un Perl Commencer le bloc ou un constructeur.

Le nouveau module et l'importateur reviendront un pscustomobject. J'essaie d'encapsuler un objet personnalisé dans un module pour éviter de longs code dans les scripts. Une méthode qui teste bien en code ouvert est la suivante: xxx

Idéalement, je voudrais laisser tomber ce code dans un module et utiliser quelque chose comme: xxx < / Pre>

et que MyObJ soit une poignée à un objet identique à celui du premier extrait que la première extraite fournit.

suggestions appréciées.


0 commentaires

3 Réponses :


2
votes

Les modules sont vraiment supposés générer des cmdlets, pas des objets. Un module doit fournir un ensemble de cmdlets connexes. Il existe un moyen d'envoyer des données dans le module à l'aide de Import-modules code> -Argumentlist CODE> Paramètre comme indique ici . Vous pouvez utiliser la technique pour fournir un nom de serveur pour vos cmdlets à vous connecter par exemple. Le module PowerCli traite des poignées différemment à l'aide d'une cmdlet qui crée un objet de connexion d'une script ( $ script: connexion code>) que les autres cmdlets recherchent et réutilisent si elles sont similaires à ceci:

#test.psm1
$script:myvar = "hi"
function Show-MyVar {Write-Host $script:myvar}
function Set-MyVar ($Value) {$script:myvar = $Value}
#end test.psm1


0 commentaires

5
votes

Ce n'est pas clair si vous souhaitez exécuter le code d'initialisation lorsqu'un module est chargé (comme le bloc de début de Perl) ou si vous souhaitez créer une classe personnalisée (ce que "constructeur" suggère).

Le code d'initialisation dans un module est facile. Tout code dans un module non incorporé dans une fonction est exécuté lorsque le module est importé.

Créer une classe personnalisée n'est pas supporté de manière nativement en PS. Mais voir: http://psclass.codeplex.com/ . Vous pouvez également écrire C #, VBScript, etc. et utiliser ADD-Type.

Importer-Module ne fonctionnera pas pour simuler une classe, car vous ne pouvez avoir qu'une instance d'un module avec un nom donné - au mieux que vous auriez une classe Singleton. (BTW, Import-Module a un paramètre -Passhanru, qui ferait plus ou moins votre dernière ligne de travail de code - en tant que singleton. Vous devrez également ajouter exporter-module -variable * -Function * < / Code> à votre code de module) Vous pouvez utiliser un nouveau module pour simuler une classe. Et vous pouvez l'envelopper dans une fonction nommée, nouveau-myclass par exemple.

BTW, si vous utilisez le paramètre -ascustomobject, vous vous retrouvez avec une haquetable, ce qui ne prend pas en charge "Ceci" (dans les mots que les valeurs de tableau de numéros de script n'ont pas de manière intégrée pour se référer à la Hashtable lui-même). Si vous utilisez un nouveau module sans -ascustomobject (et utilisez potentiellement une fonction d'usine, par exemple nouveau-myClass), vous pouvez simuler "this.varinmymodule" avec et $ mmODULE $ VARINMMODULE . Toutefois, si vous créez un PSCustomObject, à l'aide de l'add-membre, la méthode de script a accès à $ ceci et elle en général agit beaucoup plus comme un objet typique avec des propriétés et des méthodes.


1 commentaires

Avez-vous un lien vers la documentation confirmant "tout code dans un module non incorporé dans une fonction est exécuté lorsque le module est importé". Je crois que c'est une demi-vérité: les modules écrits dans PowerShell fonctionnent de cette façon, les modules écrits en C # ne semblent pas avoir un moyen de le faire (à moins que vous n'ayez pas modifié CIL et d'ajouter .ModuleinIlit, par exemple avec Fody Post-Builder, car ModuleInit n'est pas une spécification de langage courant).



0
votes

Utilisation de modules Vous pouvez exporter à la fois des propriétés et des fonctions innées et n'avez pas besoin de les exécuter via ADD-Membre ou de faire beaucoup d'acrobaties. Notez cependant qu'il a des problèmes si vous ne souhaitez pas exporter toutes les propriétés et toutes les méthodes, et tandis que vous pouvez initialiser les propriétés em> à une valeur initiale, vous ne pouvez pas appeler une fonction interne Lors de l'initialisation sans faire des acrobaties Akward.

Mais je pense que ce que vous voulez vraiment faire est d'utiliser des cours qui sont maintenant disponibles dans PowerShell 5 (ils n'étaient pas quand vous avez posté). J'ai fourni des exemples de chacun. Sysops a un tutoriel décent sur les nouvelles classes en 4 parties

Voici le plus ancien chemin avant PowerShell 5.0 P>

#requires -version 5
Class Person
    {
    hidden [String] $name #not actually private

    [string] Who ()
        {return $this.name}

    [void] Rename ([string] $name)
        {$this.name = $name}

    # constructors are weird though, you don't specify return type OR explicitly return value.
    Person ([String]$name)
        {$this.name = $name}
    <#
    # The above constructor code is secretly converted to this
    [Person] New ([string]$name) #note the added return type and renamed to New
        {
        $this.name = $name
        return $this #note that we are returning ourself, you can exploit this to create chained constructors like [person]::New("gandalf").withWizardLevel("White") but I haven't done so here
        }
    #>

    }
$me = [Person]::new("Shelob")
$you = [Person]::new("Frodo")

# $me|gm        # Note that Name doesn't show here
# $me.name      # But we can still access it...
# $me|gm -Force # Note that Name DOES show here

"`n"
"Me: $($me.who())"
"You: $($you.who())"
$you.Rename("Dinner")
"You after we meet: $($you.who())"


0 commentaires