centreon-plugins icon indicating copy to clipboard operation
centreon-plugins copied to clipboard

[os::windows::wsman::plugin updates] - JSON error

Open antonin2063 opened this issue 2 years ago • 18 comments

Hello guys, Got an issue with the wsman plugin. Got an issue using the updates mode.

/usr/lib/centreon/centreon-plugins/src/centreon_plugins.pl --plugin=os::windows::wsman::plugin --mode=updates --hostname=xxx --wsman-scheme=xxx --wsman-port=xxxx --wsman-username='xxx' --wsman-password='xxx'

Got this return error : UNKNOWN: Cannot decode json response: malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "PowerShell[.exe] [-P...") at /usr/lib/centreon/centreon-plugins/src/os/windows/wsman/mode/updates.pm line 96.

Has someone got an idea ? Thanks,

antonin2063 avatar Jun 09 '23 08:06 antonin2063

Could you provide the output with --debug-stream ?

garnier-quentin avatar Jun 09 '23 09:06 garnier-quentin

Got exactly the same output

/usr/lib/centreon/centreon-plugins/src/centreon_plugins.pl --plugin=os::windows::wsman::plugin --mode=updates --hostname=xx --wsman-scheme=xxx --wsman-port=xx --wsman-username='xx' --wsman-password='xx' --debug-stream

UNKNOWN: Cannot decode json response: malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "PowerShell[.exe] [-P...") at /usr/lib/centreon/centreon-plugins/src/os/windows/wsman/mode/updates.pm line 96.

antonin2063 avatar Jun 09 '23 09:06 antonin2063

Could you add a debug in file update.pm to display the json response ?

garnier-quentin avatar Jun 09 '23 09:06 garnier-quentin

This is the JSON response, seems like a powershell issue..

UNKNOWN: Cannot decode json response: malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "PowerShell[.exe] [-P...") at /usr/lib/centreon/centreon-plugins/src/os/windows/wsman/mode/updates.pm line 100. JSON Response:

