Managing IIS configSections programmatically via script

Written by Troy on October 17, 2012 Categories: Uncategorized Tags: , , , ,

Looking for a way to add configSections to the IIS schema, I came across this useful post by Kanwaljeet Singla of the IIS team, about using the Microsoft.ApplicationHost.WritableAdminManager class to manage IIS configuration. I’m not aware of another API that allows you to do so.

Based on that, I created the following handy script to add and remove configuration sections from the IIS schema.

var action;
var path;
var overrideMode = 'Deny';
var allowDef = 'MachineToApplication';

function addSection(sectionGroup, sectionName) {
	var section;
	for (var i = 0; i < sectionGroup.Sections.Count; i++) {
		section = sectionGroup.Sections.Item(i);
		if (section.Name == sectionName) {
			WScript.Echo('The section "' + sectionName + '" is already installed...');
			if (section.OverrideModeDefault == overrideMode && section.AllowDefinition == allowDef) {
				WScript.Echo(' ... and configured correctly');
				return false;
			}
			break;
		}
	}

	if (section == null) {
		WScript.Echo('Creating new section, "' + sectionName + '".');
		section = sectionGroup.Sections.AddSection(sectionName);
	}
	else {
		WScript.Echo(' ... updating section.');
	}
	section.OverrideModeDefault = overrideMode;
	section.AllowDefinition = allowDef;
	return true;
}


function checkArgs() {
	if (action == null || path == null) {
		printUsage();
		WScript.Quit(1);
	}
}


function doWork() {
	var admin = new ActiveXObject("Microsoft.ApplicationHost.WritableAdminManager");

	path.match(/^(.*)\/(\S+?)$/);
	var parentPath = RegExp.$1;
	var sectionName = RegExp.$2;
	var sectionGroup = getSectionGroup(admin, parentPath);
	var saveRequired = false;
	
	switch (action) {
		case 'add':
			saveRequired = addSection(sectionGroup, sectionName);
			break;
		case 'remove':
			saveRequired = removeSection(sectionGroup, sectionName);
			break;
		default:
			WScript.Echo('The action is unknown: ' + action);
			printUsage();
			WScript.Quit(2);
	}
	
	if (saveRequired) {
		WScript.Echo('Saving changes.');
		admin.CommitChanges();
	}
	else {
		WScript.Echo('No save required.');
	}
	WScript.Echo('Done.');
}


function getSectionGroup(admin, path) {
	var configManager = admin.ConfigManager;
	var appHostConfig = configManager.GetConfigFile("MACHINE/WEBROOT/APPHOST");
	var sectionGroup = appHostConfig.RootSectionGroup

	var pathSegments = path.split('/');
	while (pathSegments.length > 0) {
		var sectionGroupName = pathSegments.shift();
		sectionGroup = sectionGroup.Item(sectionGroupName);
		WScript.Echo(" ... section group: " + sectionGroup.Name);
	}
	return sectionGroup;
}


function printUsage() {
	WScript.Echo('usage: cscript configSections.js action:add|remove path:system.webServer/something/or/other');
	WScript.Echo('                                 allowDef:Everywhere|MachineOnly|MachineToWebRoot|MachineToApplication|AppHostOnly');
	WScript.Echo('                                 defaultMode:Allow|Deny');
	WScript.Echo();
}


function processArgs() {
	var args = WScript.Arguments;

	for (var i = 0; i < args.length; i++) {
		var arg = args(i);
		if (arg.match(/^action:(add|remove)$/)) {
			action = RegExp.$1;
			continue;
		}
		if (arg.match(/^path:([\S]+)$/)) {
			path = RegExp.$1;
			continue;
		}
		if (arg.match(/^allow[dD]efinition:(Everywhere|MachineOnly|MachineToWebRoot|MachineToApplication|AppHostOnly)$/)) {
			allowDef = RegExp.$1;
			continue;
		}
		if (arg.match(/^override[mM]ode:(Allow|Deny)$/)) {
			overrideMode = RegExp.$1;
			continue;
		}
		WScript.Echo('*** Unknown arg: ' + arg);
		printUsage();
		WScript.Quit(1);
	}
}


function removeSection(sectionGroup, sectionName) {
	for (var i = 0; i < sectionGroup.Sections.Count; i++) {
		var section = sectionGroup.Sections.Item(i);
		if (section.Name == sectionName) {
			WScript.Echo('Removing section, "' + sectionName + '".');
			sectionGroup.Sections.DeleteSection(sectionName);
			return true;
		}
	}

	WScript.Echo('The section "' + sectionName + '" does not exist.');
	return false;
}


processArgs();
checkArgs();
doWork();

You can use it as follows:

cscript //nologo configSections.js action:add path:system.webServer/security/authentication/superDuperAuthentication

Normally I'd have a wrapper .bat script. Also, make sure you copy your schema file into the inetsrv folder.

Interestingly I could not get this working with Powershell. Can anyone tell me why? Is this a limitation of Powershell and COM?

1 Comment

1 Comment

  • 94Chassidy says:

    Hello blogger, i must say you have very interesting posts here.

    Your website can go viral. You need initial traffic only.

    How to get it? Search for; Mertiso’s tips go viral

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>