【问题标题】:ConvertFrom-JSON to variables for POST further on to PowerBIConvertFrom-JSON 为 POST 的变量,进一步到 PowerBI
【发布时间】:2020-03-02 23:24:43
【问题描述】:

我正在从格式如下的 URL 获取 API 数据:

{
  "printers" : [ {
    "name" : "printsrv01\\printer01",
    "status" : "OK",
    "lastPrintJobSeconds" : 6495,
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.51"
  }, {
    "name" : "printsrv01\\printer02",
    "status" : "OK",
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.52"
  }, {
    "name" : "printsrv02\\printer03",
    "status" : "OK",
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.53"
  }, {
    "name" : "printsrv01\\printer04",
    "status" : "OK",
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.54"
  }, {
    "name" : "printsrv02\\printer05",
    "status" : "OK",
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.55"
  }, {
    "name" : "printsrv01\\printer06",
    "status" : "OK",
    "lastPrintJobSeconds" : 183162,
    "heldJobsCount" : 0,
    "physicalPrinterId" : "net://192.168.0.56"
  } ],
  "heldJobCountTotal" : 0,
  "heldJobsCountMax" : 0
}

我已设法使用以下代码从 JSON 转换数据:

while ($true) {
    $request = "http://serveradress:80/api/health/printers?Authorization=GHSKAskas0a5as5FFDA22asD"
    Invoke-WebRequest  $request |
        ConvertFrom-Json |
        select -Expand printers |
}

我正在使用 PowerBI 来上传数据。 如果我的值存储在变量中,这可以使用以下代码完成。

$payload = @{
    "name" = $name
    "status" = $status
    "lastPrintJobSeconds" = $lastPrintJobSeconds
    "heldJobsCount" = $heldJobsCount
    "physicalPrinterId" = $physicalPrinterId
}
Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))

如何将每个打印机信息放入每个变量中以将其发送到用于显示的 PowerBI 数据源?


编辑:

我尝试使用@TheldesOfMark建议的解决方案:

$endpoint = "https://api.powerbi.com/beta/aaa555v22-66888-ccc6-95aa-0dfb5dc31330/datasets/aaa555a666-6547-4250-950c-25s5sd5s5s5s5/rows?key=65asd55asd45asd45asd5as5d4!%54dsa5f45fc4zd56fc4"

while ($true) {
    $request = "http://server:80/api/health/printers?Authorization=asd54asas5dSSd55sd4as65d4ASDA"
    Invoke-WebRequest  $request |
        ConvertFrom-Json |
        select -Expand printers |

    foreach ($printer in $printers) {
        $payload = @{
            "name" = $printer.name
            "status" = $printer.status
            "lastPrintJobSeconds" = $printer.lastPrintJobSeconds
            "heldJobsCount" = $printer.heldJobsCount
            "physicalPrinterId" = $printer.physicalPrinterId
        }
        Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))
        Write-Host "Name: " $printer.name " Status: " $printer.status " lastPrintJobSeconds: " $printer.lastPrintJobSeconds " heldJobsCount: " $printer.heldJobsCount " physicalPrinterId: " $printer.physicalPrinterId
    }
    sleep 2
}
}

但它会产生以下错误:

