gpt4 book ai didi

powershell - 即使在 Receive-Job 之后 "HasMoreData"也是真的

转载 作者:行者123 更新时间:2023-12-04 12:35:16 30 4
gpt4 key购买 nike

我在 Powershell 中创建了一个简单的后台作业:

Start-Job {"Hello"}

我与 Get-Job 核对:
    Id        Name         State         HasMoreData      Location       Command
-- ---- ----- ----------- -------- -------
1 Job1 Completed True localhost "Hello"

接下来,我只是接收输出,然后再次运行 Get-Job
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 之后变为 False ),但是
Test-Connection . -AsJob

才不是。

最佳答案

简短的回答:

这是 PowerShell 2.0 中的一个错误。

这对 Blaine 来说效果很好,因为他使用的是 PowerShell 3,我会为此投入资金。

长答案:

开始工作 cmdlet 和 -AsJob 切换工作方式不同。文档通常解释说 开始工作 旨在在本地运行后台作业,而 -AsJob 旨在使用在远程计算机上运行但在本地创建作业对象的命令启 Action 业。虽然这通常是正确的, -AsJob 也可用于在本地运行作业,根据命令,有时甚至无法在远程计算机上运行命令。例如,获取-WMIObject 调用-AsJob -计算机名 在指定的远程计算机上运行命令,而 测试连接 调用-AsJob -计算机名在本地运行命令并ping指定的计算机。

我还看到了解释 的文档。开始工作 由本地 IPC 工作,而 -AsJob 连接到指定计算机的 WinRM 服务,即使它是本地主机,并且必须在本地和目标计算机上启用 PSRemoting。同样,它不是那么简单。我发现我可以使用 运行作业-AsJob 在禁用 WinRM 和 PSRemoting 的情况下打开本地主机。

在任何情况下,PowerShell 都会作为两种 JobType 之一(PSWmiJob 或 PSRemotingJob)启 Action 业。这是违反直觉的,因为 开始工作 ,在本地运行后台作业,总是创建一个 PSRemotingJob,而 -AsJob 通常创建一个 PSWmiJob,除非它与 一起使用调用命令 ,无论是在远程计算机还是本地主机上调用该命令,它始终会启动 PSRemoting 作业。

看看下面的 session 记录,其中我以不同的方式创建了工作。我用三个命令进行了测试:获取-WMIObject ,当使用 调用时,它会在远程计算机上运行-AsJob 计算机名 ; 测试连接 ,当用 调用时总是在本地运行-AsJob ( -ComputerName 指定要 ping 的计算机,而不是运行命令的位置);和 Get-ChildItem ,它没有 -AsJob 范围。我使用 为每个人开始工作开始工作 , 调用命令 -AsJob 在远程计算机和本地计算机上,以及 native -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 对象中。无论作业以何种方式创建,也无论命令是在本地运行还是远程运行,在 之后接工作如果 JobType 是 PSRemotingJob,则 HasMoreData 属性设置为 False,但如果 JobType 是 PSWmiJob,则保持 True。

据我所知,无法在 PSWmiJob 上将 HasMoreData 设置为 False。 停止工作 不会,重启WinRM也不会,而且属性是只读的。

关于powershell - 即使在 Receive-Job 之后 "HasMoreData"也是真的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10933732/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com