I am fetching API data from a URL which is formatted as below:
{
"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
}
I have managed to convert the data from JSON using following code:
while ($true) {
$request = "http://serveradress:80/api/health/printers?Authorization=GHSKAskas0a5as5FFDA22asD"
Invoke-WebRequest $request |
ConvertFrom-Json |
select -Expand printers |
}
I am using PowerBI where I would like to upload the data. This can be done using the below code if my values are stored in variables.
$payload = @{
"name" = $name
"status" = $status
"lastPrintJobSeconds" = $lastPrintJobSeconds
"heldJobsCount" = $heldJobsCount
"physicalPrinterId" = $physicalPrinterId
}
Invoke-RestMethod -Method Post -Uri "$endpoint" -Body (ConvertTo-Json @($payload))
How can I put each printer information in each variable to send it to the PowerBI datasource used for display?
Edit:
I tried to use the solution suggested by @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
}
}
but it generates the following errors:
At line:10 char:22 + foreach ($printer in $printers) { + ~~ Unexpected token 'in' in expression or statement. At line:10 char:21 + foreach ($printer in $printers) { + ~ Missing closing ')' in expression. At line:4 char:1 + { + ~ Missing closing '}' in statement block or type definition. At line:10 char:34 + foreach ($printer in $printers) { + ~ Unexpected token ')' in expression or statement. At line:22 char:5 + } + ~ Unexpected token '}' in expression or statement. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken
It seems like the foreach
loop is the issue?
If I don't convert from JSON it doesn´t give any errors but I doesn't get any data out if I try without converting first.
Edit 2
Changed the Invoke-WebRequest to below and Write Output works it print the data correct. But I get error on the Invoke-RestMethod:
$printers = Invoke-WebRequest 'http://server:80/api/health/printers?Authorization=asd54asas5dSSd55sd4as65d4ASDA' | ConvertFrom-Json | select -Expand printers
The errorcode is as followed:
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
Edit 3
$endpoint = "PowerBI_URL"
Invoke-WebRequest 'API_URL' |
ConvertFrom-Json |
Select-Object -Expand printers |
ForEach-Object {
Invoke-RestMethod -Method Post -Uri "$endpoint" (ConvertTo-Json @($_))
}
Error code:
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
Not all values seems to be printed. Missing some.
Edit 4 - Working script
$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
}
}
Ansgar's answer is the best answer, in my opinion. But in case there's some reason you need to have this information available to other PS processes. You can cast the variables from your current script by just looping through the array you built and assigning the variables.
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))
}