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
}
}
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