§ January 17, 2014 15:21 by
beefarino |
Earlier this week I pushed a new project to my public github repositories. This project contains a PowerShell module that enables you to change the active configuration of the appdomain that is hosting your PowerShell session. I’ve been asked a lot of questions about what this does exactly, and why someone would want to use it. This goal of this post is to clarify the scenario where this is useful.
TL;DR: if you have to ask, you don’t need it.
Let’s say you want to use a .NET library that relies on one or more settings in the application configuration file. Like what? Well, let’s say you need to add a connection string to the appdomain configuration to get a library that uses Entity Framework to work correctly. In fact, that’s where this project came from – I needed a way to manipulate connection strings in the app domain configuration to get Entity Shell to work properly.
In order to leverage such a library from PowerShell, you’ll need to modify the application configuration file for the PowerShell application, which is really bad form. Seriously. Don’t do that. That file isn’t for you. Stop touching it. Sit on your hands if you have to.
Another alternative is to make a copy of the entire PowerShell application, with its own configuration file, and then edit the copy. That’s silly. Seriously. Don’t do that. No one wants multiple copies of the same application laying about. No one I say! So just remove-item –recurse –force all those duplicate powershell.exe applications, okay?
And yet another alternative – and this was my preferred path until recently – was to use a tool called poshrunner from friend and coastal neighbor Justin Dearing. This little gem would help you spool up a new app domain using a specific configuration file, so a script could take advantage of the new configuration. I still like this approach, and it works really well as long as you’re willing to plan ahead a little bit. Which I’m not. I tend to find myself in a PowerShell session filled with state and variables that I want to keep using. Poshrunner was hard to fit into this gambitesque workflow.
So I found an alternative way. A way you can manipulate app settings and connection strings for the active PowerShell session. Here’s an example using this new module to configure a connection string in the active PowerShell session:
> import-module appDomainConfig
> add-connectionString -name 'UserGroupContext' `
-provider 'System.Data.SqlClient' `
-connectionstring 'Data Source=.\SQLExpress;Initial Catalog=SuperAwesomeWebsite.Models.UserGroupContext;Integrated Security=True'
Name : UserGroupContext
ConnectionString : Data Source=.\SQLExpress;Initial ...
ProviderName : System.Data.SqlClient
LockAttributes : {}
LockAllAttributesExcept : {}
LockElements : {}
LockAllElementsExcept : {}
LockItem : False
ElementInformation : System.Configuration.ElementInformation
CurrentConfiguration :
Pretty simple, eh? No fuss, it just works. Your PowerShell session isn’t disrupted, and the configuration change sticks for the remainder of your session without being persisted to any file.
So far the module supports adding, getting, and removing app settings and configuration strings. More features may be added if I find I need them (or you can send a pull request with your own changes).
How it Works
It cheats.
Well sort of. It uses .NET reflection to manipulate the configuration type private members and gain write access to the configuration bits for the current app domain.
Isn’t that dangerous? I guess. Well, I mean, in the grand scheme of things, this is a pretty safe thing to do. We’re not naked soaring on a flaming hang-glider over sharks-with-lasers-infested waters during an air-to-air battle with zombie-piloted Messerschmitts. You might be able to muss up your app domain configuration, but I haven’t crashed the process yet.
Isn’t that fragile? I guess. Well, I mean, that API has been around for a long time. And this is a technique I’ve been using for about 8 years now. And it still works. And if it stops working then I suppose I’ll take another look at it. I mean, how fragile could it be? “The code’s only been working for EIGHT years!”
Isn’t that bad practice? I guess. Well, I mean, I personally think the configuration API should have a programmatic interface as well as the XML one. That’s the bad practice in my mind. I’m just taking corrective measures so I can use it the way I need to use it to get my work done.
Isn’t that …. Look, if this sort of thing leaves a bad taste in your mouth, then please offer an acceptable alternative.
In the meantime, I would suggest you give the module a whirl if you think it would help you.