2012-06-07 47 views
5

我在PowerShell中創建一個簡單的後臺作業:「HasMoreData」 是真實的,即使後收到-工作

Start-Job {"Hello"} 

我檢查以Get-工作:

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

接下來,我簡單地接收輸出和運行Get-工作再次

Receive-Job 1 
Get-Job 

我可以看到「HasMoreData」現在是假的,因爲我沒有指定-keep參數。然而,只要我開始工作,而不是Start-JobInvoke-Command,那麼這個「HasMoreData」參數不會變爲False。

例子:

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

我可以繞過這個(錯誤)的行爲,使物業HasMoreData開關爲False,除非我指定-keep

謝謝!

更新:它似乎是用-AsJob參數進行的所有調用。如果您運行

Start-Job {Test-Connection .} 

它的作品( 「HasMoreData」 成爲Receive-Job後假),但

Test-Connection . -AsJob 

沒有。

回答

2

簡短回答:

這是PowerShell 2.0中的一個錯誤。

對Blaine來說它工作正常,因爲他使用的是PowerShell 3,我會把錢放在上面。


龍答:

啓動工作 cmdlet和-AsJob開關工作方式不同。文檔通常解釋爲:開始作業旨在在本地運行後臺作業,而-AsJob旨在使用在遠程計算機上運行的命令啓動作業,但在本地創建作業對象。儘管這通常是正確的,但-AsJob也可用於在本地運行作業,並且根據命令的不同,有時甚至無法在遠程計算機上運行該命令。例如,GET-WmiObject可以-AsJob調用-ComputerName運行指定的遠程計算機上的命令,而用-AsJob-computername調用試驗連接本地運行的命令和ping指定的電腦。

我也看到文檔,解釋說啓動工作作品由當地IPC,而-AsJob使得到指定計算機的WinRM服務的連接,即使是本地主機,而PSRemoting必須在本地和目標計算機上啓用。再次,這不是那麼直截了當。我發現我可以運行作業與-AsJob切換本地主機與WinRM和PSRemoting都禁用。

在任何情況下,PowerShell都會將作業作爲兩個JobType,PSWmiJob或PSRemotingJob之一啓動。這是反直覺的,因爲啓動工作,它運行在本地後臺作業,總是會創建PSRemotingJob,而-AsJob通常會創建一個PSWmiJob,當它與調用命令,它總是開始PSRemoting使用,除非作業,無論該命令是在遠程計算機還是本地主機上調用。

看看下面的會話記錄,其中我以各種方式創建了作業。我用三個命令進行測試:獲取-WmiObject可以,它運行在與-AsJob計算機名調用的遠程計算機上; 測試連接,當調用-AsJob- 計算機名稱指定要ping哪臺計算機,而不是在哪裏運行命令)時總是在本地運行。和Get-ChildItem,它沒有-AsJob參數。我開始使用開始作業,遠程計算機和本地計算機上的Invoke-Command -AsJob以及本地開關(對於具有它的命令)的本機-AsJob

每個命令末尾的| %{$_.Name = '<the command preceding the pipe symbol>'}的用途是將每個作業命名爲創建它的命令,因此在輸出中更容易看到哪個作業對應於每個命令。它對作業的操作沒有影響,它只是在創建後立即將每個作業重命名爲更有意義的名稱。

什麼,你會看到的是,接收的所有作業後(rcjb * 2>&1|Out-Null接收一次全部和抑制輸出),PSRemotingJob對象的HasMoreData屬性設置爲False是否由啓動工作或創建-AsJob,但PSWmiJob對象的HasMoreData屬性保持爲True。除了我在這裏轉載的例子之外,我發現這一貫持續。

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» 

底線:該錯誤位於PSWmiJob對象中。無論創建作業的方式如何,並且無論命令是在本地還是遠程運行,在Receive-Job之後,如果JobType爲PSRemotingJob,則HasMoreData屬性設置爲False,但如果JobType爲PSWmiJob則保持True。

據我所知,沒有辦法在PSWmiJob上將HasMoreData設置爲False。 停止作業不會這樣做,重新啓動WinRM將不會這樣做,並且屬性是隻讀的。

+0

在早期的回覆之後,我確實發現這只是Powershell V2中的情況。謝謝阿迪,不僅僅是爲了證實,而是花時間詳細解釋並付出了努力。 – Joost

0

這確實工作正常。我一直在使用HasMoreData,它的工作方式是你想要的,因爲如果你做了Receive-JobHasMoreData設置爲false。它會保持真實,直到你Receive-Job

+0

如果您使用'Start-Job'創建作業,'HasMoreData'將變爲'False'。但是,如果您運行'測試連接。 -AsJob',然後'Receive-Job','HasMoreData'保持爲'True'。這一切都取決於你如何創造這項工作。我剛剛在Powershell 2中測試過它(下週將嘗試v3)。 – Joost

+0

這是基於v3.0。當我運行v3.0時,它就像我所說的那樣工作。沒有查看v2.0。 – BlackHatSamurai

1

看到以下輸出:

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   . 

您看到作業2是頂層的工作,它與作業3名創建一個子任務。這是實際行動發生的地方。

您能否收到子作業並檢查HasMoreData是否仍然設置?

相關問題