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

Mar*_*son 3 powershell vmware powershell-2.0 powercli

我有两个数组.

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

PowerCLI > $vms.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
Run Code Online (Sandbox Code Playgroud)

我有一个从CSV文件导入的另一个数组,$importVMs其中一个字段也被调用Name.

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

我能做点什么吗 if (! $vms | ? {$_.Name -neq $importVms.Name) { # work }

似乎无法让它发挥作用.我需要foreach$importVmsif条件?

编辑

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

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
Run Code Online (Sandbox Code Playgroud)

vCenterVMs.csv看起来像

"Name","VmPathName","Location"
"test","[RAID5] test/test.vmx","testfolder"
Run Code Online (Sandbox Code Playgroud)

The*_*ian 5

使用-notin或-notcontains运算符.

$importvms | ?{$_.Name -notin $vms.name} | %{ Do Stuff }
Run Code Online (Sandbox Code Playgroud)

别名?用于Where%用于ForEach.

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

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}

$VMNameFilter = "($(($currentVms|%{[RegEx]::Escape($_.Name)}) -join "|"))"

foreach ($vm in $importVms) {
    if (! $vm.Name -match $VMNameFilter) {
        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
Run Code Online (Sandbox Code Playgroud)