Jak liczyć obiekty w PowerShell?

140

Jak czytam w podręczniku użytkownika programu PowerShell, jedną z podstawowych koncepcji programu PowerShell jest to, że polecenia akceptują i zwracają obiekty zamiast tekstu. Na przykład uruchomienie get-aliaszwraca mi kilka System.Management.Automation.AliasInfoobiektów:

PS Z: \> get-alias

Definicja nazwy typu polecenia
----------- ---- ----------
Alias% ForEach-Object
Alias ​​? Where-Object
Alias ​​ac Add-Content
Alias ​​asnp Add-PSSnapIn
Alias ​​cat Get-Content
Alias ​​cd Set-Location
Alias ​​chdir Set-Location
...

Teraz, jak mam policzyć te obiekty?

ulidtko
źródło

Odpowiedzi:

201

Dzięki temu policzysz:

get-alias | measure

Możesz pracować z wynikiem jak z obiektem:

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

A jeśli chciałbyś mieć aliasy również w jakiejś zmiennej, możesz użyć Tee-Object:

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

Więcej informacji na temat polecenia cmdlet Measure-Object znajduje się w witrynie Technet .

Nie myl go z cmdletem Measure-Command, który służy do pomiaru czasu. (ponownie w Technet )

landara
źródło
3
Użyłem, $Counter = $(get-alias | measure).Countponieważ zawsze zwraca wartość 1 na wypadek, gdyby było tylko jedno wystąpienie, tak jak powiedziałeś.
DarkLite1
6
Inna opcja:get-alias | measure | % { $_.Count }
Shameer
fyi: measurejest skrótem od Measure-Object; i zwraca wiele innych rzeczy - jak Average, Sum, Maximumitp ...
BrainSlugs83
1
Dlaczego nie po prostu (gal) .count? Wymaga PS v3 lub nowszej IIRC. EDYTUJ: na to już odpowiedziano.
uranibaba
4
@Shameer Skoro już o tym mowa, można Get-Alias | Measure-Object | Select-Object -ExpandProperty Countpozbyć się %i {}. To, co łatwiej jest pisać i czytać, służy do innej dyskusji.
LosManos
110

Krótka jak odpowiedź @ jumbo brzmi :-), możesz to zrobić jeszcze bardziej zwięźle. To po prostu zwraca Countwłaściwość tablicy zwróconej przez poprzednik podwyrażenie:

@(Get-Alias).Count

Kilka punktów do zapamiętania:

  1. Możesz wstawić dowolnie złożone wyrażenie Get-Alias, na przykład:

    @(Get-Process | ? { $_.ProcessName -eq "svchost" }).Count
  2. Początkowy znak at (@) to niezbędny do niezawodnego rozwiązania. Dopóki odpowiedź wynosi dwa lub więcej, otrzymasz równoważną odpowiedź z lub bez znaku @, ale gdy odpowiedź będzie wynosić zero lub jeden, nie otrzymasz żadnego wyniku, chyba że masz znak @! (Wymusza istnienie Countwłaściwości przez wymuszenie, aby dane wyjściowe były tablicą).

Aktualizacja 2012.01.30

Powyższe dotyczy PowerShell V2. Jedną z nowych funkcji programu PowerShell V3 jest to, że masz Countwłaściwość nawet dla pojedynczych elementów, więc znak at staje się nieistotny w tym scenariuszu.

Michael Sorens
źródło
3
Wiem, że to jest stare, ale dla innych, którzy szukają tego… wersja 3 + nie wydaje się działać bez znaku @ for count <2, jeśli Set-StrictMode -Version Latestjest używany. Właśnie spotkałem się z tym dzisiaj (na 5.1) - coś działało interaktywnie, co nie działało w funkcji. Wyśledziłem to do funkcji, w której znajduje się Set-StrictMode; kiedy ustawiłem interaktywnie tryb ścisły, to też nie działało.
vr8ce,
Dobry chwyt, @ vr8ce! Ja też jestem zdecydowanym zwolennikiem Set-StrictMode, więc powinienem był to zauważyć.
Michael Sorens,
Aby rozwinąć poradę @ vr8ce, nie mogłem użyć @ ($ myObject) do obliczenia liczby istniejących obiektów. Więc używam if ($myObject.PSobject.Properties.Name -contains "count")(ze stackoverflow.com/questions/26997511/… ) przed próbą przetestowania właściwości count. Nienawidzę tego, że PoSH zmusza mnie do tego, ale tryb ścisły jest tego wart.
channel_tape_coder
21

Po prostu użyj nawiasów i „liczyć”. Dotyczy to Powershell v3

(get-alias).count
prabhakaran
źródło
1
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienie, zostaw komentarz pod jego postem.
Zo ma
@Damien OK. Dokonałem edycji. W SO ludzie generalnie przychodzą od pierwszej do ostatniej odpowiedzi. Nie przejdą nagle do trzeciej odpowiedzi i nie będą zdezorientowani. Tak więc uczyniłem to jako kontynuację pierwszych dwóch odpowiedzi. Ta odpowiedź ma więcej sensu niż ta zredagowana.
prabhakaran
1
Jest to już omówione w tej odpowiedzi . Po prostu powtarzasz to, co już zostało powiedziane dwa lata po tym, jak zostało powiedziane.
Liam
1
@Liam To odpowiedź dotyczy powershell v2. Moja odpowiedź brzmi: PowerShell v3. Jak powiedziałeś, ta odpowiedź jest opisana / przekazana dosłownie w aktualizacji (aktualizacja 2012.01.30) w tej odpowiedzi. Właśnie dałem część kodowania.
prabhakaran
5

@($output).Countnie zawsze daje prawidłowe wyniki. Użyłem ($output | Measure).Countmetody.

Znalazłem to za pomocą polecenia cmdlet VMware Get-VmQuestion:

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

Odpowiedź, jakiej udzielił, jest jedna, a tymczasem

$output

nie wygenerowało żadnego wyniku (poprawna odpowiedź to 0, zgodnie z otrzymaną Measuremetodą).

Wydawało się, że tak jest tylko w przypadku 0 i 1. Wszystko powyżej 1 było poprawne przy ograniczonych testach.

bchris999
źródło
Chris, myślę, że aby uzyskać to, czego chciałeś, musisz to zrobić: @ (Get-VmQuestion -VM vm1) .count Nie możesz zmusić wyjścia, aby było tablicą ... gdy wynik jest już utworzony . Co właśnie robisz.
Daniel Peel