I have two arrays.
An array of objects containing Virtual Machine Information called $vms
one of the attributes called Name
. Here's the type:
PowerCLI > $vms.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
I have another array imported from a CSV file called $importVMs
where one of the fields is also called Name
.
I want to do some work if $importVMs.Name
does not exist in $vms
(i.e. it doesn't match any $vms.Name
). I'm wondering if I can do this with pipelining, or do I have to iterate through both arrays?
can I do something like if (! $vms | ? {$_.Name -neq $importVms.Name) { # work }
Can't seem to get it to work. Do I need to foreach
the $importVms
in that if
condition?
EDIT
My complete script so far:
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 looks like
"Name","VmPathName","Location"
"test","[RAID5] test/test.vmx","testfolder"
Use to -notin or -notcontains operator for that.
$importvms | ?{$_.Name -notin $vms.name} | %{ Do Stuff }
Alias ?
used for Where
, and %
used for ForEach
.
Ok, it that doesn't work we can try building a regex match string out of your array of current VM names, and matching each imported VM against that to see if it already exists. Try this script:
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