SQL 2016 DB 構成プロバイダー

Microsoft.SQLServer.2016.DBConfigurationProvider (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsMicrosoft.SQLServer.MonitoringAccount
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.PropertyBagProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$間隔 (秒)ワークフローを実行する定期的な実行間隔 (秒)。
SyncTimestring$Config/SyncTime$同期時刻24 時間形式で指定した同期時刻。省略可能です。
TimeoutSecondsint$Config/TimeoutSeconds$タイムアウト (秒)ワークフローが終了して失敗とマークされるまでの、ワークフローの許容実行時間を指定します。

Source Code:

<DataSourceModuleType ID="Microsoft.SQLServer.2016.DBConfigurationProvider" Accessibility="Internal" RunAs="GPMP!Microsoft.SQLServer.MonitoringAccount">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ConnectionString" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="SyncTime" ParameterType="string" Selector="$Config/SyncTime$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.PropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>GetSQL2016DBConfig.js</ScriptName>
<Arguments>"$Config/ConnectionString$" "$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$" "$Target/Host/Property[Type="SQL2016Core!Microsoft.SQLServer.2016.ServerRole"]/InstanceName$" "$Target/Host/Property[Type="SQL2016Core!Microsoft.SQLServer.2016.DBEngine"]/TcpPort$"</Arguments>
<ScriptBody><Script>//#Include File:SQL2016Constants.js

var MANAGEMENT_PACK_VERSION = "7.0.7.0";

//#Include File:Common.js

var MAX_DRIVER_VERSION_STR = "99999999.99999999.99999999.99999999";

Function.prototype.setAlias = function (funcName) {
this.getAlias = function () {
return funcName;
};
};

Error.prototype.toString = function () {
if (this.message) {
var parts = [];
parts.push(this.message);
parts.push('\n');

if (this.number) {
parts.push("Error Number : ");
parts.push(this.number);
parts.push('\n');
parts.push("Error Code : ");
parts.push(this.number &amp; 0xFFFF);
parts.push('\n');
parts.push("Win32 Facility : ");
parts.push((this.number &gt;&gt; 16 &amp; 0x1FFF));
parts.push('\n');
}
if (this.description) {
parts.push("Error Description : ");
parts.push(this.description);
}
parts.push('\n');
return parts.join('');
} else {
return this.toString();
}
};

if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (item) {
for (var i = 0; i &lt; this.length; i++) {
if (this[i] === item) {
return i;
}
}
return -1;
};
}

Array.prototype.intersectsWith = function (arrB) {
for (var i = 0; i &lt; this.length; i++) {
for (var j = 0; j &lt; arrB.length; j++) {
if (this[i] === arrB[j]) {
return true;
}
}
}
return false;
};

if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}

String.prototype.padLeft = function (length, padStr) {
var tmpStr = this;
padStr = padStr || " ";
while (tmpStr.length &lt; length)
tmpStr = padStr + tmpStr;
return tmpStr;
};

Date.prototype.toISO8601UtcString = function () {
function padLeft(number, length) {
return ("" + number).padLeft(length, "0");
}

return padLeft(this.getUTCFullYear(), 4) +
'-' + padLeft(this.getUTCMonth() + 1, 2) +
'-' + padLeft(this.getUTCDate(), 2) +
'T' + padLeft(this.getUTCHours(), 2) +
':' + padLeft(this.getUTCMinutes(), 2) +
':' + padLeft(this.getUTCSeconds(), 2) +
'Z';
};

var DriverVersion = function (versionStr) {
arguments.callee.setAlias('DriverVersion.constructor');
var versionRegex = /^(\d{1,8})(.\d{1,8}){0,3}$/g;
if (!versionRegex.exec(versionStr)) {
throw new Exception("Invalid version string.");
}

var parts = versionStr.split(".");
this.major = parseInt(parts[0]);
this.minor = 0;
this.build = 0;
this.revision = 0;
if (parts.length &gt; 1) {
this.minor = parseInt(parts[1]);
if (parts.length &gt; 2) {
this.build = parseInt(parts[2]);
if (parts.length &gt; 3) {
this.revision = parseInt(parts[3]);
}
}
}

this.toString = function () {
arguments.callee.setAlias('DriverVersion.toString');
return "" + this.major + "." + this.minor + "." + this.build + "." + this.revision;
};

this.compareTo = function (v) {
arguments.callee.setAlias('DriverVersion.compareTo');
if (!(v instanceof DriverVersion)) {
throw new Exception("Parameter is not an instance of type DriverVersion.");
}
var d = this.major - v.major;
if (d !== 0) {
return d;
}
d = this.minor - v.minor;
if (d !== 0) {
return d;
}
d = this.build - v.build;
if (d !== 0) {
return d;
}
d = this.revision - v.revision;
return d;
};
};

function GetDriverVersionObj(oVersion) {
arguments.callee.setAlias('GetDriverVersionObj');
if (oVersion instanceof DriverVersion) {
return oVersion;
} else {
if ((typeof oVersion) === "string") {
return new DriverVersion(oVersion);
}
}
throw new Exception("Parameter is not an instance of type DriverVersion.");
}

var VersionRange = function (sStartVersion, sEndVersion) {
arguments.callee.setAlias('VersionRange.constructor');
this.startVersion = GetDriverVersionObj(sStartVersion);
this.endVersion = GetDriverVersionObj(sEndVersion);
};

var RegistryValueTypes = {
"REG_SZ": 1,
"REG_EXPAND_SZ": 2,
"REG_BINARY": 3,
"REG_DWORD": 4,
"REG_MULTI_SZ": 7
};

function EnumerateRegistryKeyValues(hiveName, keyPath) {
arguments.callee.setAlias('EnumerateRegistryKeyValues');
var hiveId, ex;
switch (hiveName) {
case "HKEY_CLASSES_ROOT":
hiveId = 2147483648;
break;
case "HKEY_CURRENT_USER":
hiveId = 2147483649;
break;
case "HKEY_LOCAL_MACHINE":
hiveId = 2147483650;
break;
case "HKEY_USERS":
hiveId = 2147483651;
break;
case "HKEY_CURRENT_CONFIG":
hiveId = 2147483653;
break;
default:
throw new Exception("Registry hive name '" + hiveName + "' is invalid");
}

try {
var providerName = "StdRegProv";
var services = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default");
var registry = services.Get(providerName);
var enumFuncName = "EnumValues";

var inParams = registry.Methods_(enumFuncName).InParameters.SpawnInstance_();
inParams.hDefKey = hiveId;
inParams.sSubKeyName = keyPath;
var outParams = registry.ExecMethod_(enumFuncName, inParams);

var valueNames = outParams.sNames.toArray();
var valueTypes = outParams.Types.toArray();

return { ValueNames: valueNames, ValueTypes: valueTypes };
}
catch (ex) {
throw new Exception("Cannot enumerate values of registry key '" + hiveName + "\\" + keyPath + "'", ex);
}
}

var DriverItem = function (sName, oNameVersion, oDriverVersion, oParseObj) {
arguments.callee.setAlias('DriverItem.constructor');
this.name = sName;
this.nameVersion = GetDriverVersionObj(oNameVersion);
this.driverVersion = GetDriverVersionObj(oDriverVersion);
this.parseObject = oParseObj;
};

