Поддерживают ли условные операторы Powershell поиск в массивах объектов? - PullRequest
0 голосов
/ 23 января 2019

Мне нужно проверить, содержит ли массив объектов определенный объект, с помощью операторов -in и -contain , но не повезло, например:

PS C:\> ($3_devices = Get-MobileDevice -ResultSize 3).guid

Guid                                
----                                
25c2f857-0098-46c3-b965-f22008006d16
1cc13103-3b36-4b69-ab51-b7e381453326
aae35123-4695-40b4-b6e5-7ea6cd0713c2


PS C:\> ($1_device = Get-MobileDevice -Resultsize 2 | select -last 1).guid

Guid                                
----                                
1cc13103-3b36-4b69-ab51-b7e381453326

PS C:\> $1_device -in $3_devices
False

PS C:\> $3_devices -contains $1_device
False

PS C:\> $3_devices.GetType()

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


PS C:\> $1_device.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

Где ошибка или PS условные операторы поддерживают объекты?

Спасибо.

1 Ответ

0 голосов
/ 29 января 2019

«Содержит» работает только с массивами объектов, когда выполняется одно из следующих условий:

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
...