├── LT - Script Backup.xml ├── LT-ScriptExport.ps1 └── README.md /LT - Script Backup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | LT-Script Backup 8 | This script will export a copy of all LT scripts as an xml file. All scripts will have the last modified data and last user to modify appended to the file. 9 | Chris Taylor 10 | www.labtechconsulting.com 11 | 9/25/2015 12 | 0, 13 | 0, 14 | 1 15 | 0 16 | 0 17 | 0 18 | H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ih4/L6b5ssmfZm129PjN9So/2n18l38+frVenlTrZZvXRzuP73p/PT59typqvJMfvV4vZ9n1KH2dr9p8McnrdG9nRP/fvZ8ePNrdebR/kL784vFd743Hr6d1sWp/Mq+boloCdPiBfv/5upgdTT7N9x/s7Oxs3z+f7W/v7ub3tw/uT6fbOzv3d+5/mu3t3J/dN+/zC4/v+gP6jZP/B8+P+g7gAAAA 19 | H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ih6/ntbFqn2atdnRb5ykqf7d8B/05+m7ts7w7bMiL2dNetd88TKrs0Xe5rX32edlNclK7wMB9pPUqKiWR7uP74YfBK0+Xxezo8mn+f6DnZ2d7fvns/3t3d38/vbB/el0e2fn/s79T7O9nfuz+wYKv8A46weNP4LXbb6yozietoqA/qafP1sv+e+zGb7z/vIHudsZ9F7n73udv/c7f9/36FHV7dEO4Yuf+tlJtWyL5TrH5/Z3/e7L5nmxKPgV86t+c7ac5cs248HQt/6fPkkcFTaQZW8TWe7vDxPm6Hcv2+ZyOivq3/331Sn4fZ9nkzf5dK5/p0+y6dv16vFdfeH/1XTc/9mk48MNZJy37ap5dPdunV2NL4p2vp6sm7ye0iAImfG0WtwlqrZEVRpXsy5paBd3lc7b24LPthD67iJrSCbvPn+jn5++WxGNxqtmNz4Ht57C33cY5F44jaCy/vY+07n7/6np3L2lWDTvQ9NtGuh5cTF+tygHZsuQtkvyR6fv8um6zb8W5fe+acrf+1mk/N4mQXpeXaTFsq3S331aFtT/kkzU7/77/u5lNWVM9E8SqBXRquY/06xJf/fn2uArEjv6ZDlL6/Uy/ehDZOOjlNCY1nnW5umUp3Vdcx/peVHm458VjXjv/Sfy506E9nbv/9BM7v43TZifTQ7fvbeJxTuS/s0y0P1vmk4/q67J3qcb6LSqrsjLnOdlmW7nTDJqtarKYnqdTq5XWdOk25DED5Tyn5Vp+PSbnoZhOf7wadjb2TALg14Hz0ydw5v53Qds2iv+9mtZtAf/nyLgJnEXIjxKf0/55ff8WeG3g/8vkevBJn4LeKbLdAcDjCbiTHZ5WRBbzoxt7rDc0aM3xfRt3sIHJzUy46Fp0/2N5H34TZP3G7Q+fW78OuL87Pjs+enTAfI2hPW6+VpyvLvzTZPuZ5MzbzDcw+zzzUrz7jceSf1sWvGvxW/P36TbaWCc0zn58RvZUMnPHvnr9eSn8+nXsy2733i49LPJkzeRN0reN/O8zpmikzxfUjyU5nVd1WnOipKyD6mGtel5XS1S9ZbGv3HSsVKbpuBJNbv+evT//1aU8w2xd9GkTVuQMwseP3vx+a2JXS0WNLKvR+lvPGz6/wKlwfbIEJSU3J6lzXo6zZvmfF2W1+lGSj9j9+Hrs/U3Hnvditg/TGLv7t+7WTEQwBNSDxdV/TXp+P+p4Gmzy/AtPOmLKj2ZZ8uLvEmf5GV1lbZz0gZlsczTl2WeNT87qYDdrxFD7e3/f8tt/d3FjBWzoRBUcDkzLsV7cuLB+1Pwh86JH0bAoRWAYVf3PUn4jYdOP6vC/GADCe8/2DXa75sVVEzcN0ujn005ff8Y6fSFEb9vmG4/F2GS+fuprLf/P+pRo6x+HwAA 20 | 1 21 | b6e47000-5fd4-11e5-85cc-005056a205d5 22 | 0 23 | 24 | 25 |
26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /LT-ScriptExport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Backs up all LabTech scripts. 4 | 5 | .DESCRIPTION 6 | This script will export all LabTech sctipts in xml format to a specified destination. 7 | Requires the MySQL .NET connector. 8 | 9 | .LINK 10 | http://www.labtechconsulting.com 11 | https://dev.mysql.com/downloads/connector/net/6.9.html 12 | 13 | .OUTPUTS 14 | Default values - 15 | Log file stored in: $($env:windir)\LTScv\Logs\LT-ScriptExport.log 16 | Scripts exported to: $($env:windir)\Program Files(x86)\LabTech\Backup\Scripts 17 | Credentials file: $PSScriptRoot 18 | 19 | .NOTES 20 | Version: 1.0 21 | Author: Chris Taylor 22 | Website: www.labtechconsulting.com 23 | Creation Date: 9/11/2015 24 | Purpose/Change: Initial script development 25 | 26 | Version: 1.1 27 | Author: Chris Taylor 28 | Website: www.labtechconsulting.com 29 | Creation Date: 9/23/2015 30 | Purpose/Change: Added error catching 31 | #> 32 | 33 | #Requires -Version 3.0 34 | 35 | #region-[Declarations]---------------------------------------------------------- 36 | 37 | $ScriptVersion = "1.1" 38 | 39 | $ErrorActionPreference = "Stop" 40 | 41 | $Date = Get-Date 42 | 43 | #Get/Save config info 44 | if($(Test-Path $PSScriptRoot\LT-ScriptExport-Config.xml) -eq $false) { 45 | #Config file template 46 | $Config = [xml]@' 47 | 48 | 49 | 50 | 51 | 52 | 53 | 0 54 | 55 | '@ 56 | try { 57 | #Create config file 58 | $Config.Settings.LogPath = "$(Read-Host "Path of log file ($($env:windir)\LTSvc\Logs)")" 59 | if ($Config.Settings.LogPath -eq '') {$Config.Settings.LogPath = "$($env:windir)\LTSvc\Logs"} 60 | $Config.Settings.BackupRoot = "$(Read-Host "Path of exported scripts (${env:ProgramFiles(x86)}\LabTech\Backup\Scripts)")" 61 | if ($Config.Settings.BackupRoot -eq '') {$Config.Settings.BackupRoot = "${env:ProgramFiles(x86)}\LabTech\Backup\Scripts"} 62 | $Config.Settings.MySQLDatabase = "$(Read-Host "Name of LabTech database (labtech)")" 63 | if ($Config.Settings.MySQLDatabase -eq '') {$Config.Settings.MySQLDatabase = "labtech"} 64 | $Config.Settings.MySQLHost = "$(Read-Host "FQDN of LabTechServer (localhost)")" 65 | if ($Config.Settings.MySQLHost -eq '') {$Config.Settings.MySQLHost = "localhost"} 66 | $Config.Settings.CredPath = "$(Read-Host "Path of credentials ($PSScriptRoot)")" 67 | if ($Config.Settings.CredPath -eq '') {$Config.Settings.CredPath = "$PSScriptRoot"} 68 | $Config.Save("$PSScriptRoot\LT-ScriptExport-Config.xml") 69 | } 70 | Catch { 71 | $ErrorMessage = $_.Exception.Message 72 | $FailedItem = $_.Exception.ItemName 73 | Log-Error -LogPath $FullLogPath -ErrorDesc "Error durring config creation: $FailedItem, $ErrorMessage" -ExitGracefully $True 74 | } 75 | } 76 | Else { 77 | [xml]$Config = Get-Content "$PSScriptRoot\LT-ScriptExport-Config.xml" 78 | } 79 | 80 | #Location to credentials file 81 | $CredPath = $Config.Settings.CredPath 82 | 83 | #Get/Save user/password info 84 | if ($(Test-Path $CredPath) -eq $false) {New-Item -ItemType Directory -Force -Path $CredPath | Out-Null} 85 | if($(Test-Path $CredPath\LTDBCredentials.xml) -eq $false){Get-Credential -Message "Please provide the credentials to the LabTech MySQL database." | Export-Clixml $CredPath\LTDBCredentials.xml -Force} 86 | 87 | #Log File Info 88 | $LogName = "LT-ScriptExport.log" 89 | $LogPath = ($Config.Settings.LogPath) 90 | $FullLogPath = $LogPath + "\" + $LogName 91 | 92 | 93 | #Location to the backp repository 94 | $BackupRoot = $Config.Settings.BackupRoot 95 | 96 | #MySQL connection info 97 | $MySQLDatabase = $Config.Settings.MySQLDatabase 98 | $MySQLHost = $Config.Settings.MySQLHost 99 | $MySQLAdminPassword = (IMPORT-CLIXML "$CredPath\LTDBCredentials.xml").GetNetworkCredential().Password 100 | $MySQLAdminUserName = (IMPORT-CLIXML "$CredPath\LTDBCredentials.xml").GetNetworkCredential().UserName 101 | 102 | #endregion 103 | 104 | #region-[Functions]------------------------------------------------------------ 105 | 106 | Function Log-Start{ 107 | <# 108 | .SYNOPSIS 109 | Creates log file 110 | 111 | .DESCRIPTION 112 | Creates log file with path and name that is passed. Checks if log file exists, and if it does deletes it and creates a new one. 113 | Once created, writes initial logging data 114 | 115 | .PARAMETER LogPath 116 | Mandatory. Path of where log is to be created. Example: C:\Windows\Temp 117 | 118 | .PARAMETER LogName 119 | Mandatory. Name of log file to be created. Example: Test_Script.log 120 | 121 | .PARAMETER ScriptVersion 122 | Mandatory. Version of the running script which will be written in the log. Example: 1.5 123 | 124 | .INPUTS 125 | Parameters above 126 | 127 | .OUTPUTS 128 | Log file created 129 | 130 | .NOTES 131 | Version: 1.0 132 | Author: Luca Sturlese 133 | Creation Date: 10/05/12 134 | Purpose/Change: Initial function development 135 | 136 | Version: 1.1 137 | Author: Luca Sturlese 138 | Creation Date: 19/05/12 139 | Purpose/Change: Added debug mode support 140 | 141 | Version: 1.2 142 | Author: Chris Taylor 143 | Creation Date: 7/17/2015 144 | Purpose/Change: Added directory creation if not present. 145 | Added Append option 146 | 147 | 148 | 149 | .EXAMPLE 150 | Log-Start -LogPath "C:\Windows\Temp" -LogName "Test_Script.log" -ScriptVersion "1.5" 151 | #> 152 | 153 | [CmdletBinding()] 154 | 155 | Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$true)][string]$LogName, [Parameter(Mandatory=$true)][string]$ScriptVersion, [Parameter(Mandatory=$false)][switch]$Append) 156 | 157 | Process{ 158 | $FullLogPath = $LogPath + "\" + $LogName 159 | #Check if file exists and delete if it does 160 | If((Test-Path -Path $FullLogPath) -and $Append -ne $true){ 161 | Remove-Item -Path $FullLogPath -Force 162 | } 163 | 164 | #Check if folder exists if not create 165 | If((Test-Path -PathType Container -Path $LogPath) -eq $False){ 166 | New-Item -ItemType Directory -Force -Path $LogPath 167 | } 168 | 169 | #Create file and start logging 170 | If($(Test-Path -Path $FullLogPath) -ne $true) { 171 | New-Item -Path $LogPath -Name $LogName -ItemType File 172 | } 173 | 174 | Add-Content -Path $FullLogPath -Value "***************************************************************************************************" 175 | Add-Content -Path $FullLogPath -Value "Started processing at [$([DateTime]::Now)]." 176 | Add-Content -Path $FullLogPath -Value "***************************************************************************************************" 177 | Add-Content -Path $FullLogPath -Value "" 178 | Add-Content -Path $FullLogPath -Value "Running script version [$ScriptVersion]." 179 | Add-Content -Path $FullLogPath -Value "" 180 | Add-Content -Path $FullLogPath -Value "***************************************************************************************************" 181 | Add-Content -Path $FullLogPath -Value "" 182 | 183 | #Write to screen for debug mode 184 | Write-Debug "***************************************************************************************************" 185 | Write-Debug "Started processing at [$([DateTime]::Now)]." 186 | Write-Debug "***************************************************************************************************" 187 | Write-Debug "" 188 | Write-Debug "Running script version [$ScriptVersion]." 189 | Write-Debug "" 190 | Write-Debug "***************************************************************************************************" 191 | Write-Debug "" 192 | } 193 | } 194 | 195 | Function Log-Write{ 196 | <# 197 | .SYNOPSIS 198 | Writes to a log file 199 | 200 | .DESCRIPTION 201 | Appends a new line to the end of the specified log file 202 | 203 | .PARAMETER LogPath 204 | Mandatory. Full path of the log file you want to write to. Example: C:\Windows\Temp\Test_Script.log 205 | 206 | .PARAMETER LineValue 207 | Mandatory. The string that you want to write to the log 208 | 209 | .INPUTS 210 | Parameters above 211 | 212 | .OUTPUTS 213 | None 214 | 215 | .NOTES 216 | Version: 1.0 217 | Author: Luca Sturlese 218 | Creation Date: 10/05/12 219 | Purpose/Change: Initial function development 220 | 221 | Version: 1.1 222 | Author: Luca Sturlese 223 | Creation Date: 19/05/12 224 | Purpose/Change: Added debug mode support 225 | 226 | .EXAMPLE 227 | Log-Write -FullLogPath "C:\Windows\Temp\Test_Script.log" -LineValue "This is a new line which I am appending to the end of the log file." 228 | #> 229 | 230 | [CmdletBinding()] 231 | 232 | Param ([Parameter(Mandatory=$true)][string]$FullLogPath, [Parameter(Mandatory=$true)][string]$LineValue) 233 | 234 | Process{ 235 | Add-Content -Path $FullLogPath -Value $LineValue 236 | 237 | Write-Output $LineValue 238 | 239 | #Write to screen for debug mode 240 | Write-Debug $LineValue 241 | } 242 | } 243 | 244 | Function Log-Error{ 245 | <# 246 | .SYNOPSIS 247 | Writes an error to a log file 248 | 249 | .DESCRIPTION 250 | Writes the passed error to a new line at the end of the specified log file 251 | 252 | .PARAMETER FullLogPath 253 | Mandatory. Full path of the log file you want to write to. Example: C:\Windows\Temp\Test_Script.log 254 | 255 | .PARAMETER ErrorDesc 256 | Mandatory. The description of the error you want to pass (use $_.Exception) 257 | 258 | .PARAMETER ExitGracefully 259 | Mandatory. Boolean. If set to True, runs Log-Finish and then exits script 260 | 261 | .INPUTS 262 | Parameters above 263 | 264 | .OUTPUTS 265 | None 266 | 267 | .NOTES 268 | Version: 1.0 269 | Author: Luca Sturlese 270 | Creation Date: 10/05/12 271 | Purpose/Change: Initial function development 272 | 273 | Version: 1.1 274 | Author: Luca Sturlese 275 | Creation Date: 19/05/12 276 | Purpose/Change: Added debug mode support. Added -ExitGracefully parameter functionality 277 | 278 | .EXAMPLE 279 | Log-Error -FullLogPath "C:\Windows\Temp\Test_Script.log" -ErrorDesc $_.Exception -ExitGracefully $True 280 | #> 281 | 282 | [CmdletBinding()] 283 | 284 | Param ([Parameter(Mandatory=$true)][string]$FullLogPath, [Parameter(Mandatory=$true)][string]$ErrorDesc, [Parameter(Mandatory=$true)][boolean]$ExitGracefully) 285 | 286 | Process{ 287 | Add-Content -Path $FullLogPath -Value "Error: An error has occurred [$ErrorDesc]." 288 | 289 | Write-Error $ErrorDesc 290 | 291 | #Write to screen for debug mode 292 | Write-Debug "Error: An error has occurred [$ErrorDesc]." 293 | 294 | #If $ExitGracefully = True then run Log-Finish and exit script 295 | If ($ExitGracefully -eq $True){ 296 | Log-Finish -FullLogPath $FullLogPath -Limit 50000 297 | Breaåk 298 | } 299 | } 300 | } 301 | 302 | Function Log-Finish{ 303 | <# 304 | .SYNOPSIS 305 | Write closing logging data & exit 306 | 307 | .DESCRIPTION 308 | Writes finishing logging data to specified log and then exits the calling script 309 | 310 | .PARAMETER LogPath 311 | Mandatory. Full path of the log file you want to write finishing data to. Example: C:\Windows\Temp\Test_Script.log 312 | 313 | .PARAMETER NoExit 314 | Optional. If this is set to True, then the function will not exit the calling script, so that further execution can occur 315 | 316 | .PARAMETER Limit 317 | Optional. Sets the max linecount of the script. 318 | 319 | .INPUTS 320 | Parameters above 321 | 322 | .OUTPUTS 323 | None 324 | 325 | .NOTES 326 | Version: 1.0 327 | Author: Luca Sturlese 328 | Creation Date: 10/05/12 329 | Purpose/Change: Initial function development 330 | 331 | Version: 1.1 332 | Author: Luca Sturlese 333 | Creation Date: 19/05/12 334 | Purpose/Change: Added debug mode support 335 | 336 | Version: 1.2 337 | Author: Luca Sturlese 338 | Creation Date: 01/08/12 339 | Purpose/Change: Added option to not exit calling script if required (via optional parameter) 340 | 341 | Version: 1.3 342 | Author: Chris Taylor 343 | Creation Date: 7/17/2015 344 | Purpose/Change: Added log line count limit. 345 | 346 | .EXAMPLE 347 | Log-Finish -FullLogPath "C:\Windows\Temp\Test_Script.log" 348 | 349 | .EXAMPLE 350 | Log-Finish -FullLogPath "C:\Windows\Temp\Test_Script.log" -NoExit $True 351 | #> 352 | 353 | [CmdletBinding()] 354 | 355 | Param ([Parameter(Mandatory=$true)][string]$FullLogPath, [Parameter(Mandatory=$false)][string]$NoExit, [Parameter(Mandatory=$false)][int]$Limit ) 356 | 357 | Process{ 358 | Add-Content -Path $FullLogPath -Value "" 359 | Add-Content -Path $FullLogPath -Value "***************************************************************************************************" 360 | Add-Content -Path $FullLogPath -Value "Finished processing at [$([DateTime]::Now)]." 361 | Add-Content -Path $FullLogPath -Value "***************************************************************************************************" 362 | 363 | #Write to screen for debug mode 364 | Write-Debug "" 365 | Write-Debug "***************************************************************************************************" 366 | Write-Debug "Finished processing at [$([DateTime]::Now)]." 367 | Write-Debug "***************************************************************************************************" 368 | 369 | if ($Limit){ 370 | #Limit Log file to XX lines 371 | (Get-Content $FullLogPath -tail $Limit -readcount 0) | Set-Content $FullLogPath -Force -Encoding Unicode 372 | } 373 | #Exit calling script if NoExit has not been specified or is set to False 374 | If(!($NoExit) -or ($NoExit -eq $False)){ 375 | Exit 376 | } 377 | } 378 | } 379 | 380 | Function Get-LTData { 381 | <# 382 | .SYNOPSIS 383 | Executes a MySQL query aginst the LabTech Databse. 384 | 385 | .DESCRIPTION 386 | This comandlet will execute a MySQL query aginst the LabTech database. 387 | Requires the MySQL .NET connector. 388 | Original script by Dan Rose 389 | 390 | .LINK 391 | https://dev.mysql.com/downloads/connector/net/6.9.html 392 | https://www.cogmotive.com/blog/powershell/querying-mysql-from-powershell 393 | http://www.labtechconsulting.com 394 | 395 | .PARAMETER Query 396 | Input your MySQL query in double quotes. 397 | 398 | .INPUTS 399 | Pipeline 400 | 401 | .NOTES 402 | Version: 1.0 403 | Author: Chris Taylor 404 | Website: www.labtechconsulting.com 405 | Creation Date: 9/11/2015 406 | Purpose/Change: Initial script development 407 | 408 | .EXAMPLE 409 | Get-LTData "SELECT ScriptID FROM lt_scripts" 410 | $Query | Get-LTData 411 | #> 412 | 413 | Param( 414 | [Parameter( 415 | Mandatory = $true, 416 | ValueFromPipeline = $true)] 417 | [string]$Query 418 | ) 419 | 420 | Begin { 421 | $ConnectionString = "server=" + $MySQLHost + ";port=3306;uid=" + $MySQLAdminUserName + ";pwd=" + $MySQLAdminPassword + ";database="+$MySQLDatabase 422 | } 423 | 424 | Process { 425 | Try { 426 | [void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data") 427 | $Connection = New-Object MySql.Data.MySqlClient.MySqlConnection 428 | $Connection.ConnectionString = $ConnectionString 429 | $Connection.Open() 430 | 431 | $Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection) 432 | $DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command) 433 | $DataSet = New-Object System.Data.DataSet 434 | $RecordCount = $dataAdapter.Fill($dataSet, "data") 435 | $DataSet.Tables[0] 436 | } 437 | 438 | Catch { 439 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to run query : $query" -ExitGracefully $False 440 | } 441 | } 442 | 443 | End { 444 | $Connection.Close() 445 | } 446 | } 447 | 448 | Function Export-LTScript { 449 | <# 450 | .SYNOPSIS 451 | Exports a LabTech script as an xml file. 452 | 453 | .DESCRIPTION 454 | This commandlet will execute a MySQL query aginst the LabTech database. 455 | Requires Get-LTData 456 | 457 | .LINK 458 | http://www.labtechconsulting.com 459 | 460 | .PARAMETER Query 461 | Input your MySQL query in double quotes. 462 | 463 | .PARAMETER FilePath 464 | File path of exported script. 465 | 466 | .NOTES 467 | Version: 1.0 468 | Author: Chris Taylor 469 | Website: www.labtechconsulting.com 470 | Creation Date: 9/11/2015 471 | Purpose/Change: Initial script development 472 | 473 | .EXAMPLE 474 | Get-LTData "SELECT ScriptID FROM lt_scripts" -FilePath C:\Windows\Temp 475 | #> 476 | 477 | [CmdletBinding()] 478 | Param( 479 | [Parameter(Mandatory=$True,Position=1)] 480 | [string]$ScriptID 481 | ) 482 | 483 | #LabTech XML template 484 | $ExportTemplate = [xml] @" 485 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 |
509 |
510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 |
518 |
519 |
520 |
521 |
522 | "@ 523 | 524 | #Query MySQL for script data. 525 | $ScriptXML = Get-LTData -query "SELECT * FROM lt_scripts WHERE ScriptID=$ScriptID" 526 | $ScriptData = Get-LTData -query "SELECT CONVERT(ScriptData USING utf8) AS Data FROM lt_scripts WHERE ScriptID=$ScriptID" 527 | $ScriptLicense = Get-LTData -query "SELECT CONVERT(LicenseData USING utf8) AS License FROM lt_scripts WHERE ScriptID=$ScriptID" 528 | 529 | #Save script data to the template. 530 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptId = "$($ScriptXML.ScriptId)" 531 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.FolderId = "$($ScriptXML.FolderId)" 532 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptName = "$($ScriptXML.ScriptName)" 533 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptNotes = "$($ScriptXML.ScriptNotes)" 534 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.Permission = "$($ScriptXML.Permission)" 535 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.EditPermission = "$($ScriptXML.EditPermission)" 536 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ComputerScript = "$($ScriptXML.ComputerScript)" 537 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.LocationScript = "$($ScriptXML.LocationScript)" 538 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.MaintenanceScript = "$($ScriptXML.MaintenanceScript)" 539 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.FunctionScript = "$($ScriptXML.FunctionScript)" 540 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.LicenseData = "$($ScriptLicense.License)" 541 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptData = "$($ScriptData.Data)" 542 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptVersion = "$($ScriptXML.ScriptVersion)" 543 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptGuid = "$($ScriptXML.ScriptGuid)" 544 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.ScriptFlags = "$($ScriptXML.ScriptFlags)" 545 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.Parameters = "$($ScriptXML.Parameters)" 546 | 547 | #Format Script Name 548 | #Remove special characters 549 | $FileName = $($ScriptXML.ScriptName).Replace('*','') 550 | $FileName = $FileName.Replace('/','-') 551 | $FileName = $FileName.Replace('<','') 552 | $FileName = $FileName.Replace('>','') 553 | $FileName = $FileName.Replace(':','') 554 | $FileName = $FileName.Replace('"','') 555 | $FileName = $FileName.Replace('\','-') 556 | $FileName = $FileName.Replace('|','') 557 | $FileName = $FileName.Replace('?','') 558 | #Add last modification date 559 | $FileName = $($FileName) + '--' + $($ScriptXML.Last_Date.ToString("yyyy-MM-dd--HH-mm-ss")) 560 | #Add last user to modify 561 | $FileName = $($FileName) + '--' + $($ScriptXML.Last_User.Substring(0, $ScriptXML.Last_User.IndexOf('@'))) 562 | 563 | 564 | #Check folder information 565 | 566 | #Check if script is at root and not in a folder 567 | If ($($ScriptXML.FolderId) -eq 0 -or !$($ScriptXML.FolderId)) { 568 | try { 569 | #Delete folder information from template 570 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.RemoveAll() 571 | } 572 | Catch { 573 | $ErrorMessage = $_.Exception.Message 574 | $FailedItem = $_.Exception.ItemName 575 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to remove folder data from XML: $FailedItem, $ErrorMessage" -ExitGracefully $True 576 | } 577 | } 578 | Else { 579 | #Query MySQL for folder data. 580 | $FolderData = Get-LTData -query "SELECT * FROM `scriptfolders` WHERE FolderID=$($ScriptXML.FolderId)" 581 | 582 | #Check if folder is no longer present. 583 | if ($FolderData -eq $null) { 584 | Log-Write -FullLogPath $FullLogPath -LineValue "ScritID $($ScriptXML.ScriptId) references folder $($ScriptXML.FolderId), this folder is no longer present. Setting to root folder." 585 | Log-Write -FullLogPath $FullLogPath -LineValue "It is recomended that you move this script to a folder." 586 | 587 | #Set to FolderID 0 588 | $ExportTemplate.LabTech_Expansion.PackedScript.NewDataSet.Table.FolderId = "0" 589 | $ScriptXML.FolderID = 0 590 | 591 | try { 592 | #Delete folder information from template 593 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.RemoveAll() 594 | } 595 | Catch { 596 | $ErrorMessage = $_.Exception.Message 597 | $FailedItem = $_.Exception.ItemName 598 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to remove folder data from XML: $FailedItem, $ErrorMessage" -ExitGracefully $True 599 | } 600 | } 601 | Else { 602 | #Format the folder name. 603 | #Remove special characters 604 | $FolderName = $($FolderData.Name).Replace('*','') 605 | $FolderName = $FolderName.Replace('/','-') 606 | $FolderName = $FolderName.Replace('<','') 607 | $FolderName = $FolderName.Replace('>','') 608 | $FolderName = $FolderName.Replace(':','') 609 | $FolderName = $FolderName.Replace('"','') 610 | $FolderName = $FolderName.Replace('\','-') 611 | $FolderName = $FolderName.Replace('|','') 612 | $FolderName = $FolderName.Replace('?','') 613 | 614 | # Save folder data to the template. 615 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.NewDataSet.Table.FolderID = "$($FolderData.FolderID)" 616 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.NewDataSet.Table.ParentID = "$($FolderData.ParentID)" 617 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.NewDataSet.Table.Name = "$FolderName" 618 | $ExportTemplate.LabTech_Expansion.PackedScript.ScriptFolder.NewDataSet.Table.GUID = "$($FolderData.GUID)" 619 | } 620 | } 621 | 622 | #Create Folder Structure. Check for parent folder 623 | If ($($FolderData.ParentId) -eq 0 -or !$($FolderData.ParentId)) { 624 | try { 625 | #Create folder 626 | New-Item -ItemType Directory -Force -Path $BackupRoot\$($FolderData.Name) | Out-Null 627 | 628 | #Save XML 629 | $ExportTemplate.Save("$BackupRoot\$FolderName\$($FileName).xml") 630 | } 631 | Catch { 632 | $ErrorMessage = $_.Exception.Message 633 | $FailedItem = $_.Exception.ItemName 634 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to save script: $FailedItem, $ErrorMessage" -ExitGracefully $True 635 | } 636 | } 637 | Else { 638 | #Query info for parent folder 639 | $ParentFolderName = $(Get-LTData "SELECT * FROM scriptfolders WHERE FolderID=$($FolderData.ParentID)").Name 640 | 641 | #Format parent folder name 642 | #Remove special characters 643 | $ParentFolderName = $ParentFolderName.Replace('*','') 644 | $ParentFolderName = $ParentFolderName.Replace('/','-') 645 | $ParentFolderName = $ParentFolderName.Replace('<','') 646 | $ParentFolderName = $ParentFolderName.Replace('>','') 647 | $ParentFolderName = $ParentFolderName.Replace(':','') 648 | $ParentFolderName = $ParentFolderName.Replace('"','') 649 | $ParentFolderName = $ParentFolderName.Replace('\','-') 650 | $ParentFolderName = $ParentFolderName.Replace('|','') 651 | $ParentFolderName = $ParentFolderName.Replace('?','') 652 | 653 | $FilePath = "$BackupRoot\$($ParentFolderName)\$($($FolderData.Name))" 654 | 655 | try { 656 | #Create folder 657 | New-Item -ItemType Directory -Force -Path $FilePath | Out-Null 658 | 659 | #Save XML 660 | $ExportTemplate.Save("$FilePath\$($FileName).xml") 661 | } 662 | Catch { 663 | $ErrorMessage = $_.Exception.Message 664 | $FailedItem = $_.Exception.ItemName 665 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to save script: $FailedItem, $ErrorMessage" -ExitGracefully $True 666 | } 667 | } 668 | 669 | } 670 | 671 | #endregion 672 | 673 | #region-[Execution]------------------------------------------------------------ 674 | try { 675 | #Create log 676 | Log-Start -LogPath $LogPath -LogName $LogName -ScriptVersion $ScriptVersion -Append 677 | 678 | #Check backup directory 679 | if ((Test-Path $BackupRoot) -eq $false){New-Item -ItemType Directory -Force -Path $BackupRoot | Out-Null} 680 | } 681 | Catch { 682 | $ErrorMessage = $_.Exception.Message 683 | $FailedItem = $_.Exception.ItemName 684 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Error durring log/backup directory creation: $FailedItem, $ErrorMessage" -ExitGracefully $True 685 | } 686 | 687 | Log-Write -FullLogPath $FullLogPath -LineValue "Getting list of all scripts." 688 | 689 | $ScriptIDs = @{} 690 | #Query list of all ScriptID's 691 | if ($($Config.Settings.LastExport) -eq 0) { 692 | $ScriptIDs = Get-LTData "SELECT ScriptID FROM lt_scripts" 693 | } 694 | else{ 695 | $Query = $("SELECT ScriptID FROM lt_scripts WHERE Last_Date > " + "'" + $($Config.Settings.LastExport) +"'") 696 | $ScriptIDs = Get-LTData $Query 697 | } 698 | 699 | Log-Write -FullLogPath $FullLogPath -LineValue "$(@($ScriptIDs).count) scripts to process." 700 | 701 | #Process each ScriptID 702 | $n = 0 703 | foreach ($ScriptID in $ScriptIDs) { 704 | #Progress bar 705 | $n++ 706 | Write-Progress -Activity "Backing up LT scripts to $BackupRoot" -Status "Processing ScriptID $($ScriptID.ScriptID)" -PercentComplete ($n / @($ScriptIDs).count*100) 707 | 708 | #Export current script 709 | Export-LTScript -ScriptID $($ScriptID.ScriptID) 710 | } 711 | 712 | Log-Write -FullLogPath $FullLogPath -LineValue "Export finished." 713 | 714 | try { 715 | $Config.Settings.LastExport = "$($Date.ToString("yyy-MM-dd HH:mm:ss"))" 716 | $Config.Save("$PSScriptRoot\LT-ScriptExport-Config.xml") 717 | } 718 | Catch { 719 | $ErrorMessage = $_.Exception.Message 720 | $FailedItem = $_.Exception.ItemName 721 | Log-Error -FullLogPath $FullLogPath -ErrorDesc "Unable to update config with last export date: $FailedItem, $ErrorMessage" -ExitGracefully $True 722 | } 723 | 724 | Log-Finish -FullLogPath $FullLogPath -Limit 50000 725 | 726 | #endregion 727 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LabTech--Script-Backup 2 | This script will backup each LabTech script as an xml file. The script will also create the same folder structure as in LT. These exports will not include files from the transfer directory or any other scripts that are called. 3 | The last date and user modified will be appended to the script so that it can be used as version control. 4 | 5 | The MySQL .NET connector is required. 6 | https://dev.mysql.com/downloads/connector/net/6.9.html 7 | 8 | For more information please go to: 9 | 10 | http://labtechconsulting.com/labtech-script-backup-and-version-control/ 11 | 12 | --------------------------------------------------------------------------------