Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dot source function in params

Tags:

powershell

I'm going to start by saying I'm still pretty much a rookie at PowerShell and hoping there is a way to do this.

We have a utils.ps1 script that contains just functions that we dot source with in other scripts. One of the functions returns back a default value if a value is not passed in. I know I could check $args and such but what I wanted was to use the function for the default value in the parameters.

param(
    [string]$dbServer=$(Get-DefaultParam "dbServer"), 
    [string]$appServer=$(Get-DefaultParam "appServer")
)

This doesn't work since the Util script hasn't been sourced yet. I can't put the dot source first because then params doesn't work as it's not the top line. The utils isn't a module and I can't use the #require.

What I got working was this

param(
    [ValidateScript({ return $false; })]
    [bool]$loadScript=$(. ./Utils.ps1; $true),
    [string]$dbServer=$(Get-DefaultParam "dbServer"), 
    [string]$appServer=$(Get-DefaultParam "appServer")
)

Create a parameter that loads the script and prevent passing a value into that parameter. This will load the script in the correct scope, if I load it in the ValidateScript it's not in the correct scope. Then the rest of the parameters have access to the functions in the Utils.ps1. This probably is not a supported side effect, aka hack, as if I move the loadScript below the other parameters fail since the script hasn't been loaded.

  1. PowerShell guarantee parameters will always load sequential?
  2. Instead should we put all the functions in Utils.ps1 in global scope? this would need to run Utils.ps1 before the other scripts - which seems ok in scripting but less than ideal when running the scripts by hand
  3. Is there a more supported way of doing this besides modules and #require?
  4. Better to not use default value of params and just code all the checks after sourcing and check $args if we need to run the function?
like image 556
CharlesNRice Avatar asked Nov 30 '25 03:11

CharlesNRice


1 Answers

It would be beneficial to instead turn that script into a PowerShell Module, despite your statement that you desire to avoid one. This way, your functions are always available for use as long as the module is installed. Also, despite not wanting to use it, the #Require directive is how you put execution constraints on your script, such as PowerShell version or modules that must be installed for the script to function.


If you really don't want to put this into a module, you can dot-source utils.ps1 from the executing user's $profile. As long as you don't run powershell.exe with the -NoProfile parameter, the profile loads with each session and your functions will be available for use.

like image 89
Bender the Greatest Avatar answered Dec 02 '25 19:12

Bender the Greatest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!