= !PowerShell: Dot Sourcing Scripts Quirks = Jan 05 2016 [[Image(htdocs:images/powershell/PowerShell_5.0_icon.png, alt="PowerShell", align=center)]] I spent the last couple of days of 2015 porting my [Programming/Python/OrganizationOfBuildEnvironmentScripts build environment scripts] (recommend that you read that article first) over to !PowerShell. I ran into some rather quirky and inconsistent behavior when dot-sourcing scripts. I wanted to stick to the same organization and file layout that I had for the MSYS and Linux platforms. Essentially, something like this: {{{#!html
~vijay
    |-$PROFILE ![1]
    |-work
      |-repos
        |-0
        |-1
          |-private
            |-bin
              |-devenv.ps1 ![3]
            |-developer
              |-bin
              | |-devenv.ps1 ![4]
              |-project1
                |-project1.ps1 ![5]
            |-artist
              |-bin
              | |-devenv.ps1
              |-project1
                |-project1.ps1
            |-vijay
              |-bin
                |-devenv.ps1 ![2]
}}} 1. [[span(style=color: #800000, $PROFILE ![1])]] contains the Start-Dev() function 1. [[span(style=color: #008000, devenv.ps1 ![2])]] user specific overrides go here 1. [[span(style=color: #0000ff, devenv.ps1 ![3])]] common to all projects, users and roles, like build / install directories 1. [[span(style=color: #800080, devenv.ps1 ![4])]] role specific settings go here 1. [[span(style=color: #ff6600, project1.ps1 ![5])]] project and sub-project (if any) specific settings go here So, I started off with the 1:1 port attempt with necessary adjustments to naming conventions (camel case for variables, title case for functions, etc). So, the [[span(style=color: #800000, user profile script ![1])]] has a `Start-Dev()` function which is the equivalent of `startdev()` in .bashrc. Just like it works for the MSYS platform, this function in turn dot-sources the user specific [[span(style=color: #008000, devenv.ps1 ![2])]]. [[span(style=color: #008000, devenv.ps1 ![2])]] dot-sources the common [[span(style=color: #0000ff, devenv.ps1 ![3])]] and the role specific (in this case, developer) [[span(style=color: #800080, devenv.ps1 ![4])]], which dot-sources the project specific [[span(style=color: #ff6600, project1.sh ![5])]] for that role. I expected things would work fine, but they didn't. It was a tad difficult to debug initially, since the environment variables were getting set and I could see them when I invoked the `Start-Dev()` function, but functions and aliases that were setup in the dot-sourced PS1 files were missing from the !PowerShell environment. The inconsistency flummoxed me for a bit. So, I threw in some Write-Host statements immediately following the lines where the functions and aliases were defined and they were fine. Similarly, they existed in the caller, cascading upwards all the way to the initial dot-sourcing that happens in the `Start-Dev()` function. First I tried replacing the dot-sourcing with `Invoke-Expression`, but as I expected based on the documentation, that didn't work either. The behavior was inconsistent - environment variables were set / updated correctly, but function and alias definitions just disappeared, poof! I tried !PowerShell modules instead of scripts to see if that fixed the problem, but no dice. The solution I ended up with was to create a `Start-Dev.ps1` script with the contents of the function dumped into the script's global space. I dot-sourced the script like this: {{{ PS C:\Users\vijay> . Start-Dev 1 project1 }}} That did the trick. All functions and aliases defined in the dot-sourced files became defined and available in the !PowerShell environment. I wrapped up the porting work by adding an alias to simplify invocation of the Start-Dev.ps1 script.