Centrum Skryptow - Systemy Operacyjne

Jak zarządzać zadaniami programu Windows PowerShell?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

*

Jak zarządzać zadaniami programu Windows PowerShell?

Cześć, Skrypciarze! Nie jestem pewna, na ile w moim środowisku roboczym przyda się uruchomienie apletu polecenia Get-Process jako zadania. Mniej-więcej rozumiem, o co Wam chodzi — podajecie ilustrację techniki pracy z zadaniami programu Windows PowerShell — ale to, co chcę zrobić, zajmuje naprawdę dużo czasu. Chciałabym wiedzieć nie tylko, jak uruchomić proces w postaci zadania, ale także jak go zakończyć, gdyby zaczął pochłaniać zbyt dużo zasobów. Czy zadaniami programu Windows PowerShell można zarządzać po ich utworzeniu?

— BP

Cześć, BP!

Czołem, tutaj skrypciarz Ed Wilson. Dzisiaj przeglądam e-maile przesłane na adres scripter@microsoft.com, słuchając Milesa Davisa w swoim Zunie HD. Zaparzyłem ziołową herbatę, którą przywiozłem kiedyś z Niemiec. Do niemieckiej herbaty mam specjalnie dobrane niemieckie ciastka Leibniz. Jakiś czas temu prowadziłem w Berlinie zajęcia z WMI. Doskonale wspominam spacery po Placu Poczdamskim i herbatę pitą w ogródkach kawiarń. Jest tam znakomity system kolejek miejskich, dzięki którym można poruszać się po całym Berlinie. Z tamtego pobytu przywiozłem to zdjęcie, zrobione podczas któregoś ze spacerów w szczególnie pogodną noc. To jedno z moich ulubionych zdjęć z Berlina. Bardziej lubię chyba tylko zdjęcie Bramy Brandenburskiej, które pokażę w którymś z przyszłych artykułów. Berlin to świetne miejsce na robienie zdjęć.

JBP, zanim zajmiemy się zarządzaniem zadaniami programu Windows PowerShell, chciałbym poświęcić nieco więcej czasu na omówienie ich uruchamiania i rozwinąć to, co pisałem wczoraj.

Uruchamiając zadanie programu Windows PowerShell przy użyciu apletu polecenia Start-Job, można przypisać zwróconemu obiektowi zadania nazwę, w której będzie on przechowywany. Można też, używając prostego przypisania wartości, przechować obiekt zadania w zmiennej. Przechowanie i w nazwie, i w zmiennej spowoduje powstanie dwóch kopii zwróconego obiektu zadania. Widać to poniżej:

 

PS C:\> $rtn = Start-Job -Name getSoftware -ScriptBlock {gwmi win32_software}

PS C:\> Get-Job -Name get*



Id              Name            State      HasMoreData     Location             Command

--              ----            -----      -----------     --------             -------

1               getSoftware     Completed  True            localhost            gwmi win32_software





PS C:\> $rtn



Id              Name            State      HasMoreData     Location             Command

--              ----            -----      -----------     --------             -------

1               getSoftware     Completed  True            localhost            gwmi win32_software

Pobranie zadania przy użyciu apletu polecenia Receive-Job usuwa dane. Nie można więc później wrócić do zwróconych danych i pobrać ich ponownie. Ilustruje to kod widoczny poniżej:

PS C:\> Receive-Job $rtn

Invalid class

    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException

    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand



PS C:\> Receive-Job get*

PS C:\> Receive-Job $rtn

PS C:\>

Przykład ten ukazuje również, co się dzieje, jeśli blok skryptu zwróci błąd. Użycie apletu polecenia Receive-Job powoduje wyświetlenie komunikatu o błędzie. Aby odszukać dodatkowe informacje o kodzie, który spowodował błąd, należy użyć obiektu Job przechowywanego w zmiennej $rtn lub zadania o nazwie GetSoftware. Ja wolę używać obiektu zadania przechowywanego w zmiennej $rtn. Widać to poniżej:

PS C:\> $rtn.Command

gwmi win32_software

PS C:\>

Nie istnieje klasa WMI Win32_software. Właściwa nazwa klasy WMI to Win32_product. Usuńmy najpierw pozostałe obiekty job, pobierając zadania i usuwając je. Widać to poniżej:

PS C:\> Get-Job | Remove-Job

PS C:\> Get-Job

PS C:\>

Po utworzeniu nowe zadanie programu Windows PowerShell działa w tle. Nie są wyświetlane żadne informacje o zakończeniu zadania błędem lub o jego powodzeniu. Trudno nawet stwierdzić, czy zadanie zostało zakończone — trzeba w tym celu kilka razy użyć apletu polecenia Get-Job, aby sprawdzić, czy stan zadania zmienił się z Running na Completed. W przypadku wielu zadań nie jest to żaden problem. Może to być nawet bardziej korzystne, jeśli zależy nam na tym, aby odzyskać kontrolę nad konsolą programu Windows PowerShell natychmiast po rozpoczęciu wykonywania zadania. Czasem jednak chcemy otrzymać powiadomienie o zakończeniu zadania programu Windows PowerShell. W tym celu można użyć apletu polecenia Wait-Job. Apletowi polecenia Wait-Job należy nadać nazwę lub identyfikator zadania. W ten sposób konsola programu Windows PowerShell zatrzyma się do ukończenia zadania. Następnie zadanie zostanie wyświetlone w konsoli z informacją o zakończeniu. Następnie można użyć apletu polecenia służącego do odbierania zadania, odbierając rozszeregowane obiekty i przechowując je w zmiennej. Jak widać poniżej, można potem użyć właściwości count, aby sprawdzić, ile pakietów oprogramowania jest zainstalowanych na komputerze:

PS C:\> $rtn = Start-Job -ScriptBlock {gwmi win32_product}

PS C:\> $rtn



Id              Name            State      HasMoreData     Location             Command

--              ----            -----      -----------     --------             -------

5               Job5            Running    True            localhost            gwmi win32_product





PS C:\> Wait-Job -Id 5



Id              Name            State      HasMoreData     Location             Command

--              ----            -----      -----------     --------             -------

5               Job5            Completed  True            localhost            gwmi win32_product





PS C:\>

PS C:\> $prod = Receive-Job -Id 5

PS C:\> $prod.Count

145

PS C:\>

W nowej konsoli programu Windows PowerShell używany jest aplet polecenia Start-Job, uruchamiający nowe zadanie. Tworzony obiekt jest przechowywany w zmiennej $rtn. Obiekt job zawarty w zmiennej $rtn można przekazać potokiem do apletu polecenia Stop-Job, aby zatrzymać wykonywanie zadania. Jeśli spróbujemy uzyskać informacje o zadaniu, używając bezpośrednio obiektu job przechowywanego w zmiennej $rtn, zostanie wygenerowany błąd. Widać to poniżej:

PS C:\> $rtn = Start-Job -ScriptBlock {gwmi win32_product}

PS C:\> $rtn | Stop-Job

PS C:\> Get-Job $rtn

Get-Job : The command cannot find the job because the System.Management.Automation.PSRemotingJob name was not found. 

              Verify the value of the Name parameter, and then try the command again.

At line:1 char:8

+ Get-Job <<<< $rtn

    + CategoryInfo          : ObjectNotFound: (System.Manageme...n.PSRemotingJob:String) [Get-Job], PSArgumentException

    + FullyQualifiedErrorId : JobWithSpecifiedNameNotFound,Microsoft.PowerShell.Commands.GetJobCommand

Można przesłać obiekt zadania do apletu polecenia Get-Job, aby sprawdzić, że zadanie jest zatrzymane. Aplet polecenia Receive-Job pozwoli odebrać informacje o zadaniu, a właściwość count pozwoli sprawdzić, ile produktów programistycznych zawiera zmienna. Widać to poniżej:

PS C:\> $rtn | Get-Job



Id              Name            State      HasMoreData     Location             Command

--              ----            -----      -----------     --------             -------

1               Job1            Stopped    True            localhost            gwmi win32_product





PS C:\> $products = Receive-Job -Id 1

PS C:\> $products.count

73

Na powyższej liście widać, że wyliczone zostały tylko 73 pakiety oprogramowania. Jest to spowodowane tym, że polecenie Get-Wmiobject, używane do pobrania informacji z klasy Win32_Product, miało za mało czasu, aby dokończyć działanie. Zadanie zostało zatrzymane mniej-więcej w połowie działania. Chcąc wyświetlić nazwy wszystkich zainstalowanych pakietów oprogramowania, powinniśmy przesłać potokiem odebrane elementy zadania (przechowywane w zmiennej $products) do apletu polecenia Select-Object i wybrać nazwę. Poniżej widać dane wyjściowe w postaci skróconej:

PS C:\> $products | Select name



Name

----

XML Notepad 2007

PowerShellPack

Catalyst Control Center InstallProxy

Microsoft Office Visio Professional 2007

Microsoft Office OneNote MUI (English) 2007

Microsoft Office Groove Setup Metadata MUI (English) 2007

Microsoft Office InfoPath MUI (English) 2007

Microsoft Office Visio MUI (English) 2007

Microsoft Office Access MUI (English) 2007

Microsoft Office Shared Setup Metadata MUI (English) 2007

Microsoft Office Excel MUI (English) 2007

Microsoft Office Shared 64-bit Setup Metadata MUI (English) 2007

Microsoft Office Access Setup Metadata MUI (English) 2007

Microsoft Office PowerPoint MUI (English) 2007

Microsoft Office Publisher MUI (English) 2007

Microsoft Office Outlook MUI (English) 2007

Microsoft Office Office 64-bit Components 2007

Microsoft Office Shared 64-bit MUI (English) 2007

Microsoft Office Groove MUI (English) 2007

…Truncated output …

Aby wyświetlić wszystkie aplety poleceń związane z zadaniami, możemy użyć apletu polecenia Get-Command za parametrem –noun, szukając wszystkiego, co zawiera ciąg znaków „job”. Używając apletu polecenia Select-Object, pobieramy tylko nazwy apletów poleceń. Widać to poniżej:

PS C:\> Get-Command -Noun *job* | Select-Object name

 

Name

----

Get-Job

Receive-Job

Remove-Job

Start-Job

Stop-Job

Wait-Job

 

 

PS C:\>

Teraz omówiliśmy już wszystkie sześć apletów poleceń programu Windows PowerShell, które wiążą się z zadaniami. Jutro przedstawimy kolejny skrypt z serii poświęconej zadaniom programu Windows PowerShell.

Jeśli chcecie szybciej dowiadywać się, jakim tematom poświęcone będą kolejne artykuły, śledźcie nas w serwisie Twitter lub Facebook. W razie jakichkolwiek pytań piszcie do nas na adres scripter@microsoft.com lub publikujcie na oficjalnym forum skrypciarzy. Do zobaczenia jutro.

 Do początku strony Do początku strony

Centrum Skryptow - Systemy Operacyjne