如何搜索对象数组包含另一个数组中的项?

时间:2014-08-01 16:15:36

标签: powershell powershell-v2.0 vmware powercli

我有两个阵列。

包含虚拟机信息的对象数组,称为$vms称为Name的属性之一。这是类型:

PowerCLI > $vms.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

我从另一个名为$importVMs的CSV文件导入了另一个数组,其中一个字段也称为Name

如果$importVMs.Name中不存在$vms(即它与任何$vms.Name都不匹配),我想做一些工作。我想知道我是否可以使用流水线操作,或者我是否必须遍历这两个数组?

我可以执行if (! $vms | ? {$_.Name -neq $importVms.Name) { # work }

之类的操作

似乎无法让它发挥作用。我需要在foreach条件下$importVms if吗?

修改

到目前为止我的完整脚本:

Connect-VIServer -Server vCenter -Protocol https -Force | out-null
$importVms = Import-Csv vCenterVMs.csv
$VMHost = "esxi"
$currentVms = Get-VM
Write-Host "Current registered VMs" -ForeGroundColor Cyan
$currentVMs

Write-Host "Saved VMs to import" -ForeGroundColor Yellow
$importVms

$registered = @()
Write-Host "Importing VMs..." -ForeGroundColor White
#$importVms | ?{$_.Name -notcontains $currentVms}

foreach ($vm in $importVms) {
    if (! $currentVms.Name -contains $vm) {
        Write-Host "Importing $($vm.Name)"
        # put in a try block here
        $registeredVM = New-VM -VMFilePath $vm.VmPathName -VMHost $VMHost -Location $vm.Location
        $registeredList += $registeredVM.Name
    }
}

$registeredList
Disconnect-VIServer -Server * -Confirm:$false

vCenterVMs.csv看起来像

"Name","VmPathName","Location"
"test","[RAID5] test/test.vmx","testfolder"

2 个答案:

答案 0 :(得分:5)

使用-notin或-notcontains运算符。

$importvms | ?{$_.Name -notin $vms.name} | %{ Do Stuff }

用于?的别名Where和用于%的{​​{1}}。

好的,它不起作用我们可以尝试从当前VM名称数组中构建一个正则表达式匹配字符串,并将每个导入的VM与其匹配,以查看它是否已存在。试试这个脚本:

ForEach

答案 1 :(得分:0)

另一种方法,可以在脚本中更好地使用:

Foreach ($ImportVm in $ImportVms.name) { 
if ($vms.name -notcontains $ImportVm) {
DO STUFF }
}

Foreach循环遍历数组$ ImportVMs中的VM名称,在每个循环中将$ ImportVM中的每个VM名称放在变量$ ImportVM中。

然后," if"语句检查$ vms中的名称数组是否包含当前循环中的$ ImportVM。 如果这"如果"语句的计算结果为true,然后脚本将执行{}内的任何操作。 我刚把{DO STUFF}放在这里,因为你没有提到你想对这些虚拟机做什么。