dsccommunity / SqlServerDsc

This module contains DSC resources for deployment and configuration of Microsoft SQL Server.
MIT License
354 stars 225 forks source link

SqlSetup: Installing Multiple Instances on same computer from same bits #492

Open ghost opened 7 years ago

ghost commented 7 years ago

Is there a way to not have to copy a new set of the SQL bits for each instance of SQL being installed?

The process for installing an instance of SQL involves RoboCopying the SQL bits to a temp directory. I would like to be able to reuse that initial copy of the SQL bits over and over.

Windows OS: Windows Server 2012 R2 SQL Version: SQL 2012 PowerShell Version: 5.0.10514.6 Version of DSC module: 6.0.0.0 and dev

    xSqlServerSetup installSqlServer
    {
        DependsOn=@('[xDisk]Drive1','[xDisk]Drive2')
        InstanceName = $Node.InstanceName
        SourcePath  = $Node.SourcePath
        SourceCredential = $Node.ServeShareCredentials 
        Features = $Node.Features
        SetupCredential = $Node.SetupCredential
        SAPwd = $Node.SACred
        SQLSysAdminAccounts = $Node.AdminAccount
        SecurityMode = "SQL"
        InstanceDir  = $Node.InstanceDriveLetter+":\MSSQL"
        InstallSQLDataDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\MSSQL"
        SQLUserDBDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\Data"
        SQLUserDBLogDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\Data"
        SQLTempDBDir  = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\TempDB"
        SQLTempDBLogDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\TempDB"
        SQLBackupDir = $Node.BackupDriveLetter+":\Backup"
        ASDataDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\OLAP\Data"
        ASLogDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\OLAP\Data"
        ASBackupDir = $Node.DataDriveLetter+":\"+$Node.InstanceName+"\OLAP\Backup"
        ASTempDir = $Node.InstanceDriveLetter+":\"+$Node.InstanceName+"\OLAP\Temp"
        ASConfigDir = $Node.InstanceDriveLetter+":\"+$Node.InstanceName+"\OLAP\Config"
    }
johlju commented 7 years ago

If you leave out SourceCredential then it does not do robocopy

SourceCredential = $Node.ServeShareCredentials

But then you need to use the built-in parameter PsDscRunAsCredential to run the resource as that user ("impersonate") for it to be able to access the share. If you are not using PsDscRunAsCredential the resource will run as SYSTEM. There might be side effects using PsDscRunAsCredential. The resource are not fully working in all scenarios using PsDscRunAsCredential. If you search for PsDscRunAsCredential among the issue you will find the caveats.

Actually my intent was that this Easter (now) I would start look at making that work as it should. But I need to finish up some other stuff before then so might not have the time. :/

johlju commented 7 years ago

I read the question again. Do you install two or more instances of the same major version? It should reuse the same bits in the temp folder. It do verify that each file is up-to-date against the source, but it should only copy to Temp folder once, and then consecutive install just verify same temp destination against source.

Do you mean it copies to different Temp folder each time?

ghost commented 7 years ago

I have a scenario where I am deploying multiple instances of SQLExpress 2012 R2 SP3 to the same server. The instances may not be installed all at the same time either. So there may be a different DSC Script being run for each instance.

I get a different Temp Folder each time for the same exact version of the product being installed. That I have to eventually go in and clean up.

It would be nice to have the process check a path for the install, and copy if not found, use if found. I would expect to have to provide two paths, one for the network image, and one for the local image, and possibly one more parameter to force an overwrite of the local image by the network image.

johlju commented 7 years ago

There is one scenario where it will change folder each time it is run, that is if it cannot find a Leaf on the SourcePath. See here at line 795-799 Is it that you encounter, that it create a new GUID folder each time? If so that can be solved if the SourcePath has a folder it can use "as the leaf".

Regarding an extra path for the destination is surely an idea. We could add a parameter i.e MediaDestinationPath. And there could be a parameter MediaForceOverwrite that will add arguments to robocopy to force overwrite.

ghost commented 7 years ago

I noticed that as well, when I was plowing through the code, and I was hoping that I had missed something someplace else.

So this leaves us with two choices

1) Update the documentation 2) Change the Code

Changing the code is going to look something like this??

$InstallPath= $null If ( $MediaForceOverwrite -eq $false) { If (-Not [string]::IsNullOrEmpty($MediaDestinationPath ) { If (Test-Path $MediaDestinationPath) { if ($MediaDestinationPath contains the necessary bits to install SQL Server) { $InstallPath = $MediaDestinationPath } else { $MediaForceOverwrite = $true }
} else { $MedaiForceOverwrite = $true } } else { $MedaiForceOverwrite = $true } } if ($MedaiForceOverwrite -eq $true) { If (-Not [string]::IsNullOrEmpty($MediaDestinationPath ) {

Use existing process to copy files to the destination path

     $InstallPath  = $MediaDestinationPath 
 }
 else
 {
     #Use existing process to copy files to Windows Temp directory following existing rules
      $InstallPath  = $SourcePath
 }

} $pathToSetupExecutable = Join-Path -Path $InstallPath -ChildPath 'setup.exe'

perform Installation using existing code