Разное

Объекты в powershell: Как создавать объекты в PowerShell / Хабр

Содержание

Как создавать объекты в PowerShell / Хабр

Обнаружил, что поисковики рунета выдают в основном устаревшие методы типа add-member. Как создавать объекты, почему именно так и зачем это надо в переводе от гуру PowerShell. Вы ознакомитесь с приемом создания объекта из хеш таблиц, и узнаете несколько трюков по работе с ними.

PowerShell in Depth

Глава 21.1 Техника номер 1. Использование хеш таблиц для создания кастомных объектов.

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

Этот способ продемонстрирован в листинге 21.2 ниже

# Собираем какието данные, в последующем нам нужно это скомпоновать и вывести
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost |
Select –First 1

# Хэш таблица. Описывает свойства будущего объекта
$props = @{OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}

# Создаем объект из хэш таблицы и выводим
$obj = New-Object –TypeName PSObject –Property $props
Write-Output $obj

выполнив этот код вы получите результат подобный этому:

Manufacturer : Microsoft Corporation
OSVersion : 6.3.9600
OSArchitecture : 64-bit
BIOSSerial : 036685734653
ComputerName : RSSURFACEPRO2
Model : Surface Pro 2
ProcArchitecture : 64

Т.к. на выходе у вас объект имеющий более четырех свойств PowerShell сделал вывод на экран в виде списка. Вы могли бы выполнить

Write-Output $obj | ft

чтобы получить таблицу. Обратите внимание, дело в том, что вы создали один объект, путем объединения информации из четырех объектов. Вы сделали это путем создания хеш таблицы в которой прописали желаемые имена свойств, значениями для них стали значения свойств других объектов. Это то что вы сделали в хеш таблице указывая:

Manufacturer=$cs.manufacturer

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

Скобки с прешедствующим им знаком @ говорят что далее начинается хэш-таблица. Т.к. таблица находится в переменной $props ее легко передать в параметрах -property нового объекта. Объект PSObject специально предусмотрен для этих целей.

Преимущество этого подхода в том что легко построить хэш таблицу на лету и создать из нее много пользовательских объектов. Вы можете заметить что в выходном объекте свойства имеют не тот же самый порядок как они были определены в таблице. Одно из возможных решений — создать форматирование для кастомного объекта (специальный XML файл описывающий как выводить на экран, в каком порядке и т.п.) или, если вы используете powershell 3 и выше, то можно использовать свойство ordered

$props = [ordered]@{ OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}

Все остальное тоже самое. Теперь свойства объекта будут отображаться в том порядке как они были записаны. Если вы передадите $obj на Get-Member, вы увидете что это PS-CustomObject.

Примечание PowerShell по умолчанию не отслеживает порядок элементов в хэш таблице. Вот почему когда вы видете окончательный вывод его свойства идут не в том порядке в каком вы их создавали. Начиная с PowerShell 3 вы можете исправить это использовав атрибут [ordered]. Это создает упорядоченный словарь (другое название хэш таблиц) и поддерживает порядок элементов в ней.

Добавлю от себя.

Действительно этот способ очень удобен: легко читаем, легко править. Этот способ широко используется в PowerShell — от создания параметров для отправки письма по SMTP, для объединения в один объект информации для вывода из функции или скрипта.

Глава 21. Часть 2 — Создание объектов и вывод данных объектами. PowerShell in depth — Don Jones, Richard Siddaway

здесь перечислены разные способы создания объектов PowerShell. Даны советы и трюки. Текст великоват. Для всех изучающих пошик.

Кроме удобства чтения, количество нажатий на клавиши, требования к сохранению порядка свойств, все эти методы по существу делают тоже самое. Несколько тонких различий: техника 1, хэш таблица. Как правило самая быстрая, техника 2 медленнее, техника 3 может быть значительно медленнее.

В хорошей рецензии learn-powershell.net/2010/09/19/custom-powershell-objects-and-performance измерена скорость создания объектов выполненная MVP Boe Prox. Проводится сравнение скорости работы трех методов, работа Add-Member в 10 раз медленнее. Так что это плюс к технике 1. Мы не тестировали технику 4 как это делал Boe, но наши тесты показывают что техника 4 быстрее на 10% чем техника 1. Техника 5 должна быть использована в тех случаях когда типизация свойств имеет значение.

Сам перевод:

21.2 Синтаксис для создания пользовательских объектов

Мы часто говорили, что всегда есть несколько способов сделать что-либо в PowerShell, и это, верно для пользовательских объектов. Мы покажем вам все основные пути, потому что вы, наверняка столкнетесь с ними в жизни, мы хотим, чтобы вы могли распознать их и использовать их, когда вы захотите.

Глава 21.1 Техника номер 1. Использование хеш таблиц для создания кастомных объектов.

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

Этот способ продемонстрирован в листинге 21.2 ниже

# Собираем какието данные, в последующем нам нужно это скомпоновать и вывести
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

# Хэш таблица. Описывает свойства будущего объекта
$props = @{OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}

# Создаем объект из хэш таблицы и выводим
$obj = New-Object –TypeName PSObject –Property $props
Write-Output $obj

выполнив этот код вы получите результат подобный этому:

Manufacturer : Microsoft Corporation
OSVersion : 6.3.9600
OSArchitecture : 64-bit
BIOSSerial : 036685734653
ComputerName : RSSURFACEPRO2
Model : Surface Pro 2
ProcArchitecture : 64

Т.к. на выходе у вас объект имеющий более четырех свойств PowerShell сделал вывод на экран в виде списка. Вы могли бы выполнить

Write-Output $obj | ft

чтобы получить таблицу. Обратите внимание, дело в том, что вы создали один объект, путем объединения информации из четырех объектов. Вы сделали это путем создания хеш таблицы в которой прописали желаемые имена свойств, значениями для них стали значения свойств других объектов. Это то что вы сделали в хеш таблице указывая:

Manufacturer=$cs.manufacturer

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

Скобки с прешедствующим им знаком @ говорят что далее начинается хэш-таблица. Т.к. таблица находится в переменной $props ее легко передать в параметрах -property нового объекта. Объект PSObject специально предусмотрен для этих целей.

Преимущество этого подхода в том что легко построить хэш таблицу на лету и создать из нее много пользовательских объектов. Вы можете заметить что в выходном объекте свойства имеют не тот же самый порядок как они были определены в таблице. Одно из возможных решений — создать форматирование для кастомного объекта (специальный XML файл описывающий как выводить на экран, в каком порядке и т.п.) или, если вы используете powershell 3 и выше, то можно использовать свойство ordered

$props = [ordered]@{ OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}

Все остальное тоже самое. Теперь свойства объекта будут отображаться в том порядке как они были записаны. Если вы передадите $obj на Get-Member, вы увидете что это PS-CustomObject.

Примечание PowerShell по умолчанию не отслеживает порядок элементов в хэш таблице. Вот почему когда вы видете окончательный вывод его свойства идут не в том порядке в каком вы их создавали. Начиная с PowerShell 3 вы можете исправить это использовав атрибут [ordered]. Это создает упорядоченный словарь (другое название хэш таблиц) и поддерживает порядок элементов в ней.

21.2.2 Техника 2. Использование Select-Object

Этот метод был фаворитом в PowerShell v1, и мы по прежнему видим людей использующих его. Нам она не нравится поскольку ее гораздо сложнее читать. Следующий листинг показывает технику где мы создадим пустой объект, а затем запишем значения этих свойств

Листинг 21.3. Создание объекта используя Select-Object

# Наши четыре неизменные четыре команды
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

# создание объекта через Select-Object
$obj = 1 | Select-Object ComputerName,OSVersion,OSArchitecture, ProcArchitecture,Model,Manufacturer,BIOSSerial

# заполняем поля
$obj.ComputerName = $os.CSName
$obj.OSVersion = $os.version
$obj.OSArchitecture = $os.osarchitecture
$obj.ProcArchitecture = $proc.addresswidth
$obj.BIOSSerial = $bios.serialnumber
$obj.Model = $cs.model
$obj.Manufacturer = $cs.manufacturer
Write-Output $obj

Обратите внимание, что в листинге 21.3 было сделано $obj = 1, по существу значение 1 никогда не будет использовано.

СОВЕТ Вы увидите много примеров, когда пустая строка используют в качестве инициализатора: $obj=»» | select …. Это просто способ определить $obj как объект, закинуть в конвеер что-то, чтобы перейти к Select-Object, который и сделает всю работу.

В этом подходе есть недостаток. Подадим $obj в Get-Member и посмотрим на результат.

PS C:\> $obj | Get-Member
TypeName: Selected.System.Int32
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
BIOSSerial NoteProperty System.String BIOSSerial=
ComputerName NoteProperty System.String ComputerName= WIN-KNBA0R0TM23
Manufacturer NoteProperty System.String Manufacturer= VMware, Inc.
Model NoteProperty System.String Model= VMware Virtual Platform
OSArchitecture NoteProperty System.String OSArchitecture= 64-bit
OSVersion NoteProperty System.String OSVersion= 6.1.7601
ProcArchitecture NoteProperty System.UInt16 ProcArchitecture=64

Свойства на месте, но TypeName может привести к проблемам или даже просто путанице, все зависит от того что вы еще намереваетесь делать с этим объектом. Мы рекомендуем избегать эту технику.

вставка от переводчика

Здесь имеет в виду вот что:

подадим в Get-Member пример из листинга 21.2 — где мы создавали хэш таблицей

теперь подадим на GM пример из листинга 21.3 — создание через Select-Object

21.2.2 Техника 3. Использование Add-Member

Этот метод считается формальным. Мы считаем что он иллюстрирует то что происходит в жизни с формальными подходами. Он наиболее дорогостоящий в вычислительном отношении, медленее всех, так что не часто встретишь людей использующих его в реальной жизни. Это наиболее общий подход PowerShell v1. Есть две вариации, и сначала листинг с кодом.

Листинг 21.4. Создание объекта используя Add-Member

# Наши четыре неизменные четыре команды
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

# создаем объект указав его тип
$obj = New-Object –TypeName PSObject

# добавляем поля указав тип и значение
$obj | Add-Member NoteProperty ComputerName $os.CSName
$obj | Add-Member NoteProperty OSVersion $os.version
$obj | Add-Member NoteProperty OSArchitecture $os.osarchitecture
$obj | Add-Member NoteProperty ProcArchitecture $proc.addresswidth
$obj | Add-Member NoteProperty BIOSSerial $bios.serialnumber
$obj | Add-Member NoteProperty Model $cs.model
$obj | Add-Member NoteProperty Manufacturer $cs.manufacturer
Write-Output $obj

Мы создали PSObject и добавляем по одному свойству к нему за раз. Вам нужно вызвать метод каждый раз когда вы добавляете NoteProperty которая содержит только статическое значение. Для сокращения кода мы использовали позиционные параметры Add-Member. Если использовать полный синтаксис то каждый оператор Add-Member будет выглядеть следующим образом

Add-Member -MemberType NoteProperty -Name ComputerName -Value $os.CSName

вы видите что получается очень много кода.

Вариация этого метода заключается в использовании парамера -PassThru (сокращенно -Pass в листинге 21.5) команды Add-Member. Этот параметр поместит модифицированный объект обратно в конвеер, так что вы сможете передать его на следующую команду и так далее.

Покажем на примере

Листинг 21.4. Создание объекта используя Add-Member с параметром -PassThru

# Наши четыре неизменные четыре команды
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

# создаем объект указав его тип
$obj = New-Object –TypeName PSObject

# создаем свойства
$obj | Add-Member NoteProperty ComputerName $os.CSName –pass |
Add-Member NoteProperty OSVersion $os.version –pass |
Add-Member NoteProperty OSArchitecture $os.osarchitecture –Pass |
Add-Member NoteProperty ProcArchitecture $proc.addresswidth –pass |
Add-Member NoteProperty BIOSSerial $bios.serialnumber –pass |
Add-Member NoteProperty Model $cs.model –pass |
Add-Member NoteProperty Manufacturer $cs.manufacturer
Write-Output $obj

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

вставка переводчика

имеет в виду что отладка легче

21.2.4 Техника 4. Использование декларации типа

Это одна из вариаций техники 1, работает только в PowerShell v3 и v4, этот метод компактнее. Вы начинаете с тойже хэш таблицы.

# Наши четыре неизменные четыре команды
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

$obj = [pscustomobject]@{
                         OSVersion=$os.version
                         Model=$cs.model
                         Manufacturer=$cs.manufacturer
                         BIOSSerial=$bios.serialnumber
                         ComputerName=$os.CSName
                         OSArchitecture=$os.osarchitecture
                         ProcArchitecture=$proc.addresswidth
                         }
Write-Output $obj

Вы могли бы продолжать заполнять переменную $props, трюк этой техники в том что порядок свойств в объекте будет сохранен также как будто мы использовали директиву [ordered]

Совет. Тип который мы используем это PSCustomObject. Вы должны использовать этот тип потому что в .NET терминах вы используете конструктор PSObject без параметров. Не пытайтесь сократить код указав вместо PSCustomObject объект PSObject, вы не получите нужного результата.

Вы могли заметить, что предыдущие методы добавляют свойства в другом порядке чем вы их добавляете. В технике 1 например мы не добавили Computer_Name первым, но он был бы выведен первым в списке. Не беспокойтесь, в подавляющем большинстве случаев PowerShell работает со свойствами в любом порядке. Техника 4 сохраняет порядок свойств, если вам это нужно используйте ее.

21.2.5 Техника 5. Создание нового класса

Не часто используемая техника. Она дает некоторые преимущества в обработке на конвеере. Может быть оценена как продвинутая техника, не все повершельщики захотят вникать в .NET. Но возможность доступна в виде опции

Листинг 21.7 Создание объекта используя класс

$source=@"
public class MyObject
{
public string ComputerName {get; set;}
public string Model {get; set;}
public string Manufacturer {get; set;}
public string BIOSSerial {get; set;}
public string OSArchitecture {get; set;}
public string OSVersion {get; set;}
public string ProcArchitecture {get; set;}
}
"@
Add-Type -TypeDefinition $source -Language CSharpversion3

# наши четыре команды
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost | Select –First 1

$props = @{OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}
$obj = New-Object –TypeName MyObject –Property $props
Write-Output $obj

Листинг 21.7 начинается с создания записи содержащей C# код описания класса. Класс имеет имя, MyObj и делает ряд описаний свойств класса. В этом примере свойства указаны как строки, но допускается смешивать типы. И хотя мы не собираемся записывать устанавливать свойства в будущем, определение класса требует записи GET и SET, в противном случае PowerShell выдаст исключение.

Add-Type используется для компиляции класса, после чего мы можем использовать его вместо PSObject. Для установки свойств объекта может быть использована техника представленная здесь и в листинге 21.6:

$obj = [MyObject]@{OSVersion=$os.version
                                   Model=$cs.model
                                   Manufacturer=$cs.manufacturer
                                   BIOSSerial=$bios.serialnumber
                                   ComputerName=$os.CSName
                                   OSArchitecture=$os.osarchitecture
                                   ProcArchitecture=$proc.addresswidth
                                   }

проведем тестирование в Get-Member

PS C:\> $obj | get-member
TypeName: MyObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
BIOSSerial Property string BIOSSerial {get;set;}
ComputerName Property string ComputerName {get;set;}
Manufacturer Property string Manufacturer {get;set;}
Model Property string Model {get;set;}
OSArchitecture Property string OSArchitecture {get;set;}
OSVersion Property string OSVersion {get;set;}
ProcArchitecture Property string ProcArchitecture {get;set;}

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

21.2.6 Какие различия???

Кроме удобства чтения, количество нажатий на клавиши, требования к сохранению порядка свойств, все эти методы по существу делают тоже самое.

Несколько тонких различий: техника 1, хэш таблица. Как правило самая быстрая, особенно когда вы работаете с несколькими объектами, техника 2 немного медленнее, техника 3 может быть значительно медленнее.

В хорошей рецензии learn-powershell.net/2010/09/19/custom-powershell-objects-and-performance измерена скорость создания объектов выполненная MVP Boe Prox. Проводится сравнение скорости работы трех методов, работа Add-Member в 10 раз медленнее. Так что это плюс к технике 1. Мы не тестировали технику 4 как это делал Boe, но наши тесты показывают что техника 4 быстрее на 10% чем техника 1. Техника 5 должна быть использована в тех случаях когда типизация свойств имеет значение.

Основы PowerShell: введение в объекты | Windows IT Pro/RE

.

Объекты PowerShell предусматривают единообразную структуру для работы с различными типами данных, независимо от источника. Другими словами, способы, с помощью которых вы управляете данными одного объекта, схожи со способами для управления данными другого объекта. Благодаря объектно-ориентированному характеру PowerShell можно не только воспользоваться объектами, в своей основе сгенерированными встроенными командами PowerShell, но также строить и собственные объекты на основе классов в платформе Microsoft. NET Framework. Несомненно, в работе с объектами, в том числе благодаря их неотъемлемому качеству – гибкости, PowerShell демонстрирует качества эффективного и масштабного инструментария.

Объектно-ориентированная структура PowerShell

. NET Framework – это программная структура, включающая объемную библиотеку различных типов классов. Эти классы служат фундаментом, на котором строятся объекты. NET, а также обеспечивают доступ к различным системам, сетям, папкам и ресурсам хранения. PowerShell построен на специализированных классах. NET, благодаря которым возможен доступ ко всей библиотеке классов. NET внутри среды PowerShell. Можно сказать, что эти объекты формируют фундамент, на котором строится PowerShell.

В окружение PowerShell встроена коллекция команд. Каждая команда выполняет определенную операцию, будь то получение списка файлов в папке или управление службой, запущенной на компьютере. Для выполнения такой операции команда создает объект или набор объектов на основе специализированных классов PowerShell. Объекты предусматривают средства для передачи данных по конвейеру, где они могут использоваться другими командами.

Каждый объект можно представить как пакет с соответствующей информацией. Например, объект может содержать данные, необходимые для описания файла: его имя, размер, местоположение и другие атрибуты. Для работы с данными объекта вы вызываете его элементы, которые являются компонентами, позволяющими получить доступ к информации и работать с ней. Объекты PowerShell поддерживают несколько типов элементов, из них два наиболее распространенные – это свойства и методы. Свойство – это именованное значение данных, которое описывает «элементы», представленные объектом. Это может быть размер файла или дата его создания. Методы – это действия, имеющие отношение к данным объекта, такие как удаление или перемещение файла.

Работа с объектами PowerShell

Как работать с объектами PowerShell, лучше всего рассмотреть на примере. Одна из команд, которую предоставляет PowerShell, Get-Service, возвращает список служб, установленных на компьютере. Команда, указанная без определенных параметров, выдает информацию о службах на локальном компьютере.

Каждая служба, возвращаемая командой Get-Service, является объектом на основе класса. NET System.ServiceProcess.ServiceController. Как и большинство объектов, ServiceController содержит многочисленные свойства и методы, которые могут пригодиться для доступа к данным внутри этого объекта или для выполнения операций с данными. Например, объект ServiceController включает свойства Name и DisplayName. Значение данных, связанное со свойством Name, обеспечивает фактическое имя службы. Значение данных, связанное со свойством DisplayName – отображаемое имя, используемое для данной службы. Объект ServiceController также включает ряд методов. Например, вы можете использовать метод Start для запуска службы, представленной объектом, или метод Stop, чтобы остановить работу службы.

Вам не обязательно досконально знать каждое свойство, метод или другой тип элемента, связанный с объектом. В PowerShell предусмотрена команда Get-Member – удобный инструмент для доступа к информации о каждом из элементов, поддерживаемых объектом. Данная команда будет полезна для получения информации обо всех элементах или определенных типах элементов. Для получения информации обо всех элементах, прежде всего, необходимо указать команду, о которой вы хотите узнать и затем воспользоваться командой Get-Member. Разделите две команды вертикальной чертой (символ конвейера команд), как показано ниже:

Get-Service | Get-Member

В данном случае команда направляет по конвейеру объект, возвращаемый командой Get-Service, команде Get-Member. Выполнив команду, вы получите результаты, которые представлены на экране 1.

 

Экран 1. Получение информации о команде Get-Service

Как мы видим, в списке содержится имя каждого элемента, тип элемента и определение, которое может быть значимо или нет, в зависимости от ваших задач программирования. В любом случае очевидно, что объект ServiceController поддерживает ряд элементов, в большинстве своем методы и свойства. Подробнее о различных типах элементов рассказано в статье MSDN «PSMemberTypes Enumeration» (msdn.microsoft.com/en-us/library/windows/desktop/system.management.automation.psmembertypes%28v=vs.85%29.aspx)

Обратите внимание, что результаты, возвращаемые командой Get-Member, начинаются с указания имен типа класса, на которых основан объект — в данном случае, System.ServiceProcess.ServiceController. Наличие данной информации может оказаться полезным, если вы знакомы с классами. NET и хотите еще лучше освоить выполняемые операции. Еще один плюс заключается в том, что вы будете точно знать, что работаете с нужным типом объекта. Здесь мы подходим к еще одному аспекту информации, возвращаемой командой Get-Member. Как вы уже заметили, результаты включают информацию лишь об одном объекте, хотя команда Get-Service возвращает объект для каждой службы. Когда команда Get-Member видит, что возвращается множество объектов одного типа, она включает только один экземпляр этих объектов, чтобы избежать избыточности. Можно также сказать, что она возвращает только класс, на котором основаны все эти объекты.

Однако если команда возвращает более одного типа объектов, Get-Member возвращает информацию о каждом из типов. Например, если вы запускаете команду Get-ChildItem для просмотра папки, содержащей как файлы, так и другие папки, Get-Member будет возвращать информацию о классе System.IO.DirectoryInfo и классе System.IO.FileInfo. Вместе с тем, если папка содержит лишь файлы, Get-Member возвращает информацию только о System.IO.FileInfo. Таким образом, работая с Get-Member, вы должны убедиться, что просматриваете нужные типы объектов.

Команда Get-Member также позволяет увидеть список типов, таких как свойства и методы. Для этого необходимо включить параметр -MemberType, а затем указать имя типа. Например, следующая команда указывает, что возвращаются только свойства объекта:

Get-Service | Get-Member -MemberType Property

Возможность получить подробную информацию об элементе объекта, будь то все элементы или определенный тип элемента, облегчает доступ к указанной информации внутри данного объекта. Например, теперь вы знаете, что класс ServiceController поддерживает свойства Status и ServiceType. Используйте эту информацию внутри команды, чтобы уточнить свои операции. Так, следующая команда использует названные свойства с командой Where-Object для фильтрации результатов:

Get-Service | Where-Object {$_.Status -eq «Running» `
-and $_.ServiceType -eq «Win32OwnProcess»}

В данной команде результат Get-Service (то есть набор объектов ServiceController) передается по конвейеру команде Where-Object. Вам будут доступны свойства каждого объекта, переданного команде Where-Object, чтобы создать фильтры. Для этого сначала укажите символ $_ — системная переменная, указывающая на актуальный объект в конвейере — следом за точкой и именем свойства. Вы можете использовать эти свойства для возвращения указанных данных, определив логическое выражение: true (истина) или false (ложь). В данном случае сначала вы указываете свойство Status, которое должно иметь значение Running и свойство ServiceType со значением Win32OwnProcess для возвращения данных объекта. Обратите внимание, что оператор сравнения -eq используется для оператора эквивалентности, а оператор -and объединяет два выражения. Таким образом, оба условия должны быть истинными (true), для того чтобы объект был возвращен. Также обратите внимание на обратную кавычку (back tick) (`) в первой строке. Так обозначается продолжение кода на следующей строке. На экране 2 показаны возвращаемые командой результаты.

 

Экран 2. Получение подробной информации об объекте

Службы, работающие на моей системе, отвечают требованиям Where-Object, то есть службы выполняются и имеют тип службы Win32OwnProcess. Обратите внимание, что я запускаю PowerShell в виртуальной среде Windows 7.

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

