29Aug
PowerShell ha quattro tipi di lavori: lavori in background, lavori remoti, lavori WMI e lavori pianificati. Unisciti a noi quando scopriamo cosa sono e come possiamo usarli.
Leggere gli articoli precedenti della serie:
- Imparare come automatizzare Windows con PowerShell
- Imparare ad utilizzare i cmdlet in PowerShell
- Imparare come utilizzare gli oggetti in PowerShell
- Imparare la formattazione, il filtraggio e il confronto in PowerShell
- Imparare a utilizzare i servizi remoti inPowerShell
- Utilizzo di PowerShell per ottenere informazioni sul computer
- Utilizzo delle raccolte in PowerShell
E rimanere sintonizzati per il resto della serie per tutta la settimana.
Background Jobs
Fino ad ora tutto ciò che ti ho mostrato in PowerShell è stato sincrono, il che significa che scriviamo qualcosa nella shell e non possiamo davvero fare molto finché il comando non ha finito l'esecuzione. Qui è dove arrivano i lavori in background. Per avviare uno sfondo, il lavoro passa semplicemente un blocco di script al cmdlet Start-Job.
Start-Job -Name GetFileList -Scriptblock{ Get-ChildItem C: \ -Recurse}
Ora siamo liberi di fare tutto ciò che vogliamo all'interno della shell mentre quel blocco di script viene eseguito in background.
Quando si avvia un nuovo lavoro, PowerShell crea un nuovo oggetto lavoro che rappresenta quel lavoro.È possibile ottenere un elenco di tutti i lavori in qualsiasi momento eseguendo il cmdlet Get-Job.
Gli oggetti lavoro indicano lo stato dei lavori. Ad esempio, nello screenshot qui sopra possiamo vedere che abbiamo un oggetto BackgroundJob chiamato GetFileList, che è ancora in esecuzione, ma ha già iniziato a restituire i dati. Se in qualsiasi momento si decide che il lavoro è in esecuzione da troppo tempo, è possibile interromperlo facilmente collegandolo a Stop-Job.
Get-Job -Name GetFileList |Stop-Job
Tuttavia, una volta arrestato un lavoro, qualsiasi dato ricevuto fino al punto in cui è stato interrotto è ancora disponibile. C'è un gotcha, però.In PowerShell, una volta ricevuti i risultati per un lavoro, vengono eliminati. Affinché rimangano, è necessario specificare il parametro keep change di Receive-Job.
Get-Job -Name GetFileList |Receive-Job -Keep
Una volta terminato un lavoro, è consigliabile rimuoverlo. Per rimuovere il lavoro, è sufficiente collegarlo al cmdlet Remove-Job.
Get-Job -Name GetFileList |Remove-Job
Questo lo rimuoverà dall'elenco di lavori restituiti da Get-Job.
Remote Jobs
Alcune lezioni fa, abbiamo visto come possiamo usare il remoting per eseguire i comandi di PowerShell su una macchina remota usando Invoke-Command, ma sapevate che potete anche usare Invoke-Command per avviare un lavoro remoto in background? Per fare ciò, aggiungi semplicemente il parametro -AsJob alla fine del tuo comando:
Invoke-Command -ComputerName Flash, Viper -Credential administrator -ScriptBlock{ gci} -AsJob
Era un comando semplice e avrebbe dovuto terminare l'esecuzione oradiamo un'occhiata al nostro stato di lavoro.
Hmm, sembra non funzionare. Questo mi porta al mio primo scherzo con i lavori. Quando si crea un nuovo lavoro di qualsiasi tipo in PowerShell, viene creato un processo padre oltre a un processo figlio per ogni computer su cui si sta eseguendo il lavoro. Quando si utilizza il cmdlet Get-Job, vengono visualizzati solo i lavori principali e la proprietà state è lo scenario peggiore, nel senso che anche se il comando non è riuscito a essere eseguito su uno su un centinaio di computer, lo stato dei lavori principali verrà visualizzatofallito. Per visualizzare un elenco di lavori secondari è necessario utilizzare il parametro IncludeChildJob.
Se guardi più da vicino, vedrai che il lavoro ha effettivamente fallito su un solo computer, il che ci porta al successivo trucchetto. Quando si tenta di ottenere i risultati per il lavoro, se si specifica il nome o l'ID del processo del genitore, PowerShell restituirà i dati da tutti i lavori secondari. Il problema è che se c'è stato un errore in uno dei lavori secondari, ci rimane un testo rosso.
Ci sono due modi per aggirare questo problema. Innanzitutto, se si conosce a quali computer si desidera ottenere i risultati, è sufficiente utilizzare il parametro ComputerName del cmdlet Recieve -Job.
Get-Job -Id 3 |Receive-Job -Keep -ComputerName Viper
In alternativa, è possibile ottenere i risultati da un processo figlio specifico utilizzando il relativo ID lavoro.
Get-Job -Id 3 -IncludeChildJob
Get-Job -Id 5 |Receive-Job -Keep
WMI Jobs
I lavori WMIsono molto simili ai lavori remoti, richiedendo solo il parametro -AsJob da aggiungere al cmdlet Get-WmiObject.
Sfortunatamente, questo significa che sono anche soggetti agli stessi trucchi che ho menzionato nella sezione Lavori remoti. Lavori pianificati
Gli ultimi tre tipi di lavori che abbiamo esaminato non erano persistenti, il che significa che sono disponibili solo nella sessione corrente. In sostanza, ciò significa che se si avvia un lavoro e si apre un'altra Console PowerShell ed è in esecuzione Get-Job, non verranno visualizzati lavori. Tuttavia, torna alla console da cui hai dato il via, sarai in grado di vedere il suo stato. Questo è in contrasto con i Lavori programmati che sono persistenti .In sostanza, un lavoro pianificato è un blocco di script eseguito su una pianificazione. In passato, lo stesso effetto avrebbe potuto essere ottenuto utilizzando l'Utilità di pianificazione di Windows, che è davvero ciò che sta accadendo sotto il cofano. Per creare un nuovo lavoro pianificato, facciamo quanto segue:
Register-ScheduledJob -Nome GetEventLogs -ScriptBlock{ Get-EventLog -LogName Security -Newest 100} -Trigger( New-JobTrigger -Daily -At 5pm) -ScheduledJobOption( New-ScheduledJobOption-RunElevated)
C'è parecchio da fare in quel comando, quindi scomporlo.
- Innanzitutto, diamo al nostro Job pianificato il nome di GetEventLogs.
- Diciamo poi che quando viene attivato, vogliamo che esso esegua il contenuto del blocco di script specificato, che in pratica ottiene le ultime 100 voci del registro degli eventi di sicurezza.
- Successivamente, si specifica un trigger. Poiché il parametro trigger prende un oggetto trigger come input, abbiamo usato un comando parentetico per generare un trigger che andrà via ogni giorno alle 17:00.
- Dato che abbiamo a che fare con il registro eventi, dobbiamo eseguire come amministratore, che possiamo specificare creando un nuovo oggetto ScheduledJobOption e passandolo al parametro ScheduledJobOption.
Poiché si tratta di un tipo di lavoro leggermente diverso, sarà inoltre necessario utilizzare un comando diverso per recuperare un elenco di tutti i processi pianificati su una macchina.
Get-ScheduledJob
Questo è tutto ciò che c'è da fare.