Po$H Pete | Those who can… $cript
21Jan/111

Finding Which Cluster Node a Resource is Currently Via Powershell & WMI

From working with windows server clusters pretty much daily for the last 10 years, one of the annoyances I've had is that it's not always easy to know which node of a cluster a resource is currently running on. Particularly if it's an Active/Active(/Active/Active/Active!) configuration. As each node in a cluster is aware of the cluster and it's state, it's possible to remotely query WMI on any one of the cluster nodes to find out where your desired resource currently resides.

The function I've written below takes 2 parameters currently:

$Server - The single node of a cluster you want to query
$Verbose - This will tell the script to do a bit deeper querying and return more info to you.

I've made a slight change to this version which I'm putting up here as I have other ways of obtaining the server credential object, however, in this case the first thing the script does is attempt to build a credential object with the relevant credentials for the server it's going to query. You will get prompted :-) You can change this however you see fit. I'll write another blog post shortly on how to create credential objects from plain text strings (not best practice, but you may need to do it for some reason).

If you run the script as:

Get-ClusterNodeInfo MyServerName

You will firstly be prompted for a password for the remote server. The data will then return as a formatted table with 2 columns, "Nodes" and "Group" listing the resource groups on each node.

If you run the script as:

Get-ClusterNodeInfo MyServerName -Verbose

You will get an expanded view of the same data with the columns, "Node","Group,"Resource","State". As you can guess, it is a more "Verbose" output which lists each of the resources inside of each cluster group and their current state ID.

Here's the function:

Function Get-ClusterNodeInfo($Server,[SWITCH]$Verbose)
{
 
$Credentials = Get-Credential
 
If($Verbose)
 
{
 
	$maps = gwmi -Namespace root\mscluster -Class mscluster_nodetoactiveresource -computer $server -Credential $Credentials -authentication 6
	$MapTable = @()
	ForEach($Map in $maps)
	{
		$ARow = ""|Select Node,Resource
		$ARow.Node = $Map.GroupComponent.ToString().Split("=")[1]
		$ARow.Node = $ARow.Node.SubString(0,$ARow.Node.Length-1)
		$ARow.Node = $ARow.Node.SubString(1,$ARow.Node.Length-1)
		$ARow.Resource = $Map.PartComponent.ToString().Split("=")[1]
		$ARow.Resource = $ARow.Resource.Substring(0,$ARow.Resource.Length-1)
		$ARow.Resource = $ARow.Resource.Substring(1,$ARow.Resource.Length-1).replace("\\","\")
		$MapTable += $ARow
	}
 
	$resourcemaps = gwmi -Namespace root\mscluster -Class mscluster_resourcegrouptoresource -computer $server -Credential $Credentials -authentication 6
	$MapTableb = @()
	ForEach($Map in $resourcemaps)
	{
		$ARow = ""|Select Node,Resource
		$ARow.Node = $Map.GroupComponent.ToString().Split("=")[1]
		$ARow.Node = $ARow.Node.SubString(0,$ARow.Node.Length-1)
		$ARow.Node = $ARow.Node.SubString(1,$ARow.Node.Length-1)
		$ARow.Resource = $Map.PartComponent.ToString().Split("=")[1]
		$ARow.Resource = $ARow.Resource.Substring(0,$ARow.Resource.Length-1)
		$ARow.Resource = $ARow.Resource.Substring(1,$ARow.Resource.Length-1).replace("\\","\")
		$MapTableb += $ARow
	}
 
	$statemaps = gwmi -Namespace root\mscluster -Class mscluster_resource -Property Name,State -computer $server -Credential $Credentials -authentication 6
 
	$FinalTable = @()
	ForEach($Res in $MapTable)
	{
		$ARow = ""|Select Node,Group,Resource,State
		$ARow.Node = $Res.Node
		$ARow.Resource = $Res.Resource
		ForEach($Resb in $MapTableb)
		{
			if($Resb.Resource -eq $Res.Resource)
			{
				$ARow.Group = $Resb.Node
			}
		}
		ForEach($State in $statemaps)
		{
			if($State.Name -eq $Res.Resource)
			{
				$ARow.State = $State.state
			}
		}
		$FinalTable += $ARow
	}
 
	$FinalTable = $FinalTable | Sort-Object -Property Node,Group,Resource
	Return $FinalTable
}
Else
{
 
	$maps = gwmi -Namespace root\mscluster -Class mscluster_nodetoactivegroup -computer $server -Credential $Credentials -authentication 6
	$MapTable = @()
	ForEach($Map in $maps)
	{
		$ARow = ""|Select Node,Group
		$ARow.Node = $Map.GroupComponent.ToString().Split("=")[1]
		$ARow.Node = $ARow.Node.SubString(0,$ARow.Node.Length-1)
		$ARow.Node = $ARow.Node.SubString(1,$ARow.Node.Length-1)
		$ARow.Group = $Map.PartComponent.ToString().Split("=")[1]
		$ARow.Group = $ARow.Group.Substring(0,$ARow.Group.Length-1)
		$ARow.Group = $ARow.Group.Substring(1,$ARow.Group.Length-1)
		$MapTable += $ARow
	}
	$MapTable = $MapTable | Sort-Object -Property Node,Group
	Return $MapTable
}
 
 
 
}