如何执行 powershell 对象的“INNER JOIN”?

如何执行 powershell 对象的“INNER JOIN”?

我正在尝试查询各种物理磁盘健康信息。

我有两个查询,每个查询都返回有关物理磁盘秒。

>Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, Model, SerialNumber, Usage, HealthStatus, CanPool, CannotPoolReason | Format-Table
设备ID 模型 序列号 友好名称 用法 健康状况 加池 无法池化原因
0 WDC WD80EDAZ-11T 维吉尼亚州 ATA WDC WD80EDAZ-11T 自动选择 健康 错误的 在游泳池里
1 WDC WD40EFRX-68N WD-WCC7K6NE2J5J ATA WDC WD40EFRX-68N 自动选择 健康 真的
2 WDC WD40EFRX-68N WD-WCC7K5RYNVZD ATA WDC WD40EFRX-68N 热备援 健康 错误的 在游泳池里
3 WDC WD80EDAZ-11T VGGDU8GG ATA WDC WD80EDAZ-11T 自动选择 健康 错误的 在游泳池里
4 WDC WD80EDAZ-11T VGKE7HJG ATA WDC WD80EDAZ-11T 自动选择 健康 错误的 在游泳池里
5 三星 SSD 970 EVO 500GB 0025_385A_9150_212F。 三星 SSD 970 EVO 500GB 自动选择 健康 真的
6 WDC WD40EFRX-68N WD-WCC7K5KP57ZJ ATA WDC WD40EFRX-68N 热备援 健康 错误的 在游泳池里
7 WDC WD40EFRX-68N WD-WCC7K1URKJV5 ATA WDC WD40EFRX-68N 热备援 健康 错误的 在游泳池里
8 WDC WD40EFRX-68N WD-WCC7K1TZUVDD ATA WDC WD40EFRX-68N 自动选择 健康 错误的 在游泳池里
9 元素 25A3 2SGDZYXJ WD Elements 25A3 自动选择 健康 错误的 容量不足
10 WDC WD40EFRX-68N WD-WCC7K6HJV122 ATA WDC WD40EFRX-68N 自动选择 健康 错误的 在游泳池里
11 WDC WD40EFRX-68N WD-WCC7K1PHSSE7 ATA WDC WD40EFRX-68N 自动选择 健康 错误的 在游泳池里
12 WDC WD40EFRX-68N WD-WCC7K5XL728J ATA WDC WD40EFRX-68N 自动选择 健康 错误的 在游泳池里
十三 WDC WD40EFRX-68N WD-WCC7K3DNAYHT ATA WDC WD40EFRX-68N 自动选择 健康 错误的 在游泳池里

然后是相同物理磁盘的 SMART 属性:

>Get-PhysicalDisk | Get-StorageReliabilityCounter | Select-Object Number, DeviceId, PowerOnHours, ReadErrorsTotal, Temperature, ReadLatencyMax, WriteLatencyMax | Format-Table
设备ID 开机时间 读取错误总数 温度 最大读取延迟 最大写入延迟
4 40340 0 二十八 155 283
6 25774 0 二十九 712 226
8 17383 0 二十九 190 163
12 三十六 489 287
十三 1486 0 31 19376 0
5 25781 0 31 699 208
0 28385 0 二十七 1
1 35341 0 二十八 197 168
3 41524 0 二十七 177 193
11 13743 0 三十八 242 148
2 33553 0 二十八 365 422
10 14000 0 三十四 239 418
9 14000 0 三十六 234 368
7 25746 0 二十八 4

那么现在我想将它们合并成单行:

