none
Auto-chargement des modules Powershell ne fonctionne pas RRS feed

  • Question

  • Bonjour tous,

    Voici tout d’abord ma version Powershell :

    PS C:\Program Files\WindowsPowerShell\Modules> $PsVersionTable
    Name                           Value                                                                                                                                                 
    ----                           -----                                                                                                                                                 
    PSVersion                      5.1.17134.407                                                                                                                                         
    PSEdition                      Desktop                                                                                                                                               
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                               
    BuildVersion                   10.0.17134.407                                                                                                                                        
    CLRVersion                     4.0.30319.42000                                                                                                                                       
    WSManStackVersion              3.0                                                                                                                                                   
    PSRemotingProtocolVersion      2.3                                                                                                                                                   
    SerializationVersion           1.1.0.1                                                                                                                                               
    PS C:\Program Files\WindowsPowerShell\Modules>
    
    


    J’avais cru comprendre que les modules en *.psm1 étaient automatiquement chargés dès lors qu’ils étaient placés dans leur répertoire par défaut.
    (après ouverture d’une nouvelle session PowerShell)
     Les répertoires par défaut des modules et manifestes sont chez moi :

    PS C:\Users\administrateur.HJG> $env:PSModulePath -split (';')
    C:\Users\administrateur.HJG\Documents\WindowsPowerShell\Modules
    C:\Program Files\WindowsPowerShell\Modules
    C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
    C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
    PS C:\Users\administrateur.HJG>


    J’ai donc créé un module élémentaire "test-module .psm1" (module "script" dans un des répertoires par défaut .
    Quelque chose de très simple.Juste pour tester :

    PS C:\Program Files\WindowsPowerShell\Modules> Get-Content .\test-module.psm1
    Function Test-module {
    Write-Host 'Test Module'
    }
    PS C:\Program Files\WindowsPowerShell\Modules>


    Or après relance de Powershell pour nouvelle session, rien ne se passe.
    Le module n’a pas été chargé :

    PS C:\Program Files\WindowsPowerShell\Modules> test-module
    test-module : Le terme «test-module» n'est pas reconnu comme nom d'applet de commande, fonction, fichier de script ou programme exécutable. Vérifiez l'orthographe du nom, ou si un 
    chemin d'accès existe, vérifiez que le chemin d'accès est correct et réessayez.
    Au caractère Ligne:1 : 1
    + test-module
    + ~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (test-module:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException
     PS C:\Program Files\WindowsPowerShell


    Pour charger le module, je suis obligé de le faire manuellement par la cmdlet « import-module »
    Et j’ai bien alors :
    PS C:\Program Files\WindowsPowerShell\Modules> get-command    -Module test-module
    CommandType     Name                                               Version    Source                                                                                                 
    -----------     ----                                               -------    ------                                                                                                 
    Function        Test-module                                        0.0        test-module 
    PS C:\Program Files\WindowsPowerShell\Modules>



    A noter que j'ai importé des modules depuis des dépôts externes (PSGallery) à l'aide de la cmdlet "Install-Module"
    Et tout fonctionne très bien.
    Les modules se chargent bien automatiquement.
    Il y a certainement quelque chose qui m'a échappé.
    Merci pour votre aide.



    hjg






    • Modifié nonsolum lundi 24 décembre 2018 09:19
    dimanche 23 décembre 2018 17:28

Réponses

  • Bonjour,

    La demande date de plus d'un an mais n'ayant pas eu de réponse et ayant cherché moi-même. J'apporte la solution que j'ai trouvé :)

    Pour que l'auto-chargement soit effectif, il faut qu'il y est un dossier {nom du module} dans un des dossiers de 

    $env:PSModulePath

    et que ce dossier porte le même nom que les fichiers .psd1 et .psm1

    Agréable journée à tous les codeurs

    Osilio

    mardi 30 mars 2021 16:03

Toutes les réponses

  • salut nonsolum

    je crois qu'il te faut le fichier version (manifeste) du module pour l'autoload, le fichier .psd1

    une doc pdf ici sur le sujet

    PS : petit complément sur le sujet sur ce blog en anglais  rubrique "Module autoloading"

    dernière info la bonne !! :

    Importation implicite d'un module (PowerShell 3.0)

    À compter de Windows PowerShell 3.0, les modules sont importés automatiquement lorsqu'une cmdlet ou une fonction du module est utilisée dans une commande. Cette fonctionnalité fonctionne sur n'importe quel module d'un répertoire inclus dans la valeur de la variable d'environnement PSModulePath .


    • Modifié 6ratgus jeudi 27 décembre 2018 15:01
    jeudi 27 décembre 2018 11:50
  • Merci pour les infos

    J’ai bien mon module « test-module.psm1 » dans un des répertoires de la variable d’environnement PSModulePath.

    J’ai en effet :

     

    PS C:\Program Files\WindowsPowerShell\Modules> gci
    
        Répertoire : C:\Program Files\WindowsPowerShell\Modules
    
    Mode                LastWriteTime         Length Name                                                                                                                              
    ----                -------------         ------ ----                                                                                                                               
    d-----       12/04/2018     01:38                Microsoft.PowerShell.Operation.Validation                                                                                           
    d-----       12/04/2018     01:38                PackageManagement                                                                                                                   
    d-----       12/04/2018     01:38                Pester                                                                                                                              
    d-----       12/04/2018     01:38                PowerShellGet                                                                                                                       
    d-----       20/12/2018     22:00                PSLogging                                                                                                                           
    d-----       12/04/2018     01:38                PSReadline                                                                                                                          
    -a----       28/12/2018     12:24            107 Test-module.psm1                                                                                                                    
    
    PS C:\Program Files\WindowsPowerShell\Modules> 


    Je décide de compléter mon module en ajoutant la Cmdlet  « Export-ModuleMember »

     

    PS C:\Program Files\WindowsPowerShell\Modules> Add-Content`
     -Path .\Test-module.psm1 -Value "Export-ModuleMember -Function 'Test-Module' "
    
    PS C:\Program Files\WindowsPowerShell\Modules> 


    J’ai donc maintenant le module « test-module » comme suit :

     

    PS C:\Program Files\WindowsPowerShell\Modules> Get-Content .\Test-module.psm1
    Function Test-Module {
    
        Write-Host 'Test Module'
    }
    
    Export-ModuleMember -Function 'Test-Module'
    
    PS C:\Program Files\WindowsPowerShell\Modules> 


    À noter :  la documentation précise que les fonctions sont, par défaut, automatiquement exportées à l’exception des alias et des variables.

     

    Seulement, comme je l’ai précisé lors de mon précédent post, cela ne marche pas chez moi.

    Alors je crée un  « manifest » comme suit :

     

    PS C:\Program Files\WindowsPowerShell\Modules> New-ModuleManifest -Path `
    '.\test-module.psd1' -Author 'hjg' -RootModule 'test-module.psm1'
    
    PS C:\Program Files\WindowsPowerShell\Modules> 


    Et je vérifie si tout est correct :

     

    PS C:\Program Files\WindowsPowerShell\Modules> Test-ModuleManifest .\test-module.psd1
    
    ModuleType Version    Name                                ExportedCommands                                                                                                           
    ---------- -------    ----                                ----------------                                                                                                           
    Script     1.0        test-module                         Test-Module                                                                                                                
    
    PS C:\Program Files\WindowsPowerShell\Modules> 


    Pas de problème, semble-t-il.

    J’ouvre une nouvelle session PowerShell.

    Puis je teste alors le couple module/manifest :

     

    PS C:\Program Files\WindowsPowerShell\Modules> test-module
    test-module : Le terme «test-module» n'est pas reconnu comme nom d'applet de commande, fonction, fichier de script ou programme exécutable. Vérifiez l'orthographe du nom, ou si un 
    chemin d'accès existe, vérifiez que le chemin d'accès est correct et réessayez.
    Au caractère Ligne:1 : 1
    + test-module
    + ~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (test-module:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException
     
    PS C:\Program Files\WindowsPowerShell\Modules>


    Rien à faire, cela ne marche pas, même si on se situe dans le cas où serait chargé dans la foulée le module suite à l’appel de fonction « test-module ».

     Il me faut passer par la Cmdlet « Import-Module » et charger ainsi manuellement le module :

     

    PS C:\Program Files\WindowsPowerShell\Modules> Import-Module .\Test-module.psm1
    
    PS C:\Program Files\WindowsPowerShell\Modules> 

    Et puis:

    PS C:\Program Files\WindowsPowerShell\Modules> Test-Module
    Test Module
    
    PS C:\Program Files\WindowsPowerShell\Modules> 

    Si je veux rendre pérenne l’import je dois ajouter au fichier profile de PowerShell la Cmdlet « Import-module » :

    PS C:\Program Files\WindowsPowerShell\Modules> Add-Content -Path $profile`
     -Value "Import-Module 'C:\Program Files\WindowsPowerShell\Modules\Test-module.psm1'"
    
    PS C:\Program Files\WindowsPowerShell\Modules

     Où se trouve le nœud ?



    hjg



    • Modifié nonsolum dimanche 30 décembre 2018 09:49
    vendredi 28 décembre 2018 20:13
  • "Patience et longueur de temps font plus que force ni que rage"  

    De Jean de la Fontaine j'en fais ma devise.

    Mais, bon…

    Si quelqu'un pouvait m'aider, je ne dirais pas non.  :-)


    hjg

    vendredi 4 janvier 2019 14:58
  • Bonjour,

    La demande date de plus d'un an mais n'ayant pas eu de réponse et ayant cherché moi-même. J'apporte la solution que j'ai trouvé :)

    Pour que l'auto-chargement soit effectif, il faut qu'il y est un dossier {nom du module} dans un des dossiers de 

    $env:PSModulePath

    et que ce dossier porte le même nom que les fichiers .psd1 et .psm1

    Agréable journée à tous les codeurs

    Osilio

    mardi 30 mars 2021 16:03
  • Bonjour,

    La demande date de plus d'un an mais n'ayant pas eu de réponse et ayant cherché moi-même. J'apporte la solution que j'ai trouvé :)

    Pour que l'auto-chargement soit effectif, il faut qu'il y est un dossier {nom du module} dans un des dossiers de 

    $env:PSModulePath

    et que ce dossier porte le même nom que les fichiers .psd1 et .psm1

    Agréable journée à tous les codeurs

    Osilio

     

    ça fait un moment que j'étais passé à autre chose. :-)

    Je crois me souvenir que, oui, c'est la solution.

    En tout cas Merci pour cette suggestion.


    hjg

    mercredi 31 mars 2021 08:28
  • Bonjour nonsolum,

    Il faut effectivement que le module (fichier .pms1) soit dans un répertoire qui porte le BaseName du fichier .psm1 (MonModule.psm1 dans un répertoire nommé MonModule)

    Pour importer automatiquement tous les modules, tu peux le faire via le fichier profile. Ce dernier est chargé automatiquement au lancement d'un shell. Attention, il y a différents fichiers profile possible (powershell, powershell ISE, Powershell dans VScode, et pour un utilisateur ou tous, ils ne sont pas stockés au même endroit).

    # Pour tous les modules localisés dans un des path de $Env:PSpath

    Get-Module -ListAvailable | Import-Module

    # Pour les modules situés dans un autre path

    $Path = ...\MonPath\MonModule

    Import-Module -FullyQualifiedName $Path

    Point d'attention : attention le chargement de tous les modules disponibles peut être consommateur de RAM sur la machine, en vain si on n'en a pas réellement besoin. Si le chargement desdits modules prend du temps (à l'instar des Update-Module), on peut s'affranchir de ceci, toujours dans un fichier profile, en exécutant les cmdlets précédentes comme un job.

    ex. :

    Start-Job -Name "Chargement des modules" -ScriptBlock { Get-Module -ListAvailable | Import-Module}

    Ainsi, au chargement (exécution) du profile, on récupère la main tout de suite, et PS fait sa tâche d'importation des modules en tâche de fond. Cela peut sembler inutile, mais reste à tester en fonction du nombre de modules à charger.

    Personnellement, j'utilise ce principe pour mettre à jour mes modules (et j'en ai un paquet), tous les vendredi en tâche de fond.Je te mets ceci ci-dessous pour l'exemple

    # Mise à jour des modules chaque vendredi
        $Date = Get-Date
        if ($Date.DayOfWeek -eq "friday") 
            {
            Write-Host "Mise à jour des modules en tâche de fond (Get-Job pour vérifier)" -ForegroundColor 'DarkGray'
            Start-Job -Name "UpdateModule" -ScriptBlock { 
                Get-InstalledModule | 
                    foreach { 
                            $NewVersion = (find-module $_.name).version 
                            if ($NewVersion -gt $_.version) 
                                { 
                                Write-Host "$($_.name) a une mise à jour de $($_.version) vers $NewVersion" -ForegroundColor green
                                Write-Host "Mise à jour de $($_.name) vers version $NewVersion" -ForegroundColor Yellow
                                Update-Module -Name ($_.name) -Force -AcceptLicense -Scope CurrentUser
                                Write-Host "désinstallation de la version $($_.version)" -ForegroundColor Yellow
                                Uninstall-Module -Name $_.name -RequiredVersion $_.version -force
                                Write-Host "$($_.name) a été mis à jour en version $NewVersion" -ForegroundColor Yellow
                                } # end if
                            } # end foreach
                } # end scriptblock
            } # end if

    Mon profil se charge en moins de 100 ms ... et j'ai la main au bout de ce temps, malgré le fait que la mise à jour des modules puisse durer ... un certain temps pour ne pas dire un temps certain.:-) Ca bosse en tâche de fond.

    [... "Patience et longueur de temps font plus que force ni que rage"  

    De Jean de la Fontaine j'en fais ma devise....]

    Les Fables de La Fontaine devraient être enseignées de manière obligatoire dès le collège (et pas que celle-là), car elles sont toutes empreintes de vérité. Le 'sieur La Fontaine était un critique de son époque et d'aucuns diraient un contestataire. Perso, j'ai "Aide-toi, le ciel t'aidera" (Le laboureur et ses enfants) comme crédo, mais je pourrais en avoir d'autres.

    Cordialement

    Olivier

    mercredi 31 mars 2021 15:31