This still doesn't fully satisfy my needs and it's incomplete, there are valuable info in the comments section down below, if you have better answer please post them.
So far only found a way to disable the TLS versions in browser, but still not system wide, I still see connections being made over insecure TLS v1 and TLS v1.1 from time to time in Wireshark with no way to block them, mostly initiated by programs I installed.
For Microsoft Edge, TLS v1 and TLS v1.1 are already disabled by default, in order to disable TLS v1.2, run this in an elevated PowerShell:
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '1'
$Value = '0xC02B'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '2'
$Value = '0xC02F'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '3'
$Value = '0xC02C'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '4'
$Value = '0xC030'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '5'
$Value = '0xCCA9'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '6'
$Value = '0xCCA8'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '7'
$Value = '0x009E'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge\TLSCipherSuiteDenyList\'
$Name = '8'
$Value = '0x009F'
If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null }
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType string -Force
Used these 2 resources:
https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#tlsciphersuitedenylist
https://wiki.mozilla.org/Security/Server_Side_TLS
Still looking for a way to do the same for the entire OS.
UPDATE: in Windows, disabled all cipher suits and only kept those that belong to TLS v1.3
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
disable-TlsCipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
disable-TlsCipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
disable-TlsCipherSuite TLS_RSA_WITH_NULL_SHA256
disable-TlsCipherSuite TLS_RSA_WITH_NULL_SHA
disable-TlsCipherSuite TLS_PSK_WITH_AES_256_GCM_SHA384
disable-TlsCipherSuite TLS_PSK_WITH_AES_128_GCM_SHA256
disable-TlsCipherSuite TLS_PSK_WITH_AES_256_CBC_SHA384
disable-TlsCipherSuite TLS_PSK_WITH_AES_128_CBC_SHA256
disable-TlsCipherSuite TLS_PSK_WITH_NULL_SHA384
disable-TlsCipherSuite TLS_PSK_WITH_NULL_SHA256
disable-TlsCipherSuite TLS_RSA_WITH_AES_128_CBC_SHA256
disable-TlsCipherSuite TLS_RSA_WITH_AES_256_CBC_SHA256
disable-TlsCipherSuite TLS_RSA_WITH_AES_128_GCM_SHA256
disable-TlsCipherSuite TLS_RSA_WITH_AES_256_GCM_SHA384
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
disable-TlsCipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
disable-TlsCipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
disable-TlsCipherSuite TLS_AES_128_GCM_SHA256
disable-TlsCipherSuite TLS_AES_256_GCM_SHA384
Enable-TlsCipherSuite TLS_AES_128_GCM_SHA256
Enable-TlsCipherSuite TLS_AES_256_GCM_SHA384
# Added in Windows 11 https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-11
Enable-TlsCipherSuite TLS_CHACHA20_POLY1305_SHA256
This caused some websites that supported both TLS 1.3 and 1.2 use 1.3 instead, prior to this change they kept using 1.2.
in Wireshark though, this didn't stop TLS 1.1 and 1.2 from showing up, but their cipher suits are being enforced correctly, which is weird for me because I thought cipher suits used by TLS v1.3 can't be used by older TLS versions.