Variable Recognition Within Workflow and Function Calls

Welcome Forums General PowerShell Q&A Variable Recognition Within Workflow and Function Calls

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

 
Participant
3 weeks, 1 day ago.

  • Author
    Posts
  • #158229

    Participant
    Topics: 5
    Replies: 3
    Points: 65
    Rank: Member

    Greetings.  In the script below, I have a workflow that is calling two functions that for now, are just setting variables.  However, those variables are not being recognized when using the write-output cmdlet that runs after those functions are called.  I tried varying scenarios with using a global variable for the different functions, but the write-output continues to ignore the variables.

    Any ideas?  I used the Preformatting option for the code below, but it's being nulllified for some reason so sorry about the formatting.

     

    workflow CREATE_PACKAGE_1 {

    function CREATE_PACKAGE_2 {

    function Test1 {
    $Test1 = "Test1"
    }
    Test1

    function Test2 {
    $Test2 = "Test2"
    }
    Test2

    }

    CREATE_PACKAGE_2

    Write-Output $Test1
    Write-Output $Test2

    }

    CREATE_PACKAGE_1

  • #158234

    Participant
    Topics: 2
    Replies: 442
    Points: 917
    Helping Hand
    Rank: Major Contributor

    Two issues seem to be at play here. One is that variables are scoped to where they're defined by default. You defined them in a function, they're scoped to that function.

    However, I'm very unsure of how workflows handle this. Workflows are always a special case, for just about everything under the sun. I wouldn't be surprised if the workflow variable scoping is different to how it normally works, but I don't work with them closely enough to be sure.

    I'm also.... not really sure this is worth the effort to get it to work as designed. It would be significantly more effective to simply have the functions output values directly and store those as you please. Also, nesting functions inside one another is generally unnecessary and not particularly effective except in especially unusual circumstances. I'd define each function separately, having the CREATE_PACKAGE_2 function simply call the other two.

    For example:

  • #158240

    Participant
    Topics: 5
    Replies: 3
    Points: 65
    Rank: Member

    Thanks for the input.  Ultimately, I am trying to have multiple functions that calls a 1500+ lines of code script.  So run one function that sets variables to a certain value then run the large script and then run the next function that sets variables to a certain value then run the large script and so on.

    Ideally, they would run in parallel instead of one after the other, but I will take what I can get.  I also tried the below using a script block call with and without the variables set to a global condition, but the $APP_NAME in the write-output still gets ignored.

     

    $a = { Write-Output $APP_NAME }

    Function App1 {
    $APP_NAME = "App1"
    Invoke-Command -ScriptBlock $a
    }

    Function App2 {
    $APP_NAME = "App2"
    Invoke-Command -ScriptBlock $a
    }

  • #158247

    Participant
    Topics: 2
    Replies: 442
    Points: 917
    Helping Hand
    Rank: Major Contributor

    Even then, it'll be significantly easier to work with the functions if you work with such things as output rather than attempting to break scope. One possible method is to have each function output a hashtable or custom object containing the values, and assign that to a known configuration variable in the larger script.

    Breaking scope is going to give you further headaches, I guarantee it, doubly so when debugging.

    However, there is a way to do what you're after, though it of course makes any troubleshooting more complicated; dot-source the functions when calling them. Doing so imports all variables they set internally into the current scope.

    function Set-MyVariable {
        $TestVar = 7
    }
    
    . Set-MyVariable
    
    $TestVar

     

You must be logged in to reply to this topic.