2012-06-07 31 views
5

tôi có thể tạo một công việc nền đơn giản trong Powershell:"HasMoreData" là đúng ngay cả sau khi Nhận-Job

Start-Job {"Hello"} 

tôi kiểm tra với Get-Job:

Id  Name   State   HasMoreData  Location  Command 
    --  ----   -----   -----------  --------  ------- 
    1   Job1   Completed  True    localhost  "Hello" 

Tiếp theo, tôi chỉ đơn giản là nhận được đầu ra và chạy Get-Job một lần nữa

Receive-Job 1 
Get-Job 

Tôi có thể thấy rằng "HasMoreData" bây giờ là sai, vì tôi không chỉ định -keep tham số.

HOWEVER: dường như bất cứ khi nào tôi bắt đầu công việc, không phải với Start-Job hoặc Invoke-Command, thông số "HasMoreData" này không thay đổi thành False.

Ví dụ:

Get-WMIObject win32_bios -AsJob 
Test-Connection . -AsJob 

Tôi có thể bỏ qua hành vi này (sai), do đó công tắc HasMoreData tài sản để False, trừ khi tôi chỉ định -keep?

Cảm ơn!

Cập nhật: dường như tất cả các cuộc gọi được thực hiện với thông số -AsJob. Nếu bạn chạy

Start-Job {Test-Connection .} 

nó hoạt động ("HasMoreData" trở thành False sau Receive-Job), nhưng

Test-Connection . -AsJob 

không.

Trả lời

2

Câu trả lời ngắn:

Đó là lỗi trong PowerShell 2.0.

Nó hoạt động tốt cho Blaine vì anh ấy sử dụng PowerShell 3, tôi sẽ bỏ tiền vào nó.


dài câu trả lời:

Các Start-Job cmdlet và -AsJob chuyển đổi và hoạt động khác.Tài liệu thường giải thích rằng Bắt đầu công việc được thiết kế để chạy công việc nền cục bộ trong khi -AsJob nhằm mục đích bắt đầu công việc với các lệnh chạy trên máy tính từ xa nhưng tạo đối tượng công việc cục bộ. Trong khi điều đó thường đúng, -AsJob cũng có thể được sử dụng để chạy công việc cục bộ và tùy thuộc vào lệnh, đôi khi thậm chí không có khả năng chạy lệnh trên máy tính từ xa. Ví dụ, Get-WmiObject gọi với -AsJob-ComputerName chạy lệnh trên máy tính từ xa theo quy định, trong khi Test-Kết nối gọi với -AsJob-Computername chạy lệnh tại địa phương và ping máy tính được chỉ định.

Tôi cũng thấy tài liệu mà giải thích rằng Start-Job tác phẩm của IPC địa phương, trong khi -AsJob làm cho một kết nối với dịch vụ WinRM của máy tính chỉ định, ngay cả khi đó là localhost, và PSRemoting rằng phải được bật trên (các) máy tính cục bộ và đích. Một lần nữa, nó không phải là khá đơn giản. Tôi đã tìm thấy rằng tôi có thể các công việc đang chạy với các chuyển đổi -AsJob trên máy chủ cục bộ với WinRM và PSRemoting đều bị tắt.

Trong mọi trường hợp, PowerShell bắt đầu công việc là một trong hai JobTypes, PSWmiJob hoặc PSRemotingJob. Đây là phản trực giác, bởi vì Start-Job, chạy việc làm nền cục bộ, luôn luôn tạo ra một PSRemotingJob, trong khi -AsJob thường tạo ra một PSWmiJob, trừ khi nó được sử dụng với Invoke-Command, mà luôn luôn bắt đầu một PSRemoting công việc bất kể lệnh được gọi trên máy tính từ xa hay localhost.

Hãy xem bảng điểm phiên sau, trong đó tôi đã tạo công việc theo các cách khác nhau. Tôi đã thử nghiệm với ba lệnh: Get-WMIObject, chạy trên máy tính từ xa khi được gọi với -AsJobComputerName; Kết nối thử nghiệm, luôn chạy cục bộ khi được gọi với -AsJob (-ComputerName chỉ định máy tính để ping, không phải nơi để chạy lệnh); và Get-ChildItem, không có tham số -AsJob. Tôi bắt đầu công việc cho mỗi người sử dụng Bắt đầu công việc, Gọi-Command -AsJob trên cả máy tính từ xa và máy cục bộ và khóa chuyển đổi -AsJob gốc (cho các lệnh có).

