informazioni_su_impieghi

Breve descrizione

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 attività forniti da PowerShell per sostenere la concorrenza.

  • RemoteJob : comandi e script eseguiti in una sessione remota. Per ulteriori informazioni, consultare about_Remote_Jobs.
  • BackgroundJob: comandi e script vengono eseguiti in un processo separato nel computer locale.
  • PSTaskJob o 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'attività presenta un errore critico che causa l'arresto del processo, tutte le altre attività nel processo vengono terminate.

Tuttavia, i processi basati su thread richiedono un sovraccarico inferiore. Non usano lo strato di remotizzazione 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 principale che ha creato il processo monitora anche lo stato del lavoro e raccoglie i dati della pipeline. Il processo figlio viene terminato dal processo padre quando il lavoro raggiunge lo stato di completamento. Se la sessione padre viene terminata, tutti i lavori figlio in esecuzione vengono terminati insieme ai loro 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 compito. Per altre informazioni, vedere Start-Process.

Cmdlet del processo

Cmdlet (un piccolo script o comando in PowerShell) Descrizione
Start-Job Avvia un processo in background in un computer locale.
Get-Job Ottiene i processi in background avviati nella cartella
sessione corrente.
Receive-Job Ottiene i risultati dei processi in background.
Stop-Job Interrompe un processo in background.
Wait-Job Elimina il prompt dei comandi fino a quando uno o tutti i lavori non vengono
completo.
Remove-Job Elimina un processo in background.
Invoke-Command Il parametro AsJob crea un processo in background in un
computer remoto. È possibile utilizzare Invoke-Command per eseguire
qualsiasi comando di lavoro in remoto, incluso Start-Job.

Come avviare un processo nel computer locale

Per avviare un processo in background nel computer locale, usare il cmdlet Start-Job.

Per scrivere un comando Start-Job, racchiudere il comando eseguito nel processo tra parentesi graffe ({}). Usare il parametro ScriptBlock per specificare il comando.

Il comando seguente avvia un processo in background che esegue un comando Get-Process 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. Puoi continuare a lavorare nella sessione senza interruzioni mentre il processo è in esecuzione.

Il comando Start-Job 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 variabile $job.

$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 a usare il cmdlet Start-Job nell'esempio precedente.

$job = Get-Process &

Recupero di oggetti processo

Il cmdlet Get-Job 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 uno stato di Completa o Failed. 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 variabile $job.

$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 cmdlet Receive-Job.

Nell'esempio seguente, il cmdlet Receive-Job ottiene i risultati del processo usando l'oggetto processo nella variabile $job.

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 variabile $job nella variabile $results.

$results = Receive-Job -Job $job

Ottenere e mantenere risultati parziali del processo

Il cmdlet Receive-Job 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 di nuovo Receive-Job 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 di nuovo Receive-Job, si ottengono solo i nuovi risultati arrivati dopo la prima esecuzione.

I comandi seguenti mostrano i risultati dei comandi Receive-Job eseguiti prima del 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 di eliminare i risultati del processo restituiti. I comandi seguenti mostrano l'effetto dell'utilizzo del parametro Keep su 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 cmdlet Receive-Job per ottenere i risultati del processo, i risultati sarebbero incompleti. È possibile usare ripetutamente il cmdlet Receive-Job per ottenere tutti i risultati. Utilizzare la proprietà State per determinare quando il processo è stato completato.

È anche possibile usare il parametro wait del cmdlet Receive-Job. Quando si utilizza questo parametro, il cmdlet non restituisce il prompt dei comandi fino al completamento del processo e alla disponibilità di tutti i risultati.

È anche possibile usare il cmdlet Wait-Job per attendere tutti 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 cmdlet Wait-Job 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 cmdlet Stop-Job. Il comando seguente avvia un processo per ottenere ogni voce nel registro eventi di sistema. Salva l'oggetto processo nella variabile $job.

$job = Start-Job -ScriptBlock {Get-EventLog -Log System}

Il comando seguente arresta il processo. Usa un operatore pipeline (|) per inviare il processo nella variabile $job a Stop-Job.

$job | Stop-Job

Eliminazione di un processo

Per eliminare un processo in background, usare il cmdlet Remove-Job. Il comando seguente elimina il processo nella variabile $job.

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à Motivo per individuare 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".

Vedere anche