Kurze Antwort:
Es ist ein Fehler in PowerShell 2.0.
Es funktioniert gut für Blaine, weil er PowerShell 3 verwendet, würde ich Geld darauf legen.
Lange Antwort:
Die Start-Job Cmdlets und die -AsJob Schalter funktionieren anders.In der Dokumentation wird normalerweise erläutert, dass Start-Job Hintergrundaufträge lokal ausführen soll, während -AsJob Aufträge mit Befehlen starten soll, die auf Remotecomputern ausgeführt werden, das Auftragsobjekt jedoch lokal erstellt. Während das im Allgemeinen richtig ist, kann -AsJob auch verwendet werden, um Aufträge lokal auszuführen, und abhängig vom Befehl ist es manchmal nicht einmal in der Lage, den Befehl auf einem Remotecomputer auszuführen. Zum Beispiel läuft Get-WMIObject mit -AsJob und aufgerufen -ComputerName den Befehl auf dem angegebenen Remotecomputer, während Test-Connection aufgerufen mit -AsJob und -ComputerName führt den Befehl lokal und pingt den angegebenen Computer an.
Ich habe auch Dokumentation zu sehen, die erklären, dass Start-Job Arbeiten von lokalen IPC, während -AsJob eine Verbindung mit dem WinRM-Dienst des angegebenen Computers machen, auch wenn es die localhost ist, und dass PSRemoting muss auf dem lokalen und dem Zielcomputer aktiviert sein. Auch das ist nicht ganz so einfach. Ich habe festgestellt, dass ich kann Aufträge mit dem -AsJob auf dem lokalen Host mit WinRM und PSRemoting beide deaktiviert ausführen.
In jedem Fall startet PowerShell Jobs als eines von zwei JobTypes, PSWmiJob oder PSRemotingJob. Dies ist kontraintuitiv, weil Start-Job, die lokal Hintergrundjobs läuft, immer eine PSRemotingJob schafft, während -AsJob in der Regel eine PSWmiJob erzeugt, mit der Ausnahme, wenn es mit Invoke-Command, verwendet wird, die immer eine PSRemoting beginnt Job unabhängig davon, ob der Befehl auf einem Remotecomputer oder auf dem lokalen Host aufgerufen wird.
Sehen Sie sich das folgende Sitzungstranskript an, in dem ich Jobs auf unterschiedliche Weise erstellt habe. Ich habe mit drei Befehlen getestet: Get-WMIObject, die auf einem Remotecomputer ausgeführt wird, wenn mit -AsJob und aufgerufen wird ComputerName; Testverbindung, die immer lokal ausgeführt wird, wenn sie mit -AsJob aufgerufen wird (-ComputerName gibt an, welcher Computer anpingen soll, nicht wo der Befehl ausgeführt werden soll); und Get-ChildItem, das keinen -AsJob Parameter hat. Ich begann Jobs für jeden mit Start-Job, Invoke-Command -AsJob sowohl auf einen Remote-Computer und den lokalen Computer und die nativen -AsJob Schalter (für Befehle, die es haben).
Der Zweck der | %{$_.Name = '<the command preceding the pipe symbol>'}
am Ende jedes Befehls besteht darin, jeden Job als den Befehl, der es erstellt hat, zu benennen, so dass es einfacher ist, in der Ausgabe zu sehen, welcher Job jedem Befehl entspricht. Es wirkt sich nicht auf die Ausführung der Jobs aus, sondern benennt jeden Job unmittelbar nach dem Erstellen in einen aussagekräftigeren Namen um.
Was Sie sehen, ist, dass, nachdem alle Arbeitsplätze erhalten werden (rcjb * 2>&1|Out-Null
erhält sie alle auf einmal und unterdrückt die Ausgabe) wird die HasMoreData Eigenschaft PSRemotingJob Objekte auf False festgelegt, ob sie von Start-Job erstellt wurden, oder - AsJob, aber die HasMoreData-Eigenschaft von PSWmiJob-Objekten bleibt True. Abgesehen von den Beispielen, die ich hier reproduziert habe, habe ich festgestellt, dass dies konsequent gilt.
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»
Fazit: Der Fehler ist in der PSWmiJob-Objekt. Unabhängig davon, wie der Job erstellt wurde und unabhängig davon, ob der Befehl lokal oder remote ausgeführt wird, wird die HasMoreData-Eigenschaft nach Receive-Job auf False gesetzt, wenn der JobType PSRemotingJob ist, bleibt aber True, wenn der JobType PSWmiJob ist.
Soweit ich das beurteilen kann, gibt es keine Möglichkeit, HasMoreData auf einem PSWmiJob auf False zu setzen. Stop-Job wird es nicht tun, Neustart WinRM wird es nicht tun, und die Eigenschaft ist schreibgeschützt.
Ich hatte tatsächlich nach den früheren Antworten festgestellt, dass dies nur in Powershell V2 der Fall war. Danke Adi, nicht nur um zu bestätigen, sondern um sich die Zeit zu nehmen, so ausführlich und mit solcher Mühe zu erklären. – Joost