Статья размещена автором Бетке Сергей Сергеевич

Непростые операторы powershell: оператор подвыражения массива @( )

Прошу не ругать. Опишу свой печальный опыт, обеспеченный моей же собственной невнимательностью. Речь пойдёт об операторе подвыражения массива @().

Я думаю, часто возникает необходимость работать с результатом запроса, как с массивом, даже если результат – 1 объект:

$test2 = Get-ADUser -filter {sAMAccountName -like 'sergey*'}
$test2.count
3

$test = Get-ADUser -filter {sAMAccountName -like 'sergey.s.betke'}
$test.count


$test3 = @(Get-ADUser -filter {sAMAccountName -like 'sergey.s.betke'})
$test3.count
1

На указанном выше примере постараюсь пояснить свои мучения и суть оператора @. Делаем запрос к командлету в надежде получить некоторое количество объектов. Логично ожидать массив (это логика меня и подвела). А у массива есть свойство – count. И как видно, в первом случае оно выдаёт количество объектов, полученных в результате запроса. Однако, если в результате будет один объект, powershell не будет формировать массив. Будет возвращён сам объект. Поэтому во втором случае мы имеем $null, потому как нет свойства count у нашего объекта. Однако, согласитесь, хочется иметь код, который мог бы ВСЕГДА рассматривать результат как массив, хоть из 1ого объекта, хоть из нескольких.

Для этих целей как раз и служит оператора @() (третий пример). Это оператор в случае множества объектов в качестве результата ничего не меняет, в случае одного объекта – формирует массив из одного объекта.

Противоположностью ему в некотором смысле служит Оператор подвыражения $( ). Именно его поведение и соответствует поведению powershell без явного указания @(): возвращает результат одного или нескольких выражений, в случае одного результата возвращает скалярное значение. В случае нескольких результатов возвращает массив.

Наткнулся на любопытную статью: http://blogs.technet.com/b/powershell_ru/archive/2009/02/27/3214144.aspx. Автор предлагает использовать функцию в конвейере, если требуется массив:

function ToArray{
    begin {
        $output = @(); 
    }
    process {
        $output += $_; 
    }
    end {
        return ,$output; 
   }
}

Используя выше приведённую функцию, выше приведённый пример можно переписать следующим образом:

$test = Get-ADUser -filter {sAMAccountName -like 'sergey.s.betke'} | ToArray
$test.count
1

Буду надеяться, что кому-либо данная статья поможет не наломать дров.

Отзывы » (1)

  1. Сергей:

    Можно проще:[array] $test = Get-ADUser -filter {sAMAccountName -like 'sergey.s.betke'}

Опубликовать комментарий

XHTML: Вы можете использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Tags Связь с комментариями статьи:
RSS комментарии
Обратная ссылка