Custom Issues

Prev Next

Create Custom Issues when you need to detect and remediate issues that aren't included in ControlUp's built-in issue catalog. If an issue is included in ControlUp's built-in issue catalog but the default remediation is either unavailable or insufficient, you can add a custom remediation to a built-in issue.

After creating a Custom Issue, you can add it to a Template's scanning scope. Custom Issues are indicated by an icon (this icon also appears in other areas of the application to indicate a Custom Issue):

Issue in the Template creation wizard with the custom issue icon next to its name.

How it works

A Custom Issue uses scan scripts to search for an issue and remediation scripts to perform an action to fix the issue. When a Template scans a device for a Custom Issue:

  1. The Template runs scan scripts.

    • If all scan scripts return their expected outputs, then the issue is not detected and the Template doesn't perform any further action.

    • If at least one scan script doesn't return its expected output, then the issue is detected and the Template proceeds to step 2.

  2. The Template runs remediation scripts on the device.

  3. The Template runs the scan scripts for a second time to check if the issue has been fixed.

    • If all scan scripts now return their expected outputs, then the remediation is marked as successful.

    • If at least one scan script still doesn't return its expected output, then the remediation is marked as a failure.

How to create a Custom Issue

  1. Create the scan and remediation scripts and add them to ControlUp for Compliance. Read How to Add Scripts for details.

    • Scan scripts must return an output that can be used to determine whether a device has the issue.

    • Remediation scripts should perform some action on a device to fix the issue.

  2. In ControlUp for Compliance, go to Configuration > Custom Issues and click Add Custom Issue.

  3. Select Create Custom Issue.

  4. Enter a Name and Description for the Custom Issue

  5. Select a Scan Severity for the issue. A higher severity means that the issue will have a greater impact on the Issue score and Device score when detected.

  6. Select the category and subcategory for the scan. The Custom Issue will appear in the selected category when creating a Template, and when viewing detected issues on our dashboards.

  7. Add one or more scan scripts and enter their expected output under normal circumstances when there is no issue on the device.

  8. Add one or more remediation scripts. If you enable Require device restart, then the remediation is marked as successful only after the device restarts. The device will automatically restart if Auto Restart is enabled in the Template's settings. Learn more about remediation statuses.

Example

Try it yourself

To try out this example in your own environment, download the test file, scan script, and remediation script here.


CustomIssueTestFiles
1.83 KB

Employees keep having problems because their devices aren’t connecting to the goodhost server. Affected devices have a C:\temp\settings.ini file that looks like this:

[Server]
Host=badhost
Port=8080

First, you need a scan script to check the current value of Host, and you need to tell ControlUp the expected output from a healthy device that doesn’t have the problem. The following script returns:

  • 0 if the value is goodhost

  • 1 for everything else.

You can create a Custom Issue with this scan script and enter 0 as the expected output. If your Compliance Template scans for this Custom Issue and the scan script returns 0, nothing happens. If it returns 1, an Issue is reported.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 # This line is added automatically to help with Unicode characters. Please add your code below 
<#
.SYNOPSIS
    ControlUp for Compliance test: check that Host in the [Server] section of an .ini file is goodhost.
.DESCRIPTION
    Returns 0 or 1 as both the scan output and the process exit code, required for ControlUp for Compliance.
        0 = Compliant (Host=goodhost)
        1 = Non-compliant (Host is anything else, or missing)
#>
$Path = 'c:\temp\settings.ini'
$ExpectedHost = 'goodhost'

if (-not (Test-Path $Path)) {
    Write-Output 1
    exit 1
}

$section = $null
$currentHost = $null

foreach ($line in Get-Content $Path) {
    $line = $line.Trim()

    if ($line -match '^\[(.+)\]$') {
        $section = $Matches[1]
    }
    elseif ($section -eq 'Server' -and $line -match '^Host\s*=\s*(.*)$') {
        $currentHost = $Matches[1].Trim()
        break
    }
}

if ($currentHost -eq $ExpectedHost) {
    Write-Output 0
    exit 0
}

Write-Output 1
exit 1

Next, you need a remediation script. When your Compliance Template remediates the issue, it runs this script to write Host=goodhost. After the remediation script finishes, the scan script runs once again to confirm that the remediation worked. If the scan script now returns 0, the issue is resolved.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 # This line is added automatically to help with Unicode characters. Please add your code below 
<#
.SYNOPSIS
    ControlUp for Compliance remediation: set Host to goodhost in the [Server] section of an .ini file.
.DESCRIPTION
    Rewrites the Host entry in the [Server] section, leaving all other settings unchanged.
    If the Host entry does not exist, it is added to the [Server] section.
#>
$Path = 'c:\temp\settings.ini'
$NewHost = 'goodhost'

if (-not (Test-Path $Path)) {
    Write-Output ("### SIP EVENT BEGINS ###")
    Write-Output "Failed to update c:\temp\settings.ini file to goodhost: INI file not found"
    Write-Output ("### SIP EVENT ENDS ###")
    return
}

$section = $null
$fixed = $false
$output = foreach ($line in Get-Content $Path) {
    $trimmed = $line.Trim()

    if ($trimmed -match '^\[(.+)\]$') {
        # Leaving [Server] without having found Host: add it before the next section
        if ($section -eq 'Server' -and -not $fixed) {
            "Host=$NewHost"
            $fixed = $true
        }
        $section = $Matches[1]
    }

    if ($section -eq 'Server' -and $trimmed -match '^Host\s*=') {
        "Host=$NewHost"
        $fixed = $true
    }
    else {
        $line
    }
}

# [Server] was the last section and had no Host entry
if ($section -eq 'Server' -and -not $fixed) {
    $output += "Host=$NewHost"
    $fixed = $true
}

if (-not $fixed) {
    Write-Output ("### SIP EVENT BEGINS ###")
    Write-Output "Failed to update c:\temp\settings.ini file to goodhost: No [Server] section found"
    Write-Output ("### SIP EVENT ENDS ###")
    return
}

try {
    $output | Set-Content -Path $Path -Encoding UTF8 -ErrorAction Stop
    Write-Output ("### SIP EVENT BEGINS ###")
    Write-Output "Successfully updated c:\temp\settings.ini file to goodhost"
    Write-Output ("### SIP EVENT ENDS ###")
}
catch {
    Write-Output ("### SIP EVENT BEGINS ###")
    Write-Output "Failed to update c:\temp\settings.ini file to goodhost: $($_.Exception.Message)"
    Write-Output ("### SIP EVENT ENDS ###")
}