public/Add-SfCountryPicklistValue.ps1

function Add-SfCountryPicklistValue {

    <#
        .SYNOPSIS
        Adds a new country picklist entry via direct web access to the Salesforce Classic Setup UI.

        .DESCRIPTION
        The given CountryCode must not exist. The command adds the entry with country ISO code, picklist label (i.e. the country name) and the integration value.
        Active flag and visible flag are intentionally left unchecked:
        These settings are handled by Build-SfAddressSettingsMetadata and a subsequent 'sf project deploy start'.

        .LINK
        https://codeberg.org/uwe-braig/sf-metadata-toolkit
    #>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory, Position = 0)]
        [PSCustomObject] $WebSession,

        # Country ISO code of the country entry to be created.
        [Parameter(Mandatory, Position = 1)]
        [string] $CountryCode,

        # Picklist label (i.e. country name) to be set.
        [Parameter(Mandatory)]
        [string] $Label,

        # Integration value to be set.
        [Parameter(Mandatory)]
        [string] $IntegrationValue

    )

    $ScriptName = 'Add-SfCountryPicklistValue'
    $ErrorActionPreference = 'Stop'
    [bool] $IsDebug   = $DebugPreference   -ne 'SilentlyContinue'
    [bool] $IsVerbose = $VerbosePreference -ne 'SilentlyContinue'

    # --- get the form from the Salesforce Classic Setup UI
    $SetupUiUrl = $WebSession.InstanceUrl + '/i18n/ConfigureNewCountry.apexp'
    $HttpGetResult = Invoke-WebRequest -Method Get -WebSession $WebSession.WebSession -Uri $SetupUiUrl
    if ($HttpGetResult.StatusCode -eq 200) {
        Write-Verbose "$ScriptName|HTTP GET|StatusCode=$($HttpGetResult.StatusCode)|StatusDescription=$($HttpGetResult.StatusDescription)"
    } else {
        throw "$ScriptName|HTTP Get Error|StatusCode=$($HttpGetResult.StatusCode)|StatusDescription=$($HttpGetResult.StatusDescription)"
    }

    # --- prepare body and copy Visualforce view state
    $PostBody = @{}

    $ViewStateInputFields =
        $HttpGetResult.InputFields  |
        Select-Object Id, Name, Type, Value |
        Where-Object { $_.Id  -like 'com.salesforce.visualforce.ViewState*' }

    foreach ($item in $ViewStateInputFields) {
        $PostBody.Add($item.Id, $item.Value)
    }

    Write-Debug "$ScriptName|View State Input Fiels|BEGIN"
    Write-Debug ($ViewStateInputFields | Format-Table | Out-String)
    Write-Debug "$ScriptName|View State Input Fiels|END"

    # --- prepare payload form fields
    $PayloadInputFields =
        $HttpGetResult.InputFields  |
        Select-Object Id, Name, Type, Disabled, Checked, Value |
        Where-Object { $_.Id  -like 'configurenew*' }

    foreach ($item in $PayloadInputFields) {
        switch -Wildcard ($item.Id) {
            '*editName'     { $NameField = $item }
            '*editIsoCode'  { $IsoCodeField = $item }
            '*editIntVal'   { $IntegrationValueField = $item }
            '*editActive'   { $ActiveField = $item }
            '*editVisible'  { $VisibleField = $item }
            '*addButton'    { $AddButton = $item }
        }
    }
    # ---- now add our actual payload data
    $PostBody.Add('configurenew:j_id1', 'configurenew:j_id1')
    $PostBody.Add($AddButton.Id,                $AddButton.Value)
    $PostBody.Add($IsoCodeField.Id,             $CountryCode)
    $PostBody.Add($NameField.Id,                $Label)
    $PostBody.Add($IntegrationValueField.Id,    $IntegrationValue)
    $PostBody.Add($ActiveField.Id, 'false')
    $PostBody.Add($VisibleField.Id, 'false')

    Write-Debug "$ScriptName|Post Form|BEGIN"
    Write-Debug ($PostBody.GetEnumerator() | Sort-Object -Property Name | Format-Table | Out-String)
    Write-Debug "$ScriptName|Post Form|END"

    # ---- now post it
    $HttpPostResult = Invoke-WebRequest -Method Post -WebSession $WebSession.WebSession -Uri $SetupUiUrl -Body $PostBody
    if ($HttpPostResult.StatusCode -eq 200) {
        if ($HttpPostResult.Content.Contains('<h4>Errors</h4>')) {
            throw "$ScriptName|HTTP POST OK BUT WITH ERRORS|Content=$($HttpPostResult.Content)"
        } else {
            Write-Verbose "$ScriptName|HTTP POST OK|StatusCode=$($HttpPostResult.StatusCode)|StatusDescription=$($HttpPostResult.StatusDescription)"
        }
    } else {
        throw "$ScriptName|HTTP POST NOT OK|StatusCode=$($HttpPostResult.StatusCode)|StatusDescription=$($HttpPostResult.StatusDescription)"
    }
}