Windows Update Plugin - Agent not recognizing changes in check_cmk.user.yml

CMK version:
2.2.0p17 RAW

Hi!

So due to tons of timeout notifications for the Windows Update Plugins, I made a change in the check_mk.user.yml

Unfortunately, the agent doesn’t seem to actually recognize the change when I run .\check_mk_agent.exe reload_config and then showconfig.

This is what I added above the default plugin patterns/rules:

        - pattern     : '$CUSTOM_PLUGINS_PATH$\windows_updates.vbs'
          async       : yes
          timeout     : 3600
          cache_age   : 90000

Other than that, the file is at default. Does anyone know why this is not working?

What do you see on “check_mk_agent.exe showconfig”?
Mostly it is a wrong formatted yaml file causing such issues.

I have used yamllint.com to verify it is a valid file. showconfig just shows the configuration, but is missing the lines I added. Here’s the output:

PS C:\Program Files (x86)\checkmk\service> .\check_mk_agent.exe showconfig
# Environment Variables:
# MK_LOCALDIR="C:\ProgramData\checkmk\agent\local"
# MK_STATEDIR="C:\ProgramData\checkmk\agent\state"
# MK_PLUGINSDIR="C:\ProgramData\checkmk\agent\plugins"
# MK_TEMPDIR="C:\ProgramData\checkmk\agent\tmp"
# MK_LOGDIR="C:\ProgramData\checkmk\agent\log"
# MK_CONFDIR="C:\ProgramData\checkmk\agent\config"
# MK_SPOOLDIR="C:\ProgramData\checkmk\agent\spool"
# MK_INSTALLDIR="C:\ProgramData\checkmk\agent\install"
# MK_MSI_PATH="C:\ProgramData\checkmk\agent\update"
# MK_MODULESDIR="C:\ProgramData\checkmk\agent\modules"
# Loaded Config Files:
# system: 'C:\Program Files (x86)\checkmk\service\check_mk.yml'
# bakery: 'C:\ProgramData\checkmk\agent\bakery'
# user  : 'C:\ProgramData\checkmk\agent\check_mk.user.yml'

#
global:
  enabled: yes
  only_from: ~
  port: 6556
  ipv6: no
  encrypted: no
  passphrase: secret
  execute: [exe, bat, vbs, cmd, ps1]
  async: yes
  try_kill_plugin_process: safe
  sections:
    - check_mk
    - mrpe
    - skype
    - spool
    - plugins
    - local
    - winperf
    - uptime
    - systemtime
    - df
    - mem
    - services
    - msexch
    - dotnet_clrmemory
    - wmi_webservices
    - wmi_cpuload
    - ps
    - fileinfo
    - logwatch
    - openhardwaremonitor
    - agent_plugins
  disabled_sections: []
  realtime:
    enabled: no
    timeout: 90
    port: 6559
    encrypted: no
    passphrase: this is my password
    run: [mem, df, winperf_processor]
  wmi_timeout: 5
  cpuload_method: use_perf
  logging:
    location: ~
    file: ~
    debug: yes
    windbg: yes
    eventlog: yes
    max_file_count: 5
    max_file_size: 8000000
ps:
  enabled: yes
  use_wmi: yes
  full_path: no
winperf:
  enabled: yes
  exe: agent
  trace: no
  fork: yes
  prefix: winperf
  timeout: 10
  counters:
    - 234: phydisk
    - 510: if
    - 238: processor
fileinfo:
  enabled: yes
  path: []
logwatch:
  enabled: yes
  sendall: no
  vista_api: no
  skip_duplicated: no
  max_size: 500000
  max_line_length: -1
  max_entries: -1
  timeout: -1
  logfile:
    - Parameters: ignore
    - State: ignore
    - "*": warn nocontext
plugins:
  enabled: yes
  player: ""
  max_wait: 60
  async_start: yes
  folders: [$CUSTOM_PLUGINS_PATH$, $BUILTIN_PLUGINS_PATH$]
  execution:
    - pattern: $CUSTOM_PLUGINS_PATH$\cmk-update-agent.exe
      run: no
    - pattern: $CUSTOM_PLUGINS_PATH$\*.*
      timeout: 60
      run: yes
    - pattern: $BUILTIN_PLUGINS_PATH$\*.*
      timeout: 60
      run: no
    - pattern: "*"
      run: no
