views:

163

answers:

4

Does anyone know how to programatically detect that a Windows server is part of a cluster?

Further, is it possible to detect that the server is the active or passive node?

[Edit] And detect it from Win32? A registry setting maybe?

Thanks for any insight.

Doug

A: 

Any specific language you're looking for?

You might be able to employ the failover cluster cmdlets for Powershell (for Windows Server 2008 R2). Specifically Get-Cluster and Get-ClusterNode

squillman
Thanks. I need it for Win32, but that is a starting point for me to at least look at.
DougN
A: 

Go to msdn.microsoft.com, and search for 'Windows Clustering'.

There's a ton of information there.

bmargulies
A: 

I don't have an exact answer, but there are lots of APIs beginning with "Cluster" (like ClusterOpenEnum and ClusterNodeEnum) and COM interfaces beginning with "IGetCluster" that look promising.

Michael Dunn
Come on. This is a good question that deserves some votes!
Dr. Xray
+1  A: 

You can use WMI to lookup the information. That should work from XP/Win32 etc.

There is some great information here on using VBScript to do the job: http://www.activexperts.com/activmonitor/windowsmanagement/scripts/networking/clustering/

Here's some C#/.Net code that also uses WMI:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Management;

namespace SandboxConsole
{
    public class ClusterAdmin
    {
     [MTAThread]
     public static void Main()
     {
      string clusterName = "MyCluster"; // cluster alias
      string custerGroupResource = "FS_Resource1"; // Cluster group name
      ConnectionOptions options = new ConnectionOptions();
      options.Username = "ClusterAdmin"; //could be in domain\user format
      options.Password = "HisPassword";

      // Connect with the mscluster WMI namespace on the cluster named "MyCluster"
      ManagementScope s = new ManagementScope("\\\\" + clusterName + "\\root\\mscluster", options);
      ManagementPath p = new ManagementPath("Mscluster_Clustergroup.Name='" + custerGroupResource + "'");

      using (ManagementObject clrg = new ManagementObject(s, p, null))
      {
       // Take clustergroup off line and read its status property when done
       TakeOffLine(clrg);
       clrg.Get();
       Console.WriteLine(clrg["Status"]);

       System.Threading.Thread.Sleep(3000); // Sleep for a while

       // Bring back online and get status.
       BringOnLine(clrg);
       clrg.Get();
       Console.WriteLine(clrg["Status"]);
      }
     }
     static void TakeOffLine(ManagementObject resourceGroup)
     {
      ManagementBaseObject outParams =
      resourceGroup.InvokeMethod("Takeoffline", null, null);
     }
     static void BringOnLine(ManagementObject resourceGroup)
     {
      ManagementBaseObject outParams =
      resourceGroup.InvokeMethod("Takeoffline", null, null);
     }
    }
}

I found this code here and tidied it up a little.

Stuntbeaver
And this is a good answer!
Dr. Xray