Как считать объекты в PowerShell?

140

Как я читаю в руководстве пользователя PowerShell, одна из основных концепций PowerShell заключается в том, что команды принимают и возвращают объекты вместо текста. Так, например, запуск get-aliasвозвращает мне несколько System.Management.Automation.AliasInfoобъектов:

PS Z: \> get-alias

Определение имени CommandType
----------- ---- ----------
Alias% ForEach-Object
Алиас? Where-Object
Alias ​​ac Add-Content
Псевдоним asnp Add-PSSnapIn
Alias ​​cat Get-Content
Alias ​​cd Set-Location
Alias ​​chdir Set-Местоположение
...

Теперь, как я могу получить количество этих объектов?

ulidtko
источник

Ответы:

201

Это позволит вам рассчитывать:

get-alias | measure

Вы можете работать с результатом как с объектом:

$m = get-alias | measure
$m.Count

И если вы хотите иметь псевдонимы в некоторой переменной, вы можете использовать Tee-Object:

$m = get-alias | tee -Variable aliases | measure
$m.Count
$aliases

Дополнительная информация о командлете Measure-Object находится в Technet .

Не путайте его с командлетом Measure-Command, предназначенным для измерения времени. (снова на Technet )

гигантский
источник
3
Я использовал, $Counter = $(get-alias | measure).Countпоскольку он всегда возвращает значение 1 в случае, если есть только одно вхождение, как вы сказали.
DarkLite1
6
Другой вариант:get-alias | measure | % { $_.Count }
Shameer
к вашему сведению: measureэто сокращение от Measure-Object; и возвращает много других вещей - как Average, Sum, Maximumи т.д ...
BrainSlugs83
1
Почему не просто (гал) .count? Требуется PS v3 или выше IIRC. РЕДАКТИРОВАТЬ: на это уже был дан ответ.
Уранибаба
4
@ Shameer Пока мы на этом, можно использовать, Get-Alias | Measure-Object | Select-Object -ExpandProperty Countчтобы избавиться от %и {}. Что легче написать и прочитать, для другого обсуждения.
LosManos
110

Если ответ @ jumbo таков :-), вы можете сделать это еще более кратко. Это просто возвращает Countсвойство массива, возвращенного подвыражением antecedent:

@(Get-Alias).Count

Пара моментов, на которые стоит обратить внимание:

  1. Вы можете поместить произвольно сложное выражение вместо Get-Alias, например:

    @(Get-Process | ? { $_.ProcessName -eq "svchost" }).Count
  2. Начальный знак at (@) необходим для надежного решения. Если ответ равен двум или более, вы получите эквивалентный ответ с или без @, но если ответ равен нулю или единице, вы не получите никакого вывода, если у вас нет знака @! (Это заставляет Countсвойство существовать, заставляя вывод быть массивом.)

2012.01.30 Обновление

Вышесказанное верно для PowerShell V2. Одна из новых функций PowerShell V3 заключается в том, что у вас есть Countсвойство даже для синглетонов, поэтому знак «at» становится неважным для этого сценария.

Майкл Соренс
источник
3
Я знаю, что это старо, но для тех, кто ищет это ... v3 + не работает без @ для счетчика <2, если Set-StrictMode -Version Latestиспользуется. Я только что столкнулся с этим сегодня (на 5.1) - что-то работало в интерактивном режиме, что не работало в функции. Я проследил это до функции, в которой есть Set-StrictMode; когда я установил строгий режим в интерактивном режиме, он тоже не работал.
vr8ce
Хороший улов, @ vr8ce! Я тоже решительный сторонник Set-StrictMode, поэтому я должен был это заметить.
Майкл Соренс
Чтобы расширить совет @ vr8ce, я не мог использовать @ ($ myObject) для подсчета существующего объекта. Поэтому я использую if ($myObject.PSobject.Properties.Name -contains "count")(из stackoverflow.com/questions/26997511/… ) перед попыткой проверить свойство count. Я ненавижу, что PoSH заставляет меня делать это, но Строгий Режим стоит того.
duct_tape_coder
21

Просто используйте скобки и «считать». Это относится к Powershell v3

(get-alias).count
Прабхакаран
источник
1
Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
Zo Has
@Damien ОК. Я сделал редактирование. В SO люди обычно приходят от первого ответа к последнему. Они не будут внезапно прыгать в третий ответ и запутаться. Так что я сделал это как продолжение первых двух ответов. Этот ответ имеет больше смысла, чем этот отредактированный.
прабхакаран
1
Это уже освещено в этом ответе . Вы просто повторяете то, что уже было сказано через два года после того, как было сказано.
Лиам
1
@Liam Этот ответ для powershell v2. Мой ответ для powershell v3. Как вы сказали, этот ответ описан буквально в обновлении (2012.01.30 Update) в этом ответе. Я просто дал часть кодирования.
Прабхакаран
5

@($output).Countне всегда дает правильные результаты. Я использовал ($output | Measure).Countметод.

Я нашел это с помощью командлета VMware Get-VmQuestion:

$output = Get-VmQuestion -VM vm1
@($output).Count

Ответ, который он дал, один, тогда как

$output

не вывел никаких результатов (правильный ответ был 0, как получено с помощью Measureметода).

Казалось, что это только в случае с 0 и 1. Все, что выше 1, было правильным с ограниченным тестированием.

bchris999
источник
Крис, я думаю, чтобы получить то, что вы хотели, вам нужно это сделать: @ (Get-VmQuestion -VM vm1) .count Вы не можете заставить вывод быть массивом ... как только вывод уже сделан , Что ты и делаешь
Даниэль Пил