Mục đích của | %{$_.Name = '<the command preceding the pipe symbol>'} ở cuối mỗi lệnh là đặt tên cho mỗi công việc là lệnh tạo ra nó, vì vậy sẽ dễ dàng thấy ở đầu ra công việc tương ứng với mỗi lệnh. Nó không ảnh hưởng đến hoạt động của công việc, nó chỉ đổi tên mỗi công việc thành một cái tên có ý nghĩa hơn ngay lập tức sau khi tạo ra nó.

Những gì bạn sẽ thấy là sau khi tất cả các công việc được nhận (rcjb * 2>&1|Out-Null nhận tất cả chúng cùng một lúc và ngăn chặn đầu ra), tài sản của đối tượng PSRemotingJob HasMoreData được thiết lập để False cho dù họ đã được tạo ra bởi Start-Job hoặc -AsJob, nhưng thuộc tính HasMoreData của đối tượng PSWmiJob vẫn là True. Ngoài những ví dụ tôi đã sao chép ở đây, tôi đã thấy rằng điều này đúng với nhau.

07-17-13 19:44:56.30 C:\Users\ainbar» Invoke-Command -ComputerName . -ScriptBlock {Get-WMIObject win32_bios} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName . -ScriptBlock {Get-WMIObject win32_bios} -AsJob'} 
07-17-13 19:44:56.43 C:\Users\ainbar» Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-WMIObject win32_bios} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-WMIObject win32_bios} -AsJob'} 
07-17-13 19:44:56.46 C:\Users\ainbar» Start-Job -ScriptBlock {Test-Connection .} | %{$_.Name = 'Start-Job -ScriptBlock {Test-Connection .}'} 
07-17-13 19:44:57.13 C:\Users\ainbar» Test-Connection . -AsJob | %{$_.Name = 'Test-Connection . -AsJob '} 
07-17-13 19:44:57.14 C:\Users\ainbar» Invoke-Command -ComputerName . -ScriptBlock {Test-Connection .} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName . -ScriptBlock {Test-Connection .}'} 
07-17-13 19:44:57.18 C:\Users\ainbar» Invoke-Command -ComputerName ai8460p -ScriptBlock {Test-Connection .} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName ai8460p -ScriptBlock {Test-Connection .} -AsJob'} 
07-17-13 19:44:57.20 C:\Users\ainbar» Start-Job -ScriptBlock {Get-ChildItem C:\} | %{$_.Name = 'Start-Job -ScriptBlock {Get-ChildItem C:\}'} 
07-17-13 19:44:57.80 C:\Users\ainbar» Invoke-Command -ComputerName . -ScriptBlock {Get-ChildItem C:\} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName . -ScriptBlock {Get-ChildItem C:\} -AsJob'} 
07-17-13 19:44:57.82 C:\Users\ainbar» Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-ChildItem C:\} -AsJob | %{$_.Name = 'Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-ChildItem C:\} -AsJob'} 
07-17-13 19:44:57.84 C:\Users\ainbar» $fmt_gjb = 'Id','Name','Location',@{l="JobType";e={$_.GetType().name}},@{l='HasMoreData';e={"$($_.HasMoreData)"}},'State','Command' 
07-17-13 19:46:21.36 C:\Users\ainbar» gjb|ft -a $fmt_gjb 

