Jak zarządzać zadaniami programu Windows PowerShell?
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 |