local:
  enabled: yes
  player: ""
  max_wait: 60
  async_start: true
  execution:
    - pattern: "*.*"
      timeout: 60
      run: yes
mrpe:
  enabled: yes
  parallel: no
  timeout: 60
  config: ~
modules:
  enabled: yes
  python: auto
  quick_reinstall: no
  table:
    - name: python-3
      exts: [.checkmk.py, .py]
      exec: .venv\Scripts\python.exe {}
system:
  enabled: yes
  controller:
    run: yes
    detect_proxy: no
    validate_api_cert: no
    check: yes
    force_legacy: no
    agent_channel: mailslot
    local_only: yes
    on_crash: ignore
  firewall:
    mode: configure
    port: auto
  cleanup_uninstall: smart
  wait_network: 30
  service:
    restart_on_crash: yes
    error_mode: log
    start_mode: auto

One thing to note, when running reload_config, there are two warnings, but it still seems to finish the reload. Not sure what it wants to do with Mails:

PS C:\Program Files (x86)\checkmk\service> .\check_mk_agent.exe reload_config
Reloading configuration...
Asking for reload service
Failed to send data to mail slot
Asking for reload executable
Failed to send data to mail slot
Done.

If it is not shown here in the “showconfig” output, the yaml file has a syntax issue.

The mail slot message is not relevant and can be ignored.

The file gets verified as valid, so I’m not sure what the problem is. The only thing I’ve changed is the pattern for the Windows update, everything else is default. Here’s the full file:

# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

#
# User Checkmk configuration file
#

# The Agent will accept YML-File as a valid configuration file
# only when the section global is presented

# $CUSTOM_PLUGINS_PATH$  -> is ProgramData/checkmk/agent/plugins
# $BUILTIN_PLUGINS_PATH$ -> is Program Files(x86)/checkmk/service/plugins
# $CUSTOM_AGENT_PATH$    -> is ProgramData/checkmk/agent/
# $CUSTOM_LOCAL_PATH$    -> is ProgramData/checkmk/agent/local

# 1. use http://www.yamllint.com/ for example to validate your yamllint
# 2. Windows filenames contains backslash \, ergo you have to write either "c:\\windows" or 'c:\windows' 

# To disable any feature you may use two methods
# 1. commenting out with '#' recommended to use with one line declarations
# 2. renaming. Recommended to disable big parts of YAML tree
#   Most useful is adding _ at the beginning of name
#
# example 
#         _logging: # <----- this structure is fully ignored by agent
#         logging:  # <----- this structure is accepted by agent

# Overriding values from the bakery( or defauts )
# For example we want to change sections set in output

# 1. All sections are included:
# sections: []  # <--- this is accepted as FULL list of sections, agent sends all data. To save your keystrokes

# 2a. Two sections:
# sections: [check_mk, systemtime]  # <--- this is accepted as list of two sections

# 2b. One section:
# sections: [plugins]  # <--- this is accepted as list of one section

# 3. We want to return back(Use values combined from default and bakery if present)
# 3a. 
# sections: ~   # <--- this line is skipped, this value is estimated as undefined

# 3a. 
# _sections: [plugins]   # <--- this name, '_sections' is unknown and will be ignored too