Id Name                     Location JobType  HasMoreData  State Command 
-- ----                     -------- -------  -----------  ----- ------- 
1 Start-Job -ScriptBlock {Get-WMIObject win32_bios}          localhost PSRemotingJob True  Completed Get-WMIObject win32_bios 
3 Get-WMIObject win32_bios -AsJob              localhost PSWmiJob  True  Completed Get-WMIObject 
5 Get-WMIObject win32_bios -AsJob -ComputerName ai8460p         ai8460p PSWmiJob  True  Completed Get-WMIObject 
7 Invoke-Command -ComputerName . -ScriptBlock {Get-WMIObject win32_bios} -AsJob   localhost PSRemotingJob True  Completed Get-WMIObject win32_bios 
9 Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-WMIObject win32_bios} -AsJob ai8460p PSRemotingJob True  Completed Get-WMIObject win32_bios 
11 Start-Job -ScriptBlock {Test-Connection .}           localhost PSRemotingJob True  Completed Test-Connection . 
13 Test-Connection . -AsJob                .   PSWmiJob  True  Completed Test-Connection 
15 Invoke-Command -ComputerName . -ScriptBlock {Test-Connection .}      localhost PSRemotingJob True  Completed Test-Connection . 
17 Invoke-Command -ComputerName ai8460p -ScriptBlock {Test-Connection .} -AsJob   ai8460p PSRemotingJob True  Completed Test-Connection . 
19 Start-Job -ScriptBlock {Get-ChildItem C:\}           localhost PSRemotingJob True  Completed Get-ChildItem C:\ 
21 Invoke-Command -ComputerName . -ScriptBlock {Get-ChildItem C:\} -AsJob    localhost PSRemotingJob True  Completed Get-ChildItem C:\ 
23 Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-ChildItem C:\} -AsJob  ai8460p PSRemotingJob True  Completed Get-ChildItem C:\ 


07-17-13 19:46:37.94 C:\Users\ainbar» rcjb * 2>&1|Out-Null 
07-17-13 19:47:14.52 C:\Users\ainbar» gjb|ft -a $fmt_gjb 

Id Name                     Location JobType  HasMoreData  State Command 
-- ----                     -------- -------  -----------  ----- ------- 
1 Start-Job -ScriptBlock {Get-WMIObject win32_bios}          localhost PSRemotingJob False  Completed Get-WMIObject win32_bios 
3 Get-WMIObject win32_bios -AsJob              localhost PSWmiJob  True  Completed Get-WMIObject 
5 Get-WMIObject win32_bios -AsJob -ComputerName ai8460p         ai8460p PSWmiJob  True  Completed Get-WMIObject 
7 Invoke-Command -ComputerName . -ScriptBlock {Get-WMIObject win32_bios} -AsJob   localhost PSRemotingJob False  Completed Get-WMIObject win32_bios 
9 Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-WMIObject win32_bios} -AsJob ai8460p PSRemotingJob False  Completed Get-WMIObject win32_bios 
11 Start-Job -ScriptBlock {Test-Connection .}           localhost PSRemotingJob False  Completed Test-Connection . 
13 Test-Connection . -AsJob                .   PSWmiJob  True  Completed Test-Connection 
15 Invoke-Command -ComputerName . -ScriptBlock {Test-Connection .}      localhost PSRemotingJob False  Completed Test-Connection . 
17 Invoke-Command -ComputerName ai8460p -ScriptBlock {Test-Connection .} -AsJob   ai8460p PSRemotingJob False  Completed Test-Connection . 
19 Start-Job -ScriptBlock {Get-ChildItem C:\}           localhost PSRemotingJob False  Completed Get-ChildItem C:\ 
21 Invoke-Command -ComputerName . -ScriptBlock {Get-ChildItem C:\} -AsJob    localhost PSRemotingJob False  Completed Get-ChildItem C:\ 
23 Invoke-Command -ComputerName ai8460p -ScriptBlock {Get-ChildItem C:\} -AsJob  ai8460p PSRemotingJob False  Completed Get-ChildItem C:\ 


07-17-13 19:47:35.29 C:\Users\ainbar» 

Dòng dưới cùng: Lỗi nằm trong đối tượng PSWmiJob. Bất kể công việc được tạo ra ở đâu và bất kể lệnh chạy cục bộ hay từ xa, sau khi Receive-Job thuộc tính HasMoreData được đặt thành False nếu JobType là PSRemotingJob, nhưng vẫn đúng nếu JobType là PSWmiJob.

Theo như tôi có thể nói, không có cách nào để đặt HasMoreData thành False trên PSWmiJob. Dừng-công việc sẽ không làm điều đó, khởi động lại WinRM sẽ không làm điều đó, và tài sản là chỉ đọc.

+0

Tôi đã thực sự tìm thấy, sau khi phản ứng trước đó, rằng đây chỉ là trường hợp trong Powershell V2. Cảm ơn bạn Adi, không chỉ để xác nhận, mà còn dành thời gian giải thích chi tiết như vậy và với nỗ lực đó. – Joost

