【问题标题】:puppet functions exec windows command line木偶函数 exec windows 命令行
【发布时间】:2017-03-18 17:48:12
【问题描述】:

目前我正在尝试自动化 Windows 服务器服务中的启动模式。我尝试使用 puppetlabs 注册表,但意识到该模块没有按我预期的那样工作。

基本上,我有需要在每台服务器上更新的 Windows 服务列表,但在某些服务器上,这些服务可能不存在,但 puppetlabs 注册表只会在它不存在时创建新密钥,这不是预期的行为。按理说,它应该如下所述工作:

  1. 检查服务是否在服务器中
  2. 如果是,则更新清单/层次结构中提到的启动模式
  3. 如果不存在,什么都不做,直接跳到下一个服务

据我所知,检查服务密钥是否存在的唯一方法似乎是使用自定义函数。所以我已经尝试使用 win32/registry 编写一些自定义函数,但是由于出现一些错误(例如不支持 Win32API)而失败。我能想到的另一种方法是使用 reg 命令行来检查密钥是否存在。以下是木偶代码功能:

module Puppet::Parser::Functions
  newfunction(:check_winservice_exist, :type => :rvalue) do |args|

    service_name = args[0]

    unless args.length > 0 then
      raise Puppet::ParseError, ("check_winservice_exist(): wrong number of arguments (#{args.length}; must be > 0)")
    end

    command = "reg query HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\#{service_name} /f DisplayName"
    result = system command

    return result
    #if result == true
    #   return result
    #else
    #   return result
    #end
  end
end

当我在命令行中运行简化的 ruby​​ 脚本时,它会工作并返回预期值。但是当我将上述脚本用作 puppet 自定义函数时,它总是返回空。

这是我第一次编写 puppet 自定义函数,所以我不确定我在这里做错了什么。请告知我是否可以使用另一种替代方法来解决问题,或者建议我在函数脚本上做错了什么

【问题讨论】:

  • 这是人们在使用函数时常犯的典型错误:它们在主节点上运行。你需要做一个自定义事实。
  • 感谢您的反馈。除了使用自定义事实之外,还有其他方法吗?因为我有数百个服务来检查安全强化目的,并且在自定义事实中创建这些服务的列表会有点麻烦。
  • 您只需创建一个将所有服务收集到一个数组中的事实。这很容易。
  • 非常感谢您的建议。看来这是我现在可以在 puppet 上做到的唯一方法
  • 如果您对自定义事实感到困惑,或者该方法似乎导致您走上了一条严重未优化的路线,我完全建议您发布您所尝试的后续内容并重申您的目标。

标签: windows puppet puppet-enterprise


【解决方案1】:

我设法通过使用 Matt 建议的自定义因子解决了这个问题。只是分享我使用的自定义因素脚本。它可能并不完美,因为我仍然不精通 ruby​​。

require 'win32/registry'

Facter.add(:winservices) do
  confine :kernel => "windows"
  setcode do
    keyname= 'SYSTEM\CurrentControlSet\Services'
    access = Win32::Registry::KEY_ALL_ACCESS
    arr = []
    winservices_list = []

    Win32::Registry::HKEY_LOCAL_MACHINE.open(keyname, access) do |reg|
      service_lists = (reg.each_key { |key, wtime| arr.push key })
      arr.each do |service|
          service_key = "SYSTEM\\CurrentControlSet\\Services\\#{service}"
          begin
            Win32::Registry::HKEY_LOCAL_MACHINE.open(service_key, access) do |reg|
                value = reg['Start']
              winservices_list.push service
            end
          rescue
          end
      end
      winservices_list
    end

  end
end

它只需添加简单地检查服务名称是否在数组中即可工作

  if $service_name in $facts['winservices'] {
    service { "${service_name}":
      provider  => 'windows',
      enable    => $start_real,
    }
  }

【讨论】:

    猜你喜欢
    • 2020-07-11
    • 2021-01-03
    • 2021-11-27
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    相关资源
    最近更新 更多