29Aug

Escuela Geek: aprenda a usar trabajos en PowerShell

PowerShell tiene cuatro tipos de trabajos: trabajos en segundo plano, trabajos remotos, trabajos WMI y trabajos programados.Únase a nosotros mientras descubrimos cuáles son y cómo podemos usarlos.

Asegúrese de leer los artículos anteriores de la serie:

  • Aprenda a automatizar Windows con PowerShell
  • Aprenda a usar los cmdlets en PowerShell
  • Aprendizaje de cómo usar objetos en PowerShell
  • Aprendizaje Formato, filtrado y comparación en PowerShell
  • Aprenda a usar Remoting enPowerShell
  • Uso de PowerShell para obtener información del equipo
  • Trabajo con colecciones en PowerShell

Y estad atentos para el resto de la serie durante toda la semana.

Trabajos en segundo plano

Hasta ahora, todo lo que le he mostrado en PowerShell ha sido sincrónico, lo que significa que escribimos algo en el shell y no podemos hacer mucho hasta que ese comando haya terminado de ejecutarse. Aquí es donde entran los trabajos en segundo plano. Para iniciar un fondo, el trabajo simplemente pasa un bloque de script al cmdlet de Start-Job.

Start-Job -Name GetFileList -Scriptblock{ Get-ChildItem C: \ -Recurse}

Ahora podemos hacer lo que queramos dentro del shell mientras el script se ejecuta en segundo plano.

Cuando inicia un nuevo trabajo, PowerShell crea un nuevo objeto de trabajo que representa ese trabajo. Puede obtener una lista de todos los trabajos en cualquier momento ejecutando el cmdlet Get-Job.

Los objetos de trabajo le informan sobre el estado de los trabajos. Por ejemplo, en la captura de pantalla anterior, podemos ver que tenemos un BackgroundJob llamado GetFileList que todavía se está ejecutando, pero que ya ha comenzado a devolver datos. Si en algún momento decide que el trabajo se ha estado ejecutando durante demasiado tiempo, puede detenerlo fácilmente al conectarlo en Stop-Job.

Get-Job -Name GetFileList |Stop-Job

Sin embargo, una vez que haya detenido un trabajo, los datos que haya recibido hasta el momento en que lo detuvo están disponibles. Hay un gotcha, sin embargo. En PowerShell, una vez que recibe los resultados de un trabajo, se eliminan. Para que permanezcan, debe especificar el parámetro de mantener el interruptor de Recibir-Trabajo.

Get-Job -Name GetFileList |Receive-Job-Keeping

Una vez que haya terminado con un trabajo, lo mejor es eliminarlo. Para eliminar el trabajo, simplemente canalícelo al cmdlet Remove-Job.

Get-Job -Name GetFileList |Remove-Job

Esto lo eliminará de la lista de trabajos devueltos por Get-Job.

Trabajos remotos

Hace algunas lecciones, vimos cómo podemos usar la comunicación remota para ejecutar comandos de PowerShell en una máquina remota usando Invoke-Command, pero ¿sabía que también puede usar Invoke-Command para iniciar una tarea remota en segundo plano??Para hacerlo, simplemente agregue el parámetro -AsJob al final de su comando:

Invoke-Command -ComputerName Flash, Viper -Credential administrator -ScriptBlock{ gci} -AsJob

Ese fue un comando simple y debería haber terminado de ejecutarse por ahora, asíechemos un vistazo a nuestro estado de trabajos.

Hmm, parece que falló.Esto me lleva a mi primer encuentro con trabajos. Cuando crea un nuevo trabajo de cualquier tipo en PowerShell, crea un trabajo principal además de un trabajo secundario para cada computadora contra la que ejecuta el trabajo. Cuando utiliza el cmdlet Get-Job, solo muestra los trabajos principales y la propiedad de estado es el peor de los casos, lo que significa que incluso si el comando solo no se ejecutó en una de cien computadoras, el estado de los trabajos principales diráha fallado. Para ver una lista de trabajos secundarios, debe usar el parámetro IncludeChildJob.

Si miras más de cerca, verás que el trabajo solo falló en una computadora, lo que nos lleva a la siguiente pregunta. Cuando intente obtener los resultados para el trabajo, si especifica el nombre o la identificación del trabajo del padre, PowerShell devolverá los datos de todos los trabajos secundarios. El problema es que si hubo un error en uno de los trabajos secundarios, nos quedará algo de texto rojo.

Hay dos formas de evitar esto. En primer lugar, si sabe para qué equipos desea obtener los resultados, simplemente puede usar el parámetro ComputerName del cmdlet Recieve-Job.

Get-Job-Id 3 |Receive-Job-Keeping-ComputerName Viper

Alternativamente, puede obtener los resultados de un trabajo secundario específico utilizando su id de trabajo.

Get-Job -Id 3 -IncludeChildJob

Get-Job -Id 5 |Receive-Job-Keep

WMI Jobs

Las tareas

WMI son muy parecidas a las tareas remotas, por lo que solo se debe agregar el parámetro -AsJob al cmdlet Get-WmiObject.

Desafortunadamente, esto significa que también están sujetos a los mismos errores que mencioné en la sección Trabajos remotos.

Trabajos programados

Los últimos tres tipos de trabajos que vimos no fueron persistentes, lo que significa que solo están disponibles en la sesión actual. Básicamente, eso significa que si inicia un trabajo y luego abre otra Consola de PowerShell y ejecuta Get-Job, no verá ningún trabajo. Sin embargo, vuelva a la consola desde la que canceló el trabajo, podrá ver su estado. Esto está en contraste con los trabajos programados que son persistentes. Básicamente, un trabajo programado es un bloque de script que se ejecuta según un cronograma. En el pasado, el mismo efecto se podría haber logrado utilizando el Programador de tareas de Windows, que es realmente lo que está sucediendo debajo del capó.Para crear un nuevo trabajo programado, hacemos lo siguiente:

Register-ScheduledJob -Name GetEventLogs -ScriptBlock{ Get-EventLog -LogName Security -Newest 100} -Trigger( New-JobTrigger -Daily -At 5pm) -ScheduledJobOption( New-ScheduledJobOption-RunElevated)

Hay muchas cosas sucediendo en ese comando, así que desglosémoslo.

  • Primero, asignamos a nuestro trabajo programado un nombre de GetEventLogs.
  • Entonces le decimos que cuando se active, queremos que ejecute el contenido del bloque de script especificado, que básicamente obtiene las 100 entradas más nuevas del registro de eventos de seguridad.
  • A continuación, especificamos un disparador. Como el parámetro desencadenante toma un objeto desencadenante como entrada, usamos un comando entre paréntesis para generar un desencadenador que se activará todos los días a las 5 p.m.
  • Dado que se trata del registro de eventos, debemos ejecutarlo como administrador, lo que podemos especificar creando un nuevo objeto ScheduledJobOption y pasándolo al parámetro ScheduledJobOption.

Dado que este es un tipo de trabajo ligeramente diferente, también necesitará usar un comando diferente para recuperar una lista de todos los trabajos programados en una máquina.

Get-ScheduledJob

Eso es todo.