-
Notifications
You must be signed in to change notification settings - Fork 288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A question of configuration #79
Comments
Personally, I've started using option |
Mostly 1 with the added reliance on commands within the module for customization. Where configuration is persistent, it was stored in XML and more recently JSON formatted files. Configuration in my case is normally drawn in to a script level variable on module load (my a module init script). I don't personally like the idea of polluting the users session with variables so I've avoided using Global variables. The same applies to environment variables. I felt hiding the configuration variable(s) simplified the amount of validation needed in the relatively unlikely event someone was fiddling with things (or I made a mistake and wrote a conflicting change into a different module). I've used your Configuration module for changing module manifests (lately, at build time) but little beyond that so far. The module I'm updating now will use the Configuration module instead of my older approaches. TL;DR: Yes I use external configuration. I would be very happy with 2. |
Could this work just like format files (without the xml, of course)? A module could contain a default configuration, which could be added to with a command similar to Update-FormatData, maybe Update-ConfigData? |
For PSCX we created a provider for configuration such that you have a PSCX drive to tweak configuration. One issue if you create a permanent storage location for configurations is to make sure it is easily findable so when you set up a new machine, you can copy the configuration files to the new machine. For this reason, I'd rather see the user's configuration file stored in the user's $PROFILE dir. And shouldn't the default configuration reside in the module's install dir? Would machine config go in |
We already have the functionality in 1) and specifically
If you place a ps1 in the module manifest, like so Whereas if you had the ps1 in the module manifest like this This is documented (albeit not very well) via the NestedModules Parameter in the help for New-ModuleManifest which is at When we think of personalisation of modules and how I wish I could easily manipulate how they would function, I do quite like the Ideals behind how @Jaykul has implemented it in the Configuration module as personally I prefer to see any machine level information in the C:\ProgramData folder than in the Public User location. Though this is just a preference of mine. In regards to @rkeithhill point on the using the $Profile directory, I think that it could be quite useful for those in the enterprises that have mapped home drives and move between systems regularly. So in a way if you combined 1 & 2 a little you would already have all the functionality that you are looking for and although I do think the ModuleLoad Event could be interesting and useful however as noted it's not backwards compatible. Only other thing would be that I'd be suggestive of dropping the need of CompanyName from the Configuration Module and keep the paths to match up with how modules are currently stored (v5 & above) so
However there is 1 small snag and that is that in theory you'd need to also have the following for use in PowerShell Core
and potentially the following for v4 and below
BUT I like the idea and I've been spending time overhauling PowerShellGet partially due to a similar reason and as linked to I think this would make a good way forward to helping solve some of the PowerShellGet issues that have been considerably irritating over time. |
@kilasuit Apart from scoping and loading order weirdness, there are two problems with solving the 1) Module initialization script by using nested modules:
One or the other of those I can solve:
But the solution to each one makes the other one intractable.... For what it's worth, in principle, I agree about leaving the company out of the module paths, but I was nervous about the fact that it's possible to work around module name collisions by installing one as "current user" and one as "all users" ... so I chose to go with something I was more confident of. In retrospect, it makes the configuration files harder to find, so I'd probably be better off using However, I'm not sure about the location. Technically Microsoft PowerShell owns that, and could blow it all away... Of course, the exact path doesn't matter if this is built in via dependence on PowerShell or a 3rd party module, because people will learn use the cmdlets to discover it. |
Does anyone else use (external) configuration files for their modules?
How do you wish PowerShell supported that?
I looked at a bunch of modules which need configuration (like PSReadLine, PSCX, AzureRM, PowerShellGet, PSScriptAnalyzer) and every one of them is using a different way to deal with it. Most of them require you to configure them with their own commands, so you can't configure them until after you import them (and configuring them in your Profile.ps1 would force you to import them). A few use environment variables, global variables, or XML or JSON configuration files.
It seems to me that we can do better: there's an opportunity here for an RFC to the PowerShell Core project to either add a setting, or an event, or a set of configuration commands.
The idea is to create a simple common convention for a way to customize modules on import (or run initialization code after import). The requirements are:
Here are my two main ideas, along with an old suggestion I was reminded of earlier today... what do you all think? Is there a better way?
Several modules (notably AzureRM.Profile) use a "startup" script which is run by the module (within the module scope?) when the module is being loaded. Others don't have startup scripts, but still rely on cmdlets for all their customization (notable PSReadLine).
Azure is using the IModuleAssemblyInitializer interface and subtly abusing it to run a local script file for binary modules. However, we could run it any number of ways, and we could establish a pattern for the file name like "$PSHome\modulename-profile.ps1" ...
In an ideal world, we would add a setting for the module manifest, and PowerShell would automatically run that script at import time (as though it were dot-sourced at the end of the module psm1?).
I wrote the Configuration Module to allow modules to store their settings in layered (i.e. default + machine + user) PSD1 data files that are stored in your AppData folders. This allows configuration files to be manipulated using commands from the Configuration module without worrying about importing the module you're configuring (potentially before you even have it installed).
I had to write some code to make serialization to and from
psd1
work (we could use JSON, but I want more type safety and such). and I also made some assumptions about what people want/need (layering, file storage in AppData, etc).In an ideal world, we would have these commands built-in to PowerShell, and the configuration would be automatically imported and exported on module load/unload, and would populate a magic variable
$PSModuleConfig
This would not work "down level" but hypothetically, we could add a "ModuleImported" event to PowerShell 6 that would trigger (with a module name) do that someone could just write (in their main profile script) something like this:
This would be interesting because it allows you do any sort of logic you want, and would therefore be backward compatible to old modules that have existing configuration or setting commands, even though it couldn't ever work with old versions of PowerShell.
The down side, of course, would be the lack of discoverability, and the fact that it wouldn't force authors to think about how they want configuration to work ;-)
Thoughts, comments, rejections?
The text was updated successfully, but these errors were encountered: