«Содержит» работает только с массивами объектов, когда выполняется одно из следующих условий:
1) Массив содержит объекты типа, реализованного с интерфейсами IComparable и / или IEquatable. У Ли Холмса есть отличный пост в блоге об этом.
Пример: тип объекта, возвращаемый из Get-Service, [System.ServiceProcess.ServiceController], не имеет ни одного из этих интерфейсов, поэтому «-contains» не будет работать, даже если объекты выглядят одинаково:
$services = Get-Service
$service = Get-Service -Name 'Spooler'
$service.GetType().GetInterfaces()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False IComponent
True False IDisposable
$services -contains $service
False
2) Ваш объект сравнения имеет равенство ссылок с объектом в массиве - они фактически хранятся в одном месте в памяти.
Ваш пример, в котором вы извлекаете массив и объект сравнения с помощью двух разных команд, в результате дублирующиеся объекты сохраняются в разных местах в памяти. Если вместо этого вы присвоили объект сравнения из массива новой переменной ( по ссылке , по умолчанию) и сравнили с этим, он должен работать:
$services = Get-Service
$service = $services[0]
$service.GetType().IsValueType
False
$services -contains $service
True
Хотя это не особенно полезно в качестве решения.
Моя рекомендация: если вы хотите сопоставить два разных ссылочных объекта по количеству свойств, но не по всем из них, вот краткое, быстрое решение, которое не использует несколько условий '-and':
$services = Get-Service
$serviceToMatch = Get-Service -Name 'Spooler' | Select -First 1
$propertiesToMatch = @('Status','StartType')
$propertiesToMatch | ForEach { $services = $services.Where({$_.$Input -eq $serviceToMatch.$Input}) }
$services | Select Name, Status, StartType | Sort Name
В результате получается список служб, совпадающих с теми же «Status» и «StartType», что и «Spooler».
В качестве альтернативы, вы можете создать настраиваемую хеш-таблицу имен свойств для сопоставления:
$services = Get-Service
$serviceToMatch = @{
Status = 'Stopped'
StartType = 'Automatic'
}
$serviceToMatch.Keys | ForEach { $services = $services.Where({$_.$Input -eq $serviceToMatch.$Input}) }
$services | Select Name, Status, StartType | Sort Name