木偶-从哈希标题构建数组以检查exec中的内容

时间:2018-09-29 09:46:35

标签: arrays powershell hash puppet hiera

我正在尝试将thoward-windows_firewall模块应用于Windows 10并遇到一个障碍,即可以使用该模块的清除功能清除大多数内置规则,而其他一些规则(例如cortana)则不能。在早期的Windows版本中未发生此问题。解决方法似乎是使用“ netsh advfirewall reset”运行一个exec,以清除它们并阻止其重新出现。

但是,如果存在除我在Hiera中指定的防火墙规则以外的防火墙规则,我只想应用“ netsh advfirewall reset” exec。

我的方法是在hiera中仅构建标题的数组(或列表),然后在PowerShell中“仅当”或“除非”时对它们进行迭代。

到目前为止(无效)的代码为:

希拉片段:

harden::firewall:
   'Remote Desktop - User Mode (UDP-In)':
      description:      'Inbound rule for the Remote Desktop service to allow RDP traffic. [UDP 3389]'
      application_name: 'C:\Windows\system32\svchost.exe'
      service_name:     'termservice'
      protocol:         17
      local_ports:      '3389'
      remote_ports:     '*'
      local_addresses:  '%{facts.networking.ip}'
      remote_addresses: '*'
      direction:        1
      interface_types:  'All'
      enabled:          true
      grouping:         '@FirewallAPI.dll,-28752'
      profiles:         3
      action:           1

   'File and Printer Sharing (Echo Request - ICMPv4-In) 1':
      description:          'Echo Request messages are sent as ping requests to other nodes.'
      protocol:             1
      local_addresses:      '%{facts.networking.ip}'
      remote_addresses:     'LocalSubnet'
      icmp_types_and_codes: '8:*'
      direction:            1
      interface_types:      'All'
      enabled:              true
      grouping:             '@FirewallAPI.dll,-28502'
      profiles:             6
      action:               1

清单(摘录):

class harden (
Hash     $firewall_rule_names = lookup('harden::firewall'),
){

# reset firewall rules
  exec { 'reset_firewall':
    command  => 'netsh advfirewall reset',
    onlyif   => 'if (Get-NetFirewallRule | where {\$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }',
    provider => powershell,
  }

  Class { 'windows_firewall':
    profile_state => 'on',
    in_policy     => 'BlockInbound',
    out_policy    => 'BlockOutbound',
    rule_key      => 'harden::firewall',
    purge_rules   => true,
  }

我知道我需要在每个地方都有一个.each外观,并且还要“仅当”整理powershell,以便它仅查看哈希中的标题(也许重写为仅包含哈希标题的数组) ),并在主机上存在Hiera不在使用的规则的情况下运行该exec,但会有所遗漏。

任何帮助都由衷地感谢。

3 个答案:

答案 0 :(得分:1)

您写道:

  

我的方法是在hiera中仅构建标题的数组(或列表)   然后在PowerShell中“仅当”或“除非”时对它们进行迭代。

显然,您尝试使用以下声明在类参数$firewall_rule_names中构建该数组:

Hash     $firewall_rule_names = lookup('harden::firewall'),

,然后尝试在onlyif的{​​{1}}参数中使用该列表:

Exec

有很多问题。

首先,如果要将人偶变量内插到字符串中,则该字符串需要用双引号引起来( onlyif => 'if (Get-NetFirewallRule | where {\$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }', );用单引号("引号可以抑制插值(也可以将'视为两个文字字符,而不是转义序列)。

第二,以及您似乎不知所措的地方,例如如何提取\$哈希的键并对其进行适当格式化。我不确定Powershell在这里到底需要什么,但是要获得它,最好的一些工具是puppetlabs / stdlib模块或Puppet本身提供的$firewall_rule_nameskeys()函数。重新使用5.5版或更高版本。例如,如果您只需要一个用逗号分隔的名称列表,则可以执行以下操作:

join()

但是,我很怀疑您可能需要引用密钥。您可以通过巧妙地使用为$really_the_rule_names = join(keys($firewall_rule_names), ', ') 指定的定界符来获得大部分信息,但是您可能还需要考虑在将结果连接到字符串之前,使用内置的join函数处理键数组。

答案 1 :(得分:0)

我在Only IF语句中看到一个问题。 mysql> DROP TRIGGER tri_Test_Insert_Trigger; mysql> CREATE TRIGGER tri_Test_Insert_Trigger -> AFTER INSERT -> ON persons -> FOR Each row -> UPDATE persons -> SET review_date = date_add(birth_date, interval 1 year); Query OK, 0 rows affected (0.17 sec) mysql> insert into persons(lastname,birth_date) values('Özhan',date'2018-05-15'); ERROR 1442 (HY000): Cant update table 'persons' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. mysql> DROP TRIGGER tri_Test_Insert_Trigger; Query OK, 0 rows affected (0.17 sec) mysql> CREATE TRIGGER tri_Test_Insert_Trigger -> BEFORE INSERT -> ON persons -> FOR Each row -> SET new.review_date = date_add(new.birth_date, interval 1 year); Query OK, 0 rows affected (0.13 sec) mysql> insert into persons(lastname,birth_date) values('Özhan',date'2018-05-15'); Query OK, 1 row affected (0.09 sec) mysql> select * from persons; +----+----------+-----------+------------+-------------+ | ID | LastName | FirstName | Birth_Date | Review_Date | +----+----------+-----------+------------+-------------+ | 2 | Özhan | NULL | 2018-05-15 | 2019-05-15 | +----+----------+-----------+------------+-------------+ 1 row in set (0.00 sec) 应该是$_DisplayName,您需要使用Dot运算符来挑选对象的属性,并且也不需要$_.DisplayName

答案 2 :(得分:0)

@ John-Bollinger-Puppet和PowerShell = PuppetHell! :)

