I had the very same issue and I think my solution should work for you too.
First, install Fiddler. Then while fiddler is running, login to the website manually. You should see the login request in the fiddler trace - If you look at the WebForms tab on the trace you should see the Username and Password fields populated there.
For some reason, when logging in manually, the field names were different! The field names had "$" character in places that powerShell had shown as
"_" characters, e.g. ContentPlaceHolder$txtUserName, not ContentPlaceHolder_txtUserName that PowerShell displayed.
So, instead of assigning values to the Username and password fields that powerShell claimed were part of the form, I deleted those, created new fields with the same names shown in Fiddler, then populated those new fields.
Also, since "$" is a special character within powerShell, you need to prefix that with ` in order to use it simply as a dollar sign, to prevent powerShell thinking you are referring to the start of a variable name.
See code below :-
$webRequest = Invoke-WebRequest -URi "http://YourWebsite/Login.aspx" -SessionVariable SMSession
$dbForm = $webRequest.Forms[0]
# For some reason, the field values returned have underscores instead of $ signs! Need to delete this, then recreate
# with the correct values, using ` to allow $ to be passed without treating it as a variable.
$dbForm.fields.Remove("ContentPlaceHolder_txtUserName")
$dbForm.fields.Remove("ContentPlaceHolder_txtPassword")
$dbform.fields.Add("ContentPlaceHolder`$txtUserName", "admin")
$dbform.fields.Add("ContentPlaceHolder`$txtPassword", "Password2")
#$dbform.fields
$r = invoke-WebRequest -Uri ("http://YourWebsite/Login.aspx") -WebSession $SMSession -Method Post -Body $dbForm.Fields
$r.RawContent