Does anyone know if there is a way to push a custom user action to machines via API call? We are running into an issue and we would like to run a user action on to gather data live, unfortunately the user triggers for scripts are all login based and we can’t easily run them on demand for the environment.
What are you looking to do? There are a number of system triggers as well as the user triggers you mentioned. Typically if people want to "gather data" they would use a short or long interval trigger to run a script periodically that gathers the data and writes the data to a custom index.
https://support.controlup.com/docs/scripting-guide#data-collection
The problem is we need the script to run in user context. I can run it on demand but rather than go to each machine and kick off the script I wanted to just push it via API. Similar to how system has a once per day or short interval we were hoping to use something similar but in user context rather than system.
What about filtering on Windows, do a select-all, and then run the action on everything?
yea tried that, we have 9k machines it maxes at 5k
I tried to add a tag and then filter off != tag but it doesn’t allow you to assign the tag en masse like that
Not sure what you want to collect but could a Logon Complete trigger work for you?
that would work the problem is we needed it on demand
Well here is the API. https://apidoc.sip.controlup.com/
I don’t see anything regarding actions.
basically we had a lot of sessions in an unknown state and needed to do a point in time check
yea I’ve looked through it, the doc isn’t up to date I know there are things that don’t exist in that doc that are possible so was hoping someone had some experience with it
You could have the script run another script within the users context. Not a simple task but in theory doable. Then you could use an interval trigger and send data to an index.
you can call actions via the API. Just look at what the UI does. You’ll need a MFA authenticated user token though
Do you have an example of that I could look at?
But can they make 9000 API calls on demand? Asking because I don’t know…
Note that this is old. So take this with a grain of salt. As in, this was before a MFA authenticated user token was required:
> $body = ‘{"type":"RUN_SCRIPT","data":"0E5AP3YBJnySHs4Vl1as"}’
> $url = $tenant + "/api/devices/$deviceid/actions"
Where 0E5AP3YBJnySHs4Vl1as is the script ID
yea that was the other part, I planned on spacing it out. To be honest at this point my org kind of moved on from the idea but now I’m curious and would like to know for next time.
> $result = Invoke-RestMethod -Method Post -Uri $URL -Body $body -WebSession $session
Well if 5000 is the limit you could do this in 2 device groups.
it didn’t let me set groups / tags on that many machines at once
Where $session has a few headers
> $session.Headers["content-type"] = "application/json"
> $session.Headers["x-access-token"] = $auth.access_token
Note that x-access-token would need to be the user token. Not an API token.
Last but not least. This was before user actions. The example above is a system action
I meant the filter and running the select-all action.
@member has a script to set tags on multiple devices though
ironicly it did let me kick off the script on 5k at once so I was able to do roughly 50% of the farm but wasn’t able to hit all machines
Thats why I’m suggesting filters on device group.
I have a script to do that as well, but we also don’t want to change the group, I’d rather set via tag
Easily build your batches.
You could do tags as well. Any filter for that matter to get below that 5000 batch size.
if I tried to set tag on 5k devices it errors out
didn’t error on running the action though lol
Good thing setting tags/groups doesn’t have to be done in huge batches. Do smaller batches or use the script.
I didn’t see how small the list was I could tag at once. I think the API call for actions is what I’d do in the future. I grabbed the example Dennis put out and I will probably play with that
I appreciate the help on this though.
Looks like user actions are a bit different:
> https://tenant.sip.controlup.com/api/devices/deviceID/actions
run_all_users looks interesting 🙂
BTW, this would make a good User Voice item: Interval Triggers for User Scripts.
that should be in there already and if it isn’t I know there’s a ticket for it with development.
btw I have scripts to set device tags, device groups and also to run actions using api keys. Let me know what you need.
Hey Wouter, I’d love to see a script for tags and compare how your running actions via API. Also do you know if tags show as an environment variable on the device similar to device groups?
we don’t show the env variables as far as I know
be aware these are still pretty rough.
Device groups:
“`[cmdletbinding()]
param()
tenant name can be found from the agent downloads page: https://support.controlup.com/docs/edge-dx-agent-installation
$tenantname = "loftlab"
API key documentation: https://support.controlup.com/docs/edge-dx-api
$api_key = ‘hahahahahahaha’
$computername = "workgr"
$devicegroup = "Woodpecker"
function set-EdgeDXDeviceGroup {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = ‘The URL of the EdgeDX tenant, https:// part is optional’)]
[string]$Tenant,
[Parameter(Mandatory = $true, HelpMessage = ‘Name of the devicegroup to assign’)]
[string]$device_group,
[Parameter(Mandatory = $true, HelpMessage = ‘Computername to set devicegroup for (partial names are also accepted).’)]
[string]$Computername,
[Parameter(Mandatory = $true, HelpMessage = ‘The API Key for authentication.’)]
[string]$APIKey
)
# Create header
[hashtable]$headers = @{}
$headers.Add(‘x-api-key’, $APIKey)
$page = 1
$devices = @()
do {
$deviceuri = "https://$[tenantname.sip.controlup.com/api/devices?page=$page&size=100&sorters%5B0%5D%5Bfield%5D=name.keyword&sorters%5B0%5D%5Bdir%5D=asc&filters%5B0%5D%5Bfield%5D=name&filters%5B0%5D%5Btype%5D=like&filters%5B0%5D%5Bvalue%5D=$computername](http://tenantname.sip.controlup.com/api/devices?page=$page&size=100&sorters%5B0%5D%5Bfield%5D=name.keyword&sorters%5B0%5D%5Bdir%5D=asc&filters%5B0%5D%5Bfield%5D=name&filters%5B0%5D%5Btype%5D=like&filters%5B0%5D%5Bvalue%5D=$computername)"
$results = Invoke-RestMethod -Method GET -Uri $deviceuri -Headers $headers
$devices += $results.rows | Select-Object name, _id
$page++
}
until(($devices.count) -ge ($results.rows_available))
# Set URI
$body = @{}
$body.Add(‘group’, $device_group)
# Fails if not converted to JSON first
$jsnBody = $body | ConvertTo-Json -Depth 100
Write-Verbose -Message ($jsnBody | Out-String)
foreach ($device in $devices) {
$devicename = $device.name
$deviceid = $device._id
[string]$Uri = "https://$[tenant.sip.controlup.com/api/devices/$DeviceId](http://tenant.sip.controlup.com/api/devices/$DeviceId)"
write-verbose "Using url: $Uri"
try {
Write-Verbose -Message "Setting devicegroup on computer $devicename on tenant $Tenant"
$return = Invoke-RestMethod -Uri $Uri -Method POST -Headers $headers -Body $jsnBody -ContentType ‘application/json’
}
catch {
Throw "There was an error accessing the EdgeDX API:`n$($_.Exception.Message)"
}
# Write-Verbose -Message $return
}
}
$output = set-EdgeDXDeviceGroup -Tenant $tenantname -APIKey $api_key -computername $computername -device_group $devicegroup
write-verbose -message ($output | out-string )“`
tags:
“`[cmdletbinding()]
param()
tenant name can be found from the agent downloads page: https://support.controlup.com/docs/edge-dx-agent-installation
$tenantname = "loftlab"
API key documentation: https://support.controlup.com/docs/edge-dx-api
$api_key = ‘haha’
$computername = "workgr"
[array]$tags = "Woodpecker", "SpeedyGonzalez"
function set-EdgeDXTags {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = ‘The URL of the EdgeDX tenant, https:// part is optional’)]
[string]$Tenant,
[Parameter(Mandatory = $true, HelpMessage = ‘Array of tags to assign’)]
[array]$tags,
[Parameter(Mandatory = $true, HelpMessage = ‘Computername to set tags for (partial names are also accepted).’)]
[string]$Computername,
[Parameter(Mandatory = $true, HelpMessage = ‘The API Key for authentication.’)]
[string]$APIKey,
[Parameter(Mandatory = $true, HelpMessage = ‘Action to perform: create or delete’)]
[ValidateSet("create", "delete")]
[string]$Action
)
# Create header
[hashtable]$headers = @{}
$headers.Add(‘x-api-key’, $APIKey)
$page = 1
$devices = @()
do {
$deviceuri = "https://$[tenantname.sip.controlup.com/api/devices?page=$page&size=100&sorters%5B0%5D%5Bfield%5D=name.keyword&sorters%5B0%5D%5Bdir%5D=asc&filters%5B0%5D%5Bfield%5D=name&filters%5B0%5D%5Btype%5D=like&filters%5B0%5D%5Bvalue%5D=$computername](http://tenantname.sip.controlup.com/api/devices?page=$page&size=100&sorters%5B0%5D%5Bfield%5D=name.keyword&sorters%5B0%5D%5Bdir%5D=asc&filters%5B0%5D%5Bfield%5D=name&filters%5B0%5D%5Btype%5D=like&filters%5B0%5D%5Bvalue%5D=$computername)"
$results = Invoke-RestMethod -Method GET -Uri $deviceuri -Headers $headers
$devices += $results.rows | Select-Object name, _id
$page++
}
until(($devices.count) -ge ($results.rows_available))
[array]$ids = $devices._id
# Set URI
$body = [ordered]@{}
$body.Add(‘ids’, $ids)
$body.Add(‘tags’, $tags)
$body.Add(‘action’, $Action.ToLower())
# Fails if not converted to JSON first
$jsnBody = $body | ConvertTo-Json -Depth 100
Write-Verbose -Message ($jsnBody | Out-String)
[string]$Uri = "https://$[tenant.sip.controlup.com/api/devices/tags](http://tenant.sip.controlup.com/api/devices/tags)"
write-verbose "Using url: $Uri"
try {
Write-Verbose -Message "Setting device tags on computer $devicename on tenant $Tenant"
$result = Invoke-RestMethod -Uri $Uri -Method POST -Headers $headers -Body $jsnBody -ContentType ‘application/json’
}
catch {
Throw "There was an error accessing the EdgeDX API:`n$($_.Exception.Message)"
}
return $result
}
$output = set-EdgeDXTags -Tenant $tenantname -APIKey $api_key -computername $computername -tags $tags -Action "create"
write-verbose -message ($output | out-string )“`
I haven’t added the parts to locate the correct script or machine in the actions one yet:
“`[cmdletbinding()]
param()
tenant name can be found from the agent downloads page: https://support.controlup.com/docs/edge-dx-agent-installation
$tenantname = "loftlab"
API key documentation: https://support.controlup.com/docs/edge-dx-api
$api_key = ‘hahahahahahahaha get your own’
can be gathered using api’s but if you go to the device page and open a device it is part of the url (after /device/): https://loftlab.sip.controlup.com/device/DLF7MIMBswogvhJwQV1x
$device_id = ‘DLF7MIMBswogvhJwQV1x’
Script ID can be found in the url when editing a script (after /script/): https://loftlab.sip.controlup.com/script/ly77-YABaaJKzZYvrxOH
$script_id = ‘dL-qqYQBS_mJIDjUBJ_W’
function Start-EdgeDXScript {
<#
.SYNOPSIS
Starts an EdgeDX script on an EdgeDX device
.DESCRIPTION
Will run the specified script on the device and return the _action_id IF THE SCRIPT WRITES TO A DATA INDEX!
If a script does not write output to a data index, there is no record of the script having run in that index. Therefore it is always recommended to include some type of output to a data index in EdgeDX scripts.
.PARAMETER Tenant
The URL of the EdgeDX tenant, https:// part is optional
This parameter must be provided.
.PARAMETER ScriptId
The ID of the script to run
This parameter must be provided.
.PARAMETER DeviceId
The ID of the EdgeDX device.
This parameter must be provided.
.PARAMETER APIKey
APIKey as can be gathered from Edge DX
This parameter must be provided.
.PARAMETER SessionId
The SessionID is the SessionID of the user session to target
This parameter must be provided unless RunAsSystem or RunForAllUsers are supplied.
.PARAMETER RunForAllUsers
Run the script as system
This parameter must be provided unless RunAsSystem or SessionId are supplied.
.PARAMETER RunAsSystem
Run the script for all sessions
This parameter must be provided unless RunForAllUsers or SessionId are supplied.
.EXAMPLE
Start-EdgeDXScript -Tenant loftlab -ScriptID ‘afh23flaj’ -DeviceID ‘fs3tnnsg -SessionId 2 -apikey ‘dsfhifdidsf’
Returns: the _action_id of the started job IF THE SCRIPT WRITES TO A DATA INDEX!
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = ‘The URL of the EdgeDX tenant, https:// part is optional’)]
[string]$Tenant,
[Parameter(Mandatory = $true, HelpMessage = ‘The ID of the script to run’)]
[string]$ScriptId,
[Parameter(Mandatory = $true, HelpMessage = ‘The ID of the EdgeDX device.’)]
[string]$DeviceId,
[Parameter(Mandatory = $true, HelpMessage = ‘The API Key for authentication.’)]
[string]$APIKey,
[Parameter(Mandatory = $true, ParameterSetName = ‘SingleSession’, HelpMessage = ‘The Session Id for the user to run the script for.’)]
[int]$SessionId,
[Parameter(Mandatory = $true, ParameterSetName = ‘RunAsSystem’, HelpMessage = ‘Run script as system.’)]
[switch]$RunAsSystem,
[Parameter(Mandatory = $true, ParameterSetName = ‘RunForAllUsers’, HelpMessage = ‘Run script for all users.’)]
[switch]$RunForAllUsers
)
# Set URI
[string]$Uri = "https://$[tenant.sip.controlup.com/api/devices/$DeviceId/actions](http://tenant.sip.controlup.com/api/devices/$DeviceId/actions)"
write-verbose "Using url: $Uri"
# Create header
[hashtable]$headers = @{}
$headers.Add(‘x-api-key’, $APIKey)
# Create the body
$data = [ordered]@{}
$data.add(‘script_id’, $ScriptId)
if ($SessionId) {
$data.add(‘run_as_user’, $true)
$data.add(‘session_id’, $SessionId)
}
else {
$data.add(‘run_as_user’, $false)
$data.add(‘session_id’, ”)
}
if ($RunForAllUsers) {
$data.add(‘run_all_users’, $true)
}
else {
$data.add(‘run_all_users’, $false)
}
if ($RunAsSystem) {
$data.add(‘run_as_system’, $true)
}
else {
$data.add(‘run_as_system’, $false)
}
$body = [ordered]@{}
$body.add(‘type’, ‘RUN_SCRIPT_V2’)
$body.add(‘data’, ($data | convertto-json))
# Fails if not converted to JSON first
$jsnBody = $body | ConvertTo-Json -Depth 100
Write-Verbose -Message ($jsnBody | Out-String)
try {
Write-Verbose -Message "Running script on $Tenant"
$return = Invoke-RestMethod -Uri $Uri -Method POST -Headers $headers -Body $jsnBody -ContentType ‘application/json’
}
catch {
Throw "There was an error accessing the EdgeDX API:`n$($_.Exception.Message)"
}
# Return the _id of the invoked action
Write-Verbose -Message $return
Return $return._id
}
Start-EdgeDXScript -Tenant $tenantname -APIKey $api_key -ScriptId $script_id -DeviceId $device_id -RunForAllUsers“`
Continue reading and comment on the thread ‘How to push a ControlUp custom user action to machines via API call? ‘. Not a member? Join Here!
Categories: All Archives, ControlUp for Desktops, ControlUp Scripts & Triggers