global:
    # section may be fully disabled
    # enabled: yes

    # Restrict access to certain IP addresses
    # If ipv6 is enabled, all listed ipv4 adresses are also accepted as
    # source adresses in their ipv6-mapped form. I.e. if
    # 192.168.56.0/24 is listed, connections from ::ffff:c0a8:3800/120
    # are also possible
    _only_from: # 127.0.0.1 192.168.56.0/24 ::1

    # Change port where the agent is listening ( default 6556 )
    # port: 6556

    # Disable ipv6 support. By default, ipv4 is always supported
    # and ipv6 is enabled additionally if supported by the system.
    # ipv6: no

    # encryption
    # encrypted: no

    # password
    # passphrase: secret

    # Allowed file extensions. The agent launches the program(script) only 
    # when its extension is on the list of allowed ones. 
    # execute: [exe, bat, vbs, cmd, ps1] # Supported: vbs, ps1, py, pl, exe, cmd, bat

    # Run sync scripts in parallel (to each other). Default is "yes"
    # async: yes

    # Just output certain sections

    # Include all possible sections:
    # sections: []

    # Valid example, but section is renamed to _sections and wil be ignored
    _sections: 
        - check_mk 
        - mrpe 
        - skype 
        - spool 
        - plugins
        - local
        - winperf 
        - uptime 
        - systemtime 
        - df 
        - mem 
        - services 
        - msexch
        - dotnet_clrmemory
        - wmi_webservices
        - wmi_cpuload
        - ps 
        - fileinfo 
        - logwatch 
        - openhardwaremonitor 
        - agent_plugins

    # Useful example
    # sections: ~   # <--- this line is skipped as undefined
    # sections: []  # <--- this is accepted as FULL list of sections, agent send data from all sections

    # To disable section you have enumerate disabled section explicitly
    # To disable ps and fileinfo:
    _disabled_sections: [ps, fileinfo]
    
    # To ignore disabled_sections, you can use ~:
    # _disabled_sections: ~
    
    # In this case disabled_sections will be ignored too
    # disabled_sections: []

    #realtime data description
    # to control section manually change name from _realtime to realtime.
    _realtime:
        enabled: yes
        # specifies how long (in seconds) realtime updates are sent to
        # the last monitoring system that requested an update.
        # this should be longer than the request frequency (usually
        # one minute).
        # Please note that any new request cancels previous realtime
        # update schedules, so no more than one update is sent per second,
        # no matter if this timeout is "too high" or how many monitoring
        # systems are querying the agent.
        timeout: 90
    
        port: 6559
        # enable/disable encryption of regular agent output (default: no) 
        encrypted: no
    
        # passphrase for encrypted communication.
        passphrase: this is my password
        # which sections are realtime, those three are by default
        run: 
            - mem
            - df
            - winperf_processor

    # In seconds. Windows may be slow during WMI, increase the value when you have problems
    # wmi_timeout: 5

    # cpuload_method: 'use_perf' # set use_wmi if you have serious problems with the section


    # -------------------------------------------------------------- 
    # Internal log of agent
    # Write a logfile for tackling down crashes of the agent
    _logging:
        # folder with log file, empty is default which means '$CUSTOM_AGENT_PATH$\log'
        location: 
        # name of file log, default is check_mk.log
        file : 
        # log in file also internal debug messages, recommended when we have problems
        # allowed no, yes and all. Default yes!
        debug: yes
        # you may send logging messages in realtime in windows debug sink, default is yes
        windbg: yes

        # you may disable your eventlog ability
        eventlog: yes

        max_file_count: 5  # log rotation files quantity,  allowed 1..1024 
        max_file_size: 8000000 # allowed 200K..200MB

ps:
    # enabled: yes
    # use_wmi: yes
    # full_path: yes # This value has effect only when use_wmi is set

winperf:
    # enabled: yes

    # changes only section name winperf_******
    # prefix: winperf

    # no - nothing(default), yes output trace to the log/winperf.log
    #trace: no

    # yes - separate process for winnperf to prevent ahndle leaking, no - locally
    #fork: yes
    


    # default value,  increase for heavy loaded machine
    # timeout: 10
    
    # Select counters to extract. The following counters
    # are needed by checks shipped with check_mk.
    # Format:
    # - id:name
    # where id is OS counter and name is part of CHECK_MK Header 
    counters:
        #- 638: tcp_conn
        #- Terminal Services: ts_sessions

_logfiles:
    enabled: no
    # We do not support logfiles monitoring in agent at the moment
    # Please, use plugin mk_logwatch

fileinfo:
    # enabled: yes
    # below are possible examples
    path:
        # - 'c:\a\a' # generates missing| string
        # - 'c:\Users\Public\*.log' # real string to process
        # - "this\\is\\not\\recommended\\" # double quoating uses escape sequences
        # - 'c:\Users\Public\**\Desktop.ini' works, 8 files to control
        # - 'c:\Windows\Resources\**\aero\aero*.*' works too, you will get two files in 'c:\Windows\Resources\Themes\aero\'
        # - 'c:\dev\shared_public\*.*' # typical test folder, provided during development
        # - ''  # empty strings will be ignored
        # - '--' # all string without "C:\" or "\\" at start will be ignored too for security reason