Get-Service | Where-Object {$_.Status -eq «Running» `
-and $_.ServiceType -eq «Win32OwnProcess»} |
Format-Table -Autosize

Даже если исходный пример уже вывел информацию в виде таблицы, команда Format-Table позволяет включить параметр -Autosize, как показано на экране 3.

 

Экран 3. Форматирование вывода командой Format-Table

Теперь давайте рассмотрим другие возможности для просмотра элементов объекта. Начнем с возвращения информации о конкретной службе, MsDtsServer110, которая используется для запуска SQL Server Integration Services (SSIS). Для получения информации применяйте параметр -Name команды Get-Service, чтобы указать имя службы:

Get-Service -Name MsDtsServer110 | Format-List

Передавая по конвейеру результаты команды Get-Service команде Format-List, вы увидите значения свойств, связанные с данным объектом ServiceController, как показано на экране 4.

 

Экран 4. Значения свойств, связанные с объектом ServiceController

PowerShell также позволяет получить доступ к значениям указанных свойств внутри объекта. Для примера предположим, что вам нужно только узнать значение свойства Status, связанного со службой MsDtsServer110. Сделать это можно, вызвав команду Format-Wide с указанием параметра -Property:

Get-Service -Name MsDtsServer110 |
Format-Wide -Property Status

В этом случае команда возвращает только значение Stopped, связанное со свойством Status службы. Кроме того, вы можете получить доступ к объекту ServiceController и его свойству напрямую:

(Get-Service -Name MsDtsServer110).Status

Обратите внимание, что команда Get-Service заключена в скобки. Это необходимо сделать, поскольку без них PowerShell будет рассматривать MsDtsServer110.Status как полное имя службы, а не как имя службы со свойством Status. Скобки заставляют PowerShell сначала выполнить команду, генерирующую объект ServiceController. Затем PowerShell извлекает свойство Status из данного объекта. Опять же команда возвращает значение Stopped.

Этого же результата вы можете достичь и другим способом: назначить выведенный объект ServiceController переменной, а затем использовать эту переменную для вызова значения свойства:

$ssis = Get-Service -Name MsDtsServer110
$ssis.Status

Как мы видим, определена переменная $ssis, и результат Get-Service присваивается в качестве значения. В этом случае не нужно заключать команду Get-Service в скобки. Свойства не вызываются, так что нет никакой путаницы в том, что именно присваивается переменной. Работа команды заключается в создании объекта ServiceController, и этот объект становится значением переменной. Затем вы можете использовать переменную $ssis, чтобы указать на свойство Status объекта ServiceController, добавив точку и имя свойства. Как и две другие команды, эта команда возвращает значение Stopped.

Вы не ограничены лишь свойством Status. Используя переменную $ssis, вы можете получить доступ к значениям любых других свойств. Например, следующая команда задействует переменную $ssis для доступа к свойству DisplayName:

$ssis.DisplayName

Эта команда возвращает значение SQL Server Integration Services 11.0.

Важно отметить, что назначение объекта переменной в этот момент блокирует данные. Например, если статус службы изменится, свойство Status переменной не будет отражать измененный статус, потому что исходные данные уже были назначены данному объекту.

Тем не менее, это не мешает использовать методы переменной, чтобы предпринимать действия в отношении службы. Но для начала просмотрите список доступных методов. Для этого направьте по конвейеру содержимое переменной $ssis команде Get-Member, указав в качестве типа элемента Method:

$ssis | Get-Member -MemberType Method

Как и следует ожидать, команда возвращает список методов, связанных с объектом ServiceController — в этом случае объект создан для службы MsDtsServer110. Затем вы можете задействовать переменную $ssis для вызова любого из этих методов. Например, следующая команда запускает работу службы MsDtsServer110:

$ssis.Start()

Обратите внимание, что, вызывая метод, вы должны добавить скобки в конце, даже если не передаете методу параметры. Если служба уже запущена, ее легко можно остановить:

$ssis.Stop()

Таким образом, понимание принципов работы с объектами, которые генерируют команды, может помочь вам использовать PowerShell более эффективно. PowerShell не предусматривает команд для каждого. NET-класса, но вам может понадобиться задействовать один из классов, чтобы выполнить определенную операцию. В подобных случаях вы можете создавать собственные объекты на основе данных классов.

Создание объекта. NET в PowerShell

Платформа. NET Framework и ее библиотека классов предусматривает полный набор классов для выполнения широкого диапазона операций. Хотя встроенный набор команд PowerShell весьма полезен для доступа к классам, не все соответствующие операции могут быть выполнены. По этой причине PowerShell включает команду New-Object, чтобы вы могли создать собственный объект.

Также стоит заметить, что наряду с созданием объектов на основе классов. NET, PowerShell позволяет создавать модули,. NET-классы (типы), а также объекты Component Object Model (COM). Разбор этих типов объектов остается за рамками данной статьи, но вы должны знать, что возможности PowerShell выходят далеко за пределы того, что я смог вам показать здесь.

Чтобы создать объект на основе класса. NET, нужно задать команду New-Object, а затем указать параметр -TypeName и имя класса. В большинстве случаев проще всего назначить новый объект переменной, которую в дальнейшем можно использовать для доступа к элементам объекта. В следующем примере мы создаем объект на основе. NET-класса System.Net.NetworkInformation.Ping и назначаем его переменной $ping:

$ping = New-Object -TypeName Net.NetworkInformation.Ping

Обратите внимание, что при создании объекта вам не нужно определять System. PowerShell знает, где искать класс.

Это все, что нам необходимо для создания объекта. Вы можете получить доступ к элементам объекта с помощью переменной $ping. В этом случае для просмотра элементов объекта вам нужно передать по конвейеру содержимое переменной команде Get-Member:

$ping | Get-Member

На экране 5 видно, что результаты показывают элементы объекта, возвращаемого командой Get-Member.

 

Экран 5. Элементы вновь созданного объекта

Как вы и ожидаете, объект основан на классе System.Net.NetworkInformation.Ping. Обратите внимание, что класс поддерживает ряд методов, один из которых – Send. Давайте подробнее рассмотрим метод с использованием команды Get-Member для возвращения более подробной информации:

$ping | Get-Member -Name Send | Format-List

Это означает, что вы применяете команду Get-Member с параметром –Name, а затем метод Send. После этого вы направляете по конвейеру информацию, полученную от Get-Member, команде Format-List, которая возвращает результаты, показанные на экране 6.

 

Экран 6. Более подробная информация о новом объекте

Хотя описание довольно широкое, в сущности, оно показывает, что метод позволяет вам опрашивать определенные веб-сайты или IP-адреса, как указано в части, которую считывает Send(string hostNameOrAddress). В следующем примере метод Send опрашивает google.com:

$ping.Send(«google.com»)

В этом случае метод Send возвращает результаты, показанные на экране 7.

 

Экран 7. Результаты работы метода Send

Хотя это очень простой пример применения объектов, созданных на основе. NET-классов, он демонстрирует, что вы не ограничены в получении необходимой информации. Теперь вы многое знаете о различных классах, доступных в. NET, но вам, конечно же, не нужно быть экспертом в разработке. NET, чтобы эффективно использовать это свойство в PowerShell.

Объектно-ориентированный мир PowerShell

Объекты – это корень всех операций PowerShell. Чем лучше вы понимаете, как работают объекты в среде PowerShell, тем эффективнее будете использовать гибкость PowerShell и выполнять множество задач с поддержкой PowerShell. Вы сможете не только в полной мере применять команды PowerShell, но и создавать собственные объекты, а значит, использовать свои системы и сети более продуктивно. Эта статья охватывает лишь малую часть того, что можно делать с объектами в PowerShell. Объекты открывают перед вами перспективы освоения платформы. NET Framework и новые горизонты знаний, выходящие за пределы данной модели.

Поделитесь материалом с коллегами и друзьями

Создание объектов в PowerShell — PKI Extensions

А знаете ли вы, что объекты типа PsObject можно создавать очень легко?

Очень часто в скриптах мы создаём свои кастомайзенные объекты, наделяем их необходимыми свойствами, в которые уже записываем данные, полученные в процессе работы скрипта. Как это делается в классическом случае:

$Object = New-Object System.Management.Automation.PSObject
$Object | Add-Member NoteProperty Computer  ([PSObject]$null)
$Object | Add-Member NoteProperty Name  ([PSObject]$null)
$Object | Add-Member NoteProperty Path  ([PSObject]$null)
$Object | Add-Member NoteProperty Description  ([PSObject]$null)
...

и так для добавления каждого свойства делать новую строчку. В итоге мы получим вот такой объект:

[vPodans] $Object = New-Object System.Management.Automation.PSObject [vPodans] $Object | Add-Member NoteProperty Computer ([PSObject]$null) [vPodans] $Object | Add-Member NoteProperty Name ([PSObject]$null) [vPodans] $Object | Add-Member NoteProperty Path ([PSObject]$null) [vPodans] $Object | Add-Member NoteProperty Description ([PSObject]$null) [vPodans] $object | gm TypeName: System.Management.Automation.PSCustomObject Name MemberType Definition ---- ---------- ---------- Equals Method System.Boolean Equals(Object obj) GetHashCode Method System.Int32 GetHashCode() GetType Method System.Type GetType() ToString Method System.String ToString() Computer NoteProperty Computer=null Description NoteProperty Description=null Name NoteProperty Name=null Path NoteProperty Path=null [vPodans]

Но этот процесс можно сделать ещё более простым и коротким:

$Object = "" | Select Computer, Name, Path, Description

Смотрим:

[vPodans] $Object = "" | Select Computer, Name, Path, Description [vPodans] $object | gm TypeName: Selected.System.String Name MemberType Definition ---- ---------- ---------- Equals Method System.Boolean Equals(Object obj) GetHashCode Method System.Int32 GetHashCode() GetType Method System.Type GetType() ToString Method System.String ToString() Computer NoteProperty Computer=null Description NoteProperty Description=null Name NoteProperty Name=null Path NoteProperty Path=null [vPodans]

Видите, в результате объект получился такой же, зато как эффективно! Но и это ещё не всё. Если с Add-Member мы могли сразу присваивать значения параметру через параметр –Value командлета Add-Member, то и здесь мы можем на стадии создания объекта ему что-то присвоить. Присвоение производится по схеме:

$var = «»  | Select @{n = «PropertyName»;e={«PropertyValue»}}

Для примера сделаем простой объект с несколькими свойствами и сразу при создании запишем в них значения:

$Object = "" | Select @{n='Computer';e={"компик"}},`@
{n=Name;e={"имя"}},@{n="Path";e={"вот тут путь какой-то"}}

проверяем:

[vPodans] $Object = "" | Select @{n='Computer';e={"компик"}},` >> @{n='Name';e={"имя"}},@{n="Path";e={"вот тут путь какой-то"}} >> [vPodans] $Object | gm TypeName: Selected.System.String Name MemberType Definition ---- ---------- ---------- Equals Method System.Boolean Equals(Object obj) GetHashCode Method System.Int32 GetHashCode() GetType Method System.Type GetType() ToString Method System.String ToString() Computer NoteProperty System.String Computer=компик Name NoteProperty System.String Name=имя Path NoteProperty System.String Path=вот тут путь какой-то [vPodans] $Object | fl * Computer : компик Name : имя Path : вот тут путь какой-то [vPodans]

Вот такими небольшими трюками мы позволяем делать PowerShell очень удобным и простым инструментом.

Вобщем, как говорится — As always enjoy the automation of tools within powershell.exe! © Flowering Weeds 🙂

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


Powershell Get-Member работа с методами и свойствами объекта на примерах

Powershell Get-Member — это команда, которая возвращает все свойства и методы объекта. На мой взгляд, после понимания этого командлета, становится намного проще работать с PS.


Get-Member ничего не изменяет, он только показывает что содержится в объекте. Каждый результат каких-то действий формирует объект и для того что бы увидеть из чего он состоит нужно выполнить:



$a = "b"
$a | Get-Member



У каждого объекта в powershell есть метод GetType, который выводит тип данных (строка, число, дата и т.д.). В нашем случае очевидно, что это строка, но порой это бывает не ясно и можно это узнать подобным образом:



$a.GetType()


Свойства на английском Property, а методы Method и порой их бывает очень много, а нам нужно узнать только о конкретном типе. Что бы вывести все свойства выполните следующее:



$a = "test"
$a | Get-Member -MemberType Property



В нашем случае мы видим только один Property, но чаще их бывает больше. Length выводит в powershell длину строки. Вызывается аналогично:



$a.Length



 


Powershell Get-Member на примере свойств и методов файла


Получим список файлов из любой директории подобным образом:



Get-ChildItem -Path 'C:\Folder2\' | Get-Member


Мы можем увидеть, что некоторые методы похожи на командлеты PS. Например выделенный мною будет делать примерно то же (без расширенных возможностей), что и Remove-Item:



Выполнить этот метод мы можем так:



(Get-ChildItem -Path 'C:\Folder2\').Delete()


Есть так же метод, который проверит существование файла. Для примера у нас может создаваться бэкап по определенному пути и мы хотим проверять что планировщик выполнил эту задачу. Мы можем проверить через powershell наличие файла используя Exist:



(Get-Item C:\Folder2\file1.txt).Exists



У файлов много свойств и для примера я хочу получить разные даты файлов в powershell. Я знаю, что все даты хранятся в типах данных datetime и по этому значению я могу отфильтровать:



Get-ChildItem -Path 'C:\Folder2\' | Get-Member -MemberType Property | where -Property Definition -Like "*datetime*"


И затем вывести:



Get-ChildItem -Path 'C:\Folder2\' | fl -Property *Time*



Изменим одну из дат:



$file = Get-Item -Path 'C:\Folder2\file1.txt'
$date = (Get-Date).AddDays(-15)
$file.CreationTime = $date


Примеры работ с Get-Date были тут.


Есть так же свойство, которое покажет расширение файла в powershell:



(Get-ChildItem -Path 'C:\Folder2\').Extension


Теги:

#powershell

Работа в Powershell с массивами и листами на примерах

Массивы в Powershell являются аналогами списков в Python. Легче всего воспринимать эти понятия как хранение в одной переменной множества значений. То есть это структура данных, которую можно перебирать и вызывать отдельный элемент используя индексы. Массивы, они же и множества и array, в Powershell и других языках программирования являются отдельным типом данных так же как числа и строки.






Массивы являются базовой возможностью Powershell, и их создание делается просто. Для создания нужно использовать символы @() :



$array = @()
$array.count



Count (в переводе счетчик) — показывает сколько у нас элементов в массиве. Так как мы создали пустое множество он равен нулю.


Можно создать сразу со значениями. Что бы это выполнить нужно добавить значения, разделенные запятой, внутри @() :



$lst = @('Первый', 'Второй', 'Четвертый', 'Третий')
$lst.Count
$lst



Написав $array мы вывели значения переменной. Каждое из четырех значений выводится с новой строчки. 


Другой способ создания — это писать значения с новой строчки. В этом случае запятые ставить не обязательно:



$lst = @('Первый'
            '2'
            'Третий'
            4)
$lst.Count
$lst



 Хоть такая возможность и есть в Powershell, я бы не советовал использовать без запятых. В остальном, с использованием табуляции, такой синтаксис может улучшить читаемость (особенно если у нас сотни значений).


Еще один способ объявления — это не указывать скобки и знак @ :



$lst = '7',8,'Один','One'



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



$lst = Write-Output Один 2 Трии '4'



Обратите внимание, что число 4 стало строкой только тогда, когда ее поместили в кавычки.


 




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


Индексы


Когда нужно получить конкретный элемент мы указываем скобки []. Самое первое значение массива имеет идентификатор 0. На следующем примере мы получим первый объект:



$arraylist = 'Первый','Второй','Третий'
$arraylist[0]


Для получения следующих индексов просто измените число:



$arraylist[2]



На примерах выше мы получили данные по их индексам. В отличие от большинства языков в Powershell мы можем указывать несколько индексов, которые хотим получить. Так же можно вызвать один и тот же элемент неограниченное количество раз:



$arraylist[0,2]



Срез (slice) или последовательность — это когда мы получаем данные с одного индекса по другой. Последовательности обозначаются двумя точками ‘..’ . Для примера получим первые три значения:



$arraylist = @('admin@login', 'admin', 'Password', '20.02.2004', '????', '????')
$arraylist[0..2]
$arraylist[1..100]



Как видно мы можем получить данные не в строгой последовательности относительно массива. Так же указав несуществующий индекс ‘100’ мы не получили ошибку, а вывели все значения с первого до последнего. Если вызвать единственный элемент, который не будет существовать, то значения будут равны Null.



$null -eq $arraylist[200]


В большинстве языков отрицательное число ‘-1’ обозначает последний объект массива. Обратите внимание, что использование [-1..0] и [0..-1] приведет только к получению первого и последнего элемента:



$arraylist[0..-1]
$arraylist[-1..0]



Можно указать -2 для получения предпоследнего объекта и т.д. Последний объект можно получить и таким образом:



$arraylist.GetUpperBound(0)


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



$arraylist = $null,$null
$arraylist[0]
$arraylist = $null
$arraylist[0]



Возможные ошибки:


  • Не удается индексировать в массив NULL.
  • Cannot index into a null array.

Если вы не совсем понимаете как работает NULL в Powershell, то советовал бы вам прочитать предыдущую статью.


Использование счетчика Count


Счетчик удобно использовать, когда мы хотим проверить количество элементов в массиве:



$lst = '0','2','3','4'
$lst.count

if ($lst.count -eq 4){Write-Output 'Hacked!'}



Используя счетчик можно получить и элемент массива. Если вы никогда не работали с индексами обращайте внимание, что счетчик возвращает количество элементов в массиве, но индексация начинается с 0 элемента. То есть для получения последнего элемента нам нужно вычесть 1:



$lst[$lst.count - 1]
$lst[0..($lst.count - 1)]
$lst[2,($lst.count - 1)]


 


Если вы не закроете в скобки выражение в случае получения среза, то будут следующие ошибки:


  • Сбой вызова метода из-за отсутствия в [System.Object[]] метода с именем «op_Subtraction».
  • Method invocation failed because [System.Object[]] does not contain a method named ‘op_Subtraction’.

Замена элементов


Для замены элементов так же нужно указать индекс. Если мы хотим заменить первый объект, то соответственно нужно указать индекс 0:



$data = @(7,5,8,4,5)
$data[0]=0
$data
$data[-1]='Пять'
$data



Указание несуществующего индекса вызовет ошибки:


  • Index was outside the bounds of the array
  • Индекс находился вне границ массива.

 




Кроме индексов с массивом часто приходится работать используя циклы и другие методы перечисления. Далее будет рассказано об этом.


Конвейер или Pipeline


В примере ниже мы проверим доступность хостов передав каждый объект массива через конвейер:



$sites = 'localhost','fixmypc.ru'
$sites | ForEach-Object {ping $_}



Цикл ForEach


В циклах массивы используются похоже:



foreach ($site in $sites)
{
ping $site
}



Так же доступен метод foreach, который немного отличается синтаксисом, но работает так же:



$sites.foreach({ping $_})


Использование switch


Switch это аналог условий, который объединен в единую конструкцию. Мы можем объявить switch и передать в наш список:



$data = 'folder','hack'
switch( $data )
{
'folder' {'Создать папку с именем'; New-Item -Path 'C:\Array' -ItemType Directory}
'file' {'Создать файл'}
'hack' {'Взломать аську'; ping fixmypc.ru}
Default {'Ничего не создавать'}
}



Обновление значений через циклы


Если нам понадобится обновить весь массив мы обратимся к циклам и мы можем столкнуться с трудностями. Проблемы заключаются в том, что в цикле находится не сам массив, а его значения и мы не сможем их изменить так. Обойти эту ситуацию можно двумя путями.


Первый способ — это обратиться к каждому значению по индексу, а саму ‘длину’ индексов измерить методами, которые описаны выше:



$val = @(1,2,3)
0..($val.Count-1) | foreach {$val[$_]=$val[$_] + 1}


В Powershell мы можем генерировать список из чисел указав только первое и последнее число и именно это я делал в следующей строке:



0..($val.Count-1)


В другой строке я указал заменить число под этим индексом на новое прибавив 1:



$val[$_]=$val[$_] + 1


Еще один способ через ‘for’, который практически не применяется PS:



for ( $index = 0; $index -lt $array.count; $index++ )
{
$array[$index] = ($array[$index] + 1) -f $array[$index]
}



 






В предыдущих примерах мы рассматривали работу с типами данных, но массивы могут хранить любые данные и объекты. Такие методы удобно использовать, когда собираете много данных и часто с ними работаете:



$data = @(
[pscustomobject]@{Computer='localhost';Login='admin';Process=Get-Process -ComputerName 'localhost'},
[pscustomobject]@{Computer='127.0.0.1';Login='lizun';Process=Get-Process -ComputerName '127.0.0.1'}
)
$data



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


Для получения данных мы можем указывать индексы:



$data[0]


После получения объекта вызвать свойство (‘колонку’ с примера выше), которое нам нужно:



$data[0].Computer
$data[0].Process



Когда нужно будет получить, например, все имена компьютеров используем циклы:



$data | ForEach-Object {$_.Computer}


Можно вызвать напрямую или командлет Select-Object:



$data | select Computer
$data.Computer



 




Фильтрация можно использовать, например, когда нам нужно найти все цифры из массива наполненным разными данными. На следующем варианте видно, что она мало чем отличается от того, что мы применяем в командлетах:



$list = @(
[pscustomobject]@{Name='Dima';SubName='Penkin'},
[pscustomobject]@{Name='Valera';SubName='Lerov'}
)
$list | where {$_.Name -like 'D*' -and $_.SubName -like '*n'}
$list | Where-Object SubName -eq 'Lerov'



Аналогично способу выше есть метод, который фильтрует так же:



$list.Where({$_.Name -eq 'Dima'})


 




При использовании циклов таким способом мы будем обновлять значение Name во всех значениях массива:



foreach($iden in $list)
{
$iden.Name = 'Sasha'
}



Если вы хотите заменить конкретное свойство, нужно использовать условия:



$list = @(
[pscustomobject]@{Name='Dima';SubName='Penkin'},
[pscustomobject]@{Name='Valera';SubName='Lerov'}
)
foreach($iden in $list){
if ($iden.Name -eq 'Dima'){$iden.Name='dd'}
}
$list



Заменить весь объект используя цикл нельзя.


 






Join это оператор, который может преобразовать весь массив в единую строку где разделителем может быть любой символ:



$string_array = @('Masha', 'Sasha', 'Dima')
$string_array -join '.'
$string_array -join ' пошел к '



Следующие варианты просто сольют все символы в одну строку без пробелов:



$string_array = @('Masha', 'Sasha', 'Dima')
$string_array -join $null
-join $string_array


 Можно использовать для логирования ошибок:



$data = @((Get-Date).Day, 'Error 5051', (hostname))
"Ошибка $data"



-replace


Операторы замены проверит каждый элемент и выполнят замену совпадающих значений:



$massive = 'Lena','Misha','Pika'
$massive -replace 'M','S'
$massive.Replace('L','p')



Более подробно мы уже говорили о replace с Powershell.


-split


Split преобразует строку в список. В качестве разделителя я указал пробел:



$massive = 'Преобразование строки'
$massive -split ' '
$massive.Split(' ')



-contains 


Этот оператор проверяет точное вхождение и возвращает булево значение True или False:



$list = 'Вася','Федя'
# Верно
$list -contains 'Вася'
# Не верно
'Вася' -contains $list



-in


Отличия от contains в том, что он появился в Powershell 3 и создан для более удобной читаемости. В операторах Powershell важно соблюдать позиции того что мы ищем и где. Ошибки могут быть очень неявными. В случае с contains объект должен находиться слева, а в in справа:



$list = 'Вася','Федя'
# Верно
'Вася' -in $list
# Не верно
$list -in 'Вася'



Этот оператор так же можно использовать для поиска в массиве Powershell.


 -eq и -ne


При использовании сравнения ‘eq’ у нас вернется либо само значение, либо False. В случае неравенства ‘ne’ вернутся либо остальные значения, либо True. Важно использовать искомое значение справа, а объект слева:



$data = @('один','два','три')
# Верно
$data -eq 'один'
$data -ne 'один'
# Не верно
'один' -eq $data
'один' -ne $data



Если нужно проверить, что все значения в листах совпадают требованиям, можно воспользоваться такой конструкцией:



$array = @('Ok','Ok','not Ok')
if ( -not ( $array -ne 'Ok') ){'Что-то не так, это False'}

$array = @('Ok','Ok','Ok')
if ( -not ( $array -ne 'Ok') ){'Все ок'}



-match и -like


Оператор match позволяет использовать регулярные выражения. Он будет искать каждое совпадение в массиве и вернет их:



$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
# Верно
$var -match '22'
# Не верно
'22' -match $var


В операторе like можно использовать знак *, который будет идентифицировать пропущенный текст. Следующий пример сработает с ошибкой в случае с match:



$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
# Верно
$var -like '2*S'
# Не верно
'2*S' -like $var


Похоже сработает Select-String:



$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
$var | Select-String 22


 




Если мы будем проверять существующий массив, в котором нет значений, то следующий пример вернет False:



$foo = @()
if($foo -eq $null) { "Пустой" } else { "Значения есть" }


Он так же вернет False, если внутри будет $null:



$foo = @($null)
if($foo -eq $null) { "Пустой" } else { "Значения есть" }


Что бы избежать ошибок нужно добавлять счетчик:



if ( $foo -ne $null -and @($foo).count -gt 0 ){'Все по маслу'}





Для сортировки в Powershell используется командлет Sort-Object:



$sort = 4,7,3,2,4
$sort | Sort-Object
$sort = 'V','F','A'
$new_sort = $sort = 'V','F','A' | Sort-Object


Более подробно командлет Powershell Sort-Object уже рассматривался.


 




Фактически Powershell не позволяет добавлять элементы в массив. Для того что бы это сделать массив сначала удаляется, а затем создается новый. Возможно кому-то будет более понятно это под «неизменяемый объект». Тем не менее процесс удаления и создания сильно упрощен в PS и вам не составит труда это сделать.


Сложение


Для создания нового массива можно указать оператор сложения для двух существующих:



$a = @('1')
$b = @('2','4')
$c = $a + $b
$c


Другой способ существует во множестве языках:



$array_add = @('1')
$array_add += 2
$array_add



Создание из конвейера


 Можно генерировать новый массив используя старый:



$array_add = @(0)
1..5 | ForEach-Object { $array_add+=$_ }
$array_add



 




По умолчанию массив в Powershell создается типа [PSObject[]]. Это позволяет хранить любые типы данных. Если вы хотите хранить строгие типы данных, например только числа или определенный набор, то вы можете использовать следующие методы:


Массив из определенных типов данных


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



[int[]] $num = 9,2,3,'4'


Обратите внимание, что 4 объявлена строковой, но она сама преобразуется в число без ошибок. В случае добавления букв будет ошибка:


  • Не удается преобразовать значение «s» в тип «System.Int32». Ошибка: «Входная строка имела неверный формат.»
  • Cannot convert value «s» to type «System.Int32». Error: «Input string was not in a correct format.»

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



[string[]] $str = '8','s','d'
$str+= 1



Универсальные списки


Универсальные списки относятся к C#, в котором нужно определять типы данных. Так мы создадим список из строк:



$list = [System.Collections.Generic.List[string]]::new()


А так будет создан список из целых чисел:



$list = [System.Collections.Generic.List[int]]@(32,55,66)


Начиная с версии Powershell 5 можно сократить синтаксис используя using namespace. Using указывается в самом начале скрипта. 



using namespace System.Collections.Generic
$list = [List[int]]@(31,32,33)



Следующий синтаксис добавит число в список:



$list.Add(10)


Значения так же можно получать по индексам:



$list[-1]



Для удаления используется следующий синтаксис:



using namespace System.Collections.Generic
$var = [List[string]]@('Один','Два','Три')
[void]$var.Remove('Один')


Можно так же удалять по индексам:



$delete = $var[1]
$var.remove($delete)



List[PSObject]


Список из любого типа данных можно создать и так:



using namespace System.Collections.Generic
$list = [List[PSObject]]::new()



ArrayList


Для поддержки удаления, которого нет в обычных массивах, можно использовать ArrayList. Они так же быстрее работают. Для создания такого массива используйте следующий синтаксис:



$arraylist = [System.Collections.ArrayList]::new()
[void]$arraylist.Add('Someval')
$arraylist


Для удаления:



$arraylist.Remove('Someval')


 




Кроме основных методов по работе с массивами есть методы, которые позволяют генерировать списки и создавать фиксированного размера. Далее разберем на примерах.


Фиксированный размер


В Powershell можно создать список с предопределенным размером:



$data = [Object[]]::new(5)
$data.count



Умножение


Так же как и в других языках массивы можно умножать:



$var = @('A','B','C')
$var*5


Похожий метод, который создаст 10 нулей:



[int[]]::new(10)



Вложенность


Массив внутри других массивов называются вложенными. Работа с ними отличается только индексами:



$array = @(
@(2,2,2),
@(3,3,3)
)


Чтобы получить значение нужно использовать индексы дважды:



$array[0][1]
$array[1][1]



Учитывая это можно создать двумерный массив.


 




Учитывая предыдущие примеры мы сможем создать двумерный массив или матрицу:



$dv_massive = @(
@(1,2,3,4),
@(3,4,5,6),
@(7,8,9,10)
)


Для получения, например, единицы нам нужно использовать индексы дважды:



$dv_massive[0][0]


Если вызвать весь массив, то он будет выведен построчно. Можно вывести и так:



ForEach($el in $dv_massive){Write-Host $el[0] $el[1] $el[2] $el[3]}



Можно вывести указав SyncRoot:



$dv_massive | select SyncRoot


Многомерный массив можно создать и вывести с параметрами так:



$ma_massive = New-Object 'object[,]' 5,3
# Внесение в первую колонку
$ma_massive[0,0] = 1
$ma_massive[1,0] = 2
$ma_massive[2,0] = 3
$ma_massive[3,0] = 4
$ma_massive[4,0] = 5
# Во вторую
$ma_massive[0,1] = 'A'
$ma_massive[1,1] = 'B'
$ma_massive[2,1] = 'C'
$ma_massive[3,1] = 'D'
$ma_massive[4,1] = 'E'
# Третью
$ma_massive[0,2] = 1988
$ma_massive[1,2] = 1999
$ma_massive[2,2] = 1876
$ma_massive[3,2] = 1478
$ma_massive[4,2] = 1247
# Вывод
Write-Host $ma_massive[0,0] $ma_massive[0,1] $ma_massive[0,2]
Write-Host $ma_massive[1,0] $ma_massive[1,1] $ma_massive[1,2]
Write-Host $ma_massive[2,0] $ma_massive[2,1] $ma_massive[2,2]
Write-Host $ma_massive[3,0] $ma_massive[3,1] $ma_massive[3,2]
Write-Host $ma_massive[4,0] $ma_massive[4,1] $ma_massive[4,2]


 

Теги:

#powershell

Классы в Powershell. Введение, свойства

Начиная с версии 5.0 в Powershell появилась возможность использовать свои собственные классы для создания объектов. Естественно, перед тем как создавать объект пользовательского класса, его (класс) нужно определить. Этим сегодня и займёмся.

(Даже если вы не планируете создавать классы всё равно не помешает познакомиться с этой темой, так как это даст понимание модели .Net Framework.)

Вообще классы это большая и сложная тема, но я постараюсь в нескольких статьях всё подробно и просто объяснить.

Классы используются в качестве основы, каркаса, из которых мы будем создавать свои объекты. Другими словами классы – это шаблоны, которые используются для создания объектов (экземпляров класса).

 

Описание класса

Как и функции, и конфигурации, описание класса начинается с ключевого слова (Class), за которым идёт имя класса, а следом в фигурных скобках тело класса:

Class MyClass
{
    ...
}

В теле (описании) класса описываются члены класса: свойства, методы и т.д. В этой статье поговорим о свойствах.

Рассмотрим создание простого класса, описывающего робота. Допустим, наши будущие роботы будут иметь такие свойства:

(Для начала и простоты. В дальнейшем возможно добавим ещё.)

Таким образом, в простейшем случае, класс может выглядеть следующим образом:

Class Robot
{
    $Name
    $Id
    $Birthday
}

            Готово! Мы подготовили наш первый класс. Теперь можем создавать собственную армию дроидов роботов – объекты (экземпляры класса) на основе нашего класса.

             

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

            Создавать объект можно классическим способом, используя командлет New-Object:

$Verter = New-Object -TypeName Robot

(имя параметра –TypeName можно опустить)

а можно использовать статический метод  New() (что это такое поговорим в следующих статьях):

$Verter = [Robot]::new()

 

Примечание: у одного из гуру Powershell прочёл, что использование метода New() предпочтительнее, так как работает быстрее, но по факту я прироста скорости не заметил, более того, где-то в 20% случаев New() отрабатывал дольше, чем старый знакомый New-Object.

Как видно, в обоих случаях в качестве типа создаваемого объекта мы указываем имя нашего класса.

После создания объекта можем заполнять его свойства:

$Verter.Name = 'Verter'
$Verter.Id = 1
$Verter.Birthday = '2017-01-01'

На этом этапе может возникнуть вопрос: А зачем такие сложности, мы же и раньше могли создавать объекты? Например, вот так:

$Verter = New-Object -TypeName PSObject -Property @{
    '$Name' = 'Verter'
    'Id' = 5
    'Birthday' = '2017-01-01'
}

Во-первых, если посмотреть типы созданных объектов, то увидим, что во втором случае тип объекта – PSCustomObject.

PS C:\> $Verter.GetType().Name
PSCustomObject

Не слишком информативно, правда? Если бы мы его не только что его создали, трудно было-бы догадаться, что вообще находится в переменной $Verter. В то время как при использовании классов, тип объекта определяется именем созданного нами класса:

PS C:\> $Verter.GetType().name
Robot

Во-вторых, использование классов предоставляет кучу возможностей, но обо всём по порядку.

 

Типы свойств

 

Здесь ничего нового. Также как и параметрам функций, свойствам классов можно задавать типы и значения по умолчанию. Более того, задавать типы желательно всегда, так как Powershell не всегда корректно определяет типы сам, что может вылезти боком в дальнейшем. Например:

PS C:\> $Verter.Birthday.GetType().Name
String

Powershell определил тип свойства, отвечающего за дату создания, как строку, в то время как мы подразумевали дату. Поэтому добавим в наш класс типы свойств:

Class Robot
{
    [String]$Name
    [Int]$Id
    [DateTime]$Birthday
}

Теперь при задании свойства $Birthday, экземпляра класса Robot, Powershell будет ожидать дату:

        Соответственно, при задании имени будет ожидаться строка, а при задании идентификатора – целое число.

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

Понравилось это:

Нравится Загрузка…

Похожее

Работа с объектами в Windows PowerShell

В PowerShell все является объектом. Даже простой текст является объектом типа Strong. Объект — это программное представление чего-либо. У каждого объекта есть свойства и методы.

E x a m p l e — A Ноутбук

P r op e r r e s портативного компьютера включает название модели, ОС, стоимость, размер экрана и т. д…

M e t h od s портативного компьютера: включение портативного компьютера, выключение портативного компьютера, перезапуск портативного компьютера и т. Д.

G e t -Член

Используя командлет Get-Member , вы можете найти свойства и методы объекта. Вам необходимо передать объект Get-Member по конвейеру, чтобы узнать свойства и методы объекта.

Примечание

| Символ — это конвейер PowerShell.

E x a m p l e

PS C: \> Get-Service | Get-Member

Здесь будут перечислены все свойства и методы, доступные для службы.

Изображение: Свойства и методы обслуживания.

N e w -Object

Используя командлет New-Object , вы можете сгенерировать объект любого типа. Для настраиваемых объектов можно выбрать Object и PSObject.

В этом примере ниже давайте создадим новый объект с помощью PSObject и сохраним его в переменной laptopObject. Затем давайте подключим этот объект к команде Add-Member. Этот Add-Member добавит свойства или методы к объекту.

Далее мы будем использовать MemberType для NoteProperty, а затем дать имена свойствам. Затем, наконец, определим Value как все, что нам нужно.

Примечание

Разница между Object и PSObjects заключается в том, что Object создает объект класса System.Object, а PSObject создает объект класса System.Management.Automation.PSCustomObject].

Изображение Создание нового объекта

Where-Object

Мы используем W here-Object для заполнения и выбора определенных значений свойств из набора объектов.

Ex a m p l e

PS C: \> $ laptopObject | Where-Object {$ _. OS -eq «OS X»}

Это вернет тот объект, который имеет значение свойства ОС «OS X»

Select-Object

Select-Object выбирает свойства объекта или из множества предметов.

Ex a m p l e

PS C: \> $ laptopObject | Select-Object -Property LaptopName, Model, Cost

Sort-Object

В Windows PowerShell можно отсортировать объект по значениям параметра -property. Давайте рассмотрим простой пример, чтобы понять, как можно отсортировать информацию об объекте.

Ex a m p l e

PS C: \> Get-ChildItem C: \

Этот командлет возвращает все файлы и папки на My C: Drive

Теперь, если вы посмотрите на выделенную часть в выводе, значения свойства Length не сортируются.Итак, чтобы отсортировать значения свойства Length, мы используем объект sort. Примеры ниже объясняют, как отсортировать значения свойства Length.

Ex a m p l e

PS C: \> Get-ChildItem C: \ | Sort-Object -Property Length

Запустив вышеуказанный командлет, я вижу, что все значения свойства Length теперь отсортированы.

.

Создание объектов в Windows PowerShell — блог SAPIEN

Применимо к: PowerShell 5.0.10240

Недавно я был в прекрасном городе Копенгаген, Дания, где я был гостем PSUG.DK, группы пользователей PowerShell в Дании. Мы встретились в шикарных офисах Microsoft, чтобы познакомиться с классами по Windows PowerShell 5.0.

Microsoft Office, Копенгаген, Дания.

В практической лабораторной работе мы создаем класс, создаем экземпляры класса и добавляем конструкторы, свойства и методы.Затем мы пробуем некоторые из более продвинутых функций, такие как статические свойства и методы, наследование и интерфейсы.

Чтобы сделать класс достаточно кратким, когда мы создаем объекты, я показываю New-Object и New static метод объектов, но замалчиваю создание объектов из хэш-таблиц. В этой записи блога я хотел бы представить все три метода и объяснить, как их использовать.

Создание объектов в командной строке

Существует (как минимум) три способа создать объект в Windows PowerShell.Первые два метода зависят от конструкторов, определенных в классе. Третья, хэш-таблицы, требует только конструктора по умолчанию , то есть конструктора, который не имеет параметров и не принимает аргументов или значений.

Дополнительные сведения о создании объектов в Windows PowerShell см. В разделе about_Object_Creation.

О конструкторах

Конструкторы — это специальные методы, которые инициализируют объекты в классе. Конструкторы класса определяют, какие значения свойств необходимо указать для создания класса.

Один тип конструктора особенно важен. Он называется конструктором по умолчанию , хотя его часто называют пустым конструктором или конструктором без параметров . Конструктор по умолчанию не имеет параметров и не принимает аргументов или значений. Он определяется так:

Я создам класс Tree со свойствами «Виды», «Высота» и «Листопадные». Класс Tree имеет конструктор по умолчанию (без параметров), конструктор, который принимает строку Species и целое число Height, а также метод Grow.

 class Tree {

    [String] $ Species
    [int32] $ Высота
    [Boolean] Лиственный = $ True

    Дерево () {}
    Дерево ([String] $ Species, [int32] $ Height)
    {
        $ this.Species = $ Виды
        $ this.Height = $ Высота
    }

    [int32] Рост ([int32] $ Amount)
    {
        $ this.Height + = $ Сумма
        вернуть $ this.Height
    }
} 

класс Tree {

[String] $ Species
[int32] $ Высота
[Boolean] Лиственный = $ True

Дерево () {}
Дерево ([String] $ Species, [int32] $ Height)
{
$ this.Виды = $ Виды
$ this.Height = $ Высота
}

[int32] Рост ([int32] $ Amount)
{
$ this.Height + = $ Сумма
вернуть $ this.Height
}
}

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

 PS C: \> [Дерево] :: Новое

OverloadDefinitions
-------------------
Дерево новое ()
Дерево новое (String Species, int Height) 

Результат показывает, что вы можете создать объект Tree без параметров или со строкой и целым числом (в указанном порядке).

Конструктор — это метод, поэтому при его использовании вы не указываете имена параметров, а должны указывать значения в том порядке, в котором они определены в конструкторе. Если вы этого не сделаете, команда не сработает.

Конструкторы обладают двумя особенностями:

  • У них то же имя, что и у класса.
  • Вы не звоните им напрямую. Вместо этого вы используете технику, использующую конструктор, например командлет New-Object или статический метод New.

Дополнительные сведения о конструкторах см. В разделах about_Classes и Зачем нужны конструкторы?

Используйте командлет New-Object

Чтобы создать экземпляр класса с помощью командлета New-Object, используйте следующий синтаксис:

 New-Object -Typename  -ArgumentList  

New-Object -Typename -ArgumentList

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

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

 Дерево новое (вид строки, высота int) 

Дерево новое (виды строки, высота int)

Пример:

 PS C: \> $ myTree = New-Object -TypeName Tree -ArgumentList 'Maple', 10
PS C: \> $ myTree

Вид Высота Листопадные
------- ------ ---------
Клен 10 Истинный 

Если вы вводите другое количество значений или значения типа, которые не могут быть преобразованы в указанный тип, команда завершится ошибкой.

 PS C: \> Новый объект -TypeName Tree -ArgumentList 10, 'Maple'

New-Object: невозможно преобразовать аргумент «1» со значением «Maple» для «Tree» в тип «System.Int32»: «Невозможно преобразовать значение» Maple
«Входная строка была в неправильном формате».
В строке: 1 символ: 1
+ New-Object -TypeName Tree -ArgumentList 10, 'Maple'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
+ CategoryInfo: InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId: исключение ConstructorInvokedThrowException, Microsoft.PowerShell.Commands.NewObjectCommand 

Класс Tree также имеет конструктор по умолчанию — без параметров. Чтобы создать объект Tree с конструктором по умолчанию, просто опустите параметр ArgumentList. Затем вы можете присвоить значения свойствам индивидуально.

 PS C: \> $ myTree = New-Object -TypeName Tree
PS C: \> $ myTree

Вид Высота Листопадные
------- ------ ---------
0 Верно

PS C: \> $ myTree.Species = 'Клен'
PS C: \> $ myTree.Высота = 10
PS C: \> $ myTree.Deciduous = $ True 

Используйте новый статический метод

Вы также можете использовать метод New для создания объекта. (Метод не новый. Это его имя.) Новый метод — это статический метод — метод класса, а не метод объекта — поэтому вы используете синтаксис с двумя последовательными двоеточиями (: 🙂 для его вызова. .

Метод New обычно требует меньшего набора текста, чем New-Object, но он немного менее знаком пользователям PowerShell.

Чтобы использовать новый метод для создания объекта, используйте следующий синтаксис:

 [] :: New () 

[] :: New ()

Опять же, при использовании конструктора введите значения, указанные конструктором, в список, разделенный запятыми.Будьте внимательны, вводя значения в порядке, указанном конструктором. Не включайте имена параметров.

Например, чтобы создать объект «Дерево» со следующим конструктором:

 Дерево новое (вид строки, высота int) 

Дерево новое (виды строки, высота int)

Тип:

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

Использование хеш-таблицы

Хеш-таблица — очень удобный способ создания объекта. Хотя обычно для этого требуется больше ввода, чем при использовании New-Object или статического метода New, вам не нужно использовать конкретный конструктор.

Поскольку вы указываете имена параметров, вы можете указывать значения в любом порядке. (Ключи в хеш-таблице по определению неупорядочены, поэтому порядок не имеет значения.)

Однако этот метод работает только тогда, когда класс имеет конструктор по умолчанию , то есть конструктор без параметров.Кроме того, свойства, которые вы указываете в хеш-таблице, должны быть «настраиваемыми», то есть они не могут быть доступны только для чтения.

Например, класс Tree имеет конструктор по умолчанию.

 PS C:> [Дерево] :: Новое

OverloadDefinitions
-------------------
Дерево новое () #
 

Чтобы создать объект с хеш-таблицей, используйте следующий синтаксис:

 [Имя класса] @ {<Параметр> = <Значение>; <Параметр> = <Значение> ...} 

[Имя класса] @ {<Параметр> = <Значение>; <Параметр> = <Значение>...}

Например:

 [Дерево] @ {Species = 'Maple'; Высота = 10} 

[Дерево] @ {Species = 'Maple'; Высота = 10}

Однако вы также можете создать хеш-таблицу, которая не соответствует конструктору. И поскольку вы указываете имена параметров, порядок значений не имеет значения.

Эти команды тоже работают. Значения свойств, которые вы не укажете, остаются неопределенными.

 [Дерево] @ {Высота = 10; Species = 'Maple'}
[Дерево] @ {Лиственный = $ True; Высота = 10; Species = 'Maple'}
[Дерево] @ {Species = 'Maple'} 

[Дерево] @ {Высота = 10; Species = 'Maple'}
[Дерево] @ {Лиственный = $ True; Высота = 10; Species = 'Maple'}
[Дерево] @ {Species = 'Maple'}

Хеш-таблицы и классы PowerShell

Хеш-таблицы настолько удобны, что многие утверждают, что они должны быть основным способом создания классов PowerShell.

Они также особенно хорошо подходят для классов PowerShell, поскольку Windows PowerShell автоматически добавляет конструктор по умолчанию к каждому классу.

 PS C: \> класс AnyClass {}
PS C: \> [AnyClass] :: Новое

OverloadDefinitions
-------------------
AnyClass новый () 

Когда вы создаете свой собственный конструктор, конструктор по умолчанию исчезает, и вам нужно создать его заново.

Таким образом, некоторые люди утверждали, что не следует создавать конструкторы в классе PowerShell.Вы должны просто оставить конструктор по умолчанию и позволить использовать создание объектов с хеш-таблицами.

Я думаю, что это хорошая общая практика, но могут быть случаи, когда вы хотите потребовать, чтобы каждый экземпляр класса имел определенное значение свойства. В этом случае вам нужно опустить конструктор по умолчанию и создать только конструкторы, которые включают необходимое значение свойства.

Итак, вот оно. Вы можете создавать классы и экземпляры этих классов. Еще раз спасибо Клаусу, Хайне и всем фантастическим ребятам из Дании по PowerShell.

Июнь Blender - технологический евангелист в SAPIEN Technologies, Inc и MVP по Windows PowerShell. Вы можете связаться с ней по адресу [email protected] и подписаться на нее в Twitter по адресу @juneb_get_help.

.

Управление подразделениями и перемещение их объектов с помощью PowerShell

Организационное подразделение (OU) — это контейнер в Active Directory, в котором могут храниться пользователи, группы и компьютеры, а также другие подразделения. Каждый домен AD может иметь собственную иерархию организационных единиц.

В этой статье вы узнаете об управлении подразделениями и о том, как использовать сценарии PowerShell для:

PowerShell ISE — лучший инструмент для работы со сценариями PowerShell. Запустите инструмент PowerShell ISE с правами администратора, нажав «Windows + R» и введя «runas / profile / user: Administrator PowerShell_ISE» в окне «Выполнить».При появлении запроса введите пароль администратора. Кроме того, вы можете щелкнуть правой кнопкой мыши значок PowerShell ISE и выбрать параметр «Запуск от имени администратора».

Для работы с AD и его объектами необходимо импортировать модуль Active Directory для Windows PowerShell. В Microsoft Windows Server 2008 R2 вам необходимо включить этот модуль, выполнив следующую команду:

 Import-Module ActiveDirectory 

В Microsoft Windows Server 2012 и более поздних версиях этот модуль включен по умолчанию.

Создание подразделений в домене Active Directory с помощью PowerShell.

Вы можете создать новое подразделение в Active Directory с помощью командлета New-ADOrganizationalUnit и указания имени нового объекта подразделения. По умолчанию PowerShell создает OU в корне домена. Приведенная ниже команда создаст OU с именем «Regions» на DC:

 New-ADOrganizationalUnit «Regions» 

Если вам нужен другой путь LDAP OU, укажите его отличительное имя с помощью параметра командлета –Path :

 New -ADOrganizationalUnit «Regions» –Path «OU = Managers, DC = Enterprise, DC = com» 

Перемещение OU на другой адрес LDAP

Если вам нужно переместить OU в другое место, используйте Move-ADObject командлет.Обратите внимание, что целевое подразделение не должно быть защищено от случайного удаления. Если это так, используйте эту команду, чтобы удалить эту защиту:

 Set-ADOrganizationalUnit -Identity "OU = Regions, OU = Managers, DC = Enterprise, DC = Com" -ProtectedFromAccidentalDeletion $ False 

Теперь вы можете переместить OU в другое расположение:

 Move-ADObject -Identity "OU = Regions, OU = Managers, DC = Enterprise, DC = Com" -TargetPath "OU = IT, DC = Enterprise, DC = Com" 

Переименовать OU

Чтобы переименовать организационное подразделение, используйте командлет Rename-ADObject .Параметр -Identity указывает объект Active Directory для переименования и требует либо его отличительного имени (DN), либо GUID.

Эта команда переименовывает OU «Regions» в «Districts»:

 Rename-ADObject -Identity «OU = Regions, OU = IT, DC = enterprise, DC = COM» -NewName Districts 

В качестве альтернативы можно использовать Get-ADOrganizationalUnit командлет с параметром -Filter ; он не требует полного пути LDAP к OU. Однако этот командлет будет искать во всем AD, и действие будет применено ко всем подразделениям, которые содержат поисковый запрос в своих именах:

 Get-ADOrganizationalUnit -Filter "Name -eq 'Regions'" | Rename-ADObject -NewName Country 

Применение групповой политики к OU

Чтобы назначить групповую политику для OU, используйте командлет New-GPLink , который в основном устанавливает связь между указанным объектом групповой политики (GPO) и OU.Для ссылки можно указать любое из следующих свойств:

  • Включено — Если ссылка включена, настройки объекта групповой политики применяются при обработке групповой политики для сайта, домена или подразделения.
  • Принудительно — Если ссылка принудительная, ее нельзя заблокировать в контейнере нижнего уровня.
  • Порядок — порядок определяет приоритет настроек GPO.

Следующая команда связывает GPO «Block Software» с OU «Districts» с включенной и принудительной ссылкой:

 New-GPLink -Name «Block Software» -Target «OU = Districts, OU = IT, dc = enterprise, dc = com "-LinkEnabled Да -Выполнено Да 

Перемещение компьютеров и пользователей в новое OU

После того, как вы создали OU и, при необходимости, связали его с GPO, пора заполнить его пользователями и компьютеры.Командлет PowerShell Move-ADObject перемещает любой объект или набор объектов (например, пользователя, компьютер, группу или другое подразделение) в другое подразделение. Параметр -Identity указывает, какой объект или контейнер Active Directory перемещать. Обратите внимание, что вам нужно ввести полный путь LDAP или SID объекта; вы не можете использовать его SamAccountName. В приведенном ниже примере показано, как переместить пользователя (Джон Браун) в подразделение «Районы»:

 Move-ADObject -Identity "CN = John Brown, CN = Users, DC = enterprise, DC = com" -TargetPath "OU = Районы, OU = IT, DC = Enterprise, DC = Com "

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

 Move-ADObject -Identity "CN = R07GF, OU = CEO, DC = enterprise, DC = com" -TargetPath "CN = Computers, DC = Enterprise , DC = Com 

Перемещение компьютеров и пользователей AD в другое подразделение с помощью файла CSV или TXT

Если у вас есть заранее определенный список перемещаемых объектов, вы можете сохранить его как файл CSV, а затем импортировать этот файл в Active Directory. Список CSV должен иметь следующий формат:

Используйте этот сценарий PowerShell для перемещения учетных записей пользователей AD, перечисленных в файле CSV:

 # Укажите целевое подразделение.Сюда будут перемещены пользователи.
$ TargetOU = "OU = районы, OU = IT, DC = enterprise, DC = com"
# Укажите путь CSV. Импортируйте файл CSV и назначьте его переменной.
$ Imported_csv = Import-Csv -Path "C: \ temp \ MoveList.csv"

$ Imported_csv | ForEach-Object {
# Получить DN пользователя.
$ UserDN = (Get-ADUser -Identity $ _. Имя) .distinguishedName
# Переместить пользователя в целевое OU.
Move-ADObject -Identity $ UserDN -TargetPath $ TargetOU

} 

Чтобы переместить учетные записи компьютеров AD, перечисленные в текстовом файле, используйте следующий сценарий PowerShell:

 # Укажите путь к текстовому файлу с именами учетных записей компьютеров.$ computers = Get-Content C: \ Temp \ Computers.txt

# Укажите путь к OU, куда будут перемещены компьютеры.
$ TargetOU = "OU = районы, OU = IT, DC = enterprise, DC = com"
ForEach ($ компьютер в $ компьютерах) {
Get-ADComputer $ компьютер |
Move-ADObject -TargetPath $ TargetOU

} 

Удалить OU из AD

Командлет Remove-ADOrganizationalUnit удаляет OU. OU не должно быть защищено от случайного удаления. Вы можете удалить параметр случайного удаления для каждого подразделения, которое содержит «Континенты» в своем имени, используя командлеты Get-ADOrganizationalUnit и Set-ADOrganizationalUnit следующим образом:

 Get-ADOrganizationalUnit -filter «Name -eq 'Continents'» | Set-ADOrganizationalUnit -ProtectedFromAccidentalDeletion $ False 

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

 Get-ADOrganizationalUnit -filter «Name -eq 'Continents'» | Remove-ADOrganizationalUnit –Recursive 

Вам будет предложено подтвердить удаление:

Обратите внимание, что параметр -Recursive удаляет как OU, так и все его дочерние объекты.Дочерние объекты будут удалены, даже если для них включена защита от удаления.

Заключение

Теперь, когда вы узнали, как управлять подразделениями в Active Directory с помощью сценариев PowerShell, вы можете автоматизировать множество простых операций, связанных с управлением подразделениями. Перед тем, как опробовать эти команды, обязательно включите функцию корзины Active Directory, чтобы вы могли легко откатить любые ошибочные удаления. Также разумно внимательно отслеживать все изменения в ваших организационных подразделениях.

Джефф — директор по разработке глобальных решений в Netwrix.Он давний блоггер Netwrix, спикер и ведущий. В блоге Netwrix Джефф делится лайфхаками, советами и приемами, которые могут значительно улучшить ваш опыт системного администрирования.

.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *