我有一个使用[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
}
答案 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请求,您无需指定内容类型或方法。但是,如果您需要其他脚本,则可以使用-ContentType和/或-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