27

Has anyone worked out how to get PowerShell to use app.config files? I have a couple of .NET DLL's I'd like to use in one of my scripts but they expect their own config sections to be present in app.config/web.config.

Kev
  • 118,037
  • 53
  • 300
  • 385

3 Answers3

39

Cross-referencing with this thread, which helped me with the same question: Subsonic Access To App.Config Connection Strings From Referenced DLL in Powershell Script

I added the following to my script, before invoking the DLL that needs config settings, where $configpath is the location of the file I want to load:

[appdomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $configpath)
Add-Type -AssemblyName System.Configuration

See this post to ensure the configuration file specified is applied to the running context.

Ben Gripka
  • 16,012
  • 6
  • 45
  • 41
millerjs
  • 566
  • 4
  • 3
  • 3
    Wow...an answer after all these years :). Thanks I'll give this a shot. – Kev Apr 11 '11 at 18:26
  • +1 Thanks a lot! All over the net the only solution mentioned to this prroblem is `ConfigurationManager.OpenMappedExeConfiguration` and none for a scenario where we do not have control over the referenced assembly! This works perfect for my case. – fozylet Feb 22 '12 at 06:16
  • 3
    This code did not work, I ended up using Robert Mooney's solution: http://stackoverflow.com/questions/16216736/loading-app-config-into-the-appdomain#answer-33290175 – Tahir Hassan Dec 16 '15 at 10:53
  • So, does anyone know if you can set this inside the dll? i am having trouble setting it... it seems like the scope is wrong or i don't know how to write a Set-AppConfigFile inside my C# dll module. /grr – Omzig Dec 07 '17 at 02:50
6

I'm guessing that the settings would have to be in powershell.exe.config in the powershell directory, but that seems to be a bad way of doing things.

You can use ConfigurationManager.OpenMappedExeConfiguration to open a configuration file based on the executing DLL name, rather than the application exe, but this would obviously require changes to the DLLs.

samjudson
  • 56,243
  • 7
  • 59
  • 69
  • I would strongly NOT to use such a solution. Wrap it in a console app that writes data as JSON to STDOUT, or ASP.NET WebAPI app. The choice between console vs. API would depend on hosting and security. – yzorg Sep 13 '16 at 22:41
  • Another reason NOT to use this: PowerShell gets updated with the OS, and powershell.exe.config is a protected OS file, which means it can't just be edited with notepad. – yzorg Sep 13 '16 at 22:42
2

Attempting a new answer to an old question.

I think the modern answer would be: don't do that. PowerShell is a shell. The normal way of passing information between parts of the shell are shell variables. For powershell that would look like:

$global:MyComponent_MySetting = '12'
# i.e. 
$PSDefaultParameterValues
$ErrorActionPreference

If settings is expected to be inherited across processes boundaries the convention is to use environment variables. I extend this to settings that cross C# / PowerShell boundary. A couple of examples:

$env:PATH
$env:PSModulePath

If you think this is an anti-pattern for .NET you might want to reconsider. This is the norm for PAAS hosted apps, and is going to be the new default for ASP.NET running on server-optimized CLR (ASP.NET v5).

See https://github.com/JabbR/JabbRv2/blob/dev/src/JabbR/Startup.cs#L21
Note: at time of writing I'm linking to .AddEnvironmentVariables()

I've revisited this question a few times, including asking it myself. I wanted to put a stake in the ground to say PowerShell stuff doesn't work well with <appSettings>. IMO it is much better to embrace the shell aspect of PS over the .NET aspect in this regards.

If you need complex configuration take a JSON string. POSH v3+ has ConvertFrom-JSON built-in. If everything in your process uses the same complex configuration put it in a .json file and point to that file from an environment variable.

If a single file doesn't suffice there are well established solutions like the PATH pattern, GIT .gitignore resolution, or ASP.NET web.config resolution (which I won't repeat here).

yzorg
  • 4,224
  • 3
  • 39
  • 57
  • 2
    "*don't do that.*" - sure, and appreciate the time you've put into this answer. But environment variables etc won't work with these legacy assemblies, they expect to be able to read their configs out of the `AppSettings` collection. – Kev Jan 30 '15 at 21:07
  • @Kev Then those assemblies really shouldn't be used in a PowerShell context. You might have to host PowerShell yourself. See "embedding PowerShell", ala Visual Studio's "Package Manager Console". – yzorg Sep 13 '16 at 22:29