我有一个有效的PowerShell 3.0脚本利用Invoke-WebRequest
发布表单并保存相应的原始HTML输出。不幸的是,该脚本不适用于仅使用PowerShell 2.0的工作站。
我希望有人可以帮助转换以下脚本以使用PowerShell 2.0(无需安装PS模块,软件包或升级PowerShell)。看起来我需要使用.NET webclient,但我还没有足够的经验来做到这一点。一个工作示例(基于我的脚本)将非常感谢!
PS:我使用sls -pattern
过滤掉原始HTML输出中的内容。如果有更可靠的方法来识别原始输出中的某些项目,我不会介意看一个例子。
$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
编辑:下面,是我第一次尝试让脚本运行。无论如何,它显然与我上面的WORKING Invoke-WebRequest脚本没有做同样的事情
$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 :(得分:4)
这是我用来发布我的Web请求的代码,这不是确切的答案,但我想你可以适应它:
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 :(得分:1)
看起来我非常接近它的工作。出于某种原因,我还需要在POST中包含__VIEWSTATE(除了__EVENTVALIDATION)。我能够通过Fiddler验证表单数据来确定这一点。
$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();
答案 2 :(得分:0)
简单的POST可以像这样完成。 如果有效,请试试。
$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();
答案 3 :(得分:0)
如果您仍然需要可重用的脚本,那么您可以利用我所写的完全相似的问题。我只需要使用PowerShell 2.0发布。该脚本在GitHub上的不错的可重用函数中提供:Request POST REST via Reusable Function