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

时间:2021-04-30 21:01:48

标签: powershell powershell-remoting

我已经为此苦恼了几天,但我无法找到最好的方法。我有一个脚本,用于收集一堆数据并将其输出到一个 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

远程无法正常工作的部分是依赖项和可能的所有者。我知道它不起作用的原因是因为当运行脚本的服务器不是集群节点时,它无法识别 Foreach 循环 Get-ClusterResource 下的命令。但我就是不知道如何在 Foreach 循环中正确传递这些信息,但仍然使用 $ClusterResourceInfo 中的信息。

我已经用一百种不同的方式重新编写了这个,即使用基本上一个大的 Get-Cluster 变量(无法获取它来捕获 Dependency/PossOwners,始终为 $null)制作单个 Invoke-command,拆分Dependency 和 PossOwners 到他们自己单独的 Invoke-Command(我能做的最好的是显示 System.Object[],或者当我确实让它显示时,它捕获了所有对象的所有依赖项并显示在每一行上而不是将其正确拆分)。

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

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

Output

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

2 个答案:

答案 0 :(得分:1)

我可以建议的几件事。

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

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

答案 1 :(得分:0)

因此,零碎的方法给我带来了麻烦。在尝试将事物合并在一起时,我一直在打破它(主要是因为我认为已将 %{} 翻了一番)。因此,我没有合并,而是复制了已经按预期工作的部分。

最终这段代码运行良好:

$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