var DriverSelectorRule = function (sNameRegex, sNameVersionRegex, sNameMinVersion, sNameMaxVersion, oVersionRangeArray) {
arguments.callee.setAlias('DriverSelectorRule.constructor');
var _computerId = ".";
this.nameRegex = sNameRegex;
this.nameVersionRegex = sNameVersionRegex;
this.nameMinVersion = GetDriverVersionObj(sNameMinVersion);
this.nameMaxVersion = GetDriverVersionObj(sNameMaxVersion);
var _versionRangeArray = oVersionRangeArray;
this.driverCollection = new Array();
this.isNativeClient = false;
var _nameRegexObj = new RegExp(sNameRegex);

var _nameVersionRegexObj = null;
if (sNameVersionRegex) {
if (sNameVersionRegex.length &gt; 0) {
_nameVersionRegexObj = new RegExp(sNameVersionRegex);
}
}

var checkVersion = function (oVersion, vMinVersion, vMaxVersion) {
arguments.callee.setAlias('DriverSelectorRule.checkVersion');
var vVersion = GetDriverVersionObj(oVersion);
return vVersion.compareTo(vMinVersion) &gt;= 0 &amp;&amp; (vVersion.toString() === MAX_DRIVER_VERSION_STR || vMinVersion.compareTo(vMaxVersion) === 0 || vVersion.compareTo(vMaxVersion) &lt; 0);
};

this.checkNameVersion = function (oVersion) {
arguments.callee.setAlias('DriverSelectorRule.checkNameVersion');
return checkVersion(oVersion, this.nameMinVersion, this.nameMaxVersion);
};

this.checkDriverVersion = function (oVersion) {
arguments.callee.setAlias('DriverSelectorRule.checkDriverVersion');
var result = false;
for (var i = 0; i &lt; _versionRangeArray.length; i++) {
if (checkVersion(oVersion, _versionRangeArray[i].startVersion, _versionRangeArray[i].endVersion)) {
result = true;
break;
}
}
return result;
};

this.matchName = function (sName) {
arguments.callee.setAlias('DriverSelectorRule.matchName');
if (_nameRegexObj.exec(sName)) {
return true;
}
return false;
};

this.getNameVersion = function (sName) {
arguments.callee.setAlias('DriverSelectorRule.getNameVersion');
if (!_nameVersionRegexObj) {
return new DriverVersion("0");
}
var matches = _nameVersionRegexObj.exec(sName);
if (matches) {
return new DriverVersion(matches[0]);
}
throw new Exception("Driver name or version detection expression is invalid");
};

this.getDriverVersion = function (sName) {
arguments.callee.setAlias('DriverSelectorRule.getDriverVersion');
var registry = new Registry();
var driverPath = registry.Read("HKEY_LOCAL_MACHINE\\SOFTWARE\\ODBC\\ODBCINST.INI\\" + sName + "\\Driver");
try {
var objFso = new ActiveXObject("Scripting.FileSystemObject");
var sDllVersion = objFso.GetFileVersion(driverPath);
} catch (ex) {
throw new Exception("Cannot obtain driver version using path '" + driverPath + "'");
}
return new DriverVersion(sDllVersion);
};

this.addDriver = function (oDriver) {
arguments.callee.setAlias('DriverSelectorRule.addDriver');
if (!(oDriver instanceof DriverItem)) {
throw new Exception("Parameter is not an instance of type DriverItem.");
}
this.driverCollection.push(oDriver);
};

this.resetState = function () {
this.driverCollection = new Array();
};
};

var DriverSelector = function () {
arguments.callee.setAlias('DriverSelector.constructor');

// DEPRECATED
var _selectorRules = DriverSelector.createSelectorRules();
var _selectedDriverName = null;

// DEPRECATED
var _computerId = ".";
var _defaultDriverName = "SQL Server";

// DEPRECATED
var _ncli_ForceProtocolEncryption = false;
var _ncli_TrustServerCertificate = false;
var _ncli_tcpProtocolEnabled = true;
var _ncli_smProtocolEnabled = true;

var _processed = false;
var _errorCollection = [];

// TODO: 2
function getNsNameWithHighestVersion(computerName) {
arguments.callee.setAlias('DriverSelector.getNsNameWithHighestVersion');
var rootNs = "root\\Microsoft\\SqlServer";
var oWMI = new WMIProvider(rootNs);
var namespaces = oWMI.ExecQuery("SELECT Name FROM __NAMESPACE WHERE Name LIKE 'ComputerManagement%'");
if (namespaces.Count &gt; 0) {
var e = new Enumerator(namespaces);
var currentName = "";
for (; !e.atEnd(); e.moveNext()) {
var nsName = e.item().Name;
currentName = nsName &gt; currentName ? nsName : currentName;
}
} else {
throw new Exception("No namespace 'ComputerManagement*' was found");
}
return rootNs + "\\" + currentName;
}

// TODO: 1
function getNativeClientOdbcSettings(namespaceFullName, params) {
arguments.callee.setAlias('DriverSelector.getNativeClientOdbcSettings');

// ComputerName must be '.' or not provided
var wmi = new WMIProvider(namespaceFullName);
var props = null;

// Query can fail, because native client not supported
try {
props = wmi.ExecQuery("SELECT FlagName, FlagValue FROM ClientSettingsGeneralFlag");
} catch (e) {
// Do nothing, its ok, just skip this settings
return;
}

if (props.Count &gt; 0) {
var e = new Enumerator(props);
for (; !e.atEnd(); e.moveNext()) {
var prop = e.item();
switch (prop.FlagName) {
case "Force protocol encryption":
// _ncli_ForceProtocolEncryption = prop.FlagValue;
params.isForceProtocolEncryption = prop.FlagValue;
break;
case "Trust Server Certificate":
// _ncli_TrustServerCertificate = prop.FlagValue;
params.isTrustServerCertificate = prop.FlagValue;
break;
}
}
}
}

/*
* @namespace - full name
*/
function getClientProtocolsFromWMI(namespace) {
var protocols = [];

// create wmi provider for local machine
var wmi = new WMIProvider(namespace);
var result = null;

try {
result = wmi.ExecQuery('SELECT ProtocolName, ProtocolOrder FROM ClientNetworkProtocol');
} catch (e) {
// do nothing
}

// extract protocols from query
if (result &amp;&amp; result.Count &gt; 0) {
for (var e = new Enumerator(result); !e.atEnd(); e.moveNext()) {
if (e.item().ProtocolOrder &gt; 0) {
protocols.push(e.item().ProtocolName.toLowerCase());
}
}
}

return protocols;
}

/*
* Look if driver is Native client
* @namespace - full name
*/
// rename getClientProtocols
function getClientProtocolsFromRegistry(rules) {
// TODO: read

return null;
}

// TODO: 3
function getEnabledNativeClientProtocols(namespace) {
arguments.callee.setAlias('getEnabledNativeClientProtocols');

// TODO: WMI will be replaced by reading from registry
// var oQuery = null;
// var protocols = [];

// try read from WMI
// can fail because namespace remains empty for sql cluster with empty
// node
// computerName for WMIProvider must be '.' or not provided, read
// locally
// var oWMI = new WMIProvider(namespace);
// try {
// oQuery = oWMI.ExecQuery("SELECT ProtocolName, ProtocolOrder FROM ClientNetworkProtocol");
// } catch (e) {
// // do nothing
// }

// TODO: check oQuery and try read protocols from registry

// if (oQuery &amp;&amp; oQuery.Count &gt; 0) {
// for (var e = new Enumerator(oQuery) ; !e.atEnd() ; e.moveNext()) {
// if (e.item().ProtocolOrder &gt; 0) {
// protocols.push(e.item().ProtocolName.toLowerCase());
// }
// }
// }

// we try to use WMI as less as possible, read from registry first
return getClientProtocolsFromRegistry(namespace) || getClientProtocolsFromWMI(namespace);
}

/*
* Fill DriverSelector properties
* 3. getEnabledNativeClientProtocols:
* return named protocols ['tcp', 'sm', 'np']
* 2. getNsNameWithHighestVersion:
* return namespace
* 1. getNativeClientOdbcSettings:
* _ncli_ForceProtocolEncryption
* _ncli_TrustServerCertificate
*/
// REFACTOR
// 1 + 2 + 3
function getClientParameters() {
arguments.callee.setAlias('DriverSelector.getClientParameters');

var params = DriverSelector.createConnectionParams('.');

params.namespace = getNsNameWithHighestVersion();
try {
// read security settings from WMI
getNativeClientOdbcSettings(params.namespace, params);
} catch (e) {
// TODO: read security settings from registry
// throw e;
}
params.protocols = getEnabledNativeClientProtocols(params.namespace);

return params;
}

function resetState() {
_errorCollection = new Array();
for (var i = 0; i &lt; _selectorRules.length; i++) {
_selectorRules[i].resetState();
}
}

function addError(oErr) {
var errStr = typeof (oErr.toString) === 'undefined' ? "[" + (oErr.number &amp; 0xFFFF) + "] " + oErr.message : oErr.toString();
_errorCollection.push(errStr);
}

function selectFreshDriver(rules) {
var selected = null;
var rule = null;
var driver = null;

for (var r = 0; r &lt; rules.length; ++r) {
rule = rules[r];

for (var d = 0; d &lt; rules[r].driverCollection.length; ++d) {
driver = rule.driverCollection[d];

// select first if not selected
if (selected === null) {
selected = driver;
} else {
// select fresh, compare driver with selected by name and version
if (driver.nameVersion.compareTo(selected.nameVersion) &gt;= 0 &amp;&amp;
driver.driverVersion.compareTo(selected.driverVersion) &gt;= 0) {
selected = driver;
}
}
}

// all rules have order by priority, if rule contains drivers, then
// selected with high priority
if (selected) break;
}

return selected;
}

// Select most appropriate driver from filtered installed system (ODBC) drivers.
// select all available drivers
// Filter by driver name and version
// Intersected: check client and server have shared protocols
// tcp and np (Named Pipes) can work by network, sm can work only locally
// driver priorities: sm, tcp; np not used
//
// For native client need common client and server protocols
//
// Select latest namespace with highest version
// Select client protocols
// Select server protocols (enabled)
// Intersect client and server protocols
// Select odbc drivers related to inresected protocols
// We have 3 possible drivers:
// - ODBC (all protocols enabled)
// - Native Client (tcp, sm, np protocols)
// only native client can choose protocols through registry settings
// - Microsoft SQL Server (all protocols enabled)
this.processDrivers = function (serverProtocols) {
arguments.callee.setAlias('DriverSelector.processDrivers');

resetState();

var client = getClientParameters();

try {
var ncProtocolsAreIntersected = client.protocols.intersectsWith(serverProtocols);
DriverSelector.processSystemOdbcDrivers(_selectorRules, ncProtocolsAreIntersected);
} catch (ex) {
addError(ex);
_selectedDriverName = _defaultDriverName;
_processed = true;
return;
}

var driver = selectFreshDriver(_selectorRules);

// for native client detect tcp protocol is enabled,
// supposed driver selected and filled client params
if (driver &amp;&amp; driver.parseObject.isNativeClient) {
// TODO: take intersected protocols?
// _ncli_tcpProtocolEnabled = client.protocols.indexOf("tcp") &gt;= 0;
client.isTcpProtocolEnabled = client.protocols.indexOf('tcp') &gt;= 0;
client.isSharedMemoryProtocolEnabled = client.protocols.indexOf('sm') &gt;= 0;
}

if (driver) client.driverName = driver.name;

// for compatibility fill deprecated
_selectedDriverName = client.driverName;
_ncli_ForceProtocolEncryption = client.isForceProtocolEncryption;
_ncli_TrustServerCertificate = client.isTrustServerCertificate;
_ncli_tcpProtocolEnabled = client.isTcpProtocolEnabled;
_ncli_smProtocolEnabled = client.isSharedMemoryProtocolEnabled;

_processed = true;
};

this.getErrorCollection = function () {
return _errorCollection.slice();
};

this.hasErrors = function () {
return _errorCollection.length &gt; 0;
};

function throwIfNotProcessed() {
if (!_processed) {
throw new Exception("Drivers are not processed. Call 'ProcessDrivers' first.");
}
}

this.getSelectedDriverName = function () {
throwIfNotProcessed();
return _selectedDriverName;
};

this.getUseFqdn = function () {
throwIfNotProcessed();
return _ncli_ForceProtocolEncryption &amp;&amp; !_ncli_TrustServerCertificate;
};

this.getClientTcpProtocolEnabled = function () {
throwIfNotProcessed();
return _ncli_tcpProtocolEnabled;
};

this.getClientSharedMemoryProtocolEnabled = function () {
throwIfNotProcessed();
return _ncli_smProtocolEnabled;
};
};


