3

I got to the point of logging in, but I get "Your request couldn't be processed" from facebook at the last step.

# Setup
#[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$ProgressPreference = 'SilentlyContinue'

# Session
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
$session.Cookies.Add((New-Object System.Net.Cookie("datr", "value", "/", ".facebook.com"))) # Used to set Allow Cookies to Accepted, replace value with your own value form the datr cookie.
$url = 'https://facebook.com/'

# Creds and Form
$login = Invoke-WebRequest -Uri $url -WebSession $session
$form = $login.Forms[0]
$credential = Get-Credential # or Import-CliXml cred.xml
$form.Fields["email"] = $credential.GetNetworkCredential().username
$form.Fields["pass"] = $credential.GetNetworkCredential().password

# Request
$facebook = Invoke-WebRequest -Uri $url -WebSession $session -Method POST -Body $form.Fields
#$facebook.Content

The idea: Run a powershell script, provide creds, it goes to Facebook, logs you in and outputs in the console how many photos you have in total.

Eduard G
  • 443
  • 5
  • 21
  • Some sites actively block some, if not all automation efforts. So, are you then saying, this same code works in PowerShell 5x without issue, thus only a catch22 using PSCore? I've never had a FB/TWTR, et all account, for any reason since it was released. So, no way for me to validate. – postanote Sep 10 '22 at 22:57
  • Be aware that Facebook doesn't allow you to scrape them. So don't be surprised when you get banned. – WizKid Sep 12 '22 at 03:42

1 Answers1

3

Use Chromium-based browser DevTools to Generate the WebRequest code for you

By far the easiest way I've found to do this is to use Chrome's (or other chromium-based browsers) developer tools. The tools will generate all the code you need.

  • Go to the Facebook login page
  • Open the DevTools by pressing the F12 key
  • Open the Network panel
  • Enter your credentials
  • Click the "Log In" button
  • Locate the Post request in the list (should be near the top if you've just opened DevTools)
  • Right-click on the request and choose Copy > Copy as PowerShell.
  • Paste the code into a script file/VS Code/PowerShell ISE.
  • Remove ", br" from "accept-encoding"="gzip, deflate, br" from the headers hashtable or the response will NOT be readable
  • You can then use the $session variable in further requests
    • These requests can be generated the same way as the first from the DevTools network panel. Just remove all of the top $session lines so you don't overwrite the initial session cookies (and remove the br compression format again from the accept-encoding line).

Network Tab from Chrome DevTools

Generated code will look like something like this

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.33"
$session.Cookies.Add((New-Object System.Net.Cookie("fr", "0SmzDrtR5y3gEIe773d..BjT69C.eZ.AAA.0.0.BjHE333C.AWTZZ825DfGgk0", "/", ".facebook.com")))
$session.Cookies.Add((New-Object System.Net.Cookie("sb", "Qk8dY1sdf23MH4kHnd1F225Ap2akhXf", "/", ".facebook.com")))
$session.Cookies.Add((New-Object System.Net.Cookie("datr", "TEh3de4TYyf-7e2d36gFVo3wIpseiWg", "/", ".facebook.com")))
$session.Cookies.Add((New-Object System.Net.Cookie("wd", "881x863", "/", ".facebook.com")))
Invoke-WebRequest -UseBasicParsing -Uri "https://www.facebook.com/login/?privacy_mutation_token=eyJ0eXBlIjowLCJjcDFmVhd43324Glvbl90aW1dfslIjoxNjYyODY1MjE4LCJ4WxsD4Ooc2453l0ZV9pZCIDFg36MszgxMjI5MDc5NTsTQ2fQ%3D%3D" `
-Method "POST" `
-WebSession $session `
-Headers @{
"authority"="www.facebook.com"
  "method"="POST"
  "path"="/login/?privacy_mutation_token=eyJ0eXBlIjowLCJjcDFmVhd43324Glvbl90aW1dfslIjoxNjYyODY1MjE4LCJ4WxsD4Ooc2453l0ZV9pZCIDFg36MszgxMjI5MDc5NTsTQ2fQ%3D%3D"
  "scheme"="https"
  "accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
  "accept-encoding"="gzip, deflate, br"
  "accept-language"="en-US,en;q=0.9"
  "cache-control"="max-age=0"
  "origin"="https://www.facebook.com"
  "referer"="https://www.facebook.com/"
  "sec-ch-ua"="`"Microsoft Edge`";v=`"105`", `" Not;A Brand`";v=`"99`", `"Chromium`";v=`"105`""
  "sec-ch-ua-mobile"="?0"
  "sec-ch-ua-platform"="`"Windows`""
  "sec-fetch-dest"="document"
  "sec-fetch-mode"="navigate"
  "sec-fetch-site"="same-origin"
  "sec-fetch-user"="?1"
  "upgrade-insecure-requests"="1"
} `
-ContentType "application/x-www-form-urlencoded" `
-Body "jazoest=2923&lsd=AVoElEJYWu0&email=test%40gmail.com&login_source=comet_headerless_login&next=&encpass=%23PWD_BROWSER%3A5%3A16D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3EKNpw%3D%3D"

Through some trial and error this appears to be the bare minimum needed.

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
# Keep from above generated code
$session.Cookies.Add((New-Object System.Net.Cookie('datr', 'TEh3de4TYyf-7e2d36gFVo3wIpseiWg', '/', '.facebook.com'))) 

$body = [ordered]@{
    lsd   = 'AVoElEJYWu0'  # Keep from above generated code
    email = 'test@gmail.com'  # update 
    pass  = 'mypassword123' # update
} 

$params = @{
    OutFile     = 'c:\temp\facebook.html'
    Uri         = 'https://www.facebook.com/login'
    Method      = 'POST'
    Headers     = @{
        'scheme' = 'https'
        'accept' = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    }
    WebSession  = $session
    ContentType = 'application/x-www-form-urlencoded'
    Body        = $body 
}
$response = Invoke-WebRequest @params -PassThru
Daniel
  • 4,792
  • 2
  • 7
  • 20
  • Ah, exactly what I needed :) I tried like that initially but with the 'br' in it, and the response was gibberish so I gave up on that method. Thank you! Do you know what the 'br' stands for? – Eduard G Sep 11 '22 at 09:30
  • Although now that I think about it, this copy-paste request will not work forever will it? Does it have some tokens in it that expire within a time-frame? The goal of the PS script is not to have to go through the process of copy-pasting the request every now and then. – Eduard G Sep 11 '22 at 09:33
  • I was wondering the same. Not sure. Anyways, I've updated the answer with what I found to be the bare minimum headers and body needed. Still the datr cookie and lsd value in the body are needed. – Daniel Sep 11 '22 at 19:21
  • I see. It probably won't expire then, as I dont think the cookie value changes over time and I had no clue that the username and pass are also passed. In any case, it is working for me now and I am working on some automation :) Awesome stuff – Eduard G Sep 12 '22 at 06:51