From 3670644334097fab0bbcf5a456a028fd1afd781d Mon Sep 17 00:00:00 2001
From: Mocan Cosmin <cmocan@cloudbasesolutions.com>
Date: Tue, 27 Sep 2016 08:21:58 -0400
Subject: [PATCH] Fixed MSSQL template to support 2008, 2014, 2016 versions

It has been tested with standard 2008/2012/2014 and enterprise 2016.
I've added the functions Get-MSSQLVersion that checks for the version,
and Get-MSSQLLogFile that finds the log folder for the MSSQL version used.
The function Get-MSSQLParameters has been updated to filter some install
arguments that are incompatible with versions of MSSQL diffrent from 2012.

Change-Id: I438a74b081fa6dd38d9e39c10b11497032e070cb
---
 hot/Windows/MSSQLServer/MSSQL.psm1            | 55 +++++++++++++++++--
 hot/Windows/MSSQLServer/MSSQL.yaml            |  3 +-
 hot/Windows/MSSQLServer/Tests/MSSQL.Tests.ps1 | 43 ++++++++++++++-
 3 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/hot/Windows/MSSQLServer/MSSQL.psm1 b/hot/Windows/MSSQLServer/MSSQL.psm1
index 9aad00a1..90ad61fd 100755
--- a/hot/Windows/MSSQLServer/MSSQL.psm1
+++ b/hot/Windows/MSSQLServer/MSSQL.psm1
@@ -22,8 +22,6 @@ $fullPath = Join-Path $currentLocation $modulePath
 Import-Module -Name $fullPath -DisableNameChecking -Force
 
 $heatTemplateName = "MSSQL"
