I've been banging my head on this for a few days now, and I just can't figure out the best way to do it. I've got a script where I collect a bunch of data and output it to an html file (using PSWriteHTML Module, which is where the New-HTMLTable at the end comes from).
I've piecemealed the script together over time so I can gather the data from multiple servers at once, and for the most part, it all works great. As I've added data to the script to collect new info, there's a few parts that I just can't get to work right remotely. I know the piecemeal approach has left me with some redundant code, but I'm just trying to make it all work right before I re-write it again to clean it up, so my apologies for its current state.
The following code works great when I run the script from a server in a Windows Cluster, but I want things to work from any server, not necessarily a Cluster Node.
Here's orig code for this section:
try
{
$ClusterIPInfo = Invoke-command -computer $Computer {
Get-Cluster | Get-ClusterResource | %{
$_ | select Name,
@{ Name = "Address"; Expression = { $_ | Get-ClusterParameter -Name Address -ErrorAction SilentlyContinue | select -ExpandProperty Value } },
@{ Name = "SubnetMask"; Expression = { $_ | Get-ClusterParameter -Name SubnetMask -ErrorAction SilentlyContinue | select -ExpandProperty Value } }
}
} | Select -Property * -ExcludeProperty PSComputerName, RunSpaceID, PSShowComputerName
$ClusterResourceInfo = Invoke-command -computer $Computer {
Get-ClusterResource | Select Cluster, Name, State, ResourceType, OwnerGroup, OwnerNode, ID, IsCoreResource, IsNetworkClassResource, IsStorageClassResource | Sort-Object -Property OwnerGroup, Name
} | Select -Property * -ExcludeProperty PSComputerName, RunSpaceID, PSShowComputerName
$ResourceInfo = @()
foreach ($rec in $ClusterResourceInfo)
{
$Owner = (Get-ClusterResource | Sort-Object -Property OwnerGroup, Name | Get-ClusterOwnerNode | %{
$_ | select @{ Name = "Name"; Expression = { $_.ClusterObject } },
@{ Name = "PossibleOwners"; Expression = { $_.OwnerNodes } }
} | Where { $_.Name -eq $rec.Name }).PossibleOwners
$Dependency = (Get-ClusterResource | Sort-Object -Property OwnerGroup, Name | Get-ClusterResourceDependency | %{
$_ | select @{ Name = "Name"; Expression = { $_.Resource } },
@{ Name = "Dependency"; Expression = { $_ | Select-Object -ExpandProperty "DependencyExpression" } }
} | Where { $_.Name -eq $rec.Name }).Dependency
$address = ($ClusterIPInfo | Where { $_.Name -eq $rec.Name }).Address
$subnetmask = ($ClusterIPInfo | Where { $_.Name -eq $rec.Name }).SubnetMask
$recObj = New-Object PSObject
$recObj | Add-Member NoteProperty -Name "Cluster" -Value $rec.Cluster
$recObj | Add-Member NoteProperty -Name "Name" -Value $rec.Name
$recObj | Add-Member NoteProperty -Name "State" -Value $rec.State
$recObj | Add-Member NoteProperty -Name "Resource Type" -Value $rec.ResourceType
$recObj | Add-Member NoteProperty -Name "Owner Group" -Value $rec.OwnerGroup
$recObj | Add-Member NoteProperty -Name "Owner Node" -Value $rec.OwnerNode
$recObj | Add-Member NoteProperty -Name "Possible Owners" -Value $Owner
$recObj | Add-Member NoteProperty -Name "Dependency" -Value $Dependency
$recObj | Add-Member NoteProperty -Name "IP Address" -Value $address
$recObj | Add-Member NoteProperty -Name "Subnet Mask" -Value $subnetmask
$recObj | Add-Member NoteProperty -Name "Is Core Resource" -Value $rec.IsCoreResource
$recObj | Add-Member NoteProperty -Name "Is Network Resource" -Value $rec.IsNetworkClassResource
$recObj | Add-Member NoteProperty -Name "Is Storage Resource" -Value $rec.IsStorageClassResource
$ResourceInfo += $recObj
}
New-HTMLTable -DataTable $ResourceInfo -HideFooter -HideButtons -DisableSearch
The parts that don't work correctly remotely are the Dependency and PossibleOwners. I know the reason it doesn't work is because when the server running the script isn't a Cluster Node, it doesn't recognize the command under the Foreach loop Get-ClusterResource. But I just can't figure out how to make those pass correctly from within the Foreach loop, but still use the info from $ClusterResourceInfo.
I've re-written this a hundred different ways, i.e. make a single Invoke-command with basically one big Get-Cluster variable (couldn't get it to capture the Dependency/PossOwners, always $null), splitting up the Dependency and PossOwners to their own separate Invoke-Command (best I can get it to do is display System.Object[], or when I did get it to display, it captured ALL of the Dependencies for all objects and displayed on every line instead of splitting it up correctly).
I've tried every possible way I can think of or found online, but just can't get it to work correctly remotely.
Here's how the orig code above outputs (which is what I want, but I just want to fix it so it works remotely):
I am desperately hoping for some brilliance or guidance to set me on the right track. I tried so many ways, but just never quite got it where it needs to be, so any help is most appreciated and welcome. Thanks.
So the piecemeal approach is what got me in trouble. In trying to merge things together, I kept breaking it (mainly because I think had doubled up the %{}). So instead of merging, I just replicated the parts that were already working as intended.
Ultimately this code worked fine:
$ClusterInfo = Invoke-command -computer $Computer {
Get-Cluster | Get-ClusterResource | %{
$_ | select Name,
@{ Name = "Address"; Expression = { $_ | Get-ClusterParameter -Name Address -ErrorAction SilentlyContinue | select -ExpandProperty Value } },
@{ Name = "SubnetMask"; Expression = { $_ | Get-ClusterParameter -Name SubnetMask -ErrorAction SilentlyContinue | select -ExpandProperty Value } },
@{ Name = "PossibleOwners"; Expression = { $_ | Get-ClusterOwnerNode | select OwnerNodes | select -ExpandProperty OwnerNodes } },
@{ Name = "Dependency"; Expression = { $_ | Get-ClusterResourceDependency | select -ExpandProperty "DependencyExpression" } }
}
} | Select -Property * -ExcludeProperty PSComputerName, RunSpaceID, PSShowComputerName
$ClusterResourceInfo = Invoke-command -computer $Computer {
Get-ClusterResource | Select Cluster, Name, State, ResourceType, OwnerGroup, OwnerNode, IsCoreResource, IsNetworkClassResource, IsStorageClassResource | Sort-Object -Property OwnerGroup, Name
} | Select -Property * -ExcludeProperty PSComputerName, RunSpaceID, PSShowComputerName
$ResourceInfo = @()
foreach ($rec in $ClusterResourceInfo)
{
$Owner = ($ClusterInfo | Where { $_.Name -eq $rec.Name }).PossibleOwners
$Dependency = ($ClusterInfo | Where { $_.Name -eq $rec.Name }).Dependency
$address = ($ClusterInfo | Where { $_.Name -eq $rec.Name }).Address
$subnetmask = ($ClusterInfo | Where { $_.Name -eq $rec.Name }).SubnetMask
$recObj = New-Object PSObject
$recObj | Add-Member NoteProperty -Name "Cluster" -Value $rec.Cluster
$recObj | Add-Member NoteProperty -Name "Name" -Value $rec.Name
$recObj | Add-Member NoteProperty -Name "State" -Value $rec.State
$recObj | Add-Member NoteProperty -Name "Resource Type" -Value $rec.ResourceType
$recObj | Add-Member NoteProperty -Name "Owner Group" -Value $rec.OwnerGroup
$recObj | Add-Member NoteProperty -Name "Owner Node" -Value $rec.OwnerNode
$recObj | Add-Member NoteProperty -Name "Possible Owners" -Value $Owner
$recObj | Add-Member NoteProperty -Name "Dependency" -Value $Dependency
$recObj | Add-Member NoteProperty -Name "IP Address" -Value $address
$recObj | Add-Member NoteProperty -Name "Subnet Mask" -Value $subnetmask
$recObj | Add-Member NoteProperty -Name "Is Core Resource" -Value $rec.IsCoreResource
$recObj | Add-Member NoteProperty -Name "Is Network Resource" -Value $rec.IsNetworkClassResource
$recObj | Add-Member NoteProperty -Name "Is Storage Resource" -Value $rec.IsStorageClassResource
$ResourceInfo += $recObj
}
New-HTMLTable -DataTable $ResourceInfo -HideFooter -HideButtons -DisableSearch