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 oppure ThreadJob - 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:

  1. Usare Invoke-Command per creare processi eseguiti in sessioni disconnesse. Per altre informazioni, vedere about_Remote_Jobs.
  2. 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 usare Invoke-Command per eseguire qualsiasi comando di processo in remoto, incluso Start-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}

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".

Vedi anche