DriverSelector.DEFAULT_DRIVER_NAME = 'SQL Server';


DriverSelector.createConnectionParams = function (computerName) {
return {
computerName: computerName,
driverName: DriverSelector.DEFAULT_DRIVER_NAME,
namespace: '',
isForceProtocolEncryption: false,
isTrustServerCertificate: false,
isTcpProtocolEnabled: true,
isSharedMemoryProtocolEnabled: true,
protocols: []
};
};

// all rules ordered by priority
DriverSelector.createSelectorRules = function () {
var rules = [];

var pr = new DriverSelectorRule("^SQL\\sServer\\sNative\\sClient\\s\\d{1,8}(\\.\\d{1,8})?$",
"\\d{1,8}(\\.\\d{1,8})?$", "11.0", "11.0",
[
new VersionRange("2011.110.6020.0", MAX_DRIVER_VERSION_STR),
new VersionRange("2011.110.5592.0", "2011.110.6000.0"),
new VersionRange("2011.110.5347.0", "2011.110.5522.0")
]);
pr.isNativeClient = true;
rules.push(pr);

rules.push(new DriverSelectorRule("^ODBC\\sDriver\\s\\d{1,8}(\\.\\d{1,8})?\\sfor\\sSQL\\sServer$",
"\\d{1,8}(\\.\\d{1,8})?(?=\\sfor\\sSQL\\sServer$)", "11.0", MAX_DRIVER_VERSION_STR,
[
new VersionRange("2014.120.4219.0", MAX_DRIVER_VERSION_STR),
new VersionRange("2014.120.2546.0", "2014.120.4000.0")
]));

pr = new DriverSelectorRule("^SQL\\sServer\\sNative\\sClient\\s\\d{1,8}(\\.\\d{1,8})?$",
"\\d{1,8}(\\.\\d{1,8})?$", "0", MAX_DRIVER_VERSION_STR, [new VersionRange("0", MAX_DRIVER_VERSION_STR)]);
pr.isNativeClient = true;
rules.push(pr);

rules.push(new DriverSelectorRule("^ODBC\\sDriver\\s\\d{1,8}(\\.\\d{1,8})?\\sfor\\sSQL\\sServer$",
"\\d{1,8}(\\.\\d{1,8})?(?=\\sfor\\sSQL\\sServer$)", "0", MAX_DRIVER_VERSION_STR,
[new VersionRange("0", MAX_DRIVER_VERSION_STR)]));

return rules;
};


// Get available drivers in the system and fill rules drivers
// TODO: rename method
DriverSelector.processSystemOdbcDrivers = function (rules, isProtocolsIntersected) {
arguments.callee.setAlias('DriverSelector.processSystemOdbcDrivers');

var registry = new Registry();
var keys = EnumerateRegistryKeyValues("HKEY_LOCAL_MACHINE", "SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers");
var drivers = keys.ValueNames;
var values = keys.ValueTypes;
for (var i = 0; i &lt; drivers.length; ++i) {
try {
if (values[i] !== RegistryValueTypes.REG_SZ) {
continue;
}
var isInstalled = registry.Read("HKEY_LOCAL_MACHINE\\SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers" + "\\" + drivers[i]);
if (isInstalled !== "Installed") {
continue;
}
var rule = null;
for (var j = 0; j &lt; rules.length; ++j) {
rule = rules[j];
if (rule.matchName(drivers[i])) {
// TODO: extract filtering
if (!rule.isNativeClient || (rule.isNativeClient &amp;&amp; isProtocolsIntersected)) {
var nameVersion = rule.getNameVersion(drivers[i]);
if (rule.checkNameVersion(nameVersion)) {
var driverVersion = rule.getDriverVersion(drivers[i]);
if (rule.checkDriverVersion(driverVersion)) {
var driverItem = new DriverItem(drivers[i], nameVersion, driverVersion, rule);
rule.addDriver(driverItem);
}
}
}
}
}
} catch (ex) {
addError(ex);
}
}
};


var UniqueCollection = function () {
var _dict = new ActiveXObject("Scripting.Dictionary");

this.put = function (item) {
if (!_dict.Exists(item)) {
_dict.add(item, '');
}
};

this.exists = function (item) {
return _dict.Exists(item);
};

this.get = function () {
return (new VBArray(_dict.Keys())).toArray();
};

this.clear = function () {
_dict.RemoveAll();
};
};

var UtcDateOperations = function () {
this.iso8601UtcStringToDate = function (sDate) {
var matches = /^(\d{4})-(\d\d)-(\d\d)(?:T|\s)(\d\d):(\d\d):(\d\d)Z$/g.exec(sDate);

if (!matches) {
throw new Exception("Input date string is in invalid format");
}

var year = parseInt(matches[1], 10);
var month = parseInt(matches[2], 10) - 1;
var day = parseInt(matches[3], 10);

var hour = parseInt(matches[4], 10);
var minute = parseInt(matches[5], 10);
var second = parseInt(matches[6], 10);

return new Date(Date.UTC(year, month, day, hour, minute, second));
};

this.checkSecondsElapsed = function (sDate, nSeconds) {
var utcNow = new Date();
var utcDate = this.iso8601UtcStringToDate(sDate);
return (((utcNow - utcDate) / 1000) &gt; nSeconds);
};
};

var Common = function () {
arguments.callee.setAlias('Common.constructor');
this.DEBUG = false;
this.ManagementGroupName = "$Target/ManagementGroup/Name$";
this.ManagementGroupID = "$Target/ManagementGroup/Id$";

this.SQL_SERVICE_DEFAULT_NAME = "MSSQLSERVER";

this.EscapeWQLString = function (wqlString) {
return wqlString.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
};

this.ParseInputBool = function (inputVal, allowEmpty, errorMessage) {
if (inputVal === null || inputVal === "") {
if (allowEmpty) {
return "true";
} else {
throw new Exception(errorMessage);
}
}
var supportedValues = ["true", "false", "t", "f", ".t.", ".f.", "1", "0"];
var replacements = ["true", "false", "true", "false", "true", "false", "true", "false"];

var processed = ("" + inputVal).trim().toLowerCase();
var pos = supportedValues.indexOf(processed);
if (pos &lt; 0) {
throw new Exception(errorMessage);
}
return replacements[pos];
};

this.EscapeConnStringValue = function (connStringValue) {
return '{' + connStringValue.replace(/}/g, '}}') + '}';
};

this.DelimitSqlIdentifier = function (identifier) {
return "[" + identifier.replace(/\]/g, "]]") + "]";
};

this.GetConnectionString = function (driverName, dataSource, databaseName) {
return "Driver=" + this.EscapeConnStringValue(driverName) + ";Server=" + this.EscapeConnStringValue(dataSource) + ";Database=" + this.EscapeConnStringValue(databaseName) + ";Trusted_Connection=yes;";
};

this.SqlTcpPortIsEmpty = function (tcpPort) {
return tcpPort == null || tcpPort === "" || tcpPort === "0";
};

this.GetEnabledSqlServerProtocols = function (namespaceName, computerName, instanceName) {
arguments.callee.setAlias('GetEnabledSqlServerProtocols');

// TODO [dem]: check computerName must be short version
var oWMI = new WMIProvider("root\\Microsoft\\SqlServer\\" + namespaceName, computerName);
var oQuery = oWMI.ExecQuery("SELECT ProtocolName, Enabled FROM ServerNetworkProtocol WHERE InstanceName = '" + this.EscapeWQLString(instanceName) + "'");
var protocolsArr = [];

if (oQuery.Count &gt; 0) {
for (var e = new Enumerator(oQuery); !e.atEnd(); e.moveNext()) {
if (e.item().Enabled) {
protocolsArr.push(e.item().ProtocolName.toLowerCase());
}
}
}
return protocolsArr;
};

this.GetSqlServerTcpIpSettings = function (instanceName, computerName) {
arguments.callee.setAlias('GetSqlServerTcpIpSettings');

var listenAllIps = false;
var e, e2, matches;
var uc = new UniqueCollection();
var ipSettings = new ActiveXObject("Scripting.Dictionary");
var portRegex = /(?:,|^)\s*([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])\s*(?=,|$)/g;
var oWMI = new WMIProvider("root\\Microsoft\\SqlServer\\ComputerManagement13", computerName);

var oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '" + this.EscapeWQLString(instanceName) + "' AND PropertyName = 'ListenOnAllIPs'");
if (oQuery.Count &gt; 0) {
e = new Enumerator(oQuery);
e.moveFirst();
var isListenAll = e.item();
if (isListenAll.PropertyNumVal === 1) {
listenAllIps = true;
}
}
if (listenAllIps) {
oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '" + this.EscapeWQLString(instanceName) + "' AND IPAddressName = 'IPAll' AND (PropertyName = 'TcpPort' OR PropertyName = 'TcpDynamicPorts') AND PropertyStrVal != ''");
if (oQuery.Count &gt; 0) {
for (e = new Enumerator(oQuery); !e.atEnd(); e.moveNext()) {
while (matches = portRegex.exec(e.item().PropertyStrVal)) {
if (!this.SqlTcpPortIsEmpty(matches[1])) {
uc.put(matches[1]);
}
}
}
ipSettings.add("IPAll", uc.get());
}
} else {
oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '" + this.EscapeWQLString(instanceName) + "' AND IPAddressName != '' AND PropertyName = 'Enabled' AND PropertyNumVal = 1");
if (oQuery.Count &gt; 0) {
for (e = new Enumerator(oQuery); !e.atEnd(); e.moveNext()) {
var ipAddress = '';
var ipAddressName = e.item().IPAddressName;
var oQuery2 = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '" + this.EscapeWQLString(instanceName) + "' AND IPAddressName = '" + this.EscapeWQLString(ipAddressName) + "' AND PropertyName = 'IpAddress' AND PropertyStrVal != ''");
if (oQuery2.Count &gt; 0) {
e2 = new Enumerator(oQuery2);
e2.moveFirst();
ipAddress = e2.item().PropertyStrVal;
} else {
continue;
}
oQuery2 = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '" + this.EscapeWQLString(instanceName) + "' AND IPAddressName = '" + this.EscapeWQLString(ipAddressName) + "' AND (PropertyName = 'TcpPort' OR PropertyName = 'TcpDynamicPorts') AND PropertyStrVal != ''");
uc.clear();
if (oQuery2.Count &gt; 0) {
for (e2 = new Enumerator(oQuery2); !e2.atEnd(); e2.moveNext()) {
while (matches = portRegex.exec(e2.item().PropertyStrVal)) {
if (!this.SqlTcpPortIsEmpty(matches[1])) {
uc.put(matches[1]);
}
}
}
try {
ipSettings.add(ipAddress, uc.get());
} catch (ex) {
}
}
}
}
}
return { listenAllIPs: listenAllIps, ipSettings: ipSettings };
};

this.GetSqlServiceName = function (instanceName) {
arguments.callee.setAlias('GetServiceName');

if (instanceName == this.SQL_SERVICE_DEFAULT_NAME) {
return instanceName;
}
return "MSSQL$" + instanceName;
};

this.GetWMISingleValue = function (wmiProvider, query, propertyName) {
arguments.callee.setAlias('GetWMISingleValue');

return (new Enumerator(wmiProvider.ExecQuery(query))).item()[propertyName];
};

this.GetCacheKey = function (stateMpPrefix, sKeyName) {
var oApi = new OpsMgrAPI();
var regKey = oApi.ScriptAPI.GetScriptStateKeyPath(this.ManagementGroupID);
regKey = regKey + "\\" + stateMpPrefix + "\\" + sKeyName;
return regKey;
};

this.GetStringValueFromCache = function (sKeyName, sValueName, cacheExpirationTime) {
var stateMpPrefix = "SQL2016MP";

var udo = new UtcDateOperations();
var oReg = new Registry();

try {
var regKey = this.GetCacheKey(stateMpPrefix, sKeyName);

var sValuePath = "HKEY_LOCAL_MACHINE\\" + regKey + "\\" + sValueName;
var sDatePath = sValuePath + "_CreationTime";

var sDate = oReg.Read(sDatePath);
var sValue = oReg.Read(sValuePath);

if (udo.checkSecondsElapsed(sDate, cacheExpirationTime)) {
return null;
}
return sValue;
} catch (ex) {
return null;
}
};

this.PutStringValueToCache = function (sKeyName, sValueName, sValue) {
var stateMpPrefix = "SQL2016MP";

var oReg = new Registry();

try {
var regKey = this.GetCacheKey(stateMpPrefix, sKeyName);

var sValuePath = "HKEY_LOCAL_MACHINE\\" + regKey + "\\" + sValueName;
var sDatePath = sValuePath + "_CreationTime";

var sDateUtc = (new Date()).toISO8601UtcString();

oReg.Write(sValuePath, sValue, "REG_SZ");
oReg.Write(sDatePath, sDateUtc, "REG_SZ");
} catch (ex) {
}
};

