IT-Glue unofficial backup script.

The last couple of weeks I’ve been focused on some API efforts for IT-Glue and was asked by a couple of partners if I couldn’t solve the problem that IT-Glue does not have a backup feature available. This makes it difficult to move away from the product, but also access you data in case of an emergency.

So to make sure that IT-Glue partners get some form of data portability and backups I’ve created the following script. The script connects to the IT-Glue API and creates a HTML and CSV export of all Flexible Assets and Passwords in IT-Glue.

It does not currently backup documents, as those are not exposed by the API. It also does not download attachments included on Flexible Assets. The export always creates 2 files; one HTML file for quick viewing, and a CSV file with all the information included.

I’ve also decided not to directly download all configurations as we store no data in there. If anyone wants to also download the configurations, let me know and I’ll edit the script a little.

Warning: The HTML files contain all your documentation, in plain-text format. Store this in a safe location or adapt the script to upload the data to your Azure Key Vault or secondary password management tool instead. Do not store these in a public location.

All you have to do is change the variables for your environment, APIKey, APIEndpoint, and the Export Directory.

The Unofficial IT-Glue Backup Script.

#####################################################################
#The unofficial Kelvin Tegelaar IT-Glue Backup script. Run this script whenever you want to create a backup of the ITGlue database.
#Creates a file called "password.html" with all passwords in Plain-text. please only store in secure location.
#Creates folders per organisation, and copies flexible assets there as HTML table  & CSV file for data portability.
$APIKEy =  "APIKEYHERE"
$APIEndpoint = "https://api.eu.itglue.com"
$ExportDir = "C:\Hello\ITGBackup"
#####################################################################
Write-Host "Creating backup directory" -ForegroundColor Green
if (!(Test-Path $ExportDir)) { new-item $ExportDir -ItemType Directory }

#Header for HTML files, to make it look pretty.
$head = @"
<script>
function myFunction() {
    const filter = document.querySelector('#myInput').value.toUpperCase();
    const trs = document.querySelectorAll('table tr:not(.header)');
    trs.forEach(tr => tr.style.display = [...tr.children].find(td => td.innerHTML.toUpperCase().includes(filter)) ? '' : 'none');
  }</script>
<title>Audit Log Report</title>
<style>
body { background-color:#E5E4E2;
      font-family:Monospace;
      font-size:10pt; }
td, th { border:0px solid black; 
        border-collapse:collapse;
        white-space:pre; }
th { color:white;
    background-color:black; }
table, tr, td, th {
     padding: 2px; 
     margin: 0px;
     white-space:pre; }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px; }
h2 {
font-family:Tahoma;
color:#6D7B8D;
}
.footer 
{ color:green; 
 margin-left:10px; 
 font-family:Tahoma;
 font-size:8pt;
 font-style:italic;
}
#myInput {
  background-image: url('https://www.w3schools.com/css/searchicon.png'); /* Add a search icon to input */
  background-position: 10px 12px; /* Position the search icon */
  background-repeat: no-repeat; /* Do not repeat the icon image */
  width: 50%; /* Full-width */
  font-size: 16px; /* Increase font-size */
  padding: 12px 20px 12px 40px; /* Add some padding */
  border: 1px solid #ddd; /* Add a grey border */
  margin-bottom: 12px; /* Add some space below the input */
}
</style>
"@

#ITGlue Download starts here
If(Get-Module -ListAvailable -Name "ITGlueAPI") {Import-module ITGlueAPI} Else { install-module ITGlueAPI -Force; import-module ITGlueAPI}
#Settings IT-Glue logon information
Add-ITGlueBaseURI -base_uri $APIEndpoint
Add-ITGlueAPIKey $APIKEy
$i = 0
#grabbing all orgs for later use.
do {
    $orgs += (Get-ITGlueOrganizations -page_size 1000 -page_number $i).data
    $i++
    Write-Host "Retrieved $($orgs.count) Organisations" -ForegroundColor Yellow
}while ($orgs.count % 1000 -eq 0 -and $orgs.count -ne 0)
#Grabbing all passwords.

