Question:
I have a working PowerShell 3.0 script that takes advantage of Invoke-WebRequest
to post a form and save the respective raw HTML output. Unfortunately, the script doesn’t work on workstations with only PowerShell 2.0.
I was hoping someone could please help convert the below script to work with PowerShell 2.0 (without having to install PS modules, packages, or upgrade PowerShell). It looks like I need to use .NET webclient, but I’m not experienced enough to do this yet. A working example (based on my script) would be extremely appreciated!
PS: I’m using sls -pattern
to filter out content in the raw HTML output. If there’s a more reliable way to identify certain items in the raw output, I wouldn’t mind seeing an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$UserAgent = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET CLR 1.1.4322; InfoPath.3; MS-RTC LM 8; .NET4.0E)' $r=Invoke-WebRequest -Uri 'http://web.ourwebserver.com/test.aspx' -UseDefaultCredentials -SessionVariable WebSession $form = $r.Forms[0] $fields = Invoke-WebRequest -Uri 'http://web.ourwebserver.com/test.aspx' -WebSession $WebSession | select -ExpandProperty inputfields | select name, value $viewstate = $fields | ?{$_.name -match "VIEWSTATE"} | select -ExpandProperty value $eventvalidation = $fields | ?{$_.name -match "EVENTVALIDATION"} | select -ExpandProperty value $form.Fields["__EVENTVALIDATION"] = $eventvalidation $form.Fields["ctl00`$MainContent`$phone"] = "454-454-2345" $form.Fields["ctl00`$MainContent`$Submit"] = "Submit" $response = Invoke-WebRequest -Uri 'http://web.ourwebserver.com/test.aspx' -WebSession $WebSession -Method POST -Body $form.Fields -ContentType 'application/x-www-form-urlencoded' $result = $response.rawcontent |
EDIT: Below, is my first attempt at getting the script to work. Anyway, it’s obviously not doing the same thing as my WORKING Invoke-WebRequest script above
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$URL = "http://web.ourwebserver.com/test.aspx" $wc = new-object net.WebClient $wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded") $wc.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET CLR 1.1.4322; InfoPath.3; MS-RTC LM 8; .NET4.0E)") $wc.UseDefaultCredentials = $true ### EventValidation/ViewState Extraction Code ### $probe = $wc.downloadData($url) $s = [text.encoding]::ascii.getString($probe) $start = $s.indexOf('id="__VIEWSTATE"', 0) + 24 $end = $s.indexOf('"', $start) $viewstate = $s.substring($start, $end-$start) $start = $s.indexOf('id="__EVENTVALIDATION"', 0) + 30 $end = $s.indexOf('"', $start) $eventvalidation = $s.substring($start, $end-$start) ### $NVC = New-Object System.Collections.Specialized.NameValueCollection $NVC.Add("__EVENTVALIDATION", $eventvalidation) $NVC.Add("ctl00`$MainContent`$phone", "454-454-2345") $NVC.Add("ctl00`$MainContent`$Submit", "Submit") $wc.QueryString = $NVC $Result = $WC.UploadValues($URL,"POST", $NVC) [System.Text.Encoding]::UTF8.GetString($Result) $WC.Dispose(); |
Answer:
Here is the code I use to post my Web requests, this is not the exact answer, but I suppose you can adapt it :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization, System.Web.Extensions $utf8 = [System.Text.Encoding]::UTF8 function Request-Rest { [CmdletBinding()] PARAM ( [Parameter(Mandatory=$true)] [String] $URL, [Parameter(Mandatory=$false)] [System.Net.NetworkCredential] $credentials, [Parameter(Mandatory=$true)] [String] $JSON) # Remove NewLine from json $JSON = $JSON -replace "$([Environment]::NewLine) *","" # Create a URL instance since the HttpWebRequest.Create Method will escape the URL by default. # $URL = Fix-Url $Url $URI = New-Object System.Uri($URL,$true) try { # Create a request object using the URI $request = [System.Net.HttpWebRequest]::Create($URI) # Build up a nice User Agent $UserAgent = "Your user agent name" $request.UserAgent = $("{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}), [Environment]::Version, [Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win")) $request.Credentials = $credentials $request.KeepAlive = $true $request.Pipelined = $true $request.AllowAutoRedirect = $false $request.Method = "POST" $request.ContentType = "application/json" $request.Accept = "application/json" $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($JSON) $request.ContentLength = $utf8Bytes.Length $postStream = $request.GetRequestStream() $postStream.Write($utf8Bytes, 0, $utf8Bytes.Length) #Write-String -stream $postStream -string $JSON $postStream.Dispose() try { #[System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse() $response = $request.GetResponse() } catch { $response = $Error[0].Exception.InnerException.Response; Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)" } $reader = [IO.StreamReader] $response.GetResponseStream() $output = $reader.ReadToEnd() $reader.Close() $response.Close() Write-Output $output } catch { $output = @" { "error":1, "error_desc":"Request-Rest Internal : Serveur access problem $($_.Exception.Message)" } "@ Write-Output $output } } |