I'm writing a cluster resource script that is checking the cluster resources, which node they are on and node online/offline status
Right now I'm stuck in the output part, in the pipe I have the following data:
clusterresource1 node1 online
clusterresource2 node2 online
clusterresource3 node3 online
..and so on. My wish is that I could somehow link each post/word to a own variable-
ex: $a1 = clusterresource1
$a2 = node1
$a3 = online
I hope someone can point me in the right direction
Hello Ironbone.
For sure, the objects coming down your pipeline have properties that you can access by name. You could store the result of the object-pipeline in a variable ($objects), and then - to get more information - pipe that variable to the Get-Member Cmdlet:
$objects = @(...) # the pipeline that you did not provide in your post inside the brackets
$objects | Get-Member
(The @(...) makes sure that the results are treated as an array, even if only one object is returned. When you have found out what the names of the properties are (for example ClusterResource, Node and Status), you can use these names in the script to access them. Since the variable $objects is an array, you can determine the number of elements ($objects.Count) and access each element by an index between 0 and ($objects.Count - 1), for example
$objects[0].ClusterResource
The output in your script already looks like a nice table. What more are you planning to format? Have a look at the Format-Table Cmdlet, it also supports the use of calculated columns defined by hashtables.
Best regards,Wolfgang
Hi Wolfgang
Thank you for the help! I do have some problem grasping everything you wrote.
Lets say that I do the following:
$objects = @(cluster clustername group clustergroup /status | select-string -pattern "nodename"
#That gives me the follwing output in $objects:
$objects | get-member gives me alot of things like PSPath, substring etc etc but can I make so that $objects[1].Clusterresource would represent clusterresource1. $objects[2].Clusterresource would represent clustersource2 etc?
That's what I was intending, numbering starts with 0, so I wanted $objects[0] to represent the first line of output. Unfortunately, the cluster commandline tool produces strings that have to be split somehow. I case the that your names do not contain spaces, the following might work:
$lines = @(cluster clustername group clustergroup /status | Select-String -Pattern "nodename") $objects = $lines | ForEach-Objecth {$parts = ($_ -replace " +", " ").Split(" "); New-Object PSObject -Property @{ClusterResource=$parts[0];Node=$parts[1];Status=$parts[2]}} $objects | Format-Table ClusterResource, Node, Status -AutoSize
Otherwise, you could use wmi with the classes of the root\mscluster namespace to retrieve the desired information.
-- Regards,Wolfgang
Those lines were great!
now $objects is the first line, parts[0] is the first "word" and so on.... How does the index count?
[0] [1] [2]
[1,0] [1,1] [1,2]
...... ..... .......
..... .... .....
?
It would be great to have one variable for each "data post".
The $parts variable was only intended to be used inside the loop to generate the properties of new objects. The properties are ClusterResource, Node and Status. The object representing the first resource was ment to be accessed with $objects[0] and you should have been able to access it's properties using $objects[0].ClusterResource, $objects[0].Node or $objects[0].Status.
As this solution relies on the fact that the names of the resources and nodes consist of only one word, I have tried to implement a solution that uses WMI without using the cluster.exe tool.
I do have no idea if it works, because I do not have a cluster to play with. Try it and let me hear if it worked for you:
$cluster = "clustername"$groupname = "resourcegroup"
function Get-ActiveClusterNode([string] $cluster, [string] $resource){ Get-WmiObject -Query "Associators Of {$resource} Where ResultClass = MSCluster_Node" ` -Authentication PacketPrivacy -ComputerName $cluster -Namespace "Root\MSCluster"}
function Get-ClusterResource([string] $cluster, [string] $resourcegroup){ Get-WmiObject -Query "Associators Of {$resourcegroup} Where ResultClass = MSCluster_Resource" ` -Authentication PacketPrivacy -ComputerName $cluster -Namespace "Root\MSCluster"}
function Get-ClusterGroup([string] $cluster, [string] $groupname){ Get-WmiObject -Class MSCluster_ResourceGroup -Filter "Name = '$resourcegroup'" ` -Authentication PacketPrivacy -ComputerName $cluster -Namespace "Root\MSCluster"}
function Get-StateToString([int] $state){ switch ($state) { 1 { "initializing" } 2 { "online" } 3 { "offline" } 4 { "failed" } 128 { "pending" } 129 { "online pending" } 130 { "offline pending" } default { "unknown" } }}
### code starts here ###$ResourceStates = @()foreach ($g in (Get-ClusterGroup $cluster $groupname)){ foreach ($r in (Get-ClusterResource $cluster $g.__RELPATH)) { $n = Get-ActiveClusterNode $cluster, $r.__RELPATH $ResourceStates += New-Object -TypeName PSObject -Property @{ Resource = $r.Name; Node = $n.Name; State = (Get-StateToString $r.State) } } }
# Example output$ResourceStates | Format-Table Resource, Node, State
# Accessing only the first result:Write-Host ("Resource: " + $ResourceStates[0].Resource)Write-Host ("Node: " + $ResourceStates[0].Node)Write-Host ("State: " + $ResourceStates[0].State)
## End of script