如何以编程方式设置群集资源“使用网络名称作为计算机名称”复选框?

时间:2018-11-15 07:55:22

标签: windows wmi windows-clustering

我正在使用Windows MI API(Microsoft.Management.Infrastructure)以编程方式设置群集资源(特别是通用服务)。

我可以添加服务资源。但是,我的服务要求选中“使用网络名作为计算机名”复选框(在Cluster Manager UI中,通过查看该资源的属性即可使用此复选框。)

我不知道如何使用MI API进行设置。我已经在MSDN和其他许多资源中进行了搜索,但是没有运气。有人知道这是否可能吗?使用Powershell编写脚本也可以。

1 个答案:

答案 0 :(得分:0)

经过大量的尝试和错误,并在此过程中发现了API错误,我得以弄清这一点。

事实证明,集群资源对象具有一个名为PrivateProperties的属性,该属性基本上是一个属性包。在内部,有一个名为UseNetworkName的属性,它与UI中的复选框相对应(还有ServiceName属性,这对于正常工作也是必需的。)

“ wbemtest”工具在找出这一点方面非常宝贵。在其中打开资源实例后,您必须双击PrivateProperties属性以打开一个对话框,其中包含“查看嵌入”按钮,然后该对话框将向您显示内部属性。我以前以某种方式错过了它。

现在,设置此属性是另一个麻烦。由于看起来像bug in the API,因此使用CimSession.GetInstance()检索资源实例不会填充属性值。这使我误以为我必须自己添加PrivateProperties属性及其内部属性,这只会导致很多隐秘的错误。

我最终偶然发现了这个old MSDN post,在那里我意识到该属性是动态的,并由WMI自动设置。因此,最后,您要做的就是知道如何使用CimSession.QueryInstances()获取属性包,以便像其他任何属性一样设置内部属性。

这就是整个样子(我省略了添加资源的代码):

using (var session = CimSession.Create("YOUR_CLUSTER", new DComSessionOptions()))
{
    // This query finds the newly created resource and fills in the
    // private props we'll change. We have to do a manual WQL query
    // because CimSession.GetInstance doesn't populate prop values.
    var query =
        "SELECT PrivateProperties FROM MSCluster_Resource WHERE Id=\"{YOUR-RES-GUID}\"";

    // Lookup the resource. For some reason QueryInstances does not like
    // the namespace in the regular form - it must be exactly like this
    // for the call to work!
    var res = session.QueryInstances(@"root/mscluster", "WQL", query).First();

    // Add net name dependency so setting UseNetworkName works.
    session.InvokeMethod(
        res,
        "AddDependency",
        new CimMethodParametersCollection
        {
            CimMethodParameter.Create(
                "Resource", "YOUR_NET_NAME_HERE", CimFlags.Parameter)
        });

    // Get private prop bag and set our props.
    var privProps =
        (CimInstance)res.CimInstanceProperties["PrivateProperties"].Value;
    privProps.CimInstanceProperties["ServiceName"].Value = "YOUR_SVC_HERE";
    privProps.CimInstanceProperties["UseNetworkName"].Value = 1;

    // Persist the changes.
    session.ModifyInstance(@"\root\mscluster", res);
}

请注意API中的怪癖如何使事情变得比应有的复杂:QueryInstances以特殊的方式期望名称空间,并且,如果您不首先添加网络名称依赖项,则设置私有属性会自动失败。 / p>

最后,我还想出了如何通过PowerShell进行设置。您必须使用Set-ClusterParameter命令,有关完整信息,请参见this other answer