If you do multilingual installations and you need to install SQL Server, this post will save you a lot of time.
Recently I was doing some research for a potential project that was installing SQL Server 2008 Express on Windows systems in Europe. What’s interesting about this requirement is that the account names that are passed to SQL Server on the command line are going to be in different languages, depending on the country. This creates a problem. So, let’s look at that.
In InstallShield, you can add the installation of SQL Server 2008 Express to your installation. Remember, in the Redistributables view, it is listed as a prerequisite, and prerequisites come in two different forms. Setup Prerequistes and Feature Prerequisites.
A Setup Prerequisite is not associated with a feature, but is installed by the bootstrapper, Setup.exe, before the main installation takes place. A Feature Prerequisite is associated with a Feature and the user can select or deselect it for installation.
If you view the SQL Server 2008 Express prerequisite in the Prerequisite Editor, and go to the Application to Run tab, you will see the command line that is executed when the prerequisite is run. Here is the command line:
The default command line that InstallShield provides has no account references. We will need to use a different command line. Here is the command line I use to do a basic installation of SQL Server 2008 Express:
/q /ACTION=Install /FEATURES=SQL /INSTANCENAME=SQLEXPRESS /SQLSVCACCOUNT=”NT AUTHORITY\SYSTEM” /SQLSYSADMINACCOUNTS=”BUILTIN\ADMINISTRATORS”
/AGTSVCACCOUNT=”NT AUTHORITY\Network Service”
In the command line, there are three domain/account pairs. Here are the values on an English system:
- SQLSVCACCOUNT is equal to NT AUTHORITY\SYSTEM
- SQLSYSADMINACCOUNTS is equal to BUILTIN\ADMINISTRATORS
- AGTSVCACCOUNT is equal to NT AUTHORITY\Network Service
The domain/account pairs are the problem as they will be different values in different countries. The job is to retrieve the local language-specific domain/account names in each country. To do that, you need to use Security Identifiers or SIDs.
After some investigation, I found the easiest method was to use SID enumerations. Here is an example of the C# code needed to retrieve the account name value for SQLSVCACCOUNT:
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount));
string strSqlSvcAccountName = acct.Value.ToString();
From the sample, you can see that I still use Hungarian notation for some things. I know that with C# programming in .NET, Microsoft has said we are not supposed to use Hungarian notation anymore, because you would generally know what types that variables would be. Well, not if there are hundreds or thousands of variables to remember. Therefore, I never followed that recommendation and still use Hungarian notation, especially in InstallScript code. So sue me.
The key in the code sample is to use the WellKnownSidType.LocalSystemSid value. The alternatives involve more work. There are WellKnowSidTypes for the other two accounts as well.
Now that we have the domain/account pairs, how do we get SQL Server to use them during its installation?
You can’t install SQL as a setup prerequisite or a feature prerequisite, because there is no way to pass the account names to the prerequisite. You can only mimic what InstallShield does when it installs a feature prerequisite.
InstallShield tech support told me they run the feature prerequisite’s installation during the User Interface sequence of the installation. We need to mimic that behavior.
Here would be the general flow of things:
If you are using InstallScript or InstallScript MSI projects, you would need to create some InstallScript functions to do the work. Just call the functions before or after the file transfer has taken place.