Forum Discussion

bsimon504's avatar
bsimon504
Active Contributor
3 years ago

API to update LastLoginUsername in Custom Field

I’m having a hard time passing through the RawContent being returned in the System Inventory report. Does someone already have a method to update this field to make machines searchable by the last logged in user?
  • In an effort to help someone out with this who may be struggling as well, below is what I finally got to work. If you combine all of these script blocks together and ensure that you change out specific values to match your environment (e.g., $un, $pw, $customfield), this should work for you as well.

     

    Authentication:

     

    $un = 'your api id'
    $pw = 'your api key'
    
    $token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $un,$pw)))
    
    $header = @{
    'Authorization' = 'Basic ' + $token
    }
    
    $uri = "https://secure.logmein.com/public-api/v1/authentication"
    
    $auth = Invoke-WebRequest -method get -h $header -uri $uri
    
    $newheader = @{
        'Authorization' = 'Basic ' + $token
        'Content-Type' = 'application/json'
    }

     

    Get all your computers into a variable:

     

    $hosts_uri = "https://secure.logmein.com/public-api/v2/hosts"
    
    $hosts = invoke-webrequest -method get -h $newheader -uri $hosts_uri
    
    $hosts_out = (convertfrom-json $hosts.content).hosts
    
    $host_ids = $hosts_out.id

    Generate your "system inventory token" thing:

     

    $systoken_uri = "https://secure.logmein.com/public-api/v1/inventory/system/reports"
    
    $newbody = @{	
        "hostIds" = @($host_ids)
        'fields' = @('lastLogonUserName')
        }
    
    $systoken = invoke-webrequest -method post -h $newheader -uri $systoken_uri -body (convertto-json $newbody)
    
    $systoken_out = (convertfrom-json $systoken.content).token

    Then run your system inventory report. This only returns a subset of the results and I couldn't find a way to get it to stop, so I just set a timer (the .3 of a minute). You could increase this or let me know when you find a way to identify the script ending.

     

    Along with adding some "replace" parameters to get rid of extra symbols in the data, I also had to add a "unique" sort filter at the end to clean up the duplicates entries that this method generates into the variable:

     

    $sysinv_uri = "https://secure.logmein.com/public-api/v1/inventory/system/reports/$systoken_out"
    
    $sysinv_out = @()
    
    $timestart = Get-Date
    $timeend = $timestart.addminutes(.3)
    
    do {
        $sysinv_out_host = @()
        $sysinv_out_user = @() 
    
        $sysinv = invoke-webrequest -method get -h $newheader -uri $sysinv_uri
    
        $sysinv_out_host = ($sysinv.rawcontent -split "`n" -match "hostid" -replace '"hostID": ','' -replace ',','').trim()
        $sysinv_out_user = ($sysinv.rawcontent -split "`n" -match "lastLogonUserName" -replace '"lastLogonUserName": ','' -replace ',','' -replace """","" -replace "\\\\","\").trim()
    
        [int]$max = $sysinv_out_host.count
        if ([int]$sysinv_out_user.count -gt [int]$sysinv_out_host.count) { $max = $sysinv_out_user.count; }
    
        $sysinv_out += for ($i = 0; $i -lt $max; $i++)
        {
            write-verbose "$($sysinv_out_host[$i]),$($sysinv_out_user[$i])"
            [PSCustomObject]@{
                hostid = $sysinv_out_host[$i]
                lastuser = $sysinv_out_user[$i]
            }
        }
    
        $timenow = get-date
    
    } until ($timenow -ge $timeend)
    
    $sysinv_out = $sysinv_out | Sort-Object * -Unique

    Finally, take that data you painstakingly combined into a variable and apply it to each of your machines, specifying the custom field ID that you want to write to:

     

    $customfield = 'your custom field id'
    
    foreach ($i in $sysinv_out) {
    
        $cf_update_uri = "https://secure.logmein.com/public-api/v1/hosts/$($i.hostid)/custom-fields/value-by-category/$customfield"
    
        $newbody = @{
            'value' = $i.lastuser
        }
    
        invoke-webrequest -method post -h $newheader -uri $cf_update_uri -body (convertto-json $newbody)
    
    }

    Make sure you go to your Computers tab after this finishes and turn on your custom field in your view. The search bar now not only searches computer names, but the last logged in user (since you last ran the script).

     

     

     

  • bsimon504's avatar
    bsimon504
    Active Contributor

    In an effort to help someone out with this who may be struggling as well, below is what I finally got to work. If you combine all of these script blocks together and ensure that you change out specific values to match your environment (e.g., $un, $pw, $customfield), this should work for you as well.

     

    Authentication:

     

    $un = 'your api id'
    $pw = 'your api key'
    
    $token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $un,$pw)))
    
    $header = @{
    'Authorization' = 'Basic ' + $token
    }
    
    $uri = "https://secure.logmein.com/public-api/v1/authentication"
    
    $auth = Invoke-WebRequest -method get -h $header -uri $uri
    
    $newheader = @{
        'Authorization' = 'Basic ' + $token
        'Content-Type' = 'application/json'
    }

     

    Get all your computers into a variable:

     

    $hosts_uri = "https://secure.logmein.com/public-api/v2/hosts"
    
    $hosts = invoke-webrequest -method get -h $newheader -uri $hosts_uri
    
    $hosts_out = (convertfrom-json $hosts.content).hosts
    
    $host_ids = $hosts_out.id

    Generate your "system inventory token" thing:

     

    $systoken_uri = "https://secure.logmein.com/public-api/v1/inventory/system/reports"
    
    $newbody = @{	
        "hostIds" = @($host_ids)
        'fields' = @('lastLogonUserName')
        }
    
    $systoken = invoke-webrequest -method post -h $newheader -uri $systoken_uri -body (convertto-json $newbody)
    
    $systoken_out = (convertfrom-json $systoken.content).token

    Then run your system inventory report. This only returns a subset of the results and I couldn't find a way to get it to stop, so I just set a timer (the .3 of a minute). You could increase this or let me know when you find a way to identify the script ending.

     

    Along with adding some "replace" parameters to get rid of extra symbols in the data, I also had to add a "unique" sort filter at the end to clean up the duplicates entries that this method generates into the variable:

     

    $sysinv_uri = "https://secure.logmein.com/public-api/v1/inventory/system/reports/$systoken_out"
    
    $sysinv_out = @()
    
    $timestart = Get-Date
    $timeend = $timestart.addminutes(.3)
    
    do {
        $sysinv_out_host = @()
        $sysinv_out_user = @() 
    
        $sysinv = invoke-webrequest -method get -h $newheader -uri $sysinv_uri
    
        $sysinv_out_host = ($sysinv.rawcontent -split "`n" -match "hostid" -replace '"hostID": ','' -replace ',','').trim()
        $sysinv_out_user = ($sysinv.rawcontent -split "`n" -match "lastLogonUserName" -replace '"lastLogonUserName": ','' -replace ',','' -replace """","" -replace "\\\\","\").trim()
    
        [int]$max = $sysinv_out_host.count
        if ([int]$sysinv_out_user.count -gt [int]$sysinv_out_host.count) { $max = $sysinv_out_user.count; }
    
        $sysinv_out += for ($i = 0; $i -lt $max; $i++)
        {
            write-verbose "$($sysinv_out_host[$i]),$($sysinv_out_user[$i])"
            [PSCustomObject]@{
                hostid = $sysinv_out_host[$i]
                lastuser = $sysinv_out_user[$i]
            }
        }
    
        $timenow = get-date
    
    } until ($timenow -ge $timeend)
    
    $sysinv_out = $sysinv_out | Sort-Object * -Unique

    Finally, take that data you painstakingly combined into a variable and apply it to each of your machines, specifying the custom field ID that you want to write to:

     

    $customfield = 'your custom field id'
    
    foreach ($i in $sysinv_out) {
    
        $cf_update_uri = "https://secure.logmein.com/public-api/v1/hosts/$($i.hostid)/custom-fields/value-by-category/$customfield"
    
        $newbody = @{
            'value' = $i.lastuser
        }
    
        invoke-webrequest -method post -h $newheader -uri $cf_update_uri -body (convertto-json $newbody)
    
    }

    Make sure you go to your Computers tab after this finishes and turn on your custom field in your view. The search bar now not only searches computer names, but the last logged in user (since you last ran the script).

     

     

     

    • ronin_cse's avatar
      ronin_cse
      New Member

      I don't know why you don't have more replies praising your work here but HOLY CRAP! This is absolutely amazing and GoTo should hire you or something ASAP! Why this isn't built in functionality I have no idea.

       

      I do have a couple comments: First just make sure you use the custom group ID and not the name. I kind of missed that part in your walkthrough and spent way too long figuring out why I was getting an error.

       

      Second I did alter one part a little. It looks like you can only return 50 devices max with a custom inventory token. I guess they supply a continuation token in that case but I haven't been able to figure out how to get it. I added in this part:

      $hosts_out = $hosts_out | Sort-Object -Property ishostonline, hostStateChangeDate -Descending

       

      Basically just to have the most recent online computers at the top. Not perfect and doesn't get all the devices but it's the best I could figure out at this point. I'm thinking getting the continuation token working might require more coding than I want to do at the moment, but you never know.

       

      Anyways thank you again, you massively helped out at least one other admin 😉