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 và -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 và -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 -AsJob và ComputerName; 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.
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