2015-06-18 9 views
7

Ich habe ein funktionierendes PowerShell 3.0-Skript, das Invoke-WebRequest nutzt, um ein Formular zu posten und die entsprechende HTML-Ausgabe zu speichern. Leider funktioniert das Skript nicht auf Arbeitsstationen mit nur PowerShell 2.0.HTTP-Formular ohne Verwendung von 'Invoke-WebRequest' schreiben

Ich hatte gehofft, jemand könnte bitte helfen, das folgende Skript zu konvertieren, um mit PowerShell 2.0 zu arbeiten (ohne PS-Module, Pakete installieren oder PowerShell aktualisieren). Es sieht so aus, als müsste ich den .NET Webclient benutzen, aber ich bin noch nicht erfahren genug, dies zu tun. Ein funktionierendes Beispiel (basierend auf meinem Skript) würde sehr geschätzt werden!

PS: Ich benutze sls -pattern, um Inhalt in der Raw-HTML-Ausgabe herauszufiltern. Wenn es eine zuverlässigere Möglichkeit gibt, bestimmte Elemente in der Rohausgabe zu identifizieren, würde es mir nichts ausmachen, ein Beispiel zu sehen.

$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: Unten ist mein erster Versuch des Skript auf dem Weg zur Arbeit. Wie auch immer, es ist offensichtlich nicht das gleiche tun wie mein WORKING Invoke-WebRequest Skript oben

$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(); 
+0

Ich bin ziemlich sicher, dass ich den Großteil der Antwort richtig geschrieben. Ich denke, möglicherweise etwas falsch gemacht, wenn Sie Werte/Daten zu $ ​​NVC hinzufügen. – MKANET

Antwort

0

Einfache POST kann wie folgt durchgeführt werden. Bitte versuchen Sie es, wenn es funktioniert.

$URL="http://yourweb.com" 

$NVC = New-Object System.Collections.Specialized.NameValueCollection 
$NVC.Add($NAME1, $NAME_VALUE); 
$NVC.Add($NAME2, $NAME_VALUE2); 
.. 

$WC = New-Object System.Net.WebClient 
$WC.UseDefaultCredentials = $true 
$Result = $WC.UploadValues($URL,"post", $NVC); 

[System.Text.Encoding]::UTF8.GetString($Result) 
$WC.Dispose(); 
+0

Danke .. Aber wie greife ich $ viewstate und $ eventvalidation vor dem Post? Ich muss den $ eventvalidation-Wert posten, damit der Post erfolgreich ist. Wie kann ich Useragent für den Beitrag hinzufügen? – MKANET

+0

Ich habe meinen besten Versuch (in meiner ursprünglichen Frage) geschrieben, mein ursprüngliches Skript in den Webclient zu konvertieren. Ich werde jedoch Hilfe von jemandem brauchen, der über das Kopieren und Einfügen eines generischen Beispiels aus Google hinausgeht. – MKANET

4

Hier ist der Code, den ich meine Web-Anfragen stellen verwenden, ist dies nicht die genaue Antwort, aber ich nehme an, Sie es anpassen können:

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 
    } 
} 
1

Es sieht aus wie ich immer ganz in der Nähe war es funktioniert. Aus irgendeinem Grund musste ich auch __VIEWSTATE (zusätzlich zu __EVENTVALIDATION) in den POST aufnehmen. Ich konnte dies feststellen, indem ich Formulardaten über Fiddler verifizierte.

$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)") 
$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("__VIEWSTATE", $viewstate); 
$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(); 
0

Wenn Sie immer noch ein wiederverwendbares Skript benötigen, dann können Sie nutzen, was ich geschrieben habe für genau ähnliche Problem. Ich musste nur PowerShell 2.0 veröffentlichen. Das Skript ist in einer nice Wiederverwendbare Funktion hier auf GitHub: Request POST REST via Reusable Function