设备ID 友好名称 模型 序列号 用法 健康状况 加池 无法池化原因 开机时间 读取错误总数 温度 最大读取延迟 最大写入延迟
0 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K6NE2J5J 自动选择 健康 真的 28385 0 二十七 1
1 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K1TZUVDD 自动选择 健康 错误的 在游泳池里 35341 0 二十八 197 168
2 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K6HJV122 自动选择 健康 错误的 在游泳池里 33553 0 二十八 365 422
3 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K5KP57ZJ 热备援 健康 错误的 在游泳池里 41524 0 二十七 177 193
4 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K1URKJV5 热备援 健康 错误的 在游泳池里 40340 0 二十八 155 283
5 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K3DNAYHT 自动选择 健康 错误的 在游泳池里 25781 0 31 699 208
6 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K1PHSSE7 自动选择 健康 错误的 在游泳池里 25774 0 二十九 712 226
7 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K5RYNVZD 热备援 健康 错误的 在游泳池里 25746 0 二十八 4
8 ATA WDC WD40EFRX-68N WDC WD40EFRX-68N WD-WCC7K5XL728J 自动选择 健康 错误的 在游泳池里 17383 0 二十九 190 163
9 ATA WDC WD80EDAZ-11T WDC WD80EDAZ-11T VGGDU8GG 自动选择 健康 错误的 在游泳池里 14000 0 三十六 234 368
10 ATA WDC WD80EDAZ-11T WDC WD80EDAZ-11T 维吉尼亚州 自动选择 健康 错误的 在游泳池里 14000 0 三十四 239 418
11 ATA WDC WD80EDAZ-11T WDC WD80EDAZ-11T VGKE7HJG 自动选择 健康 错误的 在游泳池里 13743 0 三十八 242 148
12 三星 SSD 970 EVO 500GB 三星 SSD 970 EVO 500GB 0025_385A_9150_212F。 自动选择 健康 真的 三十六 489 287
十三 WD Elements 25A3 元素 25A3 2SGDZYXJ 自动选择 健康 错误的 容量不足 1486 0 31 19376 0

INNER JOIN在 SQL Server 关系数据库中,这将是设备ID

我怎样才能将这两组结果合并为一组?

答案1

您可以使用连接对象完成任务的模块

根据共同值连接两组对象的数据。

  • 安装 Join-Object 模块
Install-Module -Name Join-Object
  • 创建两个列表
$FirstList = Get-PhysicalDisk | Select-Object DeviceID, FriendlyName, Model, SerialNumber, Usage, HealthStatus, CanPool, CannotPoolReason
$SecondList = Get-PhysicalDisk | Get-StorageReliabilityCounter | Select-Object Number, DeviceId, PowerOnHours, ReadErrorsTotal, Temperature, ReadLatencyMax, WriteLatencyMax
  • 使用 Join-Object 连接列表
$JoinedResult = Join-Object -left $FirstList -Right $SecondList -LeftJoinProperty DeviceID -RightJoinProperty DeviceID -KeepRightJoinProperty -Type OnlyIfInBoth -Prefix r_

$JoinedResult | Select DeviceID, FriendlyName, Model, SerialNumber, Usage, HealthStatus, CanPool, CannotPoolReason, r_PowerOnHours,r_ReadErrorsTotal, r_Temperature, r_ReadLatencyMax, r_WriteLatencyMax

使用 PowerShell 的 Join-Object 模块连接数据,这里是对 Join-Object 参数的解释(将提及的内容替换为:$process 替换为 $FirstList,$services 替换为 $Secondlist,name 替换为 DevideID 和服务与r

  1. 我们有 --Left 和 --Right。这些只是我们想要连接的对象,即上面定义的 $processes 和 $services。
  2. 我们使用 --LeftJoinProperty 和 --RightJoinProperty 命令。这是我们想要连接在一起的这两个对象的属性。在本例中,它们具有相同的名称,即“name”。
  3. 下一个参数 --KeepRightJoinProperty 在连接操作的输出中包含右连接属性。我将在本教程中进一步演示这一点。
  4. --Type 参数很重要,因为这是您要指定要执行的连接类型的地方。我使用 OnlyIfInBoth 来查看任何具有相同名称的进程和服务。

直接从 PowerShell 帮助中获取的其他选项如下:

  • AllInLeft。这是默认参数,它显示输出中出现至少一次的所有 Left 元素,具体取决于 Right 中应用了多少个元素。
  • AllInRight。这与 AllInLeft 类似。
  • OnlyIfInBoth. 将左侧的所有元素放置在输出中,无论在右侧找到多少个匹配项。
  • AllInBoth。在输出中包含右侧和左侧的所有条目。
  1. 最后一个参数是 --Prefix。它用于为连接中的每个 Right 属性添加前缀,无论你决定使用什么字符串。在本例中,我使用了 _service。

答案2

为什么不直接使用正常的 PowerShell 方式,不需要任何额外的东西。只需要正常的管道内容,并带有计算属性。好吧,也可以使用哈希表或 PSCustomObject。

Clear-Host
Get-PhysicalDisk | 
ForEach-Object {
    ($RecordData = $PSItem) | 
    Get-StorageReliabilityCounter | 
    Select-Object -Property @{
                                Name       = 'DeviceId'
                                Expression = {$RecordData.DeviceId}
                            }, 
                            @{
                                Name       = 'FriendlyName'
                                Expression = {$RecordData.FriendlyName}
                            }, 
                            @{
                                Name       = 'Model'
                                Expression = {$RecordData.Model}
                            }, 
                            @{
                                Name       = 'SerialNumber'
                                Expression = {$RecordData.SerialNumber}
                            }, 
                            @{
                                Name       = 'Usage'
                                Expression = {$RecordData.Usage}
                            }, 
                            @{
                                Name       = 'HealthStatus'
                                Expression = {$RecordData.HealthStatus}
                            }, 
                            @{
                                Name       = 'CanPool'
                                Expression = {$RecordData.CanPool}
                            }, 
                            @{
                                Name       = 'CannotPoolReason'
                                Expression = {$RecordData.CannotPoolReason}
                            },
                            Number, PowerOnHours, ReadErrorsTotal, 
                            Temperature, ReadLatencyMax, WriteLatencyMax
}
# Results
<#
...

DeviceId         : 1
FriendlyName     : Samsung SSD 950 PRO 512GB
Model            : Samsung SSD 950 PRO 512GB
SerialNumber     : 0000_0000_0000_0000
Usage            : Auto-Select
HealthStatus     : Healthy
CanPool          : False
CannotPoolReason : Insufficient Capacity
Number           : 
PowerOnHours     : 
ReadErrorsTotal  : 
Temperature      : 34
ReadLatencyMax   : 252
WriteLatencyMax  : 70
...
#>

Clear-Host
Get-PhysicalDisk | 
ForEach-Object {
    ($RecordData = $PSItem) | 
    Get-StorageReliabilityCounter | 
    Select-Object -Property @{
                                Name       = 'DeviceId'
                                Expression = {$RecordData.DeviceId}
                            }, 
                            @{
                                Name       = 'FriendlyName'
                                Expression = {$RecordData.FriendlyName}
                            }, 
                            @{
                                Name       = 'Model'
                                Expression = {$RecordData.Model}
                            }, 
                            @{
                                Name       = 'SerialNumber'
                                Expression = {$RecordData.SerialNumber}
                            }, 
                            @{
                                Name       = 'Usage'
                                Expression = {$RecordData.Usage}
                            }, 
                            @{
                                Name       = 'HealthStatus'
                                Expression = {$RecordData.HealthStatus}
                            }, 
                            @{
                                Name       = 'CanPool'
                                Expression = {$RecordData.CanPool}
                            }, 
                            @{
                                Name       = 'CannotPoolReason'
                                Expression = {$RecordData.CannotPoolReason}
                            },
                            Number, PowerOnHours, ReadErrorsTotal, 
                            Temperature, ReadLatencyMax, WriteLatencyMax
} | 
Format-Table -AutoSize
# Results
<#
DeviceId FriendlyName              Model                     SerialNumber         Usage       HealthStatus CanPool CannotPoolReason      Number PowerOnHours
-------- ------------              -----                     ------------         -----       ------------ ------- ----------------      ------ ------------
...
1        Samsung SSD 950 PRO 512GB Samsung SSD 950 PRO 512GB 0000_0000_0000_0000. Auto-Select Healthy        False Insufficient Capacity                    
...                    
#>

答案3

在 PowerShell 中轻松连接两个对象列表是十年前的旧要求(例如:https://devblogs.microsoft.com/powershell/join-object/Join-Object)。我个人认为这应该是一种直观的惯用 PowerShell 语法。不幸的是,目前还没有原生的 PowerShell 命令可以做到这一点,这导致了自定义实现的泛滥。
无论如何,这是我对一个Join-Object Module
也可以看看:在 Powershell 中,将两个表合并为一个的最佳方法是什么?

Install-Module -Name JoinModule

# $Disks = Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, Model, SerialNumber, Usage, HealthStatus, CanPool, CannotPoolReason
$Disk = Read-HtmlTable https://superuser.com/q/1759239/1085094 -Table 0 # Install-Script -Name Read-HtmlTable

# Intialy, there was no DeviceID in the disk list where you might simply add it:
# $Disk = 0..13 |Join $Disk -Name DeviceId

# $Storage = Get-PhysicalDisk | Get-StorageReliabilityCounter | Select-Object Number, DeviceId, PowerOnHours, ReadErrorsTotal, Temperature, ReadLatencyMax, WriteLatencyMax
$Storage = Read-HtmlTable https://superuser.com/q/1759239/1085094 -Table 1

$Disk |Join $Storage -on DeviceId |Format-Table *

DeviceId Model                     SerialNumber         FriendlyName              Usage       HealthStatus CanPool CannotPoolReason      PowerOnHours ReadErrorsTotal Temperature ReadLatencyMax WriteLatencyMax
-------- -----                     ------------         ------------              -----       ------------ ------- ----------------      ------------ --------------- ----------- -------------- ---------------
       0 WDC WD80EDAZ-11T          VGJKAJEG             ATA WDC WD80EDAZ-11T      Auto-Select Healthy      False   In a Pool             28385        0               27          1
       1 WDC WD40EFRX-68N          WD-WCC7K6NE2J5J      ATA WDC WD40EFRX-68N      Auto-Select Healthy      True                          35341        0               28          197            168
       2 WDC WD40EFRX-68N          WD-WCC7K5RYNVZD      ATA WDC WD40EFRX-68N      Hot Spare   Healthy      False   In a Pool             33553        0               28          365            422
       3 WDC WD80EDAZ-11T          VGGDU8GG             ATA WDC WD80EDAZ-11T      Auto-Select Healthy      False   In a Pool             41524        0               27          177            193
       4 WDC WD80EDAZ-11T          VGKE7HJG             ATA WDC WD80EDAZ-11T      Auto-Select Healthy      False   In a Pool             40340        0               28          155            283
       5 Samsung SSD 970 EVO 500GB 0025_385A_9150_212F. Samsung SSD 970 EVO 500GB Auto-Select Healthy      True                          25781        0               31          699            208
       6 WDC WD40EFRX-68N          WD-WCC7K5KP57ZJ      ATA WDC WD40EFRX-68N      Hot Spare   Healthy      False   In a Pool             25774        0               29          712            226
       7 WDC WD40EFRX-68N          WD-WCC7K1URKJV5      ATA WDC WD40EFRX-68N      Hot Spare   Healthy      False   In a Pool             25746        0               28          4
       8 WDC WD40EFRX-68N          WD-WCC7K1TZUVDD      ATA WDC WD40EFRX-68N      Auto-Select Healthy      False   In a Pool             17383        0               29          190            163
       9 Elements 25A3             2SGDZYXJ             WD Elements 25A3          Auto-Select Healthy      False   Insufficient Capacity 14000        0               36          234            368
      10 WDC WD40EFRX-68N          WD-WCC7K6HJV122      ATA WDC WD40EFRX-68N      Auto-Select Healthy      False   In a Pool             14000        0               34          239            418
      11 WDC WD40EFRX-68N          WD-WCC7K1PHSSE7      ATA WDC WD40EFRX-68N      Auto-Select Healthy      False   In a Pool             13743        0               38          242            148
      12 WDC WD40EFRX-68N          WD-WCC7K5XL728J      ATA WDC WD40EFRX-68N      Auto-Select Healthy      False   In a Pool                                          36          489            287
      13 WDC WD40EFRX-68N          WD-WCC7K3DNAYHT      ATA WDC WD40EFRX-68N      Auto-Select Healthy      False   In a Pool             1486         0               31          19376          0

请给

相关内容