this.EscapeCacheValueName = function (name) {
return name.replace(/_/g, "__");
};

this.GetSqlServerHostName = function (strDNSComputerName, instanceName, namespace) {
arguments.callee.setAlias('GetSqlServerHostName');

var serviceName = this.GetSqlServiceName(instanceName);
var escapedServiceName = this.EscapeWQLString(serviceName);

var wmiProvider = new WMIProvider("ROOT\\Microsoft\\SqlServer\\" + namespace, strDNSComputerName);

var isClustered = this.GetWMISingleValue(wmiProvider, "SELECT PropertyNumValue FROM SqlServiceAdvancedProperty WHERE PropertyName = 'Clustered' AND SqlServiceType = 1 AND ServiceName = '" + escapedServiceName + "'", "PropertyNumValue");

var hostName = null;
if (isClustered === 0) {
hostName = this.GetWMISingleValue(wmiProvider, "SELECT HostName FROM SqlService WHERE SQLServiceType = 1 AND ServiceName = '" + escapedServiceName + "'", "HostName");
} else {
hostName = this.GetWMISingleValue(wmiProvider, "SELECT PropertyStrValue FROM SqlServiceAdvancedProperty WHERE PropertyName = 'VSNAME' AND SqlServiceType = 1 AND ServiceName = '" + escapedServiceName + "'", "PropertyStrValue");
}

return {
hostName: hostName,
isClustered: isClustered === 1 ? true : false
};
};

this.GetSqlServerHostNameEx = function (strDNSComputerName, instanceName, namespace) {
arguments.callee.setAlias('GetSqlServerHostNameEx');
var hostValueName = this.EscapeCacheValueName(strDNSComputerName);
var isClusteredValueName = hostValueName + "_IsClustered";
var cacheExpirationTime = 7200;

var hostName = this.GetStringValueFromCache("SqlHostNames", hostValueName, cacheExpirationTime);
if (hostName !== null) {
var isClusteredStr = this.GetStringValueFromCache("SqlHostNames", isClusteredValueName, cacheExpirationTime);
if (isClusteredStr !== null &amp;&amp; ((isClusteredStr === "1") || (isClusteredStr === "0"))) {
return {
hostName: hostName,
isClustered: isClusteredStr === "0" ? false : true
};

}
}

var hostNameData = this.GetSqlServerHostName(strDNSComputerName, instanceName, namespace);

this.PutStringValueToCache("SqlHostNames", hostValueName, hostNameData.hostName);
this.PutStringValueToCache("SqlHostNames", isClusteredValueName, hostNameData.isClustered ? "1" : "0");

return hostNameData;
};

this.GetLocalHostName = function () {
arguments.callee.setAlias('GetLocalHostName');

var wshShell = new ActiveXObject("WScript.Shell");
return wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
};

this.CheckConnectionTarget = function (dbConnection, hostName, instanceName) {
arguments.callee.setAlias('CheckConnectionTarget');

var destinationTestQuery = "select CAST(SERVERPROPERTY('MachineName') AS nvarchar(128)) as ServerName, @@servicename as InstanceName";

try {
var queryResult = dbConnection.ExecuteQuery(destinationTestQuery);
queryResult.MoveFirst();
if (!queryResult.EOF) {
var queryServerName = queryResult("ServerName").Value.toUpperCase();
var queryInstanceName = queryResult("InstanceName").Value.toUpperCase();

if (hostName.toUpperCase() === queryServerName &amp;&amp; instanceName.toUpperCase() === queryInstanceName) {
return;
}
throw new Exception("Connection target check failed: connected to " + hostName + "\\" + instanceName + ", but got " + queryServerName + "\\" + queryInstanceName + ".");
}
} catch (ex) {
if (dbConnection) {
dbConnection.Close();
}
throw ex;
}
};

this.GetDataSource = function (server, tcpPort) {
var dataSource = server;
if (!this.SqlTcpPortIsEmpty(tcpPort)) {
var nameParts = dataSource.split("\\");
dataSource = nameParts[0] + "," + tcpPort;
}
return dataSource;
};

this.BuildDataSourceFromParts = function (computerName, instanceName, tcpPort) {
var dataSource = computerName;
if (instanceName !== "MSSQLSERVER") {
dataSource = computerName + "\\" + instanceName;
}
return this.GetDataSource(dataSource, tcpPort);
};

this.GetAndCheckConnection = function (driverName, dataSource, databaseName, provider, timeout, hostName, instanceName) {
arguments.callee.setAlias('GetAndCheckConnection');

var connectionString = this.GetConnectionString(driverName, dataSource, databaseName);
var dbMasterConnection = new ADODB(connectionString, provider, timeout);
this.CheckConnectionTarget(dbMasterConnection, hostName, instanceName);
return dbMasterConnection;
};

this.SmartConnect = function (serverName, databaseName, tcpPort, machineName, instanceName) {
arguments.callee.setAlias('SmartConnect');

var dataSource;
var driverName;
var timeout;
var targetName = serverName;
var lastError = null;
var errorMessageColl = [];

var hostValueName = this.EscapeCacheValueName(machineName);
var instanceValueName = this.EscapeCacheValueName(instanceName);
var cacheExpirationTime = Number.MAX_VALUE;

var paramsPath = "SmartConnectParams" + "\\" + hostValueName + "\\" + instanceValueName
dataSource = this.GetStringValueFromCache(paramsPath, "TargetDataSource", cacheExpirationTime);
timeout = this.GetStringValueFromCache(paramsPath, "ConnectionTimeout", cacheExpirationTime);
netBiosHostName = this.GetStringValueFromCache("SqlHostNames", hostValueName, cacheExpirationTime);
driverName = this.GetStringValueFromCache(paramsPath, "DriverName", cacheExpirationTime);

if (dataSource != null &amp;&amp; timeout != null &amp;&amp; netBiosHostName != null &amp;&amp; driverName != null) {
try {
return this.GetAndCheckConnection(driverName, dataSource, databaseName, "", timeout, netBiosHostName, instanceName);
} catch (ex) {
lastError = ex;
errorMessageColl.push("Connection to data source '" + dataSource + "' failed: " + ex.message);
}
}

var netBiosHostNameData = this.GetSqlServerHostNameEx(machineName, instanceName, "ComputerManagement13");
var netBiosHostName = netBiosHostNameData.hostName;
var dnsHostName = machineName.split(".")[0];

var enabledServerProtocols = this.GetEnabledSqlServerProtocols("ComputerManagement13", machineName, instanceName);

var ds = new DriverSelector();
ds.processDrivers(enabledServerProtocols);
var hasErrors = ds.hasErrors();
var useFqdn = ds.getUseFqdn();
driverName = ds.getSelectedDriverName();

var connStr = serverName;
var result;
// Sql Server Shared Memory protocol require usage of host's NetBios name.
// Shared Memory usually the first in the driver's priority list.
// Rebuild data source string in the case of standalone Sql Server instance, NetBios host name differs
// from DNS host name and enabled Shared Memory on Client and Server
if (netBiosHostName !== dnsHostName &amp;&amp; !netBiosHostNameData.isClustered &amp;&amp; enabledServerProtocols.indexOf("sm") &gt;= 0 &amp;&amp; ds.getClientSharedMemoryProtocolEnabled) {
var localHostName = this.GetLocalHostName();
if (netBiosHostName === localHostName) {
connStr = "lpc:" + this.BuildDataSourceFromParts(netBiosHostName, instanceName, null);
}
}

//try to use SQL server browser
try {
dataSource = this.GetDataSource(connStr, "");
result = this.GetAndCheckConnection(driverName, dataSource, databaseName, "", 15, netBiosHostName, instanceName);
this.PutStringValueToCache(paramsPath, "DriverName", driverName);
this.PutStringValueToCache(paramsPath, "TargetDataSource", dataSource);
this.PutStringValueToCache(paramsPath, "ConnectionTimeout", 15);
return result;
} catch (ex) {
lastError = ex;
errorMessageColl.push("Connection to data source '" + dataSource + "' failed: " + ex.message);
}

if (enabledServerProtocols.indexOf("tcp") &gt;= 0 &amp;&amp; ds.getClientTcpProtocolEnabled()) {
var pathArray = serverName.split("\\");
var dsComputerName = pathArray[0];
targetName = useFqdn ? machineName : dsComputerName;

var tcpIpSettings = this.GetSqlServerTcpIpSettings(instanceName, dsComputerName);

if (tcpIpSettings.listenAllIPs) {
for (var j = 0; j &lt; tcpIpSettings.ipSettings.item("IPAll").length; j++) {
try {
dataSource = this.GetDataSource(targetName, tcpIpSettings.ipSettings.item("IPAll")[j]);
result = this.GetAndCheckConnection(driverName, dataSource, databaseName, "", 10, netBiosHostName, instanceName);
this.PutStringValueToCache(paramsPath, "DriverName", driverName);
this.PutStringValueToCache(paramsPath, "TargetDataSource", dataSource);
this.PutStringValueToCache(paramsPath, "ConnectionTimeout", 10);
return result;
} catch (ex) {
lastError = ex;
errorMessageColl.push("Connection to data source '" + dataSource + "' failed: " + ex.message);
}
}
} else {
var ipArr = (new VBArray(tcpIpSettings.ipSettings.Keys())).toArray();
var upc = new UniqueCollection();
for (var i = 0; i &lt; ipArr.length; i++) {
if (!upc.exists(tcpIpSettings.ipSettings.item(ipArr[i])[0])) {
upc.put(tcpIpSettings.ipSettings.item(ipArr[i])[0]);
try {
dataSource = this.GetDataSource(targetName, tcpIpSettings.ipSettings.item(ipArr[i])[0]);
result = this.GetAndCheckConnection(driverName, dataSource, databaseName, "", 10, netBiosHostName, instanceName);
this.PutStringValueToCache(paramsPath, "DriverName", driverName);
this.PutStringValueToCache(paramsPath, "TargetDataSource", dataSource);
this.PutStringValueToCache(paramsPath, "ConnectionTimeout", 15);
return reslut;
} catch (ex) {
lastError = ex;
errorMessageColl.push("Connection to data source '" + dataSource + "' failed: " + ex.message);
}
}
}
if (!useFqdn) {
for (var i1 = 0; i1 &lt; ipArr.length; i1++) {
var portArr = tcpIpSettings.ipSettings.item(ipArr[i1]);
for (var j1 = 0; j1 &lt; portArr.length; j1++) {
try {
dataSource = this.GetDataSource(ipArr[i1], tcpIpSettings.ipSettings.item(ipArr[i1])[j1]);
result = this.GetAndCheckConnection(driverName, dataSource, databaseName, "", 10, netBiosHostName, instanceName);
this.PutStringValueToCache(paramsPath, "DriverName", driverName);
this.PutStringValueToCache(paramsPath, "TargetDataSource", dataSource);
this.PutStringValueToCache(paramsPath, "ConnectionTimeout", 10);
return result;
} catch (ex) {
lastError = ex;
errorMessageColl.push("Connection to data source '" + dataSource + "' failed: " + ex.message);
}
}
}
}
}
}
throw new Exception("Cannot connect to the target Sql Server instance. Connection log:\n" + errorMessageColl.join("\n"), lastError);
};
};