Write-Host "Creating backup directory per organisation" -ForegroundColor Green
foreach($org in $orgs){
if (!(Test-Path "$($ExportDir)\$($org.attributes.name)\")) { 
    $org.attributes.name = $($org.attributes.name).Replace('\W'," ")
    new-item "$($ExportDir)\$($org.attributes.name)\" -ItemType Directory | out-null }
}

$i = 0
$Passwords = @()
Write-Host "Getting passwords" -ForegroundColor Green
    do {
        $i++
        $PasswordList += (Get-ITGluePasswords -page_size 1000 -page_number $i).data
        Write-Host "Retrieved $($PasswordList.count) Passwords" -ForegroundColor Yellow
    }while ($PasswordList.count % 1000 -eq 0 -and $PasswordList.count -ne 0)
    Write-Host "Processing Passwords. This might take some time." -ForegroundColor Yellow
foreach($PasswordItem in $passwordlist){
    $Passwords += (Get-ITGluePasswords -show_password $true -id $PasswordItem.id).data
}
Write-Host "Processed Passwords. Moving on." -ForegroundColor Yellow

    Write-Host "Getting Flexible Assets" -ForegroundColor Green
    $FlexAssetTypes = (Get-ITGlueFlexibleAssetTypes -page_size 1000).data
    foreach($FlexAsset in $FlexAssetTypes){
    $i = 0
    do {
        $i++
        Write-Host "Getting FlexibleAssets for $($Flexasset.attributes.name)" -ForegroundColor Yellow
        $FlexibleAssets += (Get-ITGlueFlexibleAssets -filter_flexible_asset_type_id $FlexAsset.id -page_size 1000 -page_number $i).data
        Write-Host "Retrieved $($FlexibleAssets.count) Flexible Assets" -ForegroundColor Yellow
    }while ($FlexibleAssets.count % 1000 -eq 0 -and $FlexibleAssets.count -ne 0)
    }
 
#Generate single HTML file with all passwords.
$Passwords.attributes | select-object 'organization-name',name,username,password,url,created-at,updated-at | convertto-html -head $head -precontent '<h1>Password export from IT-Glue</h1><input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for content.." title="Type a query">' | out-file "$($ExportDir)\passwords.html"

foreach($FlexibleAsset in $FlexibleAssets.attributes){
$HTMLTop = @"
<h1> Flexible Asset Information </h1>
<b>organization ID: </b>$($FlexibleAsset."organization-id") <br>
<b>organization Name:</b>$($FlexibleAsset."organization-name")<br>
<b>name:</b>$($FlexibleAsset.name)<br>
<b>created-at </b>$($FlexibleAsset."created-at")<br>
<b>updated-at </b>$($FlexibleAsset."updated-at")<br>
<b>resource url: </b>$($FlexibleAsset."resource-url")<br>
<b>flexible-asset-type-id: </b>$($FlexibleAsset."flexible-asset-type-id")<br>
<b>flexible-asset-type-name: </b>$($FlexibleAsset."flexible-asset-type-name")<br>
"@ 

$HTMLTables = $FlexibleAsset.traits | convertto-html -Head $head -PreContent "$HTMLTop <br> <h1> Flexible Asset Traits</h1>"

write-host "Ouputting $outputpath" -ForegroundColor Yellow
$OutputPath = "$($ExportDir)\$($flexibleasset.'organization-name')\"
$outputfilename = "$($Flexibleasset.'flexible-asset-type-name') - $($Flexibleasset.name)"
$outputfilename = $outputfilename -replace '[\W]',''
write-host "Ouputting $outputpath\$outputfilename" -ForegroundColor Yellow
$HTMLTables | out-file "$outputpath\$outputfilename HTML.html"
$FlexibleAsset.traits  | export-csv -path "$outputpath\$outputfilename CSV.csv" -NoTypeInformation
}

Follow me

Kelvin Tegelaar

I am a Microsoft Certified System Engineer working as the CTO of the Managed Services Provider Lime Networks B.V. in the Netherlands. I mostly enjoy automating business processes by deploying PowerShell solutions, but just have a large passion for Microsoft Technology in general.

If you want to contact me directly you can find me on twitter here, or via email: Kelvin {at} limenetworks.nl
Kelvin Tegelaar
Follow me

5 thoughts on “IT-Glue unofficial backup script.

  1. Jon Cross

    Script is great and seems to work well. However when I look at the passwords file the passwords column is empty. Anything we can do?

    Reply
    1. Kelvin Tegelaar Post author

      Most likely the “Passwords” permission is not set at the IT-Glue API key side. Make sure the “Passwords” checkbox is marked. Another thing that might be good to know: the script only generates the HTML file with passwords, and nothing else. If you’re looking at the CSV files its correct that these do not contain a password.

      Reply
  2. Caleb

    Thanks for creating this…I am not getting it to actually output more than one blank html file…get no error messages on run…but doesn’t seem to work.

    Creating backup directory
    Retrieved 0 Organisations
    Creating backup directory per organisation
    Getting passwords
    Retrieved 0 Passwords
    Processing Passwords. This might take some time.
    Processed Passwords. Moving on.
    Getting Flexible Assets

    If I’m in US should I be using the https://api.itglue.com as the API Endpoint…or my custom domain for our IT Glue tenant for the APIEndpoint

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.