401 error in my API endpoint, if I don't set a new app token and connect-UAServer

Hi,

I was trying to make a API to upload a CSV file, run a script and print back the job output. So far, so good… But all the time I was getting a 401 unauthorized, when I wanted to invoke the script and also I need 2x use the Connect-UAServer to get is working.

My request is this:

My endpoint code, is a mess because I don’t get it why I need to set the apptoken and reconnect:

My output is what I wanted, but now it’s text and can be better JSON? Maybe someone haves a idea:

So how can I get the same results, without setting the token and the connect to server and use the authentication, that is used by the execution of “Invoke-RestMethod”?

Kind regards,
Arjen Kocken / ARKO

Product: PowerShell Universal
Version: 2.5.5

If you’re on 2.5.5, you can actually simplify this and remove the use of app tokens. We added an -Integrated switch to some cmdlets to make executing jobs easier from APIs and dashboards.

No need to call connect or setup app tokens.

Invoke-UAScript -ID $script.ID -FileName "$SessionId.csv" -Integrated | Tee-Object -Variable | Wait-PSUJob -Integrated

$Pipeline = Get-PSUJobPipelineOutput -Job $Job -Integrated
$HostOutput = Get-PSUJobOutput  -Job $Job -Integrated

$HostOutput.Data
2 Likes

Thanks, that’s what we called “simplifyd” :heart_eyes:

But, if this changes where not applied, did I do this the right way or did I need to do something else?

I will try this tomorow :ok_hand:

Sorry. I missed part of your question.

If you return the pipeline output and not the host output, you can return it as JSON which will then be translated to PSCustomObjects by PS if you use Invoke-RestMethod.

Invoke-UAScript -ID $script.ID -FileName "$SessionId.csv" -Integrated | Tee-Object -Variable | Wait-PSUJob -Integrated

$Pipeline = Get-PSUJobPipelineOutput -Job $Job -Integrated
$HostOutput = Get-PSUJobOutput  -Job $Job -Integrated

$Pipeline | ConvertTo-Json

It won’t necessarily look exactly the same in the command line since it won’t include type data and the custom formatting may not kick in but give it a shot and see how it goes.

Hi Adam,

I think that because you are using “$script.ID”, I need to keep this line in the script:

$Script = Get-UAScript -Name "QWHMCS-Import-Trackingtime_dev.ps1"

All of your changes are working, but I get a error: Invoke-RestMethod: Call failed with status code 401 (Unauthorized): GET http://172.25.0.254:5000/api/v1/Script/QWHMCS-Import-Trackingtime_dev.ps1

I did try with a executer and admin account / token. Any idea?

Kind regards,
Arjen

Try adding -Integrated to that as well.

$Script = Get-UAScript -Name "QWHMCS-Import-Trackingtime_dev.ps1" -Integrated

Hi I did try that already and that gives me a error: Invoke-RestMethod: Failed to query.NotFound

Hmmm. I just put together an integration test to validate this and it’s working. This is how I have it configured.

Integrated.ps1

$Script = Get-PSUScript -Name 'Trigger.ps1' -Integrated
Invoke-PSUScript -Script $Script -Wait -Integrated

Trigger.ps1

"Triggered"

.universal\scripts.ps1

New-PSUScript -Name 'Integrated.ps1' -Path 'Integrated.ps1'
New-PSUScript -Name 'Trigger.ps1' -Path 'Trigger.ps1'

image

I also tried this and it worked for me.

Integrated.ps1

Invoke-PSUScript -Script 'Trigger.ps1' -Wait -Integrated

Do you notice anything different in my setup from yours?

Based on your example, I see you don’t use a folder for the script so I tested it again:

Scripts.ps1

New-PSUScript -Name "repository_root.ps1" -Path "repository_root.ps1" -InformationAction "Continue" 
New-PSUScript -Name "repository_root_scripts.ps1" -Path "scripts\repository_root_scripts.ps1" -InformationAction "Continue"
  1. Api tested with: Get-Script -Name “repository_root.ps1”
[System.IO.File]::WriteAllBytes("$QTemp\$SessionId.csv", $Data)
$Script = Get-PSUScript -Name 'repository_root.ps1' -Integrated
Invoke-PSUScript -Script $Script -FileName "$SessionId.csv" -Wait -Integrated
Remove-Item -Path $QTemp\$SessionId.csv -force

This was working

  1. Api tested with: Get-Script -Name “repository_root_scripts.ps1”
