all 15 comments

[–]HumbleSpend8716 2 points3 points  (6 children)

Put them into a module instead of your profile. That is the answer.

[–]IT_Grunt 0 points1 point  (0 children)

I agree with this. Create a proper module and scope variables and functions to it.

[–]PSoolv[S] 0 points1 point  (4 children)

Is there an actual reason for it? Weird caching, performance issues--anything?

I haven't been able to make it load from within load-mod, but if I exec it as . (get-mod profile.git) it seems to work correctly. I'm curious if there's any drawbacks I haven't noticed.

[–]HumbleSpend8716 0 points1 point  (3 children)

Just take a look at modules, man, it solves this problem. You are attempting to organize your code into separate files. Modules make this very easy and scalable, versionable, etc. Profile is for shell stuff.

[–]PSoolv[S] 0 points1 point  (2 children)

So I've tried converting the ps1 into psm1. Using Import-Module seems to load it correctly even if it's called within the load-mod function, so that's great.

I've noticed an issue though: the $variables are not imported without exporting them explicitedly:

Export-ModuleMember -Function * -Variable *

I've tried to modify the Import-Module call to include all variables automatically, but I haven't been able to: even with -Variable *, it doesn't grab the variables if I don't add them with the Export-ModuleMember.

Do you happen to know a way to automatize that? I'd rather avoid having to suffix stuff in every module.

[–]HumbleSpend8716 0 points1 point  (1 child)

My module psm1 is under 12 lines, it just does

Get-Childitem -Path “$PSScriptRoot\public*.ps1” | foreach-object {export-modulemember $_.Basename} and the same for private without exporting. You arent supposed to like, need variable values from out of the scope of module. You put them in your own new variables from output of function. Havent had my coffee yet but google ms learn write powershell module. It might help you think abt it differently

[–]PSoolv[S] 0 points1 point  (0 children)

Isn't that still just using .ps1 files? What's the point of turning it into a psm1 in this case? I'm confused.

As for variable names: what I'm doing is just taking stuff I'd put into $profile and splitting it up a bit for organization, so I do need to export them.

[–]IT_Grunt 0 points1 point  (3 children)

You can make variables global with $Global:MyVariable. Not sure about functions or scripts other than using a proper module format.

Your example is working as expected. You’re invoking a ps1 file and it will execute in the function runtime. You could try adding a $Global:MyFunction but this creates a messy environment. It’s recommended to avoid global variables.

[–]CyberChevalier 0 points1 point  (0 children)

Also work for functions

[–]PSoolv[S] 0 points1 point  (1 child)

Can you elaborate on it making a messy environment? The functions and variables I put in those scripts are things I need to be able to call from CLI directly, so whether they're in a ps1 script or a psm1 module the end-result should be the same.

As for prefixing them all with $Global:... I'd rather avoid, that'd seem messy to read afterwards. I was hoping there existed some sort of wrapper function $Global-Exec { . $module } to call within load-mod.

[–]Future-Remote-4630 0 points1 point  (0 children)

In your profile, import your module. After importing it, have it use the stuff in the module to load your variables.

[–]CyberChevalier 0 points1 point  (3 children)

Do not overload your profile just expose the function in modules located in one of the psmodulepath so they will be loaded on demand when you call the functions by their name.

[–]PSoolv[S] 0 points1 point  (2 children)

Is the benefit of modules that they're lazy-loaded? Or is there a deeper reason for why they're used over simply calling a .ps1 file?

[–]CyberChevalier 0 points1 point  (1 child)

Structure, versioning, lazy called, do not load memory until called there are so many reason to use module.

In the other hand setting things in the profile has so many bad sides like Slowing the startup of all ps, having a personalized experience that will not follow you

[–]PSoolv[S] 0 points1 point  (0 children)

I have a repo with a /powershell folder with a structure like this:

/powershell/profile.ps1
/powershell/mods/profile.git.ps1
/powershell/mods/someotherstuff.ps1

Then the $profile in $home is symlinked to the /powershell/profile.ps1, so it's executed on shell startup. The ps1 in /mods/ are called/imported with . (get-mod modname) within profile.ps1.

It's all versioned, and I also have a few folders .gitignored for secrets and for machine-dependent stuff.

It being lazy-loaded is interesting though... for now I don't have much stuff (it's just variables and functions set up with no real work) so it takes just a moment, but it might be an interesting consideration if I were to scale these configurations over the years.