0

Tính năng này hoạt động chính xác. Tôi đã làm việc với các HasMoreData và nó hoạt động theo cách bạn muốn nó, trong đó nếu bạn làm một Receive-Job, các HasMoreData được thiết lập để sai. Nó sẽ vẫn đúng, cho đến khi bạn Receive-Job.

+0

'HasMoreData' sẽ trở thành' False', NẾU bạn sử dụng 'Bắt đầu-công việc' để tạo công việc. Tuy nhiên, nếu bạn chạy 'Test-Connection. -AsJob', sau đó 'Receive-Job',' HasMoreData' vẫn là 'True'. Tất cả phụ thuộc vào cách bạn tạo công việc ngay từ đầu. Tôi vừa thử nghiệm nó trong Powershell 2 (sẽ thử với v3 vào tuần tới). – Joost

+0

Điều này dựa trên v3.0. Khi tôi chạy nó v3.0, nó hoạt động như tôi đã nói. Chưa xem v2.0. – BlackHatSamurai

1

Xem kết quả này:

PS C:\dell> Test-Connection . -AsJob 

Id  Name   PSJobTypeName State   HasMoreData  Location    Command 
--  ----   ------------- -----   -----------  --------    ------- 
2  Job2   WmiJob   Running  True   .     Test-Connection 


PS C:\dell> Get-Job 

Id  Name   PSJobTypeName State   HasMoreData  Location    Command 
--  ----   ------------- -----   -----------  --------    ------- 
2  Job2   WmiJob   Completed  True   .     Test-Connection 


PS C:\dell> Get-Job Job2 | fl 


StatusMessage : 
HasMoreData : True 
Location  : . 
Command  : Test-Connection 
JobStateInfo : Completed 
Finished  : System.Threading.ManualResetEvent 
InstanceId : d16afbe0-31f7-4189-8d2a-30ede40645c4 
Id   : 2 
Name   : Job2 
ChildJobs  : {Job3} 
PSBeginTime : 7/16/2013 10:22:58 PM 
PSEndTime  : 7/16/2013 10:22:58 PM 
PSJobTypeName : WmiJob 
Output  : {} 
Error   : {} 
Progress  : {} 
Verbose  : {} 
Debug   : {} 
Warning  : {} 
State   : Completed 



PS C:\dell> Get-Job Job3 

Id  Name   PSJobTypeName State   HasMoreData  Location    Command 
--  ----   ------------- -----   -----------  --------    ------- 
3  Job3       Completed  True   . 


PS C:\dell> Get-Job Job3 | Receive-Job 

Source  Destination  IPV4Address  IPV6Address        Bytes Time(ms) 
------  -----------  -----------  -----------        ----- -------- 
W4-G9W... localhost  127.0.0.1             32  0 
W4-G9W... localhost  127.0.0.1             32  0 
W4-G9W... localhost  127.0.0.1             32  0 
W4-G9W... localhost  127.0.0.1             32  0 


PS C:\dell> Get-Job Job2 | fl 


StatusMessage : 
HasMoreData : False 
Location  : . 
Command  : Test-Connection 
JobStateInfo : Completed 
Finished  : System.Threading.ManualResetEvent 
InstanceId : d16afbe0-31f7-4189-8d2a-30ede40645c4 
Id   : 2 
Name   : Job2 
ChildJobs  : {Job3} 
PSBeginTime : 7/16/2013 10:22:58 PM 
PSEndTime  : 7/16/2013 10:22:58 PM 
PSJobTypeName : WmiJob 
Output  : {} 
Error   : {} 
Progress  : {} 
Verbose  : {} 
Debug   : {} 
Warning  : {} 
State   : Completed 



PS C:\dell> Get-Job Job3 

Id  Name   PSJobTypeName State   HasMoreData  Location    Command 
--  ----   ------------- -----   -----------  --------    ------- 
3  Job3       Completed  False   . 

Bạn thấy rằng Job2 là công việc mục cấp đầu và có một công việc đứa trẻ được tạo ra với tên Job3. Đó là nơi hành động thực tế đang diễn ra.

Bạn có thể nhận công việc con và kiểm tra xem HasMoreData có được đặt không?

Các vấn đề liên quan