Tranistion bat文件到powershell脚本 - Invoke-RestMethod

时间:2016-02-19 16:22:29

标签: powershell batch-file curl

我有一个使用[curl]( https://curl.haxx.se/)的基本bat脚本。该脚本从名为location_ids.txt的txt文档中获取值(此文件位于与脚本相同的文件夹中)。我已将其设置为使用3个不同location_id检查urls。它运作良好。但是,它很慢!因为批处理文件没有线程化,所以每个命令都会阻塞直到它完成。我知道使用Invoke-RestMethod使用powershell脚本(windows环境)可以更轻松快捷地完成此操作。我怎样才能在ps中复制下面的内容?我想同时进行卷曲调用。

@echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=%DATE:/=-%@%TIME::=-%
set OUTPUT_FILE=file_%OUTPUT_FILE: =%.html

for /f %%i in (location_ids.txt) do (
    set LOCATION_ID=%%i
    echo ^<h2 style='color:green;'^>!LOCATION_ID::=!^</h2^> >>%OUTPUT_FILE%
    curl -k -H "application/x-www-form-urlencoded" -X GET -d "id=!LOCATION_ID::=!" http://localhost:5000/location_site1 >>%OUTPUT_FILE% 
    curl -k -H "application/x-www-form-urlencoded" -X GET -d "id=!LOCATION_ID::=!" http://localhost:5000/location_site2 >>%OUTPUT_FILE%
    curl -k -H "application/x-www-form-urlencoded" -X GET -d "id=!LOCATION_ID::=!" http://localhost:5000/location_site3 >>%OUTPUT_FILE%
    echo ^<br^>^<br^> >>%OUTPUT_FILE%
)

修改

我尝试对使用scriptblock同时运行的http://localhost:5000/location_site1运行多个Web服务器调用。以下内容未输出任何结果。

$runRoutePost =
{ param([string]$id, [string]$fileLocation)
    Write-Host "Accessing site for $id";
    $ResponseData = New-Object PSObject;
    $webclient = new-object System.Net.WebClient;
    $apiParams = "id=$_";
    $ResponseData = $webclient.UploadString("http://localhost:5000/location_site1",$apiParams) |Add-Content $fileLocation;
}

Get-Content location_ids.txt | ForEach-Object {
    Start-Job -ScriptBlock $runRoutePost -ArgumentList $_, $LOG_FILE
} 

1 个答案:

答案 0 :(得分:1)

要转换您的示例,您实际上只需要对URL发出请求并将位置ID指定为查询字符串参数。以下示例使用字符串插值来设置id参数的值。 $ _变量是ForEach-Object脚本块中枚举的当前项。

$outputFile = # not sure of your date time format 

Get-Content location_ids.txt | ForEach-Object {
    Add-Content $outputFile "<h2 style=`"color:green`">$_</h2>"
    Invoke-RestMethod -Uri "http://localhost:5000/location_site1?id=$_" | Add-Content $outputFile
    Invoke-RestMethod -Uri "http://localhost:5000/location_site2?id=$_" | Add-Content $outputFile
    Invoke-RestMethod -Uri "http://localhost:5000/location_site3?id=$_" | Add-Content $outputFile
    Add-Content $outputFile "<br><br>"
}

对于GET请求,您无需指定内容类型或方法。但是,如果您需要其他脚本,则可以使用-Co​​ntentType和/或-Method参数。

Invoke-RestMethod -Method GET -ContentType application/x-www-form-urlencoded  -Uri "http://localhost:5000/location_site3?id=$_"

运行此文件可以找到更多文档:

get-help Invoke-RestMethod -full

由于您对使用PowerShell v2有限制,因此可以使用.NET WebClient类型。

$web = new-object System.Net.WebClient
Get-Content location_ids.txt | ForEach-Object {
    Add-Content $outputFile "<h2 style=`"color:green`">$_</h2>"
    $web.DownloadString("http://localhost:5000/location_site1?id=$_") | Add-Content $outputFile
    $web.DownloadString("http://localhost:5000/location_site2?id=$_") | Add-Content $outputFile
    $web.DownloadString("http://localhost:5000/location_site3?id=$_") | Add-Content $outputFile
    Add-Content $outputFile "<br><br>"
}

如果您想使用WebClient发送POST请求,可以使用UploadString方法。但是,在这种情况下,我不确定如何设置Content-Type标头。

$web.UploadString("http://localhost:5000/location_site1","id=$_") | Add-Content $outputFile

更新以响应修改

要并行运行这些作业并收集结果,您需要等待所有作业使用Wait-Job完成,然后使用Receive-Job提取结果。

$runRoutePost = { 
    param([string]$id)

    Write-Host "Accessing site for $id"
    $webclient = new-object System.Net.WebClient
    $webclient.UploadString("http://localhost:5000/location_site1","id=$id") 
}
$Jobs = Get-Content location_ids.txt | ForEach-Object {
    Start-Job -ScriptBlock $runRoutePost -ArgumentList $_
}

Wait-Job -Job $Jobs

Receive-Job -Job $Jobs | Add-Content $LOG_FILE