Created
November 6, 2020 18:36
-
-
Save levi-turner/18f2c4db12c948ae8709d3cca34aecfd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-------------------------------------------------------------------------------------------------------------------------------- | |
# | |
# Script Name: qs-qrs-telemetry_task_fix.ps1 | |
# Description: A PowerShell script to fix & schedule tasks for Telemetry Dashboard project | |
# Dependency: None | |
# | |
# Version Date Author Change Notes | |
# 0.1 2020-04-27 Levi Turner Initial Version | |
# Many thanks to: | |
# https://stackoverflow.com/questions/19741716/how-do-i-get-date-1-formatted-as-mm-dd-yyyy-using-powershell | |
# http://webofwood.com/2010/08/13/get-a-midnight-datetime-value-in-powershell/ | |
# Known Issues: | |
# Handling of different time zones. You will need to adjust values to get them to align with what you want at the current time. | |
# Unknown Issues: | |
# Different regional settings for the Windows Server | |
#-------------------------------------------------------------------------------------------------------------------------------- | |
# Mandatory Variables | |
$createSchedule = 'Y' # Define whether the Telemetry Tasks will be scheduled | |
$scheduleCadence = 'Daily' # Define what cadence. Accepted Values: Daily / Weekly | |
$weeklyDay = 'Saturday' # Define what day the task will run if Weekly is chosen for $scheduleCadence. Accepted Values: Monday / Tuesday / Wednesday / Thursday / Friday / Saturday / Sunday | |
$hour = '4' # Hour for task to execute. Accepted Values: 0-23 (Midnight - 11PM / 2300) | |
# Build out headers for QRS API Calls | |
$hdrs = @{} | |
$hdrs.Add("X-Qlik-Xrfkey","examplexrfkey123") | |
$hdrs.Add("X-Qlik-User", "UserDirectory=INTERNAL; UserId=sa_api") | |
# Get the certificate | |
$cert = Get-ChildItem -Path "Cert:\CurrentUser\My" | Where {$_.Subject -like '*QlikClient*'} | |
# Check for the cert | |
if (!$cert) { | |
Write-Host "Client certificate not found" -ForegroundColor Red | |
Exit | |
} | |
# Construct the host to call | |
$Data = Get-Content C:\ProgramData\Qlik\Sense\Host.cfg | |
$FQDN = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($($Data))) | |
if (!$Data) { | |
Write-Host "Host.cfg file not found. Ensure script is run on a Qlik Sense node" -ForegroundColor Red | |
Exit | |
} else { | |
Write-Host "Attempting to connect to $FQDN" -ForegroundColor Green | |
} | |
# Handle TLS 1.2 exclusive environments | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' | |
# Test call /qrs/about to ensure connectivity | |
$about = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/about?xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if (!$about) { | |
Write-Host "Unable to contact QRS at $($FQDN)" -ForegroundColor Red | |
Exit | |
} else { | |
Write-Host "Connected to $FQDN" -ForegroundColor Green | |
} | |
# Check for whether the app exists | |
$app = 'Telemetry Dashboard' | |
$telemetryapp = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/app/full?filter=(name eq '$app')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if (!$telemetryapp) { | |
Write-Host "Telemetry App: [ ]" -ForegroundColor Red | |
Write-Host "Rename / Import app" -ForegroundColor Red | |
Exit | |
} | |
elseif ($telemetryapp.count -gt 1) { | |
Write-Host "Duplicate copies of apps named Telemetry Dashboard found" -ForegroundColor Red | |
Write-Host "Ensure only 1 app is named Telemetry Dashboard for task fix" -ForegroundColor Red | |
Exit | |
} | |
else { | |
Write-Host "Telemetry App: [x]" -ForegroundColor Green | |
} | |
$telemetryapp = $telemetryapp.id | |
# Check for App Metadata Fetch Task | |
$task1 = 'TelemetryDashboard-1-Generate-Metadata' | |
$fetchtask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/task/full?filter=(name eq '$task1')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if (!$fetchtask) { | |
Write-Host "Metadata Fetch: [ ]" -ForegroundColor Red | |
Write-Host "Creating Metadata Fetch Task ..." -ForegroundColor Green | |
$sharepath = (Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/servicecluster/full?xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert).settings.sharedPersistenceProperties.rootFolder | |
$sharepath = $sharepath.Replace('\', '\\') | |
$parampath = $sharepath | |
$parampath += '\\TelemetryDashboard\\TelemetryDashboard.exe\" -fetchmetadata -tasktriggered' | |
$body = '{ | |
"path": "cmd.exe",' | |
$body += '"parameters": "/C \"' | |
$body += $parampath | |
$body += '"' | |
$body += ',' | |
$body += '"name": "TelemetryDashboard-1-Generate-Metadata", | |
"taskType": 1, | |
"enabled": true, | |
"taskSessionTimeout": 1440, | |
"maxRetries": 0, | |
"impactSecurityAccess": false, | |
"schemaPath": "ExternalProgramTask" | |
}' | |
$body | |
$null = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/externalprogramtask?xrfkey=examplexrfkey123" -Method Post -Body $body -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$fetchtask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/task/full?filter=(name eq '$task1')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if ($fetchtask.count -eq '1') { | |
Write-Host "Metadata Fetch: [x]" -ForegroundColor Green | |
} | |
$trigger = 'telemetry-metadata-trigger' | |
$triggerevent = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/compositeevent/full?filter=(name eq '$trigger')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$null = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/compositeevent/$($triggerevent.id)?xrfkey=examplexrfkey123" -Method Delete -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
} | |
elseif ($fetchtask.count -gt 1) { | |
Write-Host "Multiple tasks found named TelemetryDashboard-1-Generate-Metadata" -ForegroundColor Red | |
Write-Host "Ensure only 1 task is named TelemetryDashboard-1-Generate-Metadata" -ForegroundColor Red | |
Exit | |
} | |
else { | |
Write-Host "Metadata Fetch: [x]" -ForegroundColor Green | |
} | |
# Check for App Reload Task | |
$task2 = 'TelemetryDashboard-2-Reload-Dashboard' | |
$apptask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/task/full?filter=(name eq '$task2')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if (!$apptask) { | |
Write-Host "App Reload Task: [ ]" -ForegroundColor Red | |
Write-Host "Creating Reload Task ..." -ForegroundColor Green | |
$reloadtaskbody = '{"task": { | |
"app": { | |
"id": "' | |
$reloadtaskbody += $telemetryapp | |
$reloadtaskbody += '",' | |
$reloadtaskbody += ' | |
"name": "Telemetry Dashboard" | |
}, | |
"enabled": true, | |
"isManuallyTriggered": false, | |
"maxRetries": 0, | |
"name": "TelemetryDashboard-2-Reload-Dashboard", | |
"taskSessionTimeout": 1440, | |
"taskType": 0 | |
} | |
}' | |
$null = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/reloadtask/create?xrfkey=examplexrfkey123" -Method Post -Body $reloadtaskbody -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$apptask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/task/full?filter=(name eq '$task2')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if ($apptask.count -eq '1') { | |
Write-Host "App Reload Task: [x]" -ForegroundColor Green | |
} | |
} | |
elseif ($apptask.count -gt 1) { | |
Write-Host "Multiple tasks found for app named Telemetry Dashboard" -ForegroundColor Red | |
Write-Host "Ensure only 1 task is named TelemetryDashboard-1-Generate-Metadata" -ForegroundColor Red | |
Exit | |
} | |
else { | |
Write-Host "App Reload Task: [x]" -ForegroundColor Green | |
} | |
# Check for the trigger | |
$trigger = 'telemetry-metadata-trigger' | |
$triggerevent = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/compositeevent/full?filter=(name eq '$trigger')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if (!$triggerevent) { | |
Write-Host "Tasks linked: [ ]" -ForegroundColor Red | |
Write-Host "Creating link ..." -ForegroundColor Green | |
$triggerbody = ' | |
{ | |
"compositeEvents":[ | |
{ | |
"timeConstraint":{ | |
"seconds":0, | |
"minutes":360, | |
"hours":0, | |
"days":0 | |
}, | |
"name":"telemetry-metadata-trigger", | |
"enabled":true, | |
"eventType":1, | |
"reloadTask":{ | |
"id":"' | |
$triggerbody += $apptask.id | |
$triggerbody +='" | |
}, | |
"compositeRules":[ | |
{ | |
"ruleState":1, | |
"externalProgramTask":{ | |
"id":"' | |
$triggerbody += $fetchtask.id | |
$triggerbody +='" | |
} | |
} | |
], | |
"privileges":[ | |
"read", | |
"update", | |
"create", | |
"delete" | |
] | |
} | |
] | |
}' | |
$null = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/reloadtask/update?xrfkey=examplexrfkey123" -Method Post -Body $triggerbody -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$triggerevent = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/compositeevent/full?filter=(name eq '$trigger')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
if ($triggerevent.count -eq '1') { | |
Write-Host "Tasks linked: [x]" -ForegroundColor Green | |
} | |
} | |
elseif ($triggerevent.count -gt 1) { | |
Write-Host "Multiple chains are found." -ForegroundColor Red | |
Write-Host "Trigger is named telemetry-metadata-trigger" -ForegroundColor Red | |
Write-Host "Ensure only 1 trigger is named telemetry-metadata-trigger" -ForegroundColor Red | |
Exit | |
} | |
else { | |
Write-Host "Tasks linked: [x]" -ForegroundColor Green | |
} | |
# validate variables | |
if ($createSchedule -eq 'Y') { | |
Write-Host "Metadata Fetch Will be Scheduled [x]" -ForegroundColor Green | |
} elseif ($schedule -eq 'N') { | |
Write-Host "Metadata Fetch Will Not be Scheduled [x]" -ForegroundColor Green | |
} else { | |
Write-Host "Invalid Value for createSchedule variable" -ForegroundColor Red | |
Exit | |
} | |
if ($scheduleCadence -eq 'Daily') { | |
Write-Host "Daily Reload Specified" -ForegroundColor Green | |
} elseif ($scheduleCadence -eq 'Weekly') { | |
Write-Host "Weekly Reload Specified [x]" -ForegroundColor Green | |
} else { | |
Write-Host "Invalid Value for scheduleCadence variable" -ForegroundColor Red | |
Exit | |
} | |
if ($scheduleCadence -eq 'Weekly') { | |
if ($weeklyDay -eq 'Monday') { | |
Write-Host "Configure Reload for Mon [x]" -ForegroundColor Green | |
} | |
elseif ($weeklyDay -eq 'Tuesday') {Write-Host "Configure Reload for Tue [x]" -ForegroundColor Green} | |
elseif ($weeklyDay -eq 'Wednesday') {Write-Host "Configure Reload for Wed [x]" -ForegroundColor Green} | |
elseif ($weeklyDay -eq 'Thursday') {Write-Host "Configure Reload for Thu [x]" -ForegroundColor Green} | |
elseif ($weeklyDay -eq 'Friday') {Write-Host "Configure Reload for Fri [x]" -ForegroundColor Green} | |
elseif ($weeklyDay -eq 'Saturday') {Write-Host "Configure Reload for Sat [x]" -ForegroundColor Green} | |
elseif ($weeklyDay -eq 'Sunday') {Write-Host "Configure Reload for Sun [x]" -ForegroundColor Green} | |
else { | |
Write-Host "Invalid Value for weeklyDay variable" -ForegroundColor Red | |
Exit | |
} | |
} | |
# Look to see if currently scheduled, if scheduled, delete operational | |
$task1 = 'TelemetryDashboard-1-Generate-Metadata' | |
# Get TaskID | |
$fetchtask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/task/full?filter=(name eq '$task1')&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
# Get ExternalProgramTaskID | |
$fetchtask = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/externalprogramtask/$($fetchtask.id)?xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
# Check for previously defined Schedule for the ExternalProgramTask | |
$fetchSchema = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaevent/full?filter=(externalProgramTask.id eq $($fetchtask.id))&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
# if previously scheduled, delete the Schema | |
if (!$fetchSchema) { | |
Write-Host "Metadata Fetch currently unscheduled" -ForegroundColor Green | |
} else { | |
Write-Host "Metadata Fetch Scheduled ..." -ForegroundColor Green | |
Write-Host "... deleting schedule [x]" -ForegroundColor Green | |
Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaevent/$($fetchSchema.id)?xrfkey=examplexrfkey123" -Method Delete -Headers $hdrs -ContentType 'application/json' -Certificate $cert | Out-Null | |
} | |
# Schedule bit | |
if ($scheduleCadence -eq 'Daily') { | |
$date = Get-Date | |
if ($date.Hour -gt $hour) { | |
# Schedule for tomorrow @ time | |
$dateQRS = (Get-Date -Hour $hour -Minute 00 -Second 00).AddDays(1).ToString('yyyy-MM-ddTHH:mm:ssZ') | |
$operationalBody = ' { | |
"nextExecution": "' | |
$operationalBody += $dateQRS | |
$operationalBody += '", | |
"schemaPath": "SchemaEventOperational" | |
}' | |
} else { | |
# Schedule for today | |
$dateQRS = (Get-Date -Hour $hour -Minute 00 -Second 00).ToString('yyyy-MM-ddTHH:mm:ssZ') | |
$operationalBody = ' { | |
"nextExecution": "' | |
$operationalBody += $dateQRS | |
$operationalBody += '", | |
"schemaPath": "SchemaEventOperational" | |
}' | |
} | |
# Post in the Schedule | |
$operational = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaeventoperational?xrfkey=examplexrfkey123" -Method Post -body $operationalBody -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$eventBody = '{ | |
"timeZone": "America/New_York", | |
"daylightSavingTime": 0, | |
"startDate": "' | |
$eventBody += $dateQRS | |
$eventBody +='", | |
"expirationDate": "9999-12-31T00:00:00", | |
"schemaFilterDescription": [ | |
"* * - * * * * *" | |
], | |
"incrementDescription": "0 0 1 0", | |
"incrementOption": 2, | |
"operational": { | |
"id": "' | |
$eventBody += $($operational.id) | |
$eventBody += '", "createdDate" : "' | |
$eventBody += $($operational.createdDate) | |
$eventBody += '","modifiedDate" : "' | |
$eventBody += $($operational.modifiedDate) | |
$eventBody += '", "modifiedByUserName" : "INTERNAL\\sa_api' | |
$eventBody += '", "lastEventDate" : "' | |
$eventBody += $($operational.lastEventDate) | |
$eventBody += '", "nextExecution" : "' | |
$eventBody += $($operational.nextExecution) | |
$eventBody += '", "timesTriggered" : 0, | |
"schemaPath": "SchemaEventOperational" | |
}, | |
"name": "Reload fetchmetadata.js", | |
"enabled": true, | |
"eventType": 0, | |
"externalProgramTask": { | |
"id": "' | |
$eventBody += $($fetchtask.id) | |
$eventBody += '", | |
"operational": { | |
"id": "' | |
$eventBody += $fetchtask.operational.id | |
$eventBody += '"}, | |
"name": "TelemetryDashboard-1-Generate-Metadata", | |
"taskType": 1, | |
"enabled": true, | |
"taskSessionTimeout": 1440, | |
"maxRetries": 0, | |
"privileges": null | |
}, | |
"userSyncTask": null, | |
"reloadTask": null, | |
"privileges": null, | |
"schemaPath": "SchemaEvent" | |
}' | |
} else { | |
$date = Get-Date | |
# if current date, schedule | |
if ($weeklyDay -eq 'Monday') { | |
$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Monday'} | |
} elseif ($weeklyDay -eq 'Tuesday') {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Tuesday'}} | |
elseif ($weeklyDay -eq 'Wednesday') {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Wednesday'}} | |
elseif ($weeklyDay -eq 'Thursday') {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Thursday'}} | |
elseif ($weeklyDay -eq 'Friday') {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Friday'}} | |
elseif ($weeklyDay -eq 'Saturday') {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Saturday'}} | |
else {$scheduleDate = 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Sunday'}} | |
# build schedule | |
$dateQRS = $scheduleDate.ToString('yyyy-MM-ddTHH:mm:ssZ') | |
$dateQRS = (Get-Date -Hour $hour -Minute 00 -Second 00).ToString('yyyy-MM-ddTHH:mm:ssZ') | |
$operationalBody = ' { | |
"nextExecution": "' | |
$operationalBody += $dateQRS | |
$operationalBody += '", | |
"schemaPath": "SchemaEventOperational" | |
}' | |
# Post in the Schedule | |
$operational = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaeventoperational?xrfkey=examplexrfkey123" -Method Post -body $operationalBody -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
$eventBody = '{ | |
"timeZone": "America/New_York", | |
"daylightSavingTime": 0, | |
"startDate": "' | |
$eventBody += $dateQRS | |
$eventBody +='", | |
"expirationDate": "9999-12-31T00:00:00", | |
"schemaFilterDescription": [ | |
"* * - ' | |
switch ($weeklyDay) { | |
"Sunday" {$weeklyDay = 0} | |
"Monday" {$weeklyDay = 1} | |
"Tuesday" {$weeklyDay = 2} | |
"Wednesday" {$weeklyDay = 3} | |
"Thursday" {$weeklyDay = 4} | |
"Friday" {$weeklyDay = 5} | |
"Saturday" {$weeklyDay = 6} | |
} | |
$eventBody += $weeklyDay | |
$eventBody += ' 1 * * *" | |
], | |
"incrementDescription": "0 0 1 0", | |
"incrementOption": 3, | |
"operational": { | |
"id": "' | |
$eventBody += $($operational.id) | |
$eventBody += '", "createdDate" : "' | |
$eventBody += $($operational.createdDate) | |
$eventBody += '","modifiedDate" : "' | |
$eventBody += $($operational.modifiedDate) | |
$eventBody += '", "modifiedByUserName" : "INTERNAL\\sa_api' | |
$eventBody += '", "lastEventDate" : "' | |
$eventBody += $($operational.lastEventDate) | |
$eventBody += '", "nextExecution" : "' | |
$eventBody += $($operational.nextExecution) | |
$eventBody += '", "timesTriggered" : 0, | |
"schemaPath": "SchemaEventOperational" | |
}, | |
"name": "Reload fetchmetadata.js", | |
"enabled": true, | |
"eventType": 0, | |
"externalProgramTask": { | |
"id": "' | |
$eventBody += $($fetchtask.id) | |
$eventBody += '", | |
"operational": { | |
"id": "' | |
$eventBody += $fetchtask.operational.id | |
$eventBody += '"}, | |
"name": "TelemetryDashboard-1-Generate-Metadata", | |
"taskType": 1, | |
"enabled": true, | |
"taskSessionTimeout": 1440, | |
"maxRetries": 0, | |
"privileges": null | |
}, | |
"userSyncTask": null, | |
"reloadTask": null, | |
"privileges": null, | |
"schemaPath": "SchemaEvent" | |
}' | |
} | |
# Post in the Schedule | |
Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaevent?xrfkey=examplexrfkey123" -Method Post -body $eventBody -Headers $hdrs -ContentType 'application/json' -Certificate $cert | Out-Null | |
# Ensure schemaEvent exists | |
$fetchSchema = '' | |
$fetchSchema = Invoke-RestMethod -Uri "https://$($FQDN):4242/qrs/schemaevent/full?filter=(externalProgramTask.id eq $($fetchtask.id))&xrfkey=examplexrfkey123" -Method Get -Headers $hdrs -ContentType 'application/json' -Certificate $cert | |
# if previously scheduled, delete the Schema | |
if (!$fetchSchema) { | |
Write-Host "Metadata Fetch currently unscheduled" -ForegroundColor Red | |
} else { | |
Write-Host "Metadata Fetch Scheduled [x]" -ForegroundColor Green | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment