在 Powershell 中比较数组

Comparing Arrays within Powershell

我希望执行以下步骤:

我首先尝试 运行在 Reports2 CSV 文件中缺少一个主机的脚本,这个丢失的主机显示在控制台上并写入 Reports2 文件,但是当我重新 运行 它仍然显示最后一个元素的代码(Reports2.CSV 中缺少的主机):

这是我目前正在处理的脚本:

编辑:我现在已经编辑了代码片段以反映工作解决方案

$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File

$MaitanceMode = @()
$Ticket = @()

foreach($ESXI in $esxiHosts){
 $Ticket += $ESXI | Select-Object -ExpandProperty Name
}

foreach($vCenter in $vCenter_Servers) {

$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv |  Where-Object {$_.ConnectionState -eq 'Maintenance'} |


ForEach-Object -Process {

    $maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |

         Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}

    if($maintEntered){  
     #Skipping
    }
    else {

         $MaitanceMode += $esx | Select-Object -ExpandProperty Name

         }

   }
} #Ending ForEach Loop

$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket

您应该将包含结果的数组实例化为一个空数组,可能在 ForEach-Object -Process {... 之前使用 $MaitanceMode = @() 并且当您想要向其中添加元素时,将此行替换为:

$MaitanceMode = $esx | select name

来自

$MaitanceMode += $esx | select name

编辑:

进一步替换这一行:

$esxiHosts = Import-CSV C:\Scripts\Report2.csv

通过这条线:

$esxiHosts = Import-CSV C:\Scripts\Report2.csv | Select-Object -ExpandProperty Name

这行:

$MaitanceMode += $esx | select name

通过这条线:

$MaitanceMode += $esx | Select-Object -ExpandProperty Name

并且不要忘记将 $MaitanceMode 实例化为一个空数组。现在这是强制性的。否则它将变成一个字符串而不是一个数组。

尽管 @Thomas 接受了答案,但在 PowerShell 中使用递增赋值运算符 (+=) 创建集合 正确。一方面,这是一种非常昂贵的语法。
参见:.

要在 PowerShell 中构建对象集合,您应该通过删除相关命令的 <variable> += 来使用 PowerShell 管道(这会将对象留在管道上)并通过添加 <variable> = 在迭代器前面(例如 Foreach-Object)。通过使用此 PowerShell 语法,无需启动数组 (<variable> = @() ).
以你的脚本为例:

$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File

$Ticket = foreach($ESXI in $esxiHosts){
    $ESXI | Select-Object -ExpandProperty Name
}

foreach($vCenter in $vCenter_Servers) {

$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv |  Where-Object {$_.ConnectionState -eq 'Maintenance'} |


$MaitanceMode = ForEach-Object -Process {

    $maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |

         Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}

    if($maintEntered){  
     #Skipping
    }
    else {

         $esx | Select-Object -ExpandProperty Name

         }

   }
} #Ending ForEach Loop

$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket