Example of self-help scenario

Overview

Albeit the storage capacity of hard drives is very large nowadays, it is still finite. With the daily use of a device, the hard drive tends to fill up not only with useful documents and programs, but also with many temporary files, downloads, images, etc. that consume ever more disk space. All this junk files leave less and less free space for new documents, applications, or even updates. When the amount of free disk space in a device goes below a certain threshold, the device becomes unusable because nothing else can be stored in it.

In this example, learn how to leverage both Nexthink Act and Nexthink Engage to warn end users of a low free disk space condition on their devices before it is too late and guide them through the process of liberating disk space by removing junk.

Creating the Campaigns

To warn end users of a particular issue and guide them through its resolution, self-help scenarios require the use of campaigns, which are available through the Nexthink Engage product. Remote actions are able to control the launch of campaigns and get the answers from the end users. Drive campaigns through remote actions to:

  • Inform the end user of a particular issue.

  • Propose a series of steps (possibly with different options) to resolve the issue.

  • Notify the user once the issue has been solved.

To perform the actions described above, a self-help scenario typically demands two campaigns. In the case of our low disk space example, create the following two campaigns:

  • Propose disk cleanup, a campaign that warns end users that they are running low on disk free space and proposes either:

    • A light clean of the disk.

    • A deep clean of the disk.

    • Not to clean the disk, with the following options:

      • Ask again later.

      • Never ask again.

  • Confirm disk cleanup completed, a campaign that notifies the user when the cleaning process ends; as long as the user did not refuse to clean the disk in the previous campaign.

The Propose disk cleanup campaign offers a third choice that does not trigger any disk cleanup. This choice is suitable for end users who might decide to clean their disk later, never clean the disk despite the warning, or clean the disk themselves without the help of the remote action.

To indicate that the campaign is launched from a remote action, complete the sentence Users are targeted with the option with a remote action in the RECIPIENTS section of the editor. This is how the campaign Propose disk cleanup looks like in the editor of campaings in the Finder:

And this is how the campaign Confirm disk cleanup completed is displayed:

Creating the remote action

To fix low free disk space issues, the remote action in our example shall include:

  • An investigation that selects those devices with low system drive free space.

  • A script that gathers the answers of end users to the questions of the first campaign, Propose disk cleanup, and decide whether to clean the disk of the device or not based on those answers.

Defining the target investigation

Before creating the remote action itself, create an investigation that returns the devices with 5 GB of disk space available or less on their system drive. The investigation shall filter out those devices whose owners declined the proposal to clean the disk. Contrary to standalone campaigns, find the answers to campaigns launched from remote actions as fields of the Device object and not of the User object.

Scheduling the remote action

Create now the remote action and link the previous investigation to it. In the remote action editor:

  1. Tick the option to automatically run the remote action.

  2. Drag and drop the investigation onto the appropriate area within the SCHEDULE section.

As evaluation period, the remote action executes the investigation every 10 minutes for more responsiveness. To reduce the Engine load, setting an evaluation period of 1 hour should be enough as well.

As triggering period, the remote action specifies 1 day. In that way, the remote action will not shortly bother the same user again if the device still suffers from low free disk space, but it will wait until the next day.

Adding the PowerShell script

In your favorite text editor, type in the remediation script. Remember to encode the text of the script in UTF-8 with BOM when saving the file. Failing to do so results in the script not running on the target devices when the remote action is triggered.

The script does the following:

  1. Define two parameters of the type string to hold the identifiers (Uid) of the associated campaigns.

  2. Add the Nexthink dynamic library that deals with remote actions (nxtremoteactions.dll) by means of the Add-Type cmdlet.

  3. Add the Nexthink dynamic library that deals with campaigns launched from remote actions (nxtcampaignaction.dll) by means of the Add-Type cmdlet. This library includes the object [Nxt.CampaignAction] to handle the launching and get the answers of campaigns.

  4. Define a function HandleFullResponse to get the answer of a user to the questions of the first campaign and take action accordingly: clean the disk or handle a negative answer. Note the use of the function [Nxt.CampaignAction]::GetResponseAnswer to get the actual value of the answers to the campaign.

  5. Define a function CleanupDisk that removes all files in the Recycle Bin (note that the cmdlet Clear-RecycleBin is available from PowerShell 5.0 only). For simplicity, this example script does not make a difference between a light and a deep cleanup although it accepts the type as an argument to the function. Note the use of the function [Nxt.CampaignAction]::RunStandaloneCampaign to launch the second campaign after the cleaning up. It is launched as standlalone because it is just an informative campaign and there is no answer to collect.

  6. Define a helper function GetRecycleBinSize to get the total size of all the files in the Recycle Bin for reporting the amount of space cleaned to the Engine as an output.

  7. Define a function HandleNegativeResponse to ask users who do not want their disk to be cleaned if they want just to postpone the action or never be asked again.

  8. Define a helper function WriteOuptus that sends back to the Engine the response of the user and the number of bytes erased, if any.

  9. Run the first campaign to propose users the cleaning of their disk. Note the use of the function [Nxt.CampaignAction]::RunCampaign with the Uid of the first campaign and a timeout of 120 seconds.

  10. Get the response status with the help of the function [Nxt.CampaignAction]::GetResponseStatus.

  11. Depending on the status of the response:

    • Call the function HandleFullResponse, if the user fully responded to the questions of the first campaign.

    • Postpone the campaign and return this state to the Engine, if the user answered to postpone or if the campaign timed out.

    • Decline the campaign and return this state to the Engine, if the user declined the proposal to clean the disk.

