By default, Sitecore 9 ships with the customErrors mode set to RemoteOnly. I’m not complaining.  But if you’re using SIF to configure a QA server, you may want to change that.   In a push to have infrastructure as code, the module below actually does this for you.  Here’s the modlue:

Set-StrictMode -Version 2.0

Function Invoke-SetCustomErrorsModeTask {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)]
        [string]$SiteFolder,
        [ValidateSet('On', 'Off', 'RemoteOnly', IgnoreCase = $false)]
        [Parameter(Mandatory = $true)]
        [string]$ErrorMode
    )

    Write-TaskInfo "Locating web.config in folder $SiteFolder" -Tag 'UpdateMode'

    #Get the path of the web.config
    $WebConfigPath = Join-Path $SiteFolder "web.config"
	
    $WebConfigXML = New-Object XML

    $WebConfigXML.Load($WebConfigPath)
	
    $CustomErrorsNode = $WebConfigXML.SelectSingleNode("/configuration/system.web/customErrors")
	
	$CustomErrorsNode.SetAttribute("mode", $ErrorMode)
	
	$WebConfigXML.Save($WebConfigPath)	
}
Register-SitecoreInstallExtension -Command Invoke-SetCustomErrorsModeTask -As SetCustomErrorsMode -Type Task

Nothing really fancy here.  Just open up the web.config file, navigate to the customErrors node and set the value.  Special note to line 8 above.  This enforces valid (case-sensitive!) values for the element.  Allowing other values is not a good thing.

You can invoke this module using a SIF config like the one below:

// -------------------------------------------------------------------------- //
//         Sitecore Install Framework - Sitecore Custom Errors Mode           //
//                                                                            //
//  Run this configuration to set the customErrors mode on a site             //
//                                                                            //
//  NOTE: Only single line comments are accepted in configurations.           //
// -------------------------------------------------------------------------- //
{
    "Parameters": {
        "SiteFolder": {
            "Type": "string",
            "Description": "The name of the site to be deployed."
        },
        "ErrorMode": {
            "Type": "string",
            "DefaultValue": "RemoteOnly",
            "Description": "The file path to the Solr instance."
        }
    },
    "Tasks": {
        "SetCustomErrorsMode": {
            "Type": "SetCustomErrorsMode",
            "Params": [
                {
                    "SiteFolder": "[parameter('SiteFolder')]",
                    "ErrorMode": "Off"
                }
            ]
        }
    },
    "Modules": [
        ".\\Invoke-SetCustomErrorsModeTask.psm1"
    ]
}

Nothing mystical about this either.  Just a couple of parameters, one for the mode, one for the folder the site is installed in.  Take that and run it with SIF:

scinst .\set-custom-error-mode.json -SiteFolder "<site path>" -ErrorMode "Off"

You can grab a zip of these two files here.