如何从非集群节点远程捕获集群信息

How to Capture Cluster info Remotely from a non-Clustered Node

几天来我一直在努力解决这个问题,但我就是想不出最好的方法。我有一个脚本,我在其中收集了一堆数据并将其输出到一个 html 文件(使用 PSWriteHTML 模块,这是最后的 New-HTMLTable 来自的地方)。

随着时间的推移,我将脚本拼凑在一起,这样我就可以同时从多个服务器收集数据,而且在大多数情况下,一切都很好。由于我已将数据添加到脚本以收集新信息,所以有几个部分我无法远程正常工作。我知道零碎的方法给我留下了一些冗余代码,但我只是想在我再次重写它以清理它之前让它全部正常工作,所以我对它的当前状态表示歉意。

当我 运行 来自 Windows 集群中的服务器的脚本时,以下代码工作得很好,但我希望在任何服务器上运行,不一定是集群节点。

这是本节的原始代码:

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

远程无法正常工作的部分是 Dependency 和 PossibleOwners。我知道它不起作用的原因是因为当服务器 运行ning 脚本不是集群节点时,它无法识别 Foreach 循环 Get-ClusterResource 下的命令。但我只是想不出如何使它们从 Foreach 循环中正确传递,但仍然使用来自 $ClusterResourceInfo 的信息。

我用一百种不同的方式重写了这个,即用一个大的 Get-Cluster 变量创建一个 Invoke-command(无法让它捕获 Dependency/PossOwners,总是 $null ),将 Dependency 和 PossOwners 拆分为它们自己单独的 Invoke-Command(我能做的最好的事情是显示 System.Object[],或者当我确实显示它时,它捕获了所有的所有依赖项对象并显示在每一行上,而不是正确地拆分它)。

我已经尝试了所有我能想到或在网上找到的方法,但就是无法让它在远程正常工作。

上面的原始代码是这样输出的(这是我想要的,但我只是想修复它以便它可以远程工作):

我迫切希望得到一些智慧或指导,让我走上正轨。我尝试了很多方法,但从来没有完全得到它需要的地方,所以非常感谢和欢迎任何帮助。谢谢

我可以提出一些建议。

  1. “Get-ClusterResource”cmdlet 失败,因为它未安装在服务器上。 您可以尝试使用 Import-Module 加载故障转移集群模块,如果失败(在非集群节点上),您可以使用以下 PowerShell 命令为 Windows PowerShell 功能添加故障转移集群模块: 添加-Windows功能 RSAT-Clustering-PowerShell

  2. 您可以尝试使用 WMI 连接到托管资源的远程集群节点吗? 您有足够的资源信息,可以编写经过筛选的 WMI 查询。

所以零碎的方法让我遇到了麻烦。在尝试将事物合并在一起时,我一直在破坏它(主要是因为我认为 %{} 加倍了)。因此,我没有合并,而是复制了已经按预期工作的部分。

最终这段代码运行良好:

$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