var Exception = function (message, innerException) {
arguments.callee.setAlias('Exception.constructor');
this.message = message;
this.innerException = innerException;

var parts = [];
var collectArguments = function (caller) {
parts.push('(');
for (var i = 0; i &lt; caller.length; i++) {
if (typeof (caller[i]) !== 'undefined') {
parts.push(caller[i] === null ? 'null' : (typeof (caller[i].toString) === 'undefined' ? 'Object' : caller[i].toString()));
parts.push(',');
}
}
parts.pop();
parts.push(')');
parts.push(',\n');
};
var collectCallStack = function (caller) {
arguments.callee.setAlias('Exception.collectCallStack');
parts.push(caller.callee.getAlias ? caller.callee.getAlias() : 'anonymous');
collectArguments(caller);
var nextCaller = caller.caller;
if (nextCaller) {
collectCallStack(nextCaller);
}
};
collectCallStack(arguments);
this.callStack = parts.join('');

this.toString = function () {
arguments.callee.setAlias('Exception.toStringFull');
var toStringParts = [];
toStringParts.push(this.message);
toStringParts.push('\n');
if (this.innerException) {
if (this.innerException.number || this.innerException.description) {
toStringParts.push('Inner exception: \n');
if (this.innerException.number) {
toStringParts.push("Error Number : ");
toStringParts.push(this.innerException.number);
toStringParts.push('\n');
toStringParts.push("Error Code : ");
toStringParts.push(this.innerException.number &amp; 0xFFFF);
toStringParts.push('\n');
toStringParts.push("Win32 Facility : ");
toStringParts.push((this.innerException.number &gt;&gt; 16 &amp; 0x1FFF));
toStringParts.push('\n');
}
if (this.innerException.description) {
toStringParts.push("Error Description : ");
toStringParts.push(this.innerException.description);
toStringParts.push('\n');
}
}
}
toStringParts.push('Call stack:');
toStringParts.push(this.callStack);
return toStringParts.join('');
};
};

var OpsMgrAPI = function () {
arguments.callee.setAlias('MOMAPI.constructor');
var scriptAPI;
try {
scriptAPI = new ActiveXObject('MOM.ScriptAPI');
} catch (e) {
throw new Exception("Application cannot create MOM.ScriptAPI ActiveX object.", e);
}
this.ScriptAPI = scriptAPI;

this.ErrorReturnEmptyDiscovery = function (sourceId, managedEntityId) {
var discoveryData = this.ScriptAPI.CreateDiscoveryData(0, sourceId, managedEntityId);
discoveryData.IsSnapshot = false;
this.ScriptAPI.Return(discoveryData);
};
};

var Logger = function () {
arguments.callee.setAlias('Logger.constructor');
this.common = new Common();
this.messageType = {
error: 1,
warning: 2,
information: 4
};

var opsMgrAPI = new OpsMgrAPI();

this.LogError = function (eventId, logMessage) {
arguments.callee.setAlias('Logger.LogError');
opsMgrAPI.ScriptAPI.LogScriptEvent("Management Group: " + this.common.ManagementGroupName + ". Script: " + WScript.ScriptName + ". Version: " + MANAGEMENT_PACK_VERSION, eventId, this.messageType.error, logMessage);
};
this.LogError2 = function (instanceName, eventId, logMessage) {
arguments.callee.setAlias('Logger.LogError2');
opsMgrAPI.ScriptAPI.LogScriptEvent("Management Group: " + this.common.ManagementGroupName + ". Script: " + WScript.ScriptName + ". Version: " + MANAGEMENT_PACK_VERSION + ". Instance: " + instanceName, eventId, this.messageType.error, logMessage);
};
this.LogWarning = function (eventId, logMessage) {
arguments.callee.setAlias('Logger.LogWarning');
opsMgrAPI.ScriptAPI.LogScriptEvent("Management Group: " + this.common.ManagementGroupName + ". Script: " + WScript.ScriptName + ". Version: " + MANAGEMENT_PACK_VERSION, eventId, this.messageType.warning, logMessage);
};
this.LogInformation = function (eventId, logMessage) {
arguments.callee.setAlias('Logger.LogInformation');
opsMgrAPI.ScriptAPI.LogScriptEvent("Management Group: " + this.common.ManagementGroupName + ". Script: " + WScript.ScriptName + ". Version: " + MANAGEMENT_PACK_VERSION, eventId, this.messageType.information, logMessage);
};
this.LogDebug = function (eventId, logMessage) {
if (this.common.DEBUG) {
arguments.callee.setAlias('Logger.LogDebug');
opsMgrAPI.ScriptAPI.LogScriptEvent("Management Group: " + this.common.ManagementGroupName + ". Script: " + WScript.ScriptName + ". Version: " + MANAGEMENT_PACK_VERSION, eventId, this.messageType.information, logMessage);
}
};
this.LogCustomInfo = function (param1, eventId, logMessage) {
arguments.callee.setAlias('Logger.LogCustomInfo');
opsMgrAPI.ScriptAPI.LogScriptEvent(param1, eventId, this.messageType.information, logMessage);
};
};