在行:10 字符:22 + foreach($printers 中的 $printer){ + ~~ 表达式或语句中出现意外的标记“in”。 在行:10 字符:21 + foreach($printers 中的 $printer){ + ~ 表达式中缺少结束 ')'。 在行:4 字符:1 + { + ~ 语句块或类型定义中缺少结束“}”。 在行:10 字符:34 + foreach($printers 中的 $printer){ + ~ 表达式或语句中出现意外的标记 ')'。 在行:22 字符:5 + } + ~ 表达式或语句中出现意外的标记“}”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken

似乎foreach 循环是问题所在? 如果我不从 JSON 转换,它不会给出任何错误,但如果我尝试不先转换,我不会得到任何数据。

编辑 2

将 Invoke-WebRequest 更改为下面,并且 Write Output 可以正确打印数据。 但我在 Invoke-RestMethod 上遇到错误:

$printers = Invoke-WebRequest 'http://server:80/api/health/printers?Authorization=asd54asas5dSSd55sd4as65d4ASDA' | ConvertFrom-Json | select -Expand printers

错误码如下:

Invoke-RestMethod : {"error":{"message":"The request was blocked by KeyBlocker "}}
At line:14 char:9
+         Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @( ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

编辑 3

$endpoint = "PowerBI_URL"
Invoke-WebRequest 'API_URL' |
    ConvertFrom-Json |
    Select-Object -Expand printers |
    ForEach-Object {
        Invoke-RestMethod -Method Post -Uri "$endpoint" (ConvertTo-Json @($_))
    }

错误代码:

Invoke-RestMethod : A positional parameter cannot be found that accepts argument '[
    {
        "name":  "printsrv01\\printer01",
        "status":  "OK",
        "heldJobsCount":  0,
        "physicalPrinterId":  "net://192.168.0.51"
    }
]'.
At line:6 char:9
+         Invoke-RestMethod -Method Post -Uri "$endpoint" (ConvertTo-Json @($_))
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

似乎并非所有值都已打印。缺少一些。

编辑 4 - 工作脚本

$endpoint = "https://api.powerbi.com/beta/nnf5d2dsf1-4588-88gh-b6a4-0dfb5dc31330/datasets/55562ee92-9c7d-8850-854g-1a39asdd8a4b/rows?key=ljrethjkreRDFG545REWFGGDF0DFGDGF"

while ($true) {
    $printers = Invoke-WebRequest 'http://server/api/health/printers?Authorization=sdfkjdsf044s21sDSFsdf54sdf' | ConvertFrom-Json | select -Expand printers

    foreach ($printer in $printers) {
        $payload = @{
            "name" = $printer.name
            "status" = $printer.status
            "lastPrintJobSeconds" = $printer.lastPrintJobSeconds
            "heldJobsCount" = $printer.heldJobsCount
            "physicalPrinterId" = $printer.physicalPrinterId
        }
        Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))
        #Write-Host "Name: " $printer.name " Status: " $printer.status " lastPrintJobSeconds: " $printer.lastPrintJobSeconds " heldJobsCount: " $printer.heldJobsCount " physicalPrinterId: " $printer.physicalPrinterId
        sleep 1
    }

}

【问题讨论】:

  • 如果您在尝试应用答案中建议的内容时遇到错误,并希望在当前问题的上下文中得到澄清,请避免以会使其他答案无效的方式编辑问题到原来的问题。在这种情况下,附加修改后的代码和错误有效。在其他情况下,可能需要发布后续问题。
  • 至于你得到的新错误:foreach 循环与ForEach-Object 不同,并且不从管道中读取。要使代码正常工作,您需要从管道中删除尾随 | 并将管道输出收集到变量 $printers 中。
  • 我明白了。我想我需要编辑现有的代码,这样我的问题就不会太长了。明天我会检查管道,谢谢
  • 某些 Keyblocker 出现新错误。添加上面的错误代码。
  • 这似乎是服务器响应。您确定 API(包括身份验证)按您期望的方式工作吗?

标签: powershell api powerbi-datasource


【解决方案1】:

AFAICS,您不需要将单个值提取到不同的变量中。只需将ForEach-Object 添加到您将当前对象转换为 JSON 并使用它调用 POST 请求的管道中。

Invoke-WebRequest $request |
    ConvertFrom-Json |
    Select-Object -Expand printers |
    ForEach-Object {
        $data = ConvertTo-Json $_
        Invoke-RestMethod -Method Post -Uri $endpoint -Body $data
    }

【讨论】:

    【解决方案2】:

    在我看来,Ansgar 的答案是最好的答案。但是,如果出于某种原因,您需要将此信息提供给其他 PS 进程。您可以通过循环遍历您构建的数组并分配变量来从当前脚本中转换变量。

    ForEach($printer in $printers){
        $payload = @{
            "name" = $printer.name
            "status" = $printer.status
            "lastPrintJobSeconds" = $printer.lastPrintJobSeconds
            "heldJobsCount" = $printer.heldJobsCount
            "physicalPrinterId" = $printer.physicalPrinterId
        }
        Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))
    }
    

    【讨论】:

    • 我同意 Ansgards 的代码更简洁。但是我想在你写的时候把每个值放在单独的变量中。当我尝试您的代码时,我在 for each 循环中遇到了一些错误。我更新了上面的代码
    • 由您的脚本管理。在数据库中遇到一个问题,当它包含字符时,我试图将数据存储为数字。修复了这个问题,现在我的 Edit 4 是工作代码。谢谢!
    猜你喜欢
    • 2017-07-21
    • 1970-01-01
    • 2012-05-18
    • 2018-03-18
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-24
    相关资源
    最近更新 更多