2012-06-07 12 views
5

-ジョブを受信真であります、と私はを指定しなかったので、「HasMoreData」は、今虚偽であることがわかります再び"HasMoreDataは" 後であっても、私はPowerShellでシンプルなバックグラウンドジョブを作成

Receive-Job 1 
Get-Job 

を取得し、ジョブを実行します10パラメータ。

ただし、ジョブを開始するときはいつでも、Start-JobまたはInvoke-Commandではなく、この "HasMoreData"パラメータがFalseに変更されないようです。

例:私は-keepを指定しない限り、プロパティHasMoreDataは、Falseに切り替わるように

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

は、私は、この(間違った)動作をバイパスすることはできますか?

ありがとうございます!

更新-AsJobパラメータで行われたすべての呼び出しのようです。あなたはそれが動作

Start-Job {Test-Connection .} 

を実行した場合( "HasMoreDataは" Receive-Job後に偽となる)が、

Test-Connection . -AsJob 

はしていません。

答えて

2

短い回答:

これはPowerShell 2.0のバグです。

彼はPowerShell 3を使用しているので、Blaineはうまく動作します。私はそれにお金をかけます。


長い答え:

スタート-仕事コマンドレットとは異なる-AsJobスイッチ作品。ドキュメントでは通常、Start-Jobはバックグラウンドジョブをローカルで実行することを目的としていますが、-AsJobはリモートコンピュータ上で実行するコマンドでジョブを開始することを目的としています。これは一般的に当てはまりますが、-AsJobはジョブをローカルで実行するためにも使用でき、コマンドによってはリモートコンピュータでコマンドを実行できないこともあります。 -AsJob-ComputerNameで呼び出さテスト接続がローカルコマンドを実行し、一方、例えば、のGet-WmiObjectコマンドは、-AsJob-ComputerNameが指定されたリモートコンピュータ上でコマンドを実行して起動と指定したコンピュータにpingを実行します。

私もそれはlocalhostのだ、とそのPSRemotingは、必要がある場合でも、ローカルIPCによってスタート-仕事作品は、-AsJobは、指定したコンピューターのWinRMサービスに接続するのに対し、と説明しているドキュメントを見てきましたローカルコンピュータとターゲットコンピュータで有効にする必要があります。繰り返しますが、それほど簡単ではありません。私は-AsJob WinRMとPSRemotingを両方とも無効にしてローカルホスト上でスイッチを使用してジョブを実行することがわかりました。

いずれの場合でも、PowerShellは2つのJobTypesの1つ、PSWmiJobまたはPSRemotingJobとしてジョブを開始します。 -AsJobは通常、それは常にPSRemotingを開始、Invoke-Commandコマンド、で使われている場合を除き、PSWmiJobを作成するのに対し、ローカルでバックグラウンドジョブを実行しますスタート-仕事は、常に、PSRemotingJobを作成しますので、これは、反直感的ですジョブは、リモートコンピュータまたはローカルホスト上でコマンドが呼び出されたかどうかに関係なく実行されます。

さまざまな方法でジョブを作成した次のセッションの記録を見てください。私は3つのコマンドでテストしました:Get-WMIObject -AsJobComputerNameで呼び出されたときにリモートコンピュータ上で実行されるGet-WMIObject; テスト接続は、-AsJob-ComputerNameは、コマンドを実行する場所ではなく、どのコンピュータをpingするかを指定します。 Get-ChildItem、これには-AsJobパラメータがありません。 Start-JobInvoke-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に設定する方法はありません。 Stop-Jobは実行しません。WinRMを再起動してもそれは実行されません。プロパティは読み取り専用です。

+0

以前の回答の後で、これはPowershell V2のほんの一例であったことは確かです。確認のためだけではなく、そのような詳細でそのような努力をして説明する時間をとっていただきありがとうございます。 – Joost

0

これは正しく動作します。私はHasMoreDataで作業していました。それは、あなたがReceive-Jobを実行した場合、HasMoreDataがfalseに設定されているという点で、あなたが望むように動作します。それはあなたがReceive-Jobまで真実を保つでしょう。

+0

'HasMoreData'は' Start-Job'を使ってジョブを作成すると 'False'になります。しかし、 'Test-Connection 'を実行すると。 -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   . 

あなたはJOB2がトップレベルの仕事であり、それは名前JOB3で作成された子ジョブを持っていることがわかります。それが実際の行動が起こっている場所です。

子ジョブを受け取り、HasMoreDataがまだ設定されているかどうか確認できますか?

関連する問題