Need some help with output formatting

rated by 0 users
This post has 5 Replies | 2 Followers

Top 50 Contributor
Posts 20
Ironbone Posted: 05-20-2010 12:29 PM

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

 

Top 200 Contributor
Posts 6

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

Top 50 Contributor
Posts 20

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:

clusterresource1               node1              online

 

$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?

Top 200 Contributor
Posts 6

Hello Ironbone.

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

Top 50 Contributor
Posts 20

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".

 

 

Top 200 Contributor
Posts 6

Hello Ironbone.

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

--
Regards,
Wolfgang

Page 1 of 1 (6 items) | RSS
Concentrated Tech NSoftware Dell Compellent Sponsored by Idera and Concentrated Tech and NSoftware and Dell Compellent
Copyright 2011 PowerShell.com. All rights reserved.