logwatch:
    # enabled: yes
    
    # sendall: no   # this is MANDATORY, yes is useful only for debugging
    # vista_api: no # this is RECOMMENDED
    # skip_duplicated: no # if yes the same messages will be replaced with text [the above messages repeated <n> times]
    # max_size: 500000 # default value
    # max_line_length: -1 # -1 to ignore, or any positive, max length of the line
    # max_entries: -1     # -1 to ignore, or any positive, max count of lines to receive
    # timeout: -1         # -1 to ignore, or any positive, in seconds

     # entries in the windows eventlog
    logfile:
        # - 'EventLogName': <crit|warn|all|off> + [context|nocontext]
        # - 'Application': crit context # example
        # - 'System': warn nocontext    # another example
        # - 'YourOwn': all nocontext    # yet another example
        # - '*': warn nocontext         # This is default params for not missing entries

plugins:
    # enabled: yes

    # max_wait: 60 # max timeout for every sync plugin. Agen will gather plugins data no more than max_wait time.
                 # this is useful to terminate badly written or hanging plugins   


    # async_start: yes # start plugins asynchronous, this is default

    # folders are scanned left -> right, order is important
    # all files from folders are gathered and verified, duplicated files will be removed
    # folders: ['$CUSTOM_PLUGINS_PATH$', '$BUILTIN_PLUGINS_PATH$' ]       # ProgramData/checkmk/agent/plugins & Program Files x86/checkmk/service/plugins

    _execution:
        # *********************************************************************************************
        # PATTERNS:
        # patterns 1. Absolute path: 'c:\Windows\*.exe' or '$CUSTOM_PLUGINS_PATH$\win_license.bat'
        #          2. Only Filename: 'mk_*.exe' or win_license.bat
        #             IMPORTANT: if you use relative path, then Agent takes only filename
        #                        'win_license.bat' and 'include\win_license.bat' are the same    
        #
        # PRIORITY:
        # Most important is top-most pattern:
        # Most important is check_mk.user.yml, next check_mk.bakery.yml amd least important is check_mk.yml
        #
        # DUPLICATED Plugins:
        # Plugins with Duplicated names will not be executed:
        # if you have '$CUSTOM_PLUGINS_PATH$\winstat_an.bat' and '$BUILTIN_PLUGINS_PATH$\winstat_an.bat'
        # to execute only first one will run ^^^^^^^^^^^^^^                              xxxxxxxxxxxxxx 
        #
        # *********************************************************************************************
        # execution pattern for  windows-updates.vbs:
        # all parameters below are DEFAULT set for every entry
        #- pattern     : '$CUSTOM_PLUGINS_PATH$\mk_inventory.vbs'  # Plugin name or absolute path . * and ? are allowed
        #  run         : yes                 # execute this plugin if plugin found
        #  async       : yes                 # agent will not wait for async plugins. Normally you will get data later.
        #  timeout     : 120                 # after 120 seconds process will be killed.
        #  cache_age   : 3600                # only combined with async, upto 3600 seconds we may reuse plugin output
                                             # default value is 0. Minimum positive value is 120.
        #  retry_count : 3                   # failure on start plugin, before stopping, default 0 which means never stop attempts 
        #  cmd_line    : ''                  # reserved for future use
        #
        #- pattern     : '$CUSTOM_PLUGINS_PATH$\mk_scansql.vbs'    # Plugin name or absolute path . * and ? are allowed
        #  user       : 'sql_user sql_secret' # user name(domain is allowed) and password separated with one space
        #  run         : yes                 # execute this plugin if plugin found
        #  
        #- pattern     : '$CUSTOM_PLUGINS_PATH$\network_access.bat'   # Plugin requires access to the Network.
        #  group       : 'Users'             # run plugin from the Internal Agent User belonging the this group
        #  run         : yes
        #  
        #- pattern     : '$CUSTOM_PLUGINS_PATH$\win_license.bat'   # Plugin name. * and ? are allowed
        #  run         : No                  # do not run plugin even if found




    
    
        # Default
        - pattern     : '$CUSTOM_PLUGINS_PATH$\*.*'         # in the ProgramData folder. DO NOT REMOVE THIS ENTRY
          timeout     : 30                  # after 30 seconds process will be killed. 60 sec is default in check_mk.yml
          run         : yes                 # ALL FOUND files will be started. This is default value

        - pattern     : '$BUILTIN_PLUGINS_PATH$\*.*'         # in the ProgramFiles folder. DO NOT REMOVE THIS ENTRY
          timeout     : 30                  # after 30 seconds process will be killed. 60 sec is default in check_mk.yml
          run         : no                  # No run, i.e disabled.

        - pattern     : '*'                 # This is safety entry. Try not use plugins outside your predefined folder
          run         : no                  # No run, i.e. disabked.

        # KEDO Windows Update plugin settings
        - pattern     : '$CUSTOM_PLUGINS_PATH$\windows_updates.vbs'
          async       : yes
          timeout     : 3600
          cache_age   : 90000

# ProgramData/checkmk/agent/local folder
local:
    # enabled: yes

    # max_wait: 60 # max timeout for every sync plugin. Agen will gather plugins data no more than max_wait time.
                   # this is useful to terminate badly written or hanging plugins   


    # async_start: true # start plugins asynchronous, this is normal mode. 

    # patterns will be scanned up down, 
    # configuration is assigned to the first found file matching the pattern 
    _execution:
        - pattern     : 'test_me.bat'   # Plugin name. * and ? are allowed
          #async: no                    # default is no
          timeout     : 35              # after 35 seconds process will be killed, default is 60 in check_mk.yml
          run         : yes             # execute this plugin.

        - pattern     : '*.*'           # in the user folder. DO NOT REMOVE THIS ENTRY
          run         : yes             # Do not run any files matching this pattern


mrpe:
    # enabled: yes

    ## Timeout value (seconds) - Defaults to 60, which can be considered a safe choice,
    ## as legacy Nagios checks usually execute fastly.
    # timeout: 60

    config:
        ## MRPE check entries:
        ##  check = SERVICE_DESCRIPTION [(interval=INTERVAL)] COMMAND
        ## If specified, the check result will be cached for INTERVAL seconds
        ## before executing it again.
        ## Relative path are supported for checks and includes.
        ## The path below is equal to '$CUSTOM_AGENT_PATH$\plugins\your_check.com'
        # - check = Service_Description 'plugins\your_check.ps1' CON CP /STATUS
        # - check = Console 'c:\windows\system32\mode.com' CON CP /STATUS
        # - check = Checker (interval=100) 'c:\windows\system32\mode.com'

        ## Include entries:
        ##  include [USER_NAME] = PATH_TO_CFG
        ## Add config files that contain additional MRPE check lines
        # - include = $CUSTOM_AGENT_PATH$\mrpe_checks.cfg
        # - include some_user_name = $CUSTOM_AGENT_PATH$\mrpe_checks.cfg


modules:
    enabled: yes

    #python: auto                          # allowed auto or system, system prevents module usage to execute *.py files

    #quick_reinstall: yes                  # use %temp% as temporary storage for modules when Windows agent is updated


system:
    enabled: yes

    #controller:
    #    run: yes                            # start controller if present
    #    detect_proxy: no                    # controller runtime option, see CLI for more information
    #    validate_api_cert: no               # controller runtime option, see CLI for more information
    #    check: yes                          # if yes that only the controller process connections could access agent monitoring data
                                             # set no if monitoring is lost and in log you find 'Connection forbidden: address'
    #    force_legacy: no                    # if yes always created for version with controller
    #    agent_channel: "mailslot"           # as fallback you may use also TCP-IP "localhost:ip_port", default "mailslot"
    #    local_only: no                      # bind to 127.0.0.1 or 0.0.0.0
    #    on_crash: "ignore"                  # possible values "ignore" or "emergency_mode". This is safety switch.
                                             # Use "emergency_mode" if controller crashes/disappear

    #firewall:
    #    mode: configure # allowed none, remove, configure
    #    port: auto # allowed all or auto

    #cleanup_uninstall: smart # allowed none, smart and all

    # wait_network: 30
    # 
    #service:
    #    restart_on_crash: yes  # service will restart if crashed, you may set no to disable restarting
    #                           # no may be used if you have serious problems with crasghing and starting
    #    error_mode: log        # ignore or log
    #    start_mode: auto       # Possible values are: auto - service starts with boot, demand - requires manual starting
    #                           # disabled - service cannot be started manually and should be enabled

The “_” before execution disables the complete section.
Please don’t use the complete file with all comments for production.
It is too easy to miss such a thing like this underscore.

Ohh, thank you! I don’t know a lot about YAML. I thought the User config is intended to be used like that - So do I just make a user config with only that section in it? Or does it need anything else?

This stuff should be covered by the configs in ProgramFiles anyways, right?