about_Jobs
Descrizione breve
Fornisce informazioni sul modo in cui i processi in background di PowerShell eseguono un comando o un'espressione in background senza interagire con la sessione corrente.
Descrizione lunga
PowerShell esegue contemporaneamente comandi e script tramite processi. Esistono tre tipi di processi forniti da PowerShell per supportare la concorrenza.
RemoteJob
- Comandi e script eseguiti in una sessione remota. Per informazioni, vedere about_Remote_Jobs.BackgroundJob
- Comandi e script eseguiti in un processo separato nel computer locale.PSTaskJob
oppureThreadJob
- I comandi e gli script vengono eseguiti in un thread separato all'interno dello stesso processo nel computer locale. Per altre informazioni, vedere about_Thread_Jobs.
L'esecuzione di script in remoto, in un computer separato o in un processo separato, offre un isolamento ottimale. Eventuali errori che si verificano nel processo remoto non influiscono su altri processi in esecuzione o sulla sessione padre che ha avviato il processo. Tuttavia, il livello di comunicazione remota aggiunge overhead, inclusa la serializzazione degli oggetti. Tutti gli oggetti vengono serializzati e deserializzati man mano che vengono passati tra la sessione padre e la sessione remota (processo). La serializzazione di oggetti dati complessi di grandi dimensioni può utilizzare grandi quantità di risorse di calcolo e memoria e trasferire grandi quantità di dati in rete.
I processi basati su thread non sono affidabili come i processi remoti e in background, perché vengono eseguiti nello stesso processo in thread diversi. Se un processo presenta un errore critico che arresta in modo anomalo il processo, tutti gli altri processi del processo vengono terminati.
Tuttavia, i processi basati su thread richiedono un sovraccarico inferiore. Non usano il livello remoto o la serializzazione. Gli oggetti risultato vengono restituiti come riferimenti agli oggetti attivi nella sessione corrente. Senza questo sovraccarico, i processi basati su thread vengono eseguiti più velocemente e usano meno risorse rispetto agli altri tipi di processo.
Importante
La sessione padre che ha creato il processo monitora anche lo stato del processo e raccoglie i dati della pipeline. Il processo figlio del processo viene terminato dal processo padre dopo che il processo raggiunge uno stato completato. Se la sessione padre viene terminata, tutti i processi figlio in esecuzione vengono terminati insieme ai processi figlio.
Esistono due modi per ovviare a questa situazione:
- Usare
Invoke-Command
per creare processi eseguiti in sessioni disconnesse. Per altre informazioni, vedere about_Remote_Jobs. - Usare
Start-Process
per creare un nuovo processo anziché un processo. Per altre informazioni, vedere Start-Process.
Cmdlet del processo
Start-Job
- Avvia un processo in background in un computer locale.Get-Job
: ottiene i processi in background avviati nella sessione corrente.Receive-Job
: ottiene i risultati dei processi in background.Stop-Job
- Arresta un processo in background.Wait-Job
- Elimina il prompt dei comandi fino al completamento di uno o tutti i processi.Remove-Job
- Elimina un processo in background.Invoke-Command
- Il parametro AsJob crea un processo in background in un computer remoto. È possibile usareInvoke-Command
per eseguire qualsiasi comando di processo in remoto, inclusoStart-Job
.
Come avviare un processo nel computer locale
Per avviare un processo in background nel computer locale, usare il Start-Job
cmdlet .
Per scrivere un Start-Job
comando, racchiudere il comando eseguito dal processo tra parentesi graffe ({}
). Usare il parametro ScriptBlock per specificare il comando .
Il comando seguente avvia un processo in background che esegue un Get-Process
comando nel computer locale.
Start-Job -ScriptBlock {Get-Process}
Quando si avvia un processo in background, il prompt dei comandi viene restituito immediatamente, anche se il processo richiede un tempo prolungato per il completamento. È possibile continuare a lavorare nella sessione senza interruzioni durante l'esecuzione del processo.
Il Start-Job
comando restituisce un oggetto che rappresenta il processo. L'oggetto processo contiene informazioni utili sul processo, ma non contiene i risultati del processo.
È possibile salvare l'oggetto processo in una variabile e quindi usarlo con gli altri cmdlet job per gestire il processo in background. Il comando seguente avvia un oggetto processo e salva l'oggetto processo risultante nella $job
variabile .
$job = Start-Job -ScriptBlock {Get-Process}
A partire da PowerShell 6.0, è possibile usare l'operatore in background (&
) alla fine di una pipeline per avviare un processo in background. Per altre informazioni, vedere Operatore in background.
L'uso dell'operatore in background equivale funzionalmente all'uso del Start-Job
cmdlet nell'esempio precedente.
$job = Get-Process &
Recupero di oggetti processo
Il Get-Job
cmdlet restituisce oggetti che rappresentano i processi in background avviati nella sessione corrente. Senza parametri, Get-Job
restituisce tutti i processi avviati nella sessione corrente.
Get-Job
L'oggetto processo contiene lo stato del processo, che indica se il processo è stato completato. Un processo completato ha lo stato Completato o Non riuscito. Un processo potrebbe anche essere Bloccato o In esecuzione.
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
È possibile salvare l'oggetto processo in una variabile e usarlo per rappresentare il processo in un comando successivo. Il comando seguente ottiene il processo con ID 1 e lo salva nella $job
variabile .
$job = Get-Job -Id 1
Ottenere i risultati di un processo
Quando si esegue un processo in background, i risultati non vengono visualizzati immediatamente. Per ottenere i risultati di un processo in background, usare il Receive-Job
cmdlet .
Nell'esempio seguente il Receive-Job
cmdlet ottiene i risultati del processo usando l'oggetto processo nella $job
variabile .
Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
668 7 2672 6168 104 32.26 488 csrss
...
È possibile salvare i risultati di un processo in una variabile. Il comando seguente salva i risultati del processo nella $job
variabile nella $results
variabile .
$results = Receive-Job -Job $job
Ottenere e mantenere risultati parziali del processo
Il Receive-Job
cmdlet ottiene i risultati di un processo in background. Se il processo è completo, Receive-Job
ottiene tutti i risultati del processo. Se il processo è ancora in esecuzione, Receive-Job
ottiene i risultati generati finora. È possibile eseguire Receive-Job
di nuovo i comandi per ottenere i risultati rimanenti.
Per impostazione predefinita, Receive-Job
elimina i risultati dalla cache in cui vengono archiviati i risultati del processo. Quando si esegue Receive-Job
di nuovo, si ottengono solo i nuovi risultati arrivati dopo la prima esecuzione.
I comandi seguenti mostrano i risultati dei comandi eseguiti prima del Receive-Job
completamento del processo.
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
Usare il parametro Keep per impedire Receive-Job
l'eliminazione dei risultati del processo restituiti. I comandi seguenti mostrano l'effetto dell'uso del parametro Keep in un processo non ancora completato.
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
In attesa dei risultati
Se si esegue un comando che richiede molto tempo per il completamento, è possibile utilizzare le proprietà dell'oggetto processo per determinare quando il processo è stato completato. Il comando seguente usa l'oggetto Get-Job
per ottenere tutti i processi in background nella sessione corrente.
Get-Job
I risultati vengono visualizzati in una tabella. Lo stato del processo viene visualizzato nella colonna Stato .
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
2 Job2 BackgroundJob Running True localhost Get-EventLog -Log ...
3 Job3 BackgroundJob Complete True localhost dir -Path C:\* -Re...
In questo caso, la proprietà State rivela che il processo 2 è ancora in esecuzione. Se si usasse il Receive-Job
cmdlet per ottenere i risultati del processo, i risultati sarebbero incompleti. È possibile usare ripetutamente il Receive-Job
cmdlet per ottenere tutti i risultati. Utilizzare la proprietà State per determinare quando il processo è completo.
È anche possibile usare il parametro Wait del Receive-Job
cmdlet . Quando si usa questo parametro, il cmdlet non restituisce il prompt dei comandi fino al completamento del processo e tutti i risultati sono disponibili.
È anche possibile usare il Wait-Job
cmdlet per attendere uno o tutti i risultati del processo. Wait-Job
consente di attendere uno o più processi specifici o per tutti i processi.
Il comando seguente usa il Wait-Job
cmdlet per attendere un processo con ID 10.
Wait-Job -ID 10
Di conseguenza, il prompt di PowerShell viene eliminato fino al completamento del processo.
È anche possibile attendere un periodo di tempo predeterminato. Questo comando usa il parametro Timeout per limitare l'attesa a 120 secondi. Alla scadenza, il prompt dei comandi viene restituito, ma il processo continua a essere eseguito in background.
Wait-Job -ID 10 -Timeout 120
Arresto di un processo
Per arrestare un processo in background, usare il Stop-Job
cmdlet . Il comando seguente avvia un processo per ottenere ogni voce nel registro eventi di sistema. Salva l'oggetto processo nella $job
variabile .
$job = Start-Job -ScriptBlock {Get-EventLog -Log System}
Il comando seguente arresta il processo. Usa un operatore pipeline (|
) per inviare il processo nella $job
variabile a Stop-Job
.
$job | Stop-Job
Eliminazione di un processo
Per eliminare un processo in background, usare il Remove-Job
cmdlet . Il comando seguente elimina il processo nella $job
variabile .
Remove-Job -Job $job
Analisi di un processo non riuscito
I processi possono avere esito negativo per molti motivi. L'oggetto processo contiene una proprietà Reason che contiene informazioni sulla causa dell'errore.
Nell'esempio seguente viene avviato un processo senza le credenziali necessarie.
$job = Start-Job -ScriptBlock {New-Item -Path HKLM:\Software\MyCompany}
Get-Job $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Failed False localhost New-Item -Path HKLM:...
Esaminare la proprietà Reason per trovare l'errore che ha causato l'esito negativo del processo.
$job.ChildJobs[0].JobStateInfo.Reason
In questo caso, il processo non è riuscito perché il computer remoto ha richiesto credenziali esplicite per eseguire il comando. La proprietà Reason contiene il messaggio seguente:
Connessione al server remoto non riuscita con il messaggio di errore seguente: "Accesso negato".