Kaseya Community

Script to Reconcile Kaseya Agents with Active Directory Objects?

This question is answered

Greetings Kaseya-istas! 

I'd like to find or create a script that will reconcile agents on our VSA server with their objects in AD.   Although we can remove agents that haven't checked in in X number of days, that's not practical for my use case. 

I have a working script for the AD side that finds and removes orphaned objects from hosts that we've removed from use.  So it would be nice if I could take my CSV file that lists the deleted hosts, and feed each line to a deletion script.  It's not practical for me to do this through the web console as there will be thousands of changes. 

Would this be best done through SQL, through the REST API or another way? 

-Thanks

Verified Answer
  • The following works with the flag -computername <hostname>

    What I'd really like is for the script to be able to use an encrypted credentials file. The traditional methods of doing this aren't working.

    -------------------------------

    param(

       [Parameter(Mandatory=$True)][string]$computername

     )

    function hash($algorithm, $text) {

    $data = [system.Text.Encoding]::UTF8.GetBytes($text)

    [string]$hash = -join ([Security.Cryptography.HashAlgorithm]::Create($algorithm).ComputeHash($data) | ForEach { "{0:x2}" -f $_ })

    return $hash

    }

    $vsa = 'kaseya.mysite.com/.../auth&

    $user = ''

    $password = ''

    $rand = Get-Random

    $SHA1Hash   = hash "SHA1"   "$password$user"

    $SHA256Hash = hash "SHA256" "$password$user"

    $SHA1Hash   = hash "SHA1"   "$SHA1Hash$rand"

    $SHA256Hash = hash "SHA256" "$SHA256Hash$rand"

    $auth = "user=$user,pass2=$SHA256Hash,pass1=$SHA1Hash,rand2=$rand,rpass2=$SHA256Hash,rpass1=$SHA1Hash,twofapass=:undefined"

    $encodedauth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($auth))

    $request = Invoke-RestMethod -Method Get -Uri $vsa -Headers @{'Authorization' = "Basic $encodedauth"}

    $token = $request.result.token

    $uri = "kaseya.mysite.com/.../agents`$filter=substringof('$computername', AgentName)"

    $result = Invoke-RestMethod -uri $uri -Headers @{'Authorization'="Bearer $token"} -Method Get -ContentType text/json | ConvertTo-Json | Out-File .\temp.json

    $json = (Get-Content "temp.json" -Raw) | ConvertFrom-Json

    $guid = $json.result.agentid

    $uri = "kaseya.mysite.com/.../agents$guid/false"

    $result = Invoke-RestMethod -uri $uri -Headers @{'Authorization'="Bearer $token"} -Method Delete -ContentType text/json

    del .\temp.json

All Replies
  • If I understand your need correctly, I'd go with the API method.

    I have an offboard/migration tool that use the API for this - it runs on the agent, uninstalls the agent, removes the standard local account, cleans up our local data/files, and then reaches back to VSA via the API to delete the agent. For migrations, it downloads the new agent from the target VSA and installs it, defining the partition and machine group. The API works great for this, and there's no need to figure out the convoluted table connections in SQL. We migrated a test batch of about 70 agents from our old VSA to the new "on-prem SAAS" VSA yesterday afternoon with no issues.

    Depending on what data you have will determine the method you follow - if you have agent names, you'll need to search for the agent by name and verify you have the one associated with the customer org. be sure you have the full machine group or the agent name and org-ID. The search will return results of all identically-named agents, and you'll need to enumerate the results to compare the org-ID or group name.  Then take the Agent GUID value and pass it to the Delete Agent call and verify the result. If you have the GUIDs, you can make the call directly in one step.

    We provide several "offline admin" tools to our customers that move data between VSA and Excel spreadsheets - creating new org/groups and managing server patch schedules, plus one that ciphers/deciphers credentials stored in Managed Variables used to create or update local accounts. The APIs are great for what you're trying to do.

    If coding to this level isn't your thing, reach out. We could turn this around for less than 2 hours of professional services time.

    Glenn

  • The following works with the flag -computername <hostname>

    What I'd really like is for the script to be able to use an encrypted credentials file. The traditional methods of doing this aren't working.

    -------------------------------

    param(

       [Parameter(Mandatory=$True)][string]$computername

     )

    function hash($algorithm, $text) {

    $data = [system.Text.Encoding]::UTF8.GetBytes($text)

    [string]$hash = -join ([Security.Cryptography.HashAlgorithm]::Create($algorithm).ComputeHash($data) | ForEach { "{0:x2}" -f $_ })

    return $hash

    }

    $vsa = 'kaseya.mysite.com/.../auth&

    $user = ''

    $password = ''

    $rand = Get-Random

    $SHA1Hash   = hash "SHA1"   "$password$user"

    $SHA256Hash = hash "SHA256" "$password$user"

    $SHA1Hash   = hash "SHA1"   "$SHA1Hash$rand"

    $SHA256Hash = hash "SHA256" "$SHA256Hash$rand"

    $auth = "user=$user,pass2=$SHA256Hash,pass1=$SHA1Hash,rand2=$rand,rpass2=$SHA256Hash,rpass1=$SHA1Hash,twofapass=:undefined"

    $encodedauth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($auth))

    $request = Invoke-RestMethod -Method Get -Uri $vsa -Headers @{'Authorization' = "Basic $encodedauth"}

    $token = $request.result.token

    $uri = "kaseya.mysite.com/.../agents`$filter=substringof('$computername', AgentName)"

    $result = Invoke-RestMethod -uri $uri -Headers @{'Authorization'="Bearer $token"} -Method Get -ContentType text/json | ConvertTo-Json | Out-File .\temp.json

    $json = (Get-Content "temp.json" -Raw) | ConvertFrom-Json

    $guid = $json.result.agentid

    $uri = "kaseya.mysite.com/.../agents$guid/false"

    $result = Invoke-RestMethod -uri $uri -Headers @{'Authorization'="Bearer $token"} -Method Delete -ContentType text/json

    del .\temp.json