#
# Clean Recycle Bin
# Version 1.0.0.0
# Copyright (C) 2017 Nexthink SA, Switzerland
#

param(
    [string]$ProposeCampaignId,
    [string]$ConfirmCampaignId
)

Add-Type -Path $env:NEXTHINK\RemoteActions\nxtremoteactions.dll
Add-Type -Path $env:NEXTHINK\RemoteActions\nxtcampaignaction.dll

trap {
    $host.ui.WriteErrorLine($_.ToString())
    exit 1
}

function HandleFullResponse($response) {
    $responseAnswer = [Nxt.CampaignAction]::GetResponseAnswer($response, "Clean disk")[0]
 switch($responseAnswer) {
 "Light" { CleanupDisk($responseAnswer) }
 "Deep"  { CleanupDisk($responseAnswer) } 
 "No"    { HandleNegativeResponse($response) }
 default { throw "Invalid answer, please ensure the first question name is set to 'Clean disk'" }    
    }
}

function CleanupDisk($type) {
    $path="$($env:SystemDrive)\`$recycle.bin"
    $bytesCleaned = GetRecycleBinSize($path)
        Clear-RecycleBin -Force -ErrorAction SilentlyContinue
    WriteOutputs $type $bytesCleaned
    [Nxt.CampaignAction]::RunStandAloneCampaign($ConfirmCampaignId)
}

function GetRecycleBinSize($path) {
    $measure=0
    Try {
        $measure=(Get-ChildItem $path -force -recurse -ErrorAction SilentlyContinue) | measure length -sum
    }
    Catch {
    }   
 return $measure.sum
}

function HandleNegativeResponse($response) {
    $responseAnswer = [Nxt.CampaignAction]::GetResponseAnswer($response, "Ask again")
 switch($responseAnswer) {
 "Postponed" { WriteOutputs("Postponed") }
 "Declined"  { WriteOutputs("Declined") }
 default     { throw "Invalid answer, please ensure the second question name is set to 'Ask again'" }
    }
}

function WriteOutputs($userReply, $bytesCleaned){
    [Nxt]::WriteOutputString("UserReply", $userReply)
    [Nxt]::WriteOutputSize("SpaceCleaned", $bytesCleaned)
}

$response = [Nxt.CampaignAction]::RunCampaign($ProposeCampaignId, 120)
$responseStatus = [Nxt.CampaignAction]::GetResponseStatus($response)
switch($responseStatus) {
 "fully"     { HandleFullResponse($response) }
 "timeout"   { WriteOutputs("Postponed") }
 "postponed" { WriteOutputs("Postponed") }
 "declined"  { WriteOutputs("Declined") }
 default  { throw "Failed to handle campaign response: " + $responseStatus }
}

For security reasons, Nexthink recommends that you sign your scripts. For testing purposes, it is safe though to use unsigned scripts in pre-production environments only.

In the editor of the remote actions, click Import... to link the script to the remote action. The Finder interprets the source of the script and lists both the detected parameters and the outputs under the script. The Parameters of the script are the Uids of the two campaigns previously created and the Outputs are the response of the user and the size of disk space cleaned.

To pass the Uid of a campaign to the remote action:

  1. In the left-hand side menu of the Finder, select the Campaigns section.

  2. Right-click the desired campaign.

  3. From the menu select Export > Campaign Uid to clipboard.

  4. In the left-hand side menu of the Finder, select the Remote actions section.

  5. Double-click the name of the remote action that will launch the campaign to open the editor of remote actions.

  6. In the Parameters section under the text of the script, right-click the text input box that corresponds to the string parameter that holds the Uid of the campaign in the script.

  7. Select Paste to insert the Uid of the desired campaign.

Advanced configuration

Since the remote action does not require administrative privileges, tick the option to run the script as the current interactive user. Remote action that require administrative privileges must be run as the local system account instead.

Allocate enough time so that the user can answer the campaign and the script is able to finish before being timed out. The example defines a timeout value of 300 seconds (5 minutes).

Last updated