PowerShell Invoke-WebRequest: Una guía completa

¿Alguna vez has deseado navegar por la web a través de la línea de comandos? Sí. Yo tampoco. Pero ¿alguna vez has necesitado extraer información de una página web, monitorear un sitio web o enviar información mediante automatización? Yo sí, ¡y uso Invoke-Webrequest para hacerlo!

El cmdlet de PowerShell Invoke-WebRequest es la navaja suiza para la web. Este cmdlet puede enviar cualquier verbo HTTP a un servicio web junto con cosas comunes como parámetros HTTP, especificar diferentes encabezados HTTP, entre otros. Invoke-WebRequest junto con su hermano, Invite-RestMethod, son los dos cmdlets de PowerShell con los que debes familiarizarte si necesitas realizar cualquier tipo de automatización web.

El cmdlet Invoke-WebRequest es parte del módulo Microsoft.PowerShell.Utility que viene con Windows PowerShell y PowerShell Core. Este cmdlet se incluyó en PowerShell desde la versión 3 y es extremadamente poderoso pero fácil de usar.

Al usar Invoke-WebRequest, PowerShell permite que un desarrollador trabaje con sitios web, servicios web y API REST de diferentes formas.

Uso básico

En su forma más básica, el cmdlet Invoke-WebRequest envía un método de solicitud HTTP a un punto final como una URI o URL. El cmdlet admite todos los métodos de solicitud comunes.

De lejos, el método más común es el método GET. Este método lee información, como información de un sitio web o tal vez hace consultas a una API REST. El método se define usando el parámetro Method. Como necesitamos un punto final para hacer la consulta, también necesitaremos una URI. Para facilitar esto, elegiré cualquier sitio web. Para promocionar descaradamente TechSnips, elegiré techsnips.io.

Digamos que quiero obtener una lista de todos los videos publicados más recientes, como se muestra a continuación.

Example webpage

I can get an HTML representation of this page by running Invoke-WebRequest -Uri 'https://techsnips.io' -Method GET. When I do this, Invoke-WebRequest downloads the entire web page and returns an output with various parsed information around the elements of the page.

Invoke-WebRequest response

Para obtener los videos, necesitaré investigar un poco. Cuando veo la propiedad de enlaces, veo una característica común en todos los enlaces de video: tienen una clase de ng-binding, como se muestra a continuación.

$result.Links | where {$_.class -eq ‘ng-binding’}

Una vez que sé esto, puedo encontrar todos esos elementos y devolver solo la propiedad innerHTML ¡y listo!

$result.links | where {$_.class -eq ‘ng-binding’} | Select-Object innerHtml

Descargando archivos con Invoke-WebRequest

También podemos usar Invoke-WebRequest para descargar archivos de la web y es realmente fácil. Podemos descargar archivos simplemente apuntando Invoke-WebRequest a una URI de un archivo y usando el parámetro OutFile para indicarle al cmdlet que guarde el archivo en el disco local.

Como ejemplo, a continuación estoy descargando la utilidad Handle de SysInternals y descomprimiendo el archivo zip una vez descargado. ¡Es realmente tan fácil!

Invoke-WebRequest -Uri 'https://download.sysinternals.com/files/Handle.zip' -OutFile C:\handle.zi Expand-Archive -Path C:\handle.zip

Enviar un formulario y trabajar con sesiones

Podemos usar Invoke-WebRequest para completar formularios. Para hacer esto, comúnmente necesitamos trabajar con sesiones web. HTTP es un protocolo naturalmente sin estado y su navegador (en este caso, PowerShell) debe ser capaz de crear una sesión que se utilizará para rastrear cosas como las cookies, por ejemplo. Un formulario común es un formulario de inicio de sesión/contraseña, así que vamos a iniciar sesión en un sitio web ficticio!

Supongamos que nuestro formulario de inicio de sesión ficticio está en la URL http://somewebsite.com. Primero debemos ejecutar Invoke-WebRequest para descargar la estructura HTML y crear una sesión.

$response = Invoke-WebRequest -Uri 'http://somewebsite.com' -SessionVariable rb

Una vez que hagamos esto, la respuesta tendrá una propiedad Forms que podemos llenar con un nombre de usuario y una contraseña. En este caso, el nombre de usuario está representado por un campo llamado user y la contraseña debe estar en un campo llamado password. Esto dependerá de la página web.

$form = $response.Forms[0]
$form.Fields["user"] = "username"
$form.Fields["password"] = "password"

Una vez que se haya llenado el formulario, podemos usar nuevamente Invoke-WebRequest, pero esta vez reutilizamos la sesión que acabamos de crear y automáticamente descubrimos la URI a la que enviarla leyendo la propiedad Action que está en el formulario, como se muestra a continuación.

$response = Invoke-WebRequest -Uri $form.Action -WebSession $rb -Method POST

Si hemos ingresado correctamente todos los nombres de campo adecuados y la página web no está realizando ninguna acción especial, deberíamos haber iniciado sesión con el nombre de usuario y la contraseña dentro de la variable de sesión web $rb. En este punto, puedes leer varias páginas detrás de esa autenticación si utilizas la variable de sesión web $rb.

Resolución de URI cortas

Finalmente, otro gran uso de Invoke-WebRequest es resolver URIs cortos. ¡Tal vez necesites saber qué hay detrás de esa URL acortada pero no quieras hacer clic en ella para averiguarlo! No hay problema. Usando Invoke-WebRequest, podemos leer la propiedad AbsoluteUri de la respuesta analizada que nos proporciona.

Observa que también estoy utilizando el parámetro UseBasicParsing. De forma predeterminada, Invoke-WebRequest intenta utilizar Internet Explorer (IE) para analizar el HTML devuelto. Esto no funciona en sistemas sin IE. Para solucionar eso, podemos usar el parámetro UseBasicParsing para descargar el contenido pero analizarlo de forma ligera.

$Url = 'buff.ly/2sWvPOH'
$Web = Invoke-WebRequest -Uri $Url -UseBasicParsing
$Web.BaseResponse.ResponseUri.AbsoluteUri

Resumen

El cmdlet Invoke-WebRequest es uno de los cmdlets más versátiles que vienen con PowerShell. Si hay una acción que se puede realizar a través de un navegador gráfico típico, el cmdlet Invoke-WebRequest también puede hacerlo. Puedes encontrar un ejemplo de uso de este cmdlet echando un vistazo a este artículo sobre la supervisión de APIs REST.

Source:
https://adamtheautomator.com/invoke-webrequest/