PowershellFrameworkCollective / psframework

A module that provides tools for other modules and scripts
MIT License
427 stars 41 forks source link

`Export-PSFConfig -SkipUnchanged` works only for prior initialized configs #624

Closed Callidus2000 closed 8 months ago

Callidus2000 commented 8 months ago

Hi, I wanted to store modified settings for my PowerShell Universal Server in JSON files using Export-PSFConfig. I tried using the switch -SkipUnchanged but this only exports settings which are modified after initialization.

For example

$confFileName=".\MyBugDemo.json"
Set-PSFConfig -Module MyBugDemo -Name "Config" -Value "Init123d" -AllowDelete  -Initialize
Set-PSFConfig -Module MyBugDemo -Name "Config" -Value "Modified456"
Export-PSFConfig -Module MyBugDemo -OutPath $confFileName -SkipUnchanged

creates the json file while

$confFileName=".\MyBugDemo.json"
Set-PSFConfig -Module MyBugDemo -Name "Config" -Value "Init123d" -AllowDelete 
Set-PSFConfig -Module MyBugDemo -Name "Config" -Value "Modified456"
Export-PSFConfig -Module MyBugDemo -OutPath $confFileName -SkipUnchanged

does not.

I would have expected the function to export every setting that

FriedrichWeinmann commented 8 months ago

Yeah, that's a somewhat odd parameter, due to the way persistence and initialization interact. Since the configuration setting is independent of the modules consuming it, it is possible to define/customize settings before the module implementing them is imported. This always happens when you persist settings, as they are loaded on PSFramework import. Even if the implementing module is imported, PSFramework as its dependency will be imported first, so there is a guaranteed situation where setting values exist before the module using the setting is loaded. Modules can also define settings with attached logic that is executed when the setting is changed from its default value. To catch that, Initialization was created, so that validation and change event can happen for settings that have already been there, before the module came along.

It gets more complex though: What if the same setting is defined in multiple locations (e.g. both User Policy and System Policy)? Well, in that case the setting will be iteratively overwritten through the multiple sources and only the last value will run through validation and handler logic during initialization.

-SkipUnchanged refers to a change from the initialized default value - including if the value has been already there and is the first, original value before the setting was ever initialized. Again, the persistence scenario. Before that, its state as "unchanged" is more of a gray zone and you always have the option to initialize a setting with the first value.

All things considered ... not a perfect solution as it is, but I do not believe there is one for this. Not going to change the existing implementation - might be a breaking change - but if it's something you care about enough, I could add a new parameter for it where we consider any changes after persistence (or the first setting if not persisted) a change.

Callidus2000 commented 8 months ago

Thanks for the quick reply. I think I've found a workaround....

For the background: Nearly every module I develop uses PSF, and the configuration framework in special. This results that every app logic for my PowerShell Universal apps is packaged as a module.

To make it easier for my colleagues to configure the apps (e.g. switching between prod and dev backends) I'm developing a PSU dashboard which

image

I wanted to store the changes in json files besides the PSU repository. A startup script loads the files, no problem.

For saving the changed settings I've now got the following workaround:

Testing was successful, now comes the weekend...