*EDITED

mały tutorial o przetwarzaniu przekazywanych wartości, który może radykalnie zmienić czas przetwarzania skryptu. wiadomka – pipelining jest podstawowym mechanizmem PS a przy przetwarzaniu wielu elementów, czasem wręcz odruchowo, wpisuje się ‚%’ czyli foreach-object. przykładowo – znajdź wszystkich, którzy mają nazwisko na ‚x’ i wyślij im wiadomość:

a teraz standardowy scenariusz z życia codziennego: dostajemy jakieś listy w postaci pliqw tekstowych. załóżmy, że są w nim nazwy kont, z którymi coś trzeba zrobić. szkielet jest trywialny:

…mija czas i okazuje się, że nasze ‚do-something’ rozbudowaliśmy do postaci skryptu, ponieważ ilość wykonywanych czynności rośnie i oneliner jest zbyt mało wygodny. wartości można do skryptu przekazywać na dwa sposoby – bezpośrednio, jako parametr lub – tak jak powyżej – przez pipelining. druga metoda nie działa ‚od ręki’, wymaga włączenia poprzez specjalny parametr: ‚valueFromPipeline‚ [lub valueFromPipelineByPropertyName… ale to na inny wpis].

żeby pokazać co się będzie działo załóżmy, że mamy listę komputerów i operacja wymaga uwierzytelnienia się do zdalnego zasobu:

w takim przypadq, aby uruchomić skrypt dla całej listy, należy przekazać listę przez parametr:

polecenie w nawiasach ‚( )’ zostanie przetworzone, listing pliq zwraca tablicę stringów string[] i to zostanie przetworzone w skrypcie. jak na razie oczywiste oczywistości. nuda… ale zadanie nad którym pracujemy chcemy coraz bardziej automatyzować, cały proces do którego piszemy skrypty jest dość rozbudowany, a więc nasze skrypty muszą ze sobą gadać – output z jednego chcemy móc przekierować na kolejny. czyli trzeba włączyć pipelining:

jeśli przekażemy wartości przez parametr tak, jak do tej pory, to nic się nie zmieni. ale jeśli przekażemy przez pipe … coś nie halo:

..wyświetli tylko dla ostatniego elementu /: [zwróć uwagę, że skrypt ‚do-something’ wywołany jest bez parametru – valueFromPipeline oznacza ‚jeśli potok wyjściowy jest przekierowany, przekaż go do tej zmiennej oznaczonej valueFromPipeline’ ]

ah! no oczywiście! zapomnieliśmy foreach:

[tutaj już musi być parametr – $_ . a to dla tego, że nawiasy klamrowe ‚{ }’ definiują blok danych, separując potok od polecenia. niby niuans ale pokazuje, że totalnie zmienia się mechanika pod spodem]

hmm… no ale mamy kolejny problem – teraz skrypt przed każdym wywołaniem prosi o dane uwierzytelniające. lama poradzi sobie dodając parametr ‚credential’ i przekazując go podczas wywołania. ale to nie jest zawsze dobry sposób i dobrze wiedzieć czemu tak się dzieje. błąd został popełniony w momencie dodania ‚foreach’ (2). parametr ‚identities’ w skrypcie został sprytnie zadeklarowany jako tablica, a więc powinien tablicę przyjąć. ale dodając ‚foreach’, rozbijamy tablicę na poszczególne elementy i uruchamiamy skrypt wiele razy, przekazując każdą kolejną wartość jako parametr wywołania. a nie o to chodziło.

rozwiązaniem jest dodanie składni ‚begin-process-end’ do skryptu. standardowo skrypt czeka na pojedynczą wartość, po dodaniu tego bloq tworzy ‚pułapkę’ zawartą w bloq ‚process’, która będzie się uruchamiać dla każdego kolejnego elementu. co więcej, ‚process’ zostanie wykonany dla każdego przekazywanego elementu dokładnie tak, jak ‚foreach’, a więc można się pozbyć tego fragmentu:

teraz jeśli uruchomi się ‚do-sthelse | do-something’ – zostaniemy zapytanie o credsy tylko raz, po czym wykonana zostanie część ‚process’, a na koniec jednokrotnie wykona się klauzula ‚end’. wyrzucam ‚gwmi’ żeby pokazać przetwarzanie i zostawiam tylko write-host:

o to chodziło.

co zapamiętać

czym innym jest przekazanie tablicy a czym innym kolejne przekazywanie parametrów tablicy – czyli foreach. jeśli skrypt jest duży, to można dużo oszczędzić. dla tego przy pokaźnych operacjach warto zajrzeć do pomocy, opisu parametrów skryptu i sprawdzić czy deklaracja:

  • pozwala na przekazanie tablicy – np. [string[]]
  • pozwala na przekazanie przez pipe – valueFromPipeline

ponadto trzeba pamiętać, że ponieważ ‚valueFromPipeline’ jest pewnego rodzaju wskaźnikiem ‚TU PRZEKIERUJ WSZYSTKO CO WPADA’ – to może być zadeklarowane tylko raz. zadeklarowanie wielokrotnie nie spowoduje błędu składniowego, skrypt uruchomi się, ale wyniki będą mocno niedeterministyczne…

eN.