我终于设法解决了这个问题,但是觉得我的代码块太长了,替换太多了。我尝试过较短的方法都没有用,因此,如果有人可以建议使用较短的代码,将不胜感激。

简而言之,我最终不得不

  1. 通过以下方法将hiera哈希键(标题)转换为合适的数组语法以进行Powershell比较:

    a。添加单引号和逗号作为分隔符

    b。在数组的开头和结尾添加单引号和双引号

    c。当PowerShell在数组上的任意位置插入括号时,将其删除掉

    $firewall_hiera = regsubst(regsubst(regsubst(join(keys($firewall_rules), "', '"), '^', '"\''), '$', '\'"'), '[\(\)]', '', 'G')
    

产生

    "'Core Networking - DNS UDP-Out', 'Core Networking - Dynamic Host Configuration Protocol DHCP-Out', 'File and Printer Sharing Echo Request - ICMPv4-Out', 'Internet Browsing HTTP-Out', 'Internet Browsing HTTPS-Out'"

...

  1. 使用Powershell exec清除Puppet hiera中未定义的防火墙,方法是:

    a。使用exec命令清除以下内容的主机防火墙规则:

    command   => 'netsh advfirewall firewall delete rule name=all; reg delete "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules" /f',
    

    b。使用非常长的除非声明来确保幂等:

    unless => "if (@(Compare-Object((Get-NetFirewallRule | foreach {\"'\"+\$_.DisplayName+\"'\"}) -join ', ' -replace '[()]') $firewall_hiera).length -eq 0) {exit 0} else {exit 1}",
    

为以下内容与上面创建的$ firewall_hiera进行比较

    'Core Networking - DNS UDP-Out', 'Core Networking - Dynamic Host Configuration Protocol DHCP-Out', 'File and Printer Sharing Echo Request - ICMPv4-Out', 'Internet Browsing HTTP-Out', 'Internet Browsing HTTPS-Out'

然后使用thoward-windows_firewall模块(在相同的源层次结构上迭代)重新创建所需的规则(如果发生清除)。该模块比相当简陋的puppetlabs-windows_firewall模块要好,但在用户登录后无法处理Windows 10的可怕防火墙添加剂。

有趣的是,只有人偶创建的数组需要外部双引号。由于puppetlabs-powershell模块没有在磁盘上回显.ps1的内容,因此我不得不手动将它们回显,以了解实际创建的内容并在Powershell ISE中对其进行测试(较早的Josh Cooper powershell模块确实创建了临时的。 ps1,虽然安全性较差,但还是很方便)

我能够在数组中放置一些regsubst或替换字符,但是^和$在数组中的表现不理想。

所有这些都是为了解决Windows 10仅在用户登录后不断创建其他无意义防火墙规则的情况。这间歇地继续进行约6次木偶跑,最后停止。例如,Server 2012 R2从未遇到此问题。

删除以下注册表项(使用Puppetlabs注册表模块,确保=>缺失)提供了一些额外的静默功能,但它本身并没有目的:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules

再次,希望对缩短上述代码,特别是关于regsubst和-replace命令有任何帮助。请记住,生成的数组需要使用Powershell的“比较对象”功能或类似功能进行比较。

感谢@ John-Bollinger让我开始使用键和联接函数从hiera哈希创建数组。