var ADODB = function (connectionString, provider, connectionTimeout) {
arguments.callee.setAlias('ADODB.constructor');
if (!connectionString) {
throw new Exception("Connection string cannot be null or empty string");
}

this.connectionTimeout = connectionTimeout ? connectionTimeout : 30;

var connection;
try {
connection = new ActiveXObject("ADODB.Connection");
} catch (e) {
throw new Exception("Can't create ActiveXObject 'ADODB.Connection'", e);
}

if (provider) {
connection.Provider = provider;
}

connection.ConnectionTimeout = this.connectionTimeout;
connection.ConnectionString = connectionString;
connection.CommandTimeout = 60;
this.provider = connection.Provider;

try {
connection.Open();
} catch (e) {
throw new Exception("Can't connect to SQL Server. Connection string : '" + connectionString + "'. Error description: " + e.message, e);
}

this.ExecuteQuery = function (query) {
arguments.callee.setAlias('ADODB.ExecuteQuery');
var dbSet;
try {
dbSet = connection.Execute(query);
} catch (e) {
throw new Exception("Can't execute query '" + query + "': " + e.message, e);
}
return dbSet;
};

this.ExecuteQueryWithParams = function (query) {
arguments.callee.setAlias('ADODB.ExecuteQueryWithParams');
if (arguments.length &lt;= 1) {
throw new Exception("Can't go without any params");
}
var dbSet;
try {
var command = new ActiveXObject("ADODB.Command");
command.ActiveConnection = connection;
command.CommandText = query;
command.CommandType = 1; // adCmdText
for (var i = 1; i &lt; arguments.length; i++) {
this.AddParam(command, arguments[i]);
}
dbSet = command.Execute();
} catch (e) {
throw new Exception("Can't execute query '" + query + "': " + e.message, e);
}
return dbSet;
};

this.AddParam = function (cmd, value) {
var parameter;
switch (typeof value) {
case "number":
parameter = cmd.CreateParameter("", 20, 1, 8, value); // , adBigInt, adParamInput
break;
case "string":
parameter = cmd.CreateParameter("", 202, 1, Math.max(value.length, 1), value); // , adVarWChar, adParamInput
break;
default:
throw new Exception("Unknown parameter type: " + typeof value);
}
cmd.Parameters.Append(parameter);
};

this.Close = function () {
arguments.callee.setAlias('ADODB.Close');
try {
if (connection &amp;&amp; connection.State != 0) {
connection.Close();
}
}
catch (e) {
throw new Exception("Can't close connection.", e);
}
};
};

var Registry = function () {
arguments.callee.setAlias('Registry.constructor');
var registry;
try {
registry = new ActiveXObject("WScript.Shell");
} catch (e) {
throw new Exception("Can't create ActiveXObject 'WScript.Shell'", e);
}

this.Write = function (key, value, type) {
arguments.callee.setAlias('Registry.Write');
try {
if (type) {
registry.RegWrite(key, value, type);
} else {
registry.RegWrite(key, value);
}
} catch (e) {
throw new Exception("Can't write value '" + value.toString() + "' by registry key '" + key.toString() + "'.", e);
}
};
this.Read = function (key) {
arguments.callee.setAlias('Registry.Read');
var value;
try {
value = registry.RegRead(key);
} catch (e) {
throw new Exception("Can't read value from registry key '" + key.toString() + "'.", e);
}
return value;
};
this.IsKeyExists = function (key) {
arguments.callee.setAlias('Registry.IsKeyExists');
var result;
try {
registry.RegRead(key);
result = true;
} catch (e) {
result = false;
}
return result;
};
this.Delete = function (key) {
arguments.callee.setAlias('Registry.Delete');
var value;
try {
value = registry.RegDelete(key);
} catch (e) {
throw new Exception("Can't delete registry key '" + key.toString() + "'.", e);
}
return value;
};
};

var WMIProvider = function (wmiNamespace, computerName) {
arguments.callee.setAlias('WMIProvider.constructor');
this.wmiNamespace = wmiNamespace;
this.computerName = computerName || ".";
var sWbemLocator;
try {
sWbemLocator = new ActiveXObject("WbemScripting.SWbemLocator");
} catch (e) {
throw new Exception("Cannot create 'WbemScripting.SWbemLocator' object.", e);
}
this.SWbemLocator = sWbemLocator;

var wmiService;
try {
wmiService = this.SWbemLocator.ConnectServer(this.computerName, this.wmiNamespace);
} catch (e) {
throw new Exception("Cannot connect to WMI of computer '" + this.computerName + "' by namespace '" + this.wmiNamespace + "'.", e);
}
this.WMIService = wmiService;

this.ExecQuery = function (query) {
arguments.callee.setAlias('WMIProvider.ExecQuery');
var result = null;
try {
result = this.WMIService.ExecQuery(query, "WQL", 0x0);
} catch (e) {
throw new Exception("Cannot execute WMI query '" + query + "'.", e);
}
return result;
};
};

var DBHelper = function () {
arguments.callee.setAlias('DBHelper.constructor');
this.EVENT_ID = 4211;
this.DatabaseState = {
ONLINE: 0,
RESTORING: 1,
RECOVERING: 2,
RECOVERY_PENDING: 3,
SUSPECT: 4,
EMERGENCY: 5,
OFFLINE: 6
};
this.common = new Common();
this.logger = new Logger();

this.IsRunningInstanceSQLServer = function (sqlInstanceName, computerName) {
arguments.callee.setAlias('IsRunningInstanceSQLServer');
var isRunning = false;
try {
var wmiProvider = new WMIProvider("root\\Microsoft\\SqlServer\\ComputerManagement13", computerName);
var sqlService = wmiProvider.ExecQuery("select state from SqlService WHERE (ServiceName = '" + this.common.EscapeWQLString(sqlInstanceName) + "' OR ServiceName = 'MSSQL$" + this.common.EscapeWQLString(sqlInstanceName) + "') and SQLServiceType ='1'");

if (sqlService.Count &gt; 0) {
var e = new Enumerator(sqlService);
e.moveFirst();
var sqlServiceObject = e.item();

if (sqlServiceObject.State === 4) {
isRunning = true;
}
}
} catch (exception) {
}
return isRunning;
};

this.GetDatabaseExcludeList = function (instanceName) {
arguments.callee.setAlias('GetDatabaseExcludeList');
var databaseExcludeList = "";
try {
var opsMgrAPI = new OpsMgrAPI();
var registryKey = opsMgrAPI.ScriptAPI.GetScriptStateKeyPath(this.common.ManagementGroupID);
this.logger.LogDebug(this.EVENT_ID, "ScriptStateKeyPath: " + registryKey);

var registry = new Registry();
var databaseExcludeListKey = "HKEY_LOCAL_MACHINE\\" + registryKey + "\\" + instanceName + "\\DatabaseExcludeList";
if (registry.IsKeyExists(databaseExcludeListKey)) {
databaseExcludeList = registry.Read(databaseExcludeListKey);
databaseExcludeList = databaseExcludeList.replace(/(^\s+)|(\s+$)/g, "");
if (databaseExcludeList !== '*') {
var excludeDatabases = databaseExcludeList.split(",");
for (var i = 0; i &lt; excludeDatabases.length; i++) {
excludeDatabases[i] = excludeDatabases[i].replace(/(^\s+)|(\s+$)/g, "");
}
databaseExcludeList = excludeDatabases.join(",");
}
}
} catch (e) {
throw new Exception("Can't read database exclude list from registry.", e);
}
return databaseExcludeList;
};

// Returns -1: If DB is not in AlwaysOn
// Returns 0: If DB is in AlwaysOn and replica allow connections is NO
// Returns 1: If DB is in AlwaysOn and replica allow connections is YES
this.AlwaysOnReplicaAllowConnections = function (aDbConnection, aDatabaseID) {
var query = " SELECT columns.id, " +
" CASE WHEN OBJECT_ID('sys.availability_replicas') IS NOT NULL THEN 1 ELSE 0 END AS HasAlwaysOn " +
" FROM master.sys.syscolumns columns where name = 'replica_id' and id = OBJECT_ID('sys.databases')";

var result = aDbConnection.ExecuteQuery(query);
if (!result.EOF) {
result.MoveFirst();
if (result("HasAlwaysOn").Value === 1) {
query = "SELECT d.name, d.database_id, drs.is_primary_replica AS db_is_primary_replica " +
", CASE WHEN d.replica_id IS NULL THEN 0 ELSE 1 END AS is_replica " +
", CASE WHEN drs.is_primary_replica = 1 THEN ar.primary_role_allow_connections ELSE ar.secondary_role_allow_connections END AS role_allow_connections " +
", CASE WHEN drs.is_suspended = 0 THEN -1 ELSE suspend_reason END AS db_suspended_state " +
" FROM sys.databases as d " +
" JOIN sys.dm_hadr_database_replica_states drs ON drs.database_id = d.database_id " +
" JOIN sys.availability_replicas ar on d.replica_id = ar.replica_id WHERE drs.is_local = 1 AND d.database_id = ?";

result = aDbConnection.ExecuteQueryWithParams(query, aDatabaseID);
if (!result.EOF) {
if (result("is_replica").Value === 1) {
if (result("role_allow_connections").Value &lt;= 1) {
return 0;
} else {
if ((result("db_suspended_state").Value &gt; 0) &amp;&amp;
(!result("db_is_primary_replica").Value || (result("db_is_primary_replica").Value &amp;&amp; result("db_suspended_state").Value !== 5))) {
return 0;
}
return 1;
}
}
}
}
}
return -1;
};
};

