Search code examples
tfsazure-devops-server-2019unattend-file

What are the available parameters/inputs for configuring unattended setup for TFS?


When I create an INI file for Azure DevOps Server 2022 using

tfsconfig unattend /create /type:NewServerAdvanced /unattendfile:advanced.ini

the only setting in the created ini-file available for Search is

ConfigureSearchService=False

Other components is thoroughly documented in the generated ini-file. But Search has no other options.

When changing the option to True, I was greeted with errors that provided me with additional parameters that I needed.

ElasticsearchUser
ElasticsearchPassword

But the configuration still fails with

[Error] [Search Configuration] Cannot create the folder for the Search index store. Check
that the installation wizard has the appropriate permissions to access the folder you
specified, or create and specify a new folder for the index store.

MS has no further help on their site MS Learn - Azure DevOps - Perform an unattended installation

After searching for a while i found references to https://devblogs.microsoft.com/tfsao, but that blog area has since long been deleted by MS. It's not even been archived by the Wayback Machine.

How do I configure Search using the unattend file?


Solution

  • Ok, the answer seems to be guessing the parameters to use based on the error messages received on the console and in the unattend log file...

    So far I've found the following additional parameters...

    ServiceAccountPassword
    SmtpFromAddress
    SmtpServer
    IndexLocation
    ElasticsearchUser
    ElasticsearchPassword
    

    I actually found IndexLocation in a question at MS Developer Community...
    I'm still missing the parameter to disable 'SMTP Authentication' and how to set the 'Search Service Account'.

    A somewhat clean, quite and unattended setup might look like this using PowerShell...

    Preparing the DB after a SQL Server setup:

    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
    
    $SqlConnection.ConnectionString = 
      "Server=DBSrv,1433;" +
      "Database=master;" +
      "Trusted_Connection=True;"
    
    $Command = New-Object System.Data.SqlClient.SqlCommand
    $Command.CommandType = 1
    $Command.Connection = $SqlConnection
    $SqlConnection.Open()
    
    $Command.CommandText = "create login [domain\azdos_service] from windows with " + 
      "default_database=[master], default_language=[us_english]"
    $Command.ExecuteNonQuery()
    
    $Command.CommandText = "create login [domain\azdos_setupaccount] from windows with " +
      "default_database=[master], default_language=[us_english]"
    $Command.ExecuteNonQuery()
    
    $Command.CommandText = "exec master..sp_addsrvrolemember " +
      "@loginame = N'domain\azdos_service', @rolename = N'sysadmin'"
    $Command.ExecuteNonQuery()
    
    $Command.CommandText = "exec master..sp_addsrvrolemember " +
      "@loginame = N'domain\azdos_setupaccount', @rolename = N'sysadmin'"
    $Command.ExecuteNonQuery()
    

    On the DevOps Server (after downoading the media of course):

    Start-Process d:\AzureDevOps2022.0.1.exe -Args '/Silent' -Wait
    
    Start-Process msiexec -ArgumentList "/i C:\Users\public\downloads\zulu8.72.0.17-ca-jre8.0.382-win_x64.msi ADDLOCAL=FeatureJavaHome /qn" -Wait
    
    cd 'C:\Program Files\Azure DevOps Server 2022\Tools\'
    
    .\TfsConfig.exe unattend /create /type:NewServerAdvanced /unattendfile:advanced.ini
    
    $inputs = @(
      "SendFeedback=False"
      "SqlInstance=DBSrv,1433"
      "IsServiceAccountBuiltIn=False"
      "ServiceAccountName=domain\azdos_service"
      "ServiceAccountPassword=Password!"
      "SiteBindings=https:*:443:devops:My:generate"
      "PublicUrl=https://devops/"
      "FileCacheFolder=C:\AzureDevOpsData\ApplicationTier\_fileCache"
      "SmtpEmailEnabled=True"
      "[email protected]"
      "SmtpServer=mysmtpgateway"
      "EnableSshService=False"
      "ConfigureSearch=True"
      "IndexLocation=C:\AzureDevOpsData\Search\IndexStore"
      "ElasticsearchUser=Search1234"
      "ElasticsearchPassword=search1234!"
      "CollectionName=DevOps"
    )
    
    ($inputs | where {$_ -like '*password*'}) | Out-File -Append .\advanced.ini -Encoding utf8
    $inputs = ($inputs | where {$_ -notlike '*password*'}) -join ';'
    
    .\TfsConfig.exe unattend /configure /unattendfile:advanced.ini /continue /inputs:$inputs
    

    Please ignore the bad handling of passwords in this example.