Invoke-WebRequest: realice solicitudes HTTP, descargue archivos, analice la web con PowerShell

los Invocar-WebRequest El cmdlet se puede usar para solicitar recursos HTTP/HTTPS/FTP directamente desde la consola de PowerShell. Puede usar este comando para enviar solicitudes HTTP (GET y POST), descargar archivos de un sitio web, analizar páginas web HTML, realizar autenticación, completar y enviar formularios web, etc. En este artículo, cubriremos ejemplos básicos del uso el cmdlet Invoke-WebRequest en PowerShell para interactuar con los servicios web.

Obtener contenido de la página web con el cmdlet Invoke-WebRequest

los Invocar-WebRequest cmdlet le permite enviar la solicitud HTTP, HTTPS o FTP con el método GET a la página web especificada y recibir una respuesta del servidor. Este cmdlet ha estado disponible en Windows desde la versión PowerShell 3.0.

Hay dos alias para el comando Invoke-WebRequest en Windows: iwk y wget.

Ejecute el siguiente comando:

Invoke-WebRequest -Uri "http://woshub.com"

Invoke-WebRequest obtener contenido de la página web usando powershell

Consejo. Si está conectado a Internet a través de un servidor proxy, debe configurar correctamente PowerShell para acceder a la Web a través del servidor proxy. Si no configura los parámetros del proxy, recibirá un error cuando ejecute el comando IWK:

Invoke-WebRequest:  Unable to connect to the remote server
CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Invoke-WebRequest: no se puede conectar al servidor remoto

El comando cargó la página y mostró su contenido en la consola de PowerShell. La respuesta devuelta no es solo el código HTML de la página. El cmdlet Invoke-WebRequest devuelve un objeto de tipo HtmlWebResponseObject. Dicho objeto es una colección de formularios, enlaces, imágenes y otros elementos importantes de un documento HTML. Veamos todas las propiedades de este objeto:

$WebResponseObj = Invoke-WebRequest -Uri "http://woshub.com"
$WebResponseObj| Get-Member

Propiedades de HtmlWebResponseObject

Para obtener el código HTML sin procesar de la página web que se encuentra en el HtmlWebResponseObject objetar, ejecutar:

$WebResponseObj.content

Puede enumerar el código HTML junto con los encabezados HTTP devueltos por el servidor web:

$WebResponseObj.rawcontent

Invoke-WebRequest obtenga código html sin procesar y estados http en la página web

Solo puede verificar el código de estado HTTP del servidor web y los encabezados HTTP de la página HTML:

$WebResponseObj.Headers

Como puede ver, el servidor ha devuelto una respuesta. 200. Esto significa que la solicitud ha sido exitosa y el servidor web está disponible y funciona correctamente.

Key               Value
---               -----
Transfer-Encoding chunked
Connection        keep-alive
Vary              Accept-Encoding,Cookie
Cache-Control     max-age=3, must-revalidate
Content-Type      text/html; charset=UTF-8
Date              Wed, 13 Jul 2022 02:28:32 GMT
Server            nginx/1.20.2
X-Powered-By      PHP/5.6.40

Para obtener la hora de la última modificación de una página web:

$WebResponseObj.ParsedHtml | Select lastModified

powershell obtener la fecha de última modificación de la página web

Puede especificar una cadena de agente de usuario al conectarse a un recurso web. PowerShell tiene un conjunto de cadenas de agente de usuario integradas:

invoke-webRequest -Uri $uri -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)

La lista de agentes disponibles en PowerShell se puede mostrar así:

[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name, @{n='UserAgent';e={ [Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name) }}

powershell: configurar el agente de usuario

O puede establecer su propia cadena de UserAgent:

Invoke-WebRequest -Uri $uri -UserAgent 'MyApplication/1.1'

Uso de Invoke-WebRequest con autenticación

Algunos recursos web requieren autenticación para acceder. Puede usar varios tipos de autenticación con el cmdlet Invoke-WebRequest (Básica, NTLM, Kerberos, OAuth o autenticación de certificado).

Para realizar la autenticación básica (autenticación por nombre y contraseña codificada en base64), primero debe obtener el nombre de usuario y la contraseña:

$cred = Get-Credential
wget -Uri 'https://somesite.com' -Credential $cred

Para utilizar las credenciales de usuario de Windows actuales para realizar la autenticación NTLM o Kerberos, agregue la opción -UseDefaultCredentials:

Invoke-WebRequest 'https://somesite.com' -UseDefaultCredentials

DefaultCredentials no funciona con la autenticación básica.

Para autenticarse con un certificado, debe especificar su huella digital:

Invoke-WebRequest 'https://somesite.com' -CertificateThumbprint xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Puede usar la autenticación de token Bearer/OAuth moderna en sus scripts de PowerShell.

  1. Primero, debe obtener un token OAuth de su proveedor de API REST (fuera del alcance de esta publicación);
  2. Convertir token con el cmdlet ConvertTo-SecureString: $Token = "12345678912345678901234567890" | ConvertTo-SecureString -AsPlainText –Force
  3. Ahora puede realizar la autenticación OAuth:
    $Params = @{
    Uri = "https://somesite.com"
    Authentication = "Bearer"
    Token = $Token }
    Invoke-RestMethod @Params

Parse and Scrape HTML de una página web con PowerShell

El cmdlet Invoke-WebRequest le permite analizar rápida y cómodamente el contenido de cualquier página web. Al procesar una página HTML, se crean colecciones de enlaces, formularios web, imágenes, scripts, etc.

Veamos cómo acceder a objetos específicos en una página web. Por ejemplo, quiero obtener una lista de todos los enlaces salientes (objetos A HREF) en la página web HTML de destino:

$SiteAdress = "http://woshub.com"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Foreach {$_.href }

Invoke-WebRequest crea una colección html hrefs

Para obtener el texto del enlace en sí (contenido en el elemento InnerText), puede usar el siguiente comando:

$HttpContent.Links | fl innerText, href

Solo puede seleccionar enlaces con una clase CSS específica:

$HttpContent.Links | Where-Object {$_.class -eq "page-numbers"} | fl innerText, href

O texto específico en la dirección URL:

$HttpContent.Links | Where-Object {$_.href -like "*powershell*"} | fl innerText,href

filtrado de objetos html con posh

Luego muestre una lista de todas las imágenes en esta página:

$Img.Images

Cree una colección de rutas URL completas a estas imágenes:

$images = $Img.Images | select src

Inicialice una nueva instancia de la clase WebClient:

$wc = New-Object System.Net.WebClient

Y descargue todos los archivos de imagen de la página (con sus nombres de archivo originales) a la carpeta c:too1s:

$images | foreach { $wc.DownloadFile( $_.src, ("c:tools"+[io.path]::GetFileName($_.src) ) ) }

Página HTML de análisis de Invoke-WebRequest

¿Cómo descargar un archivo a través de HTTP/FTP con PowerShell Wget (Invoke-WebRequest)?

Invoke-WebRequest le permite descargar archivos desde una página web o sitio FTP (funciona como Wget o cURL en Windows). Suponga que desea descargar un archivo de un HTTP usando PowerShell. Ejecute el siguiente comando de PowerShell:

wget "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe" -outfile “c:toolsfirefox_setup.exe”

powershell: usando el alias de wget para descargar el archivo http/https

Este comando descargará el archivo del sitio HTTP y lo guardará en el directorio especificado.

Puede obtener el tamaño de un archivo en MB antes de descargarlo con wget:

$url = "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe"
(Invoke-WebRequest $url -Method Head).Headers.'Content-Length'/1Mb

wget: powershell obtiene el tamaño del archivo por enlace http

A continuación se muestra un ejemplo de un script de PowerShell que encontrará todos los enlaces a los archivos *.pdf en una página web de destino y descargará en masa todos los archivos encontrados del sitio web a su computadora (cada archivo pdf se guarda con un nombre aleatorio):

$OutDir="C:docsdownloadPDF"
$SiteAdress = "https://sometechdocs.com/pdf"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Where-Object {$_.href -like "*.pdf"} | %{Invoke-WebRequest -Uri $_.href -OutFile ($OutDir + $(Get-Random 200000)+".pdf")}

Como resultado de la secuencia de comandos en el directorio de destino, se descargarán todos los archivos pdf de la página. Cada archivo se guarda con un nombre aleatorio.

En PowerShell Core moderno (6.1 y más reciente), el cmdlet Invoke-WebRequest admite el modo de reanudación. Actualice su versión de PowerShell Core y podrá usar el -Reanudar opción en el comando Invoke-WebRequest para reanudar automáticamente la descarga de un archivo en caso de que un canal de comunicación o servidor no esté disponible:

Invoke-WebRequest -Uri $Uri -OutFile $OutFile –Resume

¿Cómo llenar y enviar un formulario HTML con PowerShell?

Muchos servicios web requieren completar varios datos en formularios HTML. Con Invoke-WebRequest, puede acceder a cualquier formulario HTML, completar los campos necesarios y enviar el formulario completado al servidor. En este ejemplo, mostraremos cómo iniciar sesión en Facebook a través de su formulario web estándar usando PowerShell.

Rellene y envíe el formulario de inicio de sesión de Facebook con Powershell

Con el siguiente comando, guardaremos la información sobre las cookies de conexión en una variable de sesión separada:

$fbauth = Invoke-WebRequest https://www.facebook.com/login.php -SessionVariable session

Usando el siguiente comando, muestre la lista de los campos para completar el formulario HTML de inicio de sesión (login_form):

$fbauth.Forms["login_form"].Fields

Asigne los valores deseados a todos los campos:

$fbauth.Forms["login_form"].Fields["email"] = "[email protected]"

$fbauth.Forms["login_form"].Fields["pass"] = "Coo1P$wd"

Etc.

Para enviar (enviar) el formulario completo al servidor, llame al atributo de acción del formulario HTML:

$Log = Invoke-WebRequest -method POST -URI ("https://www.facebook.com/login.php" + $fbauth.Forms["login_form"].Action) -Body $fbauth.Forms["login_form"].Fields -WebSession $session

También puedes usar el formato JSON para enviar datos a una página web con el método POST:

$headers = @{
'Content-Type'='application/json'
'apikey'='0987654321'
}
$jsonbody = @{
"siteUrl" ="https://somesite.com"
"email" = "[email protected]"
}
Invoke-WebRequest -Method 'Post' -Uri $url -Body ($jsonbody |ConvertTo-Json) -Headers $headers -ContentType "application/json"

Invoke-WebRequest: Ignorar comprobaciones de certificados SSL/TLS

Otro problema es que el cmdlet Invoke-WebRequest está estrechamente relacionado con Internet Explorer. Por ejemplo, en las ediciones de Windows Server Core en las que IE no está instalado (o eliminado), no se puede usar el cmdlet Invoke-WebRequest.

Invoke-WebRequest: The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer’s first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.

En este caso, se puede usar la clase WebClient en lugar de Invoke-WebRequest. Por ejemplo, para descargar un archivo desde una URL específica, use el comando.

(New-Object -TypeName 'System.Net.WebClient').DownloadFile($Url, $FileName)

Si se usa un certificado SSL no válido en un sitio HTTPS o si PowerShell no admite este tipo de protocolo SSL/TLS, el cmdlet Invoke-WebRequest descarta la conexión.

Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.

invoque-webrequest powershell: no se pudo establecer una relación de confianza Canal seguro SSL TLS

De forma predeterminada, Windows PowerShell (en versiones anteriores de Windows 10, Windows Server 2016 y versiones anteriores de Windows) usa el protocolo TLS 1.0 heredado e inseguro para las conexiones (consulte la publicación de blog que describe el error de instalación del módulo de PowerShell: Install-Module: Unable para descargar desde URI).

Si los protocolos heredados TLS 1.0 y TLS 1.1 no están deshabilitados en Windows, debe ejecutar el siguiente comando para usar TLS 1.2 en las conexiones de PowerShell:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Si se usa un certificado autofirmado en el sitio HTTPS, el cmdlet Invoke-WebRequest se niega a recibir datos de él. Para ignorar (omitir) un certificado SSL no válido, use el siguiente código de PowerShell:

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$result = Invoke-WebRequest -Uri "https://somesite.com"

En PowerShell Core, el cmdlet Invoke-WebRequest tiene un parámetro adicional:SkipCertificateCheck que le permite ignorar los certificados SSL/TLS no válidos.

Otro inconveniente importante del cmdlet Invoke-WebRequest es su rendimiento bastante bajo. Al descargar un archivo, la secuencia HTTP se almacena completamente en la memoria y solo después de que se completa la descarga completa se guarda en el disco. Por lo tanto, al descargar archivos de gran tamaño mediante Invoke-WebReques, es posible que se quede sin RAM.

Artículos Interesantes