Search code examples
powershellzabbix

Russian symbols. powershell - zabbix_sender


Sending data to zabbix using PS script (for LLD):

The $ Name variable consists of Russian letters, separated by spaces.

"$ zhost $ zkey $ Json" | Write-Host - displays the correct JSON with Russian characters and in the zabbix appear "????? ???? ???? ????" Apparently, the encoding is breaking somewhere, I cannot understand where, and how to fix it.

Please, help

$ARCHIVEPATH="D:\Work\apdex"
$zsender="D:\Work\apdex\zabbix\zabbix_sender.exe"
$zconfig="D:\Work\apdex\zabbix\zabbix_agentd.win.conf"
$zhost="UPP_Apdex"
$zkey="uids.discovery"
$zparams=@("-c", '"D:\Work\apdex\zabbix\zabbix_agentd.win.conf"')
$zparams=$zparams+@(
    "-i", "-", "-v"
  )
Get-ChildItem "$ARCHIVEPATH" -Filter *.xml | Sort-Object -Property LastWriteTime, Name |
    Foreach-Object {
        $sSourceFile = "$ARCHIVEPATH\$_" 
        $oXmlDocument = New-Object -TypeName System.Xml.XmlDocument
        $oXmlDocument.load($sSourceFile)
        $oXmlDocument.Performance.KeyOperation |
        ForEach-Object -Process {
            $Uid = $_.Uid
            $Name = $_.Name
            $Target = $_.targetValue
                $Json = @{
    'data' = @(
            @{
                '{#OPERKEY}' = $Uid;
                '{#OPERNAME}' = $Name
            }
        )

}
            $Json=($Json | ConvertTo-Json -Compress)
            "$zhost $zkey $Json" | Write-Host
            "$zhost $zkey $Json" | & $zsender $zparams
    }
    }

Solution

  • Although I do not have zabbix, trying for myself simply executing a cmd file that does nothing more then echo %1, I also found that the chcp 65001 did not work as expected.

    Apparently, executing chcp 65001 only sets the Console's OutputEncoding to UTF-8 which is not enough. You must also change PowerShells own $OutputEncoding (which implicitely also uses chcp 65001).

    To make PowerShell use UTF-8 when communicating with external utilities, the following code worked for me:

    $oldOutputEncoding = $OutputEncoding
    $oldConsoleEncoding = [Console]::OutputEncoding
    
    # change the output encoding to use UTF-8
    $OutputEncoding = New-Object System.Text.Utf8Encoding
    [Console]::OutputEncoding = New-Object System.Text.Utf8Encoding
    
    $oldConsoleEncoding
    
    # This is where your zabbix related code goes to finally execute the zabbix_sender.exe 
    # In my test case I'm just running a cmd file that does nothing more then echo the input parameter back to console.
    & "D:\blah.cmd" "русский"
    
    # switch back to the original output encoding whe finished
    $OutputEncoding = $oldOutputEncoding
    [Console]::OutputEncoding = $oldConsoleEncoding
    

    The same can be done for [Console]::InputEncoding if PowerShell is to recieve UTF8 strings from external applications.

    You can see what the current encoding for output is by simply typing $OutputEncoding in PowerShell. On my machine this is what I get:

    IsSingleByte      : True
    BodyName          : iso-8859-1
    EncodingName      : West-Europees (Windows)
    HeaderName        : Windows-1252
    WebName           : Windows-1252
    WindowsCodePage   : 1252
    IsBrowserDisplay  : True
    IsBrowserSave     : True
    IsMailNewsDisplay : True
    IsMailNewsSave    : True
    EncoderFallback   : System.Text.InternalEncoderBestFitFallback
    DecoderFallback   : System.Text.InternalDecoderBestFitFallback
    IsReadOnly        : True
    CodePage          : 1252
    

    After performing $OutputEncoding = New-Object System.Text.Utf8Encoding it shows this:

    BodyName          : utf-8
    EncodingName      : Unicode (UTF-8)
    HeaderName        : utf-8
    WebName           : utf-8
    WindowsCodePage   : 1200
    IsBrowserDisplay  : True
    IsBrowserSave     : True
    IsMailNewsDisplay : True
    IsMailNewsSave    : True
    IsSingleByte      : False
    EncoderFallback   : System.Text.EncoderReplacementFallback
    DecoderFallback   : System.Text.DecoderReplacementFallback
    IsReadOnly        : True
    CodePage          : 65001
    

    Hope this helps