How To Create a Windows Firewall Rule
// This script creates a rule in Windows Firewall. When used as an MSI custom action, it must be run in Deferred mode,
// with it's CustomActionData set to INSTALLDIR
// It is written so it can be run outside of MSI to [vastly] simplify debugging.
var ClassName_ScriptingRuntimeShell = "WScript.Shell";
var argumentString = "";
var arguments = null;
var installDir = "";
// CustomActionData format: [INSTALLDIR]<?>
// If running in MSI, use arguments via standard CustomActionData interface, otherwise assume running outside MSI in debugger
if (DetectRunningInMSI())
argumentString = Session.Property("CustomActionData");
else
argumentString = "c:\\Program Files\\MyProgramDir";
arguments = argumentString.split("<?>");
if (arguments.length == 1)
{
installDir = arguments[0];
}
else
{
LogMessage("Argument string invalid (" +arguments.length+ "): " +argumentString);
throw 3;
}
installDir = EnsureEndsInBackslash(installDir);
// Don't let a failure here fail the install
try
{
CreateFirewallRule("Rule Description", installDir +"MyProgramFilename.exe")
}
catch (unexpectedException)
{
LogMessage("Error " +unexpectedException.number+ " creating firewall rules: " +unexpectedException.message);
}
function CreateFirewallRule( ruleName, exePathname )
{
var firewallConfig = null;
var firewallPolicy = null;
var newApplicationRule = null;
var activeApplicationRules = null;
firewallConfig = SafeGetActiveXObject("HNetCfg.FwMgr");
if (firewallConfig != null)
newApplicationRule = SafeGetActiveXObject("HNetCfg.FwAuthorizedApplication");
if (newApplicationRule != null)
{
firewallPolicy = firewallConfig.LocalPolicy.CurrentProfile;
newApplicationRule.Name = ruleName;
newApplicationRule.IPVersion = 2;
newApplicationRule.ProcessImageFileName = exePathname;
newApplicationRule.RemoteAddresses = "*";
newApplicationRule.Scope = 0;
newApplicationRule.Enabled = true;
activeApplicationRules = firewallPolicy.AuthorizedApplications
activeApplicationRules.Add(newApplicationRule)
LogMessage("Added rule for "+exePathname);
}
}
function LogMessage( messageString )
// Writes a line to the MSI log, or the console if running outside MSI.
{
var customActionName = "CreateFirewallRules";
if (DetectRunningInMSI())
{
var msiMessageTypeInfo = 0x04000000
var logRecord = null;
var currTime = new Date();
logRecord = Installer.CreateRecord(1);
logRecord.StringData(0) = currTime.toTimeString() +" "+ customActionName +": [1]";
logRecord.StringData(1) = messageString;
Session.Message(msiMessageTypeInfo, logRecord);
logRecord = null;
}
else
{
var currTime = new Date();
messageString = currTime.toTimeString() +" "+ customActionName +": "+ messageString;
WScript.Echo(messageString);
}
}
function DetectRunningInMSI()
// Returns TRUE if running in MSI, else FALSE
{
var returnVal = true;
var stringVal = "";
try
{
// Try to reference the Session object, which is only provided by the MSI runtime engine
stringVal = Session.Property("ProductCode");
}
catch (thisException)
{
// An exception is only thrown if the runtime couldn't resolve Session, which means
// this script is not running under MSI
returnVal = false;
}
return returnVal;
}
function SafeGetActiveXObject( className )
// Creates an instance of className and returns it, or null if an error occurs, and logs the error
{
var returnVal = null;
try
{
returnVal = new ActiveXObject(className);
}
catch (createException)
{
LogMessage("SafeGetActiveXObject: Error " +createException.number+ " creating object of class " +className+ ": " +createException.message);
}
return returnVal;
}
function EnsureEndsInBackslash( directoryPath )
// Returns directoryPath ending in a backslash if it does not already end in one.
{
var returnVal = directoryPath;
if (returnVal.substring(returnVal.length, returnVal.length-1) != "\\")
returnVal = returnVal + "\\";
return returnVal;
}