PowerShell[.exe] [-PSConsoleFile | -Version ] [-NoLogo] [-NoExit] [-Sta][-Mta] [-NoProfile] [-NonInteractive] [-InputFormat {Text | XML}] [-OutputFormat {Text | XML}] [-WindowStyle

PowerShell[.exe] -Help | -? | /?

-PSConsoleFile Charge le fichier de console Windows PowerShell sp▒cifi▒. Pour cr▒er un fichier de console, utilisez Export-Console dans Windows PowerShell.

-Version D▒marre la version sp▒cifi▒e de Windows PowerShell. Entrez un num▒ro de version avec le param▒tre, tel que ▒ -version 2.0 ▒.

-NoLogo Masque la banni▒re de copyright au d▒marrage.

-NoExit Ne se ferme pas apr▒s l'ex▒cution des commandes de d▒marrage.

-Sta D▒marre l'interpr▒teur de commandes ▒ l'aide d'un cloisonnement monothread. Le cloisonnement monothread (STA) est utilis▒ par d▒faut.

-Mta D▒marrer l'interpr▒teur de commandes ▒ l'aide d'un cloisonnement multithread.

-NoProfile Ne charge pas le profil Windows PowerShell.

-NonInteractive N'affiche pas d'invite interactive pour l'utilisateur.

-InputFormat D▒crit le format des donn▒es envoy▒es ▒ Windows PowerShell. Les valeurs valides sont ▒ Text ▒ (cha▒nes de texte) ou ▒ XML ▒ (format CLIXML s▒rialis▒).

-OutputFormat D▒termine la m▒thode de mise en forme de la sortie de Windows PowerShell. Les valeurs valides sont ▒ Text ▒ (cha▒nes de texte) ou ▒ XML ▒ (format CLIXML s▒rialis▒).

-WindowStyle D▒finit le style de fen▒tre sur Normal, Minimized, Maximized ou Hidden.

-EncodedCommand Accepte une version de cha▒ne cod▒e en base 64 d'une commande. Utilisez ce param▒tre pour envoyer des commandes ▒ Windows PowerShell n▒cessitant des guillemets complexes ou des accolades.

-ConfigurationName Sp▒cifie un point de terminaison de configuration dans lequel Windows PowerShell est ex▒cut▒. Il peut s'agir de tout point de terminaison enregistr▒ sur la machine locale, notamment les points de terminaison ▒ distance par d▒faut Windows PowerShell, ou un point de terminaison personnalis▒ dot▒ de capacit▒s sp▒cifiques au r▒le utilisateur.

-File Ex▒cute le script sp▒cifi▒ dans l'▒tendue locale (avec ▒ dot-sourcing ▒), de sorte que les fonctions et variables cr▒▒es par le script soient disponibles dans la session active. Entrez le chemin d'acc▒s au fichier de script et les param▒tres ▒ventuels. Le fichier doit ▒tre le dernier param▒tre de la commande, car tous les caract▒res entr▒s apr▒s le nom de param▒tre File sont interpr▒t▒s comme ▒tant le chemin d'acc▒s au fichier de script, suivi des param▒tres du script.

-ExecutionPolicy D▒finit la strat▒gie d'ex▒cution par d▒faut de la session active et l'enregistre dans la variable d'environnement $env:PSExecutionPolicyPreference. Ce param▒tre ne modifie pas la strat▒gie d'ex▒cution Windows PowerShell d▒finie dans le Registre.

-Command Ex▒cute les commandes sp▒cifi▒es (et les param▒tres ▒ventuels) comme si elles ▒taient entr▒es dans l'invite de commandes Windows PowerShell, puis se ferme, sauf si NoExit est sp▒cifi▒. La valeur de la commande peut ▒tre ▒ - ▒, une cha▒ne ou un bloc de script.

Si la valeur de la commande est ▒ - ▒, le texte de la commande est lu dans
l'entr▒e standard.

Si la valeur de la commande est un bloc de script, celui-ci doit ▒tre plac▒
entre accolades ({}). Vous pouvez sp▒cifier un bloc de script uniquement
lorsque vous ex▒cutez PowerShell.exe dans Windows PowerShell. Les r▒sultats du bloc de script sont renvoy▒s ▒ l'interpr▒teur de commandes
parent sous forme d'objets XML d▒s▒rialis▒s et non pas sous forme d'objets actifs.

Si la valeur de la commande est une cha▒ne, la commande doit ▒tre le dernier
param▒tre de la commande, car les caract▒res entr▒s apr▒s la commande sont
interpr▒t▒s comme arguments de commande.

Pour ▒crire une cha▒ne qui ex▒cute une commande Windows PowerShell,
utilisez le format :
    "& {<commande>}"
o▒ les guillemets indiquent une cha▒ne et l'op▒rateur d'appel (&)
entra▒ne l'ex▒cution de la commande.

-Help, -?, /? Affiche ce message. Si vous entrez une commande PowerShell.exe dans Windows PowerShell, pr▒fixez les param▒tres de la commande avec un tiret (-) et non pas avec une barre oblique (/). Vous pouvez utiliser un tiret ou une barre oblique dans Cmd.exe.

EXAMPLES PowerShell -PSConsoleFile SqlSnapIn.Psc1 PowerShell -version 2.0 -NoLogo -InputFormat text -OutputFormat XML PowerShell -ConfigurationName AdminRoles PowerShell -Command {Get-EventLog -LogName security} PowerShell -Command "& {Get-EventLog -LogName security}"

# Pour utiliser le param▒tre -EncodedCommand :
$command = 'dir "c:\program files" '
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -encodedCommand $encodedCommand

antonin2063 avatar Jun 09 '23 09:06 antonin2063

Do you find a file pendingupdates-xxxx in directory C:/Windows/Temp ?

garnier-quentin avatar Jun 13 '23 09:06 garnier-quentin

Yes, they are all there.

antonin2063 avatar Jun 13 '23 10:06 antonin2063

The script return this error : Unable to process command, because the value specified with -EncodedCommand is not correctly encoded. This value must use Base64 encoding.

antonin2063 avatar Jun 13 '23 10:06 antonin2063

Try to execute following command:

echo|set /P="powershell -encodedcommand ">>C:/Windows/Temp/pendingupdates-xxxx

garnier-quentin avatar Jun 13 '23 12:06 garnier-quentin

Hello, sorry for the late response. Here is the result

$culture = new-object "System.Globalization.CultureInfo" "en-us" [System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture

function Escape-JSONString($str) { if ($str -eq $null) {return ""} $str = $str.ToString().Replace('','\').Replace('"','"').Replace("n",'\n').Replace("r",'\r').Replace( return $str; }

function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) { begin { $data = @() } process{ $data += $_ }

end{
    if ($data.length -eq 1 -and $forceArray -eq $false) {
        $value = $data[0]
    } else {
        $value = $data
    }

    if ($value -eq $null) {
        return "null"
    }

    $dataType = $value.GetType().Name

    switch -regex ($dataType) {
            'String'  {
                return  "`"{0}`"" -f (Escape-JSONString $value )
            }
            '(System\.)?DateTime'  {return  "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $value}
            'Int16|Int32|Double' {return  "$value"}
            'Boolean' {return  "$value".ToLower()}
            '(System\.)?Object\[\]' { # array

                if ($maxDepth -le 0){return "`"$value`""}

                $jsonResult = ''
                foreach($elem in $value){
                    #if ($elem -eq $null) {continue}
                    if ($jsonResult.Length -gt 0) {$jsonResult +=','}
                    $jsonResult += ($elem | ConvertTo-JSON-20 -maxDepth ($maxDepth -1))
                }
                return "[" + $jsonResult + "]"
            }
            '(System\.)?Hashtable' { # hashtable
                $jsonResult = ''
                foreach($key in $value.Keys){
                    if ($jsonResult.Length -gt 0) {$jsonResult +=','}
                    $jsonResult +=

@" "{0}":{1} "@ -f $key , ($value[$key] | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) ) } return "{" + $jsonResult + "}" } default { #object if ($maxDepth -le 0){return ""{0}"" -f (Escape-JSONString $value)}

                return "{" +
                    (($value | Get-Member -MemberType *property | % {

@" "{0}":{1} "@ -f $.Name , ($value.($.Name) | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) )

                }) -join ',') + "}"
            }
    }
}

}

$ProgressPreference = "SilentlyContinue"

Try { $ErrorActionPreference = "Stop"

$updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateupdateSearcher()
$updates = @($updateSearcher.Search("IsHidden=0 and IsInstalled=0").Updates)

$items = New-Object System.Collections.Generic.List[Hashtable];

Foreach ($update in $updates) {
    $item = @{
        title = $update.Title;
        isMandatory = $update.IsMandatory;
    }

    $items.Add($item)
}

$jsonString = $items | ConvertTo-JSON-20 -forceArray $true
Write-Host $jsonString

} Catch { Write-Host $Error[0].Exception exit 1 }

exit 0

antonin2063 avatar Jun 20 '23 13:06 antonin2063

I'm sorry. Could you execute file created in tmp ?

garnier-quentin avatar Jun 20 '23 13:06 garnier-quentin

I'm having the same answer.

Unable to process command, because the value specified with -EncodedCommand is not correctly encoded. This value must use Base64 encoding

antonin2063 avatar Jun 20 '23 13:06 antonin2063

Could you decode the base64 part ?

garnier-quentin avatar Jul 04 '23 07:07 garnier-quentin

Hello Quentin, I can decode correctly image

antonin2063 avatar Sep 06 '23 14:09 antonin2063

If it's working in command line, i don't understand the powershell error. I need to reproduce it. If you still have the issue, we can do a session

garnier-quentin avatar Sep 06 '23 14:09 garnier-quentin

I just encountered the same error and I think I understood the problem. It should be related to the limits of the CMD command line. The .bat is executed using the cmd.exe executables that has a command line max lenght of 8191 characters. The script is 6176 characters long, all on one single line, but it is encoded in UTF-16 and then in base64, so the total length is far more than the cmd limit (16455 bytes).

If you execute the command in the powershell environment, by copying the command and pasting it on the command line, it works, because the length limit there is 64k. If you execute the bat file it fails with encoding error.

I tried to reduce the script size but without any success.

The solution, IMHO, should be to avoid encoding, write the ps1 script in the temp directory, and simply invoke powershell.exe with the ps1 command.

Manually it works, but I'm not able to translate it in the code (or better, I tried but miserably failed :( )

thezipman avatar Nov 27 '23 18:11 thezipman

Hello,

First thanks @thezipman for your contribution to resolve this issue. I'll put all this information in a backlog ticket. Can you tell me if one of you @thezipman and/or @antonin2063 are ready to test a solution when we will work on it?

lucie-tirand avatar Jun 24 '24 12:06 lucie-tirand

Hello, I'm ready to test a solution when you're ready. Thank you,

antonin2063 avatar Aug 12 '24 13:08 antonin2063

and similar issue seem's on --mode=updates UNKNOWN: Cannot decode json response: malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "PowerShell[.exe] [-P...")

joschi99 avatar Mar 21 '25 15:03 joschi99