var ServicesHelper = function () {
arguments.callee.setAlias('ServicesHelper.constructor');

this.EVENT_ID = 4211;
this.IsServiceUnavailable = "ServiceUnavailable";
this.logger = new Logger();
this.common = new Common();

this.GetServiceUnavailableRegistryKey = function (serviceName) {
arguments.callee.setAlias('GetRegistryKeyForService');
var opsMgrAPI = new OpsMgrAPI();
var registryKey = opsMgrAPI.ScriptAPI.GetScriptStateKeyPath(this.common.ManagementGroupID);
var key = "HKEY_LOCAL_MACHINE\\" + registryKey + "\\" + serviceName + "\\";
return key;
};

this.ReturnServiceStateToOpsMgr = function (serviceState) {
var opsMgrAPI = new OpsMgrAPI();
this.logger.LogDebug(this.EVENT_ID, "Return to OpsMgr state of service = " + serviceState);
var propertyBag = opsMgrAPI.ScriptAPI.CreatePropertyBag();
propertyBag.AddValue("ServiceState", serviceState);
opsMgrAPI.ScriptAPI.AddItem(propertyBag);
opsMgrAPI.ScriptAPI.ReturnItems();
};
};
//#Include File:GetSQL2016DBConfig.js
// Copyright (c) Microsoft Corporation. All rights reserved.
// Parameters that should be passed to this script
// 0 connectionString
// 1 Computer (FQDN) that SQL instance is hosted on
// 2 SQL Instance that this rule is being run for
// 3 Pre-discovered TCP port

var DatabaseOption = function (dbRow) {
arguments.callee.setAlias('DatabaseOption.constructor');

var boolOptions = new Array(2);
boolOptions[1] = "OFF";
boolOptions[2] = "ON";

var pageVerifyOption = Array(3);
pageVerifyOption[1] = "NONE";
pageVerifyOption[2] = "TORN_PAGE_DETECTION";
pageVerifyOption[3] = "CHECKSUM";

var recoveryModelOptions = Array(3);
recoveryModelOptions[1] = "FULL";
recoveryModelOptions[2] = "BULK_LOGGED";
recoveryModelOptions[3] = "SIMPLE";

this.AutoUpdateSet = boolOptions[dbRow("is_auto_update_stats_on").Value + 1];
this.AutoUpdateAsyncStat = boolOptions[dbRow("is_auto_update_stats_async_on").Value + 1];

var isDbChainingOn = dbRow("is_db_chaining_on").Value;
this.DBChaining = isDbChainingOn !== 'N/A' ? boolOptions[parseInt(isDbChainingOn) + 1] : isDbChainingOn;

this.AutoClose = boolOptions[dbRow("is_auto_close_on").Value + 1];
this.AutoShrink = boolOptions[dbRow("is_auto_shrink_on").Value + 1];
this.AutoCreateStat = boolOptions[dbRow("is_auto_create_stats_on").Value + 1];

var isTrustworthyOn = dbRow("is_trustworthy_on").Value;
this.TrustWorthy = isTrustworthyOn !== 'N/A' ? boolOptions[parseInt(isTrustworthyOn) + 1] : isTrustworthyOn; //dbRow("is_trustworthy_on").Value + 1];

this.PageVerify = pageVerifyOption[dbRow("page_verify_option").Value + 1];
this.RecoveryModel = recoveryModelOptions[dbRow("recovery_model").Value];
};

var GetSQL2016DBConfig = function () {
arguments.callee.setAlias('GetSQL2016DBConfig.constructor');

this.EVENT_ID = 4211;

this.common = new Common();
this.dbHelper = new DBHelper();
this.logger = new Logger();

this.MainFunc = function (serverName, targetComputer, instanceName, tcpPort) {
arguments.callee.setAlias('Main');

var opsMgrAPI = new OpsMgrAPI();
var propertyBag = opsMgrAPI.ScriptAPI.CreatePropertyBag();

if (!this.dbHelper.IsRunningInstanceSQLServer(instanceName, targetComputer)) {
opsMgrAPI.ScriptAPI.Return(propertyBag);
return;
}

try {
var dbConnection = this.common.SmartConnect(serverName, "master", tcpPort, targetComputer, instanceName);

var dbSet = dbConnection.ExecuteQuery("SELECT db.name, " +
" db.[is_auto_update_stats_on] " +
",db.[page_verify_option] " +
",CASE db.name " +
" when 'tempdb' then 'N/A' " +
" when 'master' then 'N/A' " +
" when 'msdb' then 'N/A' " +
" else STR (db.[is_db_chaining_on]) end as is_db_chaining_on " +
",db.[is_auto_close_on] " +
",db.[is_auto_shrink_on] " +
",db.[is_auto_create_stats_on] " +
",db.[is_auto_update_stats_async_on] " +
",CASE db.name " +
" when 'tempdb' then 'N/A' " +
" when 'master' then 'N/A' " +
" when 'msdb' then 'N/A' " +
" else STR (db.[is_trustworthy_on]) end as is_trustworthy_on " +
",db.[recovery_model] " +
"FROM sys.databases as db " +
"WHERE db.source_database_id IS NULL ORDER BY name");

for (dbSet.MoveFirst() ; !dbSet.EOF; dbSet.MoveNext()) {
var dbName = dbSet("name").Value;
var dbOption = new DatabaseOption(dbSet);
propertyBag.AddValue(dbName + "-AutoUpdateSet", dbOption.AutoUpdateSet);
propertyBag.AddValue(dbName + "-AutoUpdateAsyncStat", dbOption.AutoUpdateAsyncStat);
propertyBag.AddValue(dbName + "-DBChaining", dbOption.DBChaining);
propertyBag.AddValue(dbName + "-AutoClose", dbOption.AutoClose);
propertyBag.AddValue(dbName + "-AutoShrink", dbOption.AutoShrink);
propertyBag.AddValue(dbName + "-AutoCreateStat", dbOption.AutoCreateStat);
propertyBag.AddValue(dbName + "-TrustWorthy", dbOption.TrustWorthy);
propertyBag.AddValue(dbName + "-PageVerify", dbOption.PageVerify);
propertyBag.AddValue(dbName + "-RecoveryModel", dbOption.RecoveryModel);
}
dbConnection.Close();
opsMgrAPI.ScriptAPI.Return(propertyBag);
} catch (e) {
var parts = serverName.split('\\');
serverName = parts[0];
if (e.innerException &amp;&amp; (e.innerException.number &amp; 0xFFFF) === 16389) { // Login failed
this.logger.LogError(this.EVENT_ID, "Cannot login to database [" + serverName + "][" + instanceName + ":master] ");
} else {
throw new Exception("Script '" + WScript.ScriptName + "' failed.", e);
}
}
};

this.Launch = function (args) {
if (args.Count() !== 4) {
WScript.Quit();
}
var serverName = args(0);
var targetComputer = args(1);
var instanceName = args(2);
var tcpPort = args(3);

arguments.callee.setAlias('Launch');
try {
this.MainFunc(serverName, targetComputer, instanceName, tcpPort);
} catch (e) {
this.logger.LogError(this.EVENT_ID, e.toString());
}
};
};

new GetSQL2016DBConfig().Launch(WScript.Arguments);</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>