Script working by itslef but not when in a module

Welcome Forums General PowerShell Q&A Script working by itslef but not when in a module

This topic contains 6 replies, has 3 voices, and was last updated by

 
Senior Moderator
1 month, 3 weeks ago.

  • Author
    Posts
  • #167470

    Participant
    Topics: 6
    Replies: 11
    Points: 97
    Rank: Member

    Hello everybody, i'm coming to you with a strange problem.

     

    Here is a summary:

    I'm working on a script for work to do a lot of different actions on Active directory.

    Two of those action are "Get who is a member of this group" and "What groups is this user a member of"
    It works really fine when i just launch the PS1 and everything is good.

    BUT

    I want to integrate all my scripts in a main script that can launch module, so i took my script and made a PSM1 that i can load from my "main menu" But when i do that, i don't get anything from my requests.

     

    Here are the active parts that works fine by themselves but not in a module:

     Function inventaire {
    $Grpinventaire = read-host "entré le nom du groupe"
    $infoMember = Get-AdgroupMember $grpinventaire -server "****"
    foreach ($member in $infoMember) { get-aduser -server "****" $member.samaccountname -properties displayname | select displayname,name }
    pause
    } 
    Function inventaireUT {
    $UT = read-host "entrer le matricule de l'utilisateur"
    get-ADPrincipalGroupMembership -identity $UT -server "*****" | select name
    pause

     

    And there is how i load the module containing those functions

     

    
    #Menu principal#
    function Show-Menu-main
    {
    param (
    [string]$Title1 = 'Regroupement Script N2 par Kevin LION'
    )
    Clear-Host
    Write-Host "================ $Title1 ================" -ForegroundColor yellow -BackgroundColor Black
    Write-Host "1: Ajout/suppression de groupe AD" -BackgroundColor Black -foregroundcolor green
    Write-Host "2: Obtention d'information sur compte AD/groupe "-BackgroundColor Black -foregroundcolor green
    Write-Host "3: Administration du proxyadresse sur compte AD"-BackgroundColor Black -foregroundcolor green
    }
    
    #Fonction de menu#
    function menu-main
    {
    switch ($selectionmain)
    {
    '1' {
    import-module admanpo #This is the module with my non-working script#
    } '2' {
    Import-module *still need to create this one*
    } '3' {
    Import-module AliasManpo
    } 'q' {
    exit
    }
    }
    }
    
    #Debut du programme partie active#
    While ($selectionmain -ne "q") {
    show-menu-main
    $selectionmain = read-host "entre un chiffre"
    menu-main
    }
    
    

     

    I tried to launch the menu in administrator and in normal mode and still the same, i don't have any error message, it just doesn't give me anything as a result.

     

    I'm sorry if its not clear enough, i'll edit the message if anymore information is needed.

  • #167473

    Senior Moderator
    Topics: 8
    Replies: 1040
    Points: 3,433
    Helping Hand
    Rank: Community Hero

    can you try calling

    menu-main (read-host "entre un chiffre")
    
  • #167476

    Participant
    Topics: 6
    Replies: 11
    Points: 97
    Rank: Member

    I'm sorry i'm not sure i understand what you mean =(

    I tried:

     #Debut du programme partie active#
    While ($selectionmain -ne "q") {
    show-menu-main
    $selectionmain = read-host "entre un chiffre"
    menu-main (read-host "entre un chiffre") 

    And it did not change anything, i just had to enter 1 twice instead of once

    To add some information, when i enter 1, i do load the module without any problem, but the command inside the module doesn't give anything

     

    i'd love to upload images of the results but i can't seem to find how to add images to the forum.

    • #167776

      Senior Moderator
      Topics: 8
      Replies: 1040
      Points: 3,433
      Helping Hand
      Rank: Community Hero

      missed to add,

      change menu-main to accept parameter

      function menu-main {
          param($selectionmain)
          # your switch statement
      }
      
      menu-main -selectionmain (read-host "entre un chiffre")
      
      #or 
      
      function menu-main {
      param(
        $selectionmain = $(read-host "entre un chiffre")
      )
          # your switch statement
      }
      menu-main
      
  • #167524

    Participant
    Topics: 2
    Replies: 54
    Points: 277
    Helping Hand
    Rank: Contributor

    I think your problem is due to scopes. When you run a script from a module inside your main script, the module script is a child of the main script. As a result, all variables created by the child script are held only in the local scope of the child script and are not available to the main script (which is the parent).

    You can change the scope of variables as they are created in order to make them available to a parent scope. An easy way to do this is to make all of the variables in your module scripts global. You have to be careful with this though, because if two child scripts share a global variable name they will overwrite each other.

  • #167668

    Participant
    Topics: 6
    Replies: 11
    Points: 97
    Rank: Member

    Thanks a lot four your answer, i did some reading on scopes and the way to set a variable in global and i edited my child script this way:

    functions and variables are now global.

    
    #Fonction d'inventaire des membres d'un groupe
    Function global:inventaire {
    $global:Grpinventaire = read-host "Entrez le nom du groupe"
    $global:infoMember = Get-AdgroupMember $global:Grpinventaire -server "irc.mpw.fra"
    foreach ($global:inventmember in $global:infoMember) { get-aduser -server "irc.mpw.fra" $global:inventmember.samaccountname -properties displayname | select displayname,name }
    pause
    }
    
    #Fonction inventaire groupe d'un utilisateur
    Function global:inventaireUT {
    $UT = read-host "Entrez le matricule de l'utilisateur"
    get-ADPrincipalGroupMembership -identity $UT -server "irc.mpw.fra" -cred $global:cred | select name
    pause
    }
    
    

    But still, i get results when i launch it by itself and nothing when launched by module =\ did i miss something?

    • #167764

      Participant
      Topics: 2
      Replies: 54
      Points: 277
      Helping Hand
      Rank: Contributor

      Where are these functions? are they part of your module scripts, or your main script? How do they relate to the whole project?

      Basically, what you need to do is establish a path through which information can be passed from child scopes up to the parent scope. Also, be aware that if you store information in a variable in one child script, it won't be available to another child script unless you arrange to make it available.

      In looking back at some of my own work, I fixed this by declaring variables in the script scope, like this:

      $script:variablename

      As long as the variable declaration executes before the child script that uses it, values will be stored in the variable properly. It is not necessary to write the variable name with the scope declaration "$script:" every time you call the variable, only the first time you declare it. The scope for that variable will remain set until you either destroy the variable or end the script.

      You need to decide which variables will be accessible across the whole script, and which ones will only be needed in the module scripts. Only the ones that are needed for the whole script need to be declared as script or global variables, and you should declare those in your main script before any of the module scripts that require them are started. It may be useful to draw how the information passes between your modules out on paper just to keep track of what information goes where.

      I suspect that this is where your modules are going wrong. Either they require information from a variable that is not available to them, or more likely, they store information in a local variable that is lost as soon as the module script exits.

      Alternatively, you could try a completely different approach. Instead of worrying about scopes, you could have the important parts of each module's output write out to a text file, and then have the main script read the data from the file as needed. This would also let you retain the data between runs, if that's useful.

      You should set this:

      Set-PSDebug -Trace 2

      and run your main script. Read through the output to see whether your modules are being executed the way you think, and whether the variables are actually getting data stored in them.

You must be logged in to reply to this topic.