-$sqlLogFile = Join-Path ${ENV:ProgramFiles} -ChildPath `
-                 "\Microsoft SQL Server\110\Setup Bootstrap\Log\Summary.txt"
 
 function Log {
     param(
@@ -81,8 +79,13 @@ function Get-MSSQLParameters {
     $parameters += "/IACCEPTSQLSERVERLICENSETERMS=1 "
     $parameters += "/INSTANCENAME=$MssqlInstanceName "
     $parameters += "/FEATURES=$MssqlFeatures "
+    if (($MSSQLVersion -gt 12) -and($MssqlFeatures -split "," -contains "ADV_SSMS")) {
+        Log "MSSQL 2016 is not compatible with ADV_SSMS feature"
+    }
     $parameters += "/SQLSYSADMINACCOUNTS=Admin "
-    $parameters += "/UpdateEnabled=1 "
+    if ($MSSQLVersion -gt 10) {
+        $parameters += "/UpdateEnabled=1 "
+    }
     $parameters += "/AGTSVCSTARTUPTYPE=Automatic "
     $parameters += "/BROWSERSVCSTARTUPTYPE=Automatic "
     $parameters += "/SECURITYMODE=SQL "
@@ -129,6 +132,43 @@ function Add-NetRules {
         -Protocol TCP -LocalPort 100-65000 -Program $sqlServerBinaryPath
 }
 
+function Load-XML {
+    Param (
+        [Parameter(Mandatory =$true)]
+        [string]$XMLFile
+        )
+    $xml=New-Object System.Xml.XmlDataDocument
+    $xml.Load($XMLFile)
+    return $xml
+}
+
+function Get-MSSQlVersion {
+    Param (
+        [Parameter(Mandatory =$true)]
+        [string]$MediaInfoXMLPath
+        )
+    if( -not (Test-Path $MediaInfoXMLPath)) {
+        Log "MediaInfoXMLPath does not exist!"
+    }
+    $xml = Load-XML ($MediaInfoXMLPath)
+    try {
+        return $xml.MediaInfo.Properties.Property[1].Value.ToString().SubString(0,2)
+    } catch {
+        # Note: for MSSQL Server 2008, the value does not exist
+        return 10
+      }
+}
+
+function Get-MSSQLLogFile {
+    Param (
+        [Parameter(Mandatory =$true)]
+        [string]$MSSQLVersion
+        )
+    $sqlLogFile = Join-Path ${ENV:ProgramFiles} -ChildPath `
+                 ("\Microsoft SQL Server\{0}0\Setup Bootstrap\Log\Summary.txt" -f $MSSQLVersion)
+    return $sqlLogFile
+}
+
 function Install-MSSQLInternal {
     param(
         $MssqlServiceUsername,
@@ -150,8 +190,13 @@ function Install-MSSQLInternal {
     $localIsoPath = Copy-FilesLocal $MssqlIsoUNCPath
     Log "MSSQL ISO Mount."
     $iso = Mount-DiskImage -PassThru $localIsoPath
+    Get-PSDrive | Out-Null
+    $driveLetter = (Get-Volume -DiskImage $iso).DriveLetter
+    $MediaInfoXMLPath = $driveLetter + ":\MediaInfo.xml"
+    $MSSQLVersion = Get-MSSQLVersion $MediaInfoXMLPath
+    $isoSetupPath = $driveLetter + ":\setup.exe"
+    $sqlLogFile= Get-MSSQLLogFile $MSSQLVersion
 
-    $isoSetupPath = (Get-Volume -DiskImage $iso).DriveLetter + ":\setup.exe"
     if (Test-Path $sqlLogFile) {
         Remove-Item $sqlLogFile -Force
     }
@@ -176,7 +221,7 @@ function Install-MSSQLInternal {
     Add-NetRules
 
     $successMessage = "Finished MSSQL instalation."
-    Log $successMessage 
+    Log $successMessage
     Send-HeatWaitSignal -Endpoint $MssqlWaitConditionEndpoint `
         -Message $successMessage -Success $true `
         -Token $MssqlWaitConditionToken
diff --git a/hot/Windows/MSSQLServer/MSSQL.yaml b/hot/Windows/MSSQLServer/MSSQL.yaml
index aba38c3b..ff566a9e 100755
--- a/hot/Windows/MSSQLServer/MSSQL.yaml
+++ b/hot/Windows/MSSQLServer/MSSQL.yaml
@@ -50,8 +50,7 @@ parameters:
 
   mssql_features:
     type: string
-    default: >
-      SQLENGINE,ADV_SSMS
+    default: SQLENGINE,ADV_SSMS
     description: >
       The mssql features to be installed
 
diff --git a/hot/Windows/MSSQLServer/Tests/MSSQL.Tests.ps1 b/hot/Windows/MSSQLServer/Tests/MSSQL.Tests.ps1
index 3cefcabe..f699d84b 100755
--- a/hot/Windows/MSSQLServer/Tests/MSSQL.Tests.ps1
+++ b/hot/Windows/MSSQLServer/Tests/MSSQL.Tests.ps1
@@ -53,10 +53,44 @@ InModuleScope $moduleName {
     }
 }
 
+InModuleScope $moduleName {
+    Describe "Test Get MSSQLLogFile" {
+        Context "On Success" {
+            $MSSQLVersion = "13"
+            Mock Join-Path { return $true } -Verifiable
+
+            Get-MSSQLLogFile $MSSQLVersion
+
+            It "should verify caled all mocks" {
+                Assert-VerifiableMocks
+            }
+        }
+    }
+}
+
+InModuleScope $moduleName {
+    Describe "Test Get MSSQLVersion" {
+        Context "On Success" {
+            $MSSQLVersion = "13"
+            Mock Load-XML { return $MSSQLVersion } -Verifiable
+            Mock Log { return $true} -Verifiable
+            $version =Get-MSSQLVersion $MSSQLVersion
+
+            It "should verify caled all mocks" {
+                Assert-VerifiableMocks
+            }
+        }
+    }
+}
+
+
 InModuleScope $moduleName {
     Describe "Test Get MSSQL Error" {
+    $sqlLogFile = Join-Path ${ENV:ProgramFiles} -ChildPath `
+"\Microsoft SQL Server\110\Setup Bootstrap\Log\Summary.txt"
         Context "With errors" {
             $fakeErrors = @("err1")
+
             Mock Select-String { return $fakeErrors } -Verifiable
             Mock Log { return $true } -Verifiable
 
@@ -72,6 +106,7 @@ InModuleScope $moduleName {
         }
         Context "No errors" {
             $fakeErrors = @()
+
             Mock Select-String { return $fakeErrors } -Verifiable
 
             $result = Get-MSSQLError
@@ -137,6 +172,8 @@ InModuleScope $moduleName {
             Mock Copy-FilesLocal { return $true } -Verifiable
             Mock Mount-DiskImage { return $cimInstance } -Verifiable
             Mock Get-Volume { return $true } -Verifiable
+            Mock Get-MSSQLVersion { return $MediaInfoXMLPath } -Verifiable
+            Mock Get-MSSQLLogFile { return $MSSQLVersion } -Verifiable
             Mock Test-Path { return $true } -Verifiable
             Mock Remove-Item { return $true } -Verifiable
             Mock Get-MSSQLParameters { return $true } -Verifiable
@@ -198,8 +235,12 @@ InModuleScope $moduleName {
                         -MssqlWaitConditionToken $MssqlWaitConditionToken
 
             It "should be successful" {
+                $result | Should Be $true
+            }
+
+            It "should verify caled all mocks" {
                 Assert-VerifiableMocks
             }
         }
     }
-}
\ No newline at end of file
+}