Powershell. Как создать изменяемый массив

Немного теории

Почему сейчас стоит поговорить про типизацию и классы?
Для того что бы  создать изменяемый массив, нужно присвоить объект к определенному классу, содержащему необходимые методы

Powershell относят к языкам с динамической типизацией и таким образом, тип переменной определяется в момент присваивания  значения, в зависимости от типа самого этого значения.

И если заранее вручную не создать экземпляр нужного класса(объект), то по умолчанию, объект которому мы присваиваем ряд значений, будет принадлежать к классу System.Array.

В свою очередь, объект System.Array не имеет возможности использовать метод add, т.к. является фиксированным массивом.

 

Подробно о том, почему у System.Array имеется метод add, но использовать его нельзя, читайте здесь

 

Классами, которые позволяют добавлять объекты в массив, являются:
[System.Collections.Generic.List]
или
[System.Collections.ArrayList]

Так как для класса List заявлена более высокая производительность, за счет возможности явно задать его тип данных, а ArrayList имеет те же самые методы,
то разбирать работу с массивом мы будем на примере класса List

Так же у метода add() массива List упразднен вывод индекса добавляемого элемента в консоль

Плюсы:
Массив имеет не фиксированный размер, что указывает на то, что в него можно добавлять, или же удалять из него элементы
Минусы:
Не сохраняется порядок объектов в массиве при выводе, в отличии от PSCustomObject
Но это не доставляет особых проблем, т.к. можно выполнить последующую сортировку, например средствами Sort-Object

Summary простыми словами:

  • Объекты содержащие ряд значений называется массивом
  • Массивы бывают разными
  • В зависимости от класса к которому относится массив, меняется его набор свойств и методов
  • Массив класса [System.Collections.Generic.List] позволяет добавлять элементы

Практическая часть

Пример создания массива

Сначала создадим экземпляр класса List

$List = New-Object 'System.Collections.Generic.List[System.Object]'

Чтобы проверить наличие у объекта нужного метода можно выполнив этот метод опустив скобки «()»

$List.add

Это вернуло нам определения перегрузок метода.
Если ничего не возвращает, то метод у объекта отсутствуют. 

Что из себя представляют перегрузки методов?

Перегрузка указывают на то, как один и тот же метод, в зависимости от количества и типа данных аргументов, может выдавать отличающиеся результаты.

Определения перегрузок(OverloadDefinitions) возвращают возможные варианты перегрузок.

После того как мы убедились в наличии метода add, мы можем  добавлять в массив элементы!

Добавление элементов в массив

Что бы окончательно понять как создать изменяемый массив, давайте разберем какой нибудь реальный кейс полезный для повседневной работы. Например, в рамках задачи по апгрейду устаревшего железа нам нужно провести для всех компьютеров в домене инвентаризацию объема оперативной памяти, количества занятых, и количества свободных слотов памяти.

$Computers = ( Get-ADComputer -f {Enabled -eq $true} ).Name
$List = New-Object 'System.Collections.Generic.List[System.Object]'
foreach($Computer in $Computers ){
    if( Test-Connection $Computer -Count 1){
            $RAM = ( Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer )
            $TotalMemory = "{0:N0} GB"-f $( [math]::Truncate([math]::Round((Get-WmiObject Win32_ComputerSystem -ComputerName $Computer ).TotalPhysicalMemory / 1GB )))
            $Count = $RAM.DeviceLocator.Count
            $MaxSlots = ( Get-WmiObject win32_PhysicalMemoryArray -ComputerName $Computer ).MemoryDevices
            $List.add( ( @{CompName=$Computer;TotalMemory=$TotalMemory;CountRAM=$Count;MaxSlots=$MaxSlots} | % { New-Object object | Add-Member -NotePropertyMembers $_ -PassThru }) )
    }
}

$List | Sort-Object | select CompName,TotalMemory,CountRAM,MaxSlots

 

По полученному результату можно сделать заключение о необходимости и возможности апгрейда RAM

Так же можно добавить объекты в коллекцию и с помощью оператора += , но известно что данный метод более медлителен, так как в каждой итерации перезаписывает массив:

$List += [PSCustomObject]@{CompName=$Computer;TotalMemory=$TotalMemory;CountRAM=$Count;MaxSlots=$MaxSlots}

 

Помимо более низкой производительности, после его использования, коллекция становится фиксированной.

Поэтому лучше сразу использовать ту же конструкцию для метода add:

$List.Add( [PSCustomObject]@{Motherboard=$SysInfo;User=$user} )

Тем не менее, для простых скриптов оператор += может вполне пригодиться

Удаление элементов из массива

Есть несколько методов для удаления объектов из массива

Remove()
$List.Remove($List[3])

Для удаления нужно целиком  указать объект. Проще всего это сделать указав конкретный элемент нашего массива

RemoveAt()

Так же можно удалить элемент по его порядковому номеру в массиве

$List.RemoveAt(0)
RemoveRange()

Как следует из названия, удаляет диапазон значений по их порядковым номерам

$List.RemoveRange(4,6)

 

Добавить комментарий

Ваш адрес email не будет опубликован.