Here's a stored procedure that accepts a setting name and returns the setting value for all components that have it. It's not SQL, but can be executed from SQL :)

You can call it this way -- this example returns the port setting for all components that have it:

call Sample.Util_SettingsByName('Port')

Here's the source code as XML export format. Copy this into a file and then import it using Studio, terminal, or the System Management Portal.

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2016.1.1 (Build 108U)" ts="2016-10-12 16:15:39">
<Class name="Sample.Util">

<UDLText name="T">
         *                 ** N O T I C E **                 *
         *               - TEST/DEMO SOFTWARE -              *
         * This and related items are not supported by       *
         * InterSystems as part of any released product.     *
         * It is supplied by InterSystems as a demo/test     *
         * tool for a specific product and version.          *
         * The user or customer is fully responsible for     *
         * the maintenance of this software after delivery,  *
         * and InterSystems shall bear no responsibility nor *
         * liabilities for errors or misuse of this item.    *
         *                                                   *

<Query name="SettingsByName">
<Parameter name="ROWSPEC" value="BusinessHost:%String,SettingName:%String,SettingValue:%String"/>

<Method name="SettingsByNameExecute">
    s qHandle=##class(%ArrayOfObjects).%New()

    &sql(select %DLIST(id) into :tHostIDs from ENS_Config.Item order by Name desc)
    s tHostIDList=##class(%Library.ListOfDataTypes).%New()
    s tSC=tHostIDList.InsertList(tHostIDs)
    s tSC=qHandle.SetAt(tHostIDList,"HostIDs")

    s tSC=qHandle.SetAt(##class(%ArrayOfDataTypes).%New(),"Counters")
    s tSC=qHandle.GetAt("Counters").SetAt(0,"CurrHost")
    s tSC=qHandle.GetAt("Counters").SetAt(0,"CurrSetting")
    if ($L(SettingNames)>1) {
        s SettingNames=$ZCONVERT(SettingNames,"U")
        s tFilterList=##class(%Library.ListOfDataTypes).%New()
        s tSC=tFilterList.InsertList($LISTFROMSTRING(SettingNames))
         s tSC=qHandle.SetAt(tFilterList,"FilterList")

    Quit $$$OK

<Method name="SettingsByNameClose">
<Implementation><![CDATA[    Quit $$$OK

<Method name="SettingsByNameFetch">
    s tCurrHost=qHandle.GetAt("Counters").GetAt("CurrHost")
    s tCurrSetting=qHandle.GetAt("Counters").GetAt("CurrSetting")
    s tHostIDs=qHandle.GetAt("HostIDs")
    s tFilterList=qHandle.GetAt("FilterList")
    s oHost=qHandle.GetAt("Host")

    do {
        if ('$IsObject(oHost)||(oHost.VirtualSettings.Count()<tCurrSetting)) {
            if (tCurrHost=tHostIDs.Count()) {
                s AtEnd=1

            s tCurrHost=tCurrHost+1
            s tCurrSetting=1
            s tHostID=tHostIDs.GetAt(tCurrHost)
            s oHost=##class(Ens.Config.Item).%OpenId(tHostID,0)
            s tSC=oHost.PopulateVirtualSettings()

            s tSC=qHandle.SetAt(oHost,"Host")                
            s tSC=qHandle.GetAt("Counters").SetAt(tCurrHost,"CurrHost")

        s tSettings=oHost.VirtualSettings
        s tSetting=tSettings.GetAt(tCurrSetting)
        s tStngName=$LISTGET(tSetting,2)
        s tStngValue=$LISTGET(tSetting,3)
        s tCurrSetting=tCurrSetting+1
    } while ($IsObject(tFilterList)&&('tFilterList.Find($ZCONVERT(tStngName,"U"))))
    if ('AtEnd) {
        s Row=$LB(oHost.Name,tStngName,tStngValue)
    s tSC=qHandle.GetAt("Counters").SetAt(tCurrSetting,"CurrSetting")
    Quit $$$OK

Ens.StreamContainer's %New() method expects a string as the first parameter rather than a stream object.

Something like this should work:

set tRequest=##class(Ens.StreamContainer).%New()
set tSC=tRequest.StreamSet(pInput)

Or if you're trying to send one Ens.StreamContainer for each line from the input file you could do this:

while 'pInput.AtEnd {
    set tReadLength=32000
    set tLine=pInput.ReadLine(.tReadLength,.tSC)
    set tRequest=##class(Ens.StreamContainer).%New(tLine)
    //... do other stuff

One other thing you should be aware of. The following will not work if TargetConfigNames has more than one target selected:

set tSC = ..SendRequestAsync(..TargetConfigNames,tRequest)

You should add a loop using $LENGTH and $PIECE and do a SendRequestAsync for each item in TargetConfigNames' comma-separated string.

The resulting XML files can be imported again using %System.OBJ.Load().

If you prefer GOF format you can use %Global.Export() instead, however it doesn't accept wildcards so you would need to first put together a list of which globals you want to export.

For automation you can execute these methods from your own custom class or routine. If you want to schedule it to run automatically, you can create your custom class as a %SYS.Task.Definition and schedule it to run using Task Manager.

You're correct -- you can't restore specific globals from an Online Backup (.cbk) file.

Or it looks like I was handling the zero issue manually:

if $L(tHexByte)=1 s tHexByte="0"_tHexByte

Here's a (very simple) working example of uploading to an AWS S3 bucket. I used essentially the same approach that Cliff originally used to generate the hex. I didn't experience the same problem, but I may have just been lucky and not had any zeroes in the value I'm converting.

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2017.2.1 (Build 801_3U)" ts="2018-10-04 08:14:32">
<Class name="Demo.Cloud.Storage.Util">

<Method name="TestS3Upload">
    set tAccessKeyId="[Shh... it's a secret]"
    set tSecretAccessKey="[Shh... it's a secret]"
    set tAWSRegion="us-east-1"
    set tAWSService="s3"
    set tHost=""
    set tPort="443"
    set tBucket="MyBucket12345"
    set tContentType="text/plain; charset=UTF-8"

    set tSSLConfig="AWS"
    set tUseHTTPS=1
    set tContentStream=##class(%Stream.TmpCharacter).%New()
    do tContentStream.Write("this is some test content oh yeah!")
    do tContentStream.Rewind()

    set tHorolog=$h
    set tDateKey=$System.Encryption.HMACSHA(256,$ZD(tHorolog,8),"AWS4"_tSecretAccessKey)
    set tDateRegionKey=$System.Encryption.HMACSHA(256,tAWSRegion,tDateKey)
    set tDateRegionServiceKey=$System.Encryption.HMACSHA(256,tAWSService,tDateRegionKey)
    set tSigningKey=$System.Encryption.HMACSHA(256,"aws4_request",tDateRegionServiceKey)
    set tHashedPayload=..BytesToHex($System.Encryption.SHAHashStream(256,tContentStream,.tSC))
    set tTmpTime=$ZDT(tHorolog,2,7)
    set tHeaderDate=$ZD(tHorolog,11)_", "_$E(tTmpTime,1,11)_" "_$E(tTmpTime,13,*-1)_" GMT"
    set tAmzDate=$TR($zdt(tHorolog,8,7),":","")

    set tKeyName="test_"_tHorolog_".txt"

    set tCanonicalURI="/"_tBucket_"/"_tKeyName
    set tCanonicalURI=$zconvert(tCanonicalURI,"O","URL")

    set tHttpVerb="PUT"
    set tCanonicalHeaders="content-length:"_tContentStream.Size_$c(10)_"content-type:"_tContentType_$c(10)_"host:"_tHost_$c(10)_"x-amz-content-sha256:"_tHashedPayload_$c(10)_"x-amz-date:"_tAmzDate_$c(10)
    set tSignedHeaders="content-length;content-type;host;x-amz-content-sha256;x-amz-date"
    set tCanonicalRequest=tHttpVerb_$c(10)_tCanonicalURI_$c(10,10)_tCanonicalHeaders_$c(10)_tSignedHeaders_$c(10)_tHashedPayload
    set tStringToSign="AWS4-HMAC-SHA256"_$c(10)_$TR($zdt(tHorolog,8,7),":","")_$c(10)_$zd(tHorolog,8)_"/"_tAWSRegion_"/"_tAWSService_"/aws4_request"_$c(10)_..BytesToHex($System.Encryption.SHAHash(256,tCanonicalRequest))
    set tSignature=..BytesToHex($System.Encryption.HMACSHA(256,tStringToSign,tSigningKey))    
    set tAuthHeader="AWS4-HMAC-SHA256 Credential="_tAccessKeyId_"/"_$zd(tHorolog,8)_"/"_tAWSRegion_"/"_tAWSService_"/aws4_request,SignedHeaders="_tSignedHeaders_",Signature="_tSignature

    set tHReq=##class(%Net.HttpRequest).%New()
    set tHReq.Server=tHost
    set tHReq.Port=tPort
    set tHReq.SSLConfiguration=tSSLConfig
    set tHReq.Https=tUseHTTPS

    do tHReq.SetHeader("Authorization",tAuthHeader)
    do tHReq.SetHeader("Content-Type","text/plain")
    do tHReq.SetHeader("Content-Length",tContentStream.Size)
    do tHReq.SetHeader("Host",tHost)
    do tHReq.SetHeader("x-amz-content-sha256",tHashedPayload)
    do tHReq.SetHeader("x-amz-date",tAmzDate)

    do tHReq.EntityBody.CopyFrom(tContentStream)

    //do tHReq.OutputHeaders()

    s tSC=tHReq.Put(tCanonicalURI)
    do $System.OBJ.DisplayError(tSC)
    write "Status Code:",tHReq.HttpResponse.StatusCode,!
    //Do tHReq.HttpResponse.OutputToDevice()
    if $isobject(tHReq.HttpResponse.Data) {
        s ^zresp=tHReq.HttpResponse.Data.Read(1000000)
    } else {
        s ^zresp=tHReq.HttpResponse.Data

<Method name="BytesList">
    s l=$LISTFROMSTRING(pBytes," ")
    f i=1:1:$LL(l)  s st=$G(st)_$CHAR($ZHEX($LISTGET(l,i)))
    return st

<Method name="BytesToHex">
    set tHex=""
    for i=1:1:$L(pBytes) {
        set tHexByte=$ZHEX($ASCII($E(pBytes,i)))
        if $L(tHexByte)=1 s tHexByte="0"_tHexByte
        set tHex=tHex_tHexByte
    return $ZCONVERT(tHex,"L")

Have you tried setting "DefCharEncoding" to UTF-8 in the settings for EnsLib.HL7.Operation.HTTPOperation?

Here are the details from the popup-help. Especially note the highlighted line. Using "!UTF-8" will cause the operation to ignore what's in MSH:18 and always use UTF-8.

Default Character Encoding to use when reading or writing HL7 messages.
If MSH field 18 (Character Set) is empty, this encoding will be used. Choices you can use for this setting include:

Native: Use the default character encoding of the installed locale of the IRIS server.
latin1: The ISO Latin1 8-bit encoding. This is the default.
ISO-8859-1: The ISO Latin1 8-bit encoding.
UTF-8: The Unicode 8-bit encoding.
Unicode: The Unicode 16-bit encoding (Little-Endian).
UnicodeBig: The Unicode 16-bit encoding (Big-Endian).
Any other NLS definitions installed on this IRIS server.
@<ttable>: <ttable> means a raw InterSystems character translation table name. A prefix of '@' means to use the named table.
Putting ! before the encoding name will force the use of the named encoding and will ignore any value found in MSH:18.

In the case of moving from AIX to Windows, you're not just changing the OS but also changing the platform (IBM Power to Intel).

As Dmitry said, there's no relation to the OS but there is an important issue when changing platforms: endianness. AIX on Power is big-endian while Windows/Linux/etc. on Intel are little-endian.

The upshot is: when moving a cache.dat from AIX to Windows you'll need to run an included utility to convert it from big-endian to little-endian.