“HasMoreData” is true even after Receive-Job
我在Powershell中创建一个简单的后台作业:
1 | Start-Job {"Hello"} |
我通过Get-Job检查:
1 2 3 | Id Name State HasMoreData Location Command -- ---- ----- ----------- -------- ------- 1 Job1 Completed True localhost "Hello" |
接下来,我仅接收输出,然后再次运行Get-Job
1 2 | Receive-Job 1 Get-Job |
我可以看到" HasMoreData"现在为false,因为我没有指定
但是:似乎每当我开始工作而不是不使用
例子:
1 2 | Get-WMIObject win32_bios -AsJob Test-Connection . -AsJob |
我是否可以绕过此(错误)行为,以便属性HasMoreData切换为False,除非我指定
谢谢!
更新:似乎是所有使用
1 | Start-Job {Test-Connection .} |
它起作用(
1 | Test-Connection . -AsJob |
才不是。
简短答案:
这是PowerShell 2.0中的错误。
对于Blaine来说,它工作正常,因为他正在使用PowerShell 3,我会花钱在上面。
长答案:
Start-Job cmdlet和-AsJob开关的工作方式不同。文档通常说明Start-Job用于在本地运行后台作业,而-AsJob用于使用在远程计算机上运行但在本地创建作业对象的命令启动作业。尽管通常是这样,但-AsJob也可用于在本地运行作业,并且根据命令,有时甚至无法在远程计算机上运行命令。例如,用-AsJob和-ComputerName调用的Get-WMIObject在指定的远程计算机上运行命令,而用-AsJob和-Computername调用的Test-Connection在本地运行命令并ping指定的计算机。
我还看到了说明Start-Job由本地IPC起作用的文档,而-AsJob与指定计算机的WinRM服务建立了连接,即使它是本地主机,也必须在本地计算机和目标计算机上启用PSRemoting (s)。同样,它不是那么简单。我发现我可以在本地计算机上使用-AsJob开关运行作业,同时禁用WinRM和PSRemoting。
无论如何,PowerShell都会以两种JobType(PSWmiJob或PSRemotingJob)之一启动作业。这是违反直觉的,因为在本地运行后台作业的Start-Job总是创建PSRemotingJob,而-AsJob通常创建PSWmiJob,除非与Invoke-Command一起使用时,Invoke-Command总是启动PSRemoting作业,而不管命令是否在远程计算机或本地主机上调用。
看看下面的会话记录,其中我以各种方式创建了作业。我用以下三个命令进行了测试:Get-WMIObject,当用-AsJob和ComputerName调用时,它在远程计算机上运行; Test-Connection,当用-AsJob调用时总是在本地运行(-ComputerName指定要对哪台计算机执行ping操作,而不是在何处运行命令);和Get-ChildItem,它没有-AsJob参数。我在远程计算机和本地计算机上都使用Start-Job,Invoke-Command -AsJob和本机-AsJob开关(对于具有该命令的命令)启动了每个作业。
每个命令末尾的
您将看到,在接收所有作业(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 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对象中。不管创建作业的方式如何,以及无论该命令在本地还是远程运行,在Job-Job之后,如果JobType为PSRemotingJob,则HasMoreData属性将设置为False,而如果JobType为PSWmiJob,则该属性将保持True。
据我所知,没有办法在PSWmiJob上将HasMoreData设置为False。 Stop-Job不会执行此操作,重新启动WinRM不会执行此操作,并且该属性为只读。
看到以下输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 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是否仍然设置吗?