[System.IO.File]::WriteAllBytes("$QTemp\$SessionId.csv", $Data)
$Script = Get-PSUScript -Name 'repository_root_scripts.ps1' -Integrated
Invoke-PSUScript -Script $Script -FileName "$SessionId.csv" -Wait -Integrated
Remove-Item -Path $QTemp\$SessionId.csv -force

Thiis gives: Failed to query.NotFound

  1. Api tested with: Get-Script -Name “scripts\repository_root_scripts.ps1”
[System.IO.File]::WriteAllBytes("$QTemp\$SessionId.csv", $Data)
$Script = Get-PSUScript -Name 'scripts\repository_root_scripts.ps1' -Integrated
Invoke-PSUScript -Script $Script -FileName "$SessionId.csv" -Wait -Integrated
Remove-Item -Path $QTemp\$SessionId.csv -force

This was working based on the subfolder, but I did enter the “-path” variable instead of the “-name” variable

So my conclusion is that when you use “get-uascript -name”

  1. The “-name” paramater is working, based on the name in “scripts.ps1”, for subfolder items when using “$apptoken =” and “Connect-UAServer” inside the API request
  2. If you use the new simplified version, with the “-integrated” it can’t resolve based on the “-name” variable from “scripts.ps1”, if you replace it with using the “-path” variable instead by using “Get-PSU -Name” it can resolve the script.
  3. Another thing I saw in your new example, is that you replaced “Invoke-UAScript” with, “Invoke-PSUScript”
    3.1. I did test it also with “Get-UAScript” & “Invoke-UASCript”, what is giving the same results as “Get-PSUScript” & “Invoke-PSUSCript”
    3.2. So this means they are doing exactly the same?

I will get a cup of coffee, and will try to combine it with you’r first sugestions for recieving the Job output.

Thanks for all the info. It helped me to reproduce this issue. I’ve got a fix for it, and it will be in 2.6.

1 Like

No problem! I found another problem also, when I try to combine all together with your solutions before:

  1. 401 error in my API endpoint, if I don't set a new app token and connect-UAServer - #2 by adam
  2. 401 error in my API endpoint, if I don't set a new app token and connect-UAServer - #4 by adam

I have this as the base code

# Get a file upload from the API
[System.IO.File]::WriteAllBytes("$QTemp\$SessionId.csv", $Data)

# Set the script variable to load
$Script = Get-PSUScript -Name 'repository_root.ps1' -Integrated

# Invoke the script and return the job output
Invoke-PSUScript -Script $Script -FileName "$SessionId.csv" -Integrated | Tee-Object -Variable Job | Wait-PSUJob -Integrated

# Cleanup tempory session CSV file
Remove-Item -Path $QTemp\$SessionId.csv -force

# Read the job pipeline output from the Tee-Object variable
$Pipeline = Get-PSUJobPipelineOutput -Job $Job -Integrated
$HostOutput = Get-PSUJobOutput  -Job $Job -Integrated

1.1. When I add your 1st solution add the end;

# Returning the exact Job ouput
$HostOutput.Data

I get exactly what I was asking for, a print of the complete job outpu

1.2. When I change it to your second solution

# Return the pipeline output as Json
$Pipeline | ConvertTo-Json

I get this colorized Output:

  • Whats looking clear
  • But only when I add a pipe " | ConvertTo-Json" add the end of my “Invoke-Restmethod” I get a JSON output
  1. Now I get interested what’s inside the $Hostoutput, so when set
$Hostoutput

I get a intresting output
image

What set me on thinking, if my “write-host” for logging is the best way or is there another way log the script / job steps what can be retrieved as a correct Json output also?

To make it a little more clear what I want to know if it’s possible both output in Json

  1. The “$Pipeline” in Json, what’s the information I also needed
  2. And separated the script logging / steps output in Json?
  • Because the above image looks like some logging to, I checked all cmdlets from the docs, can’t find a command for logging, maybe there is?
  1. And af the end get 2 json outputs
    3.1. The data that’s imported
    3…2. A log, what maybe can get requested with a parameter
    3.3. What can make it very useful when I start creating a dashboard I have in mind, to see the data and a log and set them side by side, almost like PSU does :rofl:

It’s just a idea what’s coming up, you don’t need to write the complete code for me but maybe you can bring me a little in the right direction. And I want to build as most as possible based on API command and Json output, because I will create some WHMCS modules that need to talk to the API. >> What must make it possible to in the end integrate all kind off services in WHMCS, if it’s talking API / Powershell, then you can intergrade it inside a module from like everything.