某些 JSON 文件出现 PowerShell FilterScript 错误

标签 powershell

感谢 iRon 本周早些时候通过此 question 提供的帮助,他为我目前正在进行的一项工作提供了巨大帮助。

总之,我们有一个 Azure CICD 管道来部署策略。我们有一个包含 200 多个 JSON 策略文件的文件夹,CICD 流程将它们全部放在 1 个 JSON 文件中并将它们部署出来。我们发现的最初问题是参数需要一个额外的前导“[”,否则该过程将失败。这在 article 中得到了强调。 (如果您搜索 [[)。

无论如何,解决问题。 iRons 支持帮了很大的忙,但在 200 个文件中,我们得到了一些文件,其中我们收到以下消息:

Cannot bind argument to parameter 'FilterScript' because it is null.

代码:

iRon 提供的功能:

function Get-Node {
    [CmdletBinding()][OutputType([Object[]])] param(
        [ScriptBlock]$Where,
        [Parameter(ValueFromPipeLine = $True, Mandatory = $True)]$InputObject,
        [Int]$Depth = 10
    )
    process {
        if ($_ -isnot [String] -and $Depth -gt 0) {
            if ($_ -is [Collections.IDictionary]) {
                if (& $Where) {$_}
                $_.get_Values() | Get-Node -Where $Where -Depth ($Depth -1)
            }
            elseif  ($_ -is [Collections.IEnumerable]) {
                for ($i = 0; $i -lt $_.get_Count(); $i++) { $_[$i] | Get-Node -Where $Where -Depth ($Depth -1) }
            }
            elseif ($Nodes = $_.PSObject.Properties.Where{$_.MemberType -eq 'NoteProperty'}) {
                $Nodes.ForEach{
                    if (& $Where) { $_ }
                    $_.Value | Get-Node -Where $Where -Depth ($Depth -1)
                }
            }
        }
    }
}

我调用上述函数的位置(此代码位于每个文件的循环中):

    $policyRule = @("notIn", "in", "value", "equals", "field", "effect", "like", "greaterOrEquals", "name", "resourceGroupName", "resourceGroup", "location", "storageName", "uniqueStorage", "storageContainerPath", "storageAccountAccessKey", "dependsOn", "targetResourceId", "storageId", "enabled")
    
    if ($content.properties -ne $null){
        # Loop all the Policy Rule names for fix the values within them
        foreach ($rule in $policyRule){
            $Node = $content.properties.policyRule | Get-Node -Where {$_.name -eq $rule -and $_.value -Match "^\[\w+" -and $_.value -ne ""} 
            $Node | ForEach-Object {$_.Value  = '[' + $_.Value}
        }                 
    }

有效的 JSON 文件:

{
  "name": "POLICY-001",
  "properties": {
    "displayName": "Allowed Locations for Resources",
    "policyType": "Custom",
    "mode": "Indexed",
    "description": "This policy enables you to restrict the locations your organization can specify when deploying resources. Use to enforce your geo-compliance requirements. Excludes resource groups, Microsoft.AzureActiveDirectory/b2cDirectories, and resources that use the 'global' region.",
    "metadata": {
      "version": "1.0.0",
      "category": "General"
    },
    "parameters": {
      "listOfAllowedLocations": {
        "type": "Array",
        "metadata": {
          "description": "The list of locations that can be specified when deploying resources.",
          "strongType": "location",
          "displayName": "Allowed locations"
        },
        "allowedValues": [
          "uksouth",
          "ukwest"
        ],
        "defaultValue": [
          "uksouth",
          "ukwest"
        ]
      }
    },
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "location",
            "notIn": "[parameters('listOfAllowedLocations')]"
          },
          {
            "field": "location",
            "notEquals": "global"
          },
          {
            "field": "type",
            "notEquals": "Microsoft.Resources/subscriptions/resourceGroups"
          },
          {
            "field": "type",
            "notEquals": "Microsoft.Resources/b2cDirectories"
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  },
  "excludedScopes": [
    
  ],
  "nonComplianceMessage": "only allow resources to be deployed from UK South and UK West"
}

失败的一个:

{
  "Name": "Policy-106",
  "Properties": {
    "Description": "This policy automatically deploys and enable diagnostic settings to Log Analytics",
    "DisplayName": "Apply diagnostic settings for Log Analytics Workspaces",
    "Mode": "Indexed",
    "policyType": "Custom",
    "Metadata": {
      "version": "1.0",
      "category": "Monitoring"
    },
    "Parameters": {
      "diagnosticsSettingNameToUse": {
        "type": "string",
        "metadata": {
          "displayName": "Apply diagnostic settings for Log Analytics Workspaces - Setting name",
          "description": "Name of the policy for the diagnostics settings."
        },
        "defaultValue": "setViaPolicy"
      },
      "logAnalytics": {
        "type": "string",
        "metadata": {
          "displayName": "Apply diagnostic settings for Log Analytics Workspaces - Log Analytics workspace",
          "description": "Select the Log Analytics workspace from dropdown list",
          "strongType": "omsWorkspace",
          "assignPermissions": true
        },
        "defaultValue": "/subscriptions/......"
      }
    },
    "PolicyRule": {
      "if": {
        "field": "type",
        "equals": "Microsoft.OperationalInsights/Workspaces"
      },
      "then": {
        "effect": "deployIfNotExists",
        "details": {
          "type": "Microsoft.Insights/diagnosticSettings",
          "roleDefinitionIds": [
            "/providers/Microsoft.Authorization/roleDefinitions/123"
          ],
          "existenceCondition": {
            "allOf": [
              {
                "field": "Microsoft.Insights/diagnosticSettings/logs.enabled",
                "equals": "True"
              },
              {
                "field": "Microsoft.Insights/diagnosticSettings/metrics.enabled",
                "equals": "True"
              },
              {
                "field": "Microsoft.Insights/diagnosticSettings/workspaceId",
                "matchInsensitively": "[parameters('logAnalytics')]"
              }
            ]
          },
          "deployment": {
            "properties": {
              "mode": "incremental",
              "template": {
                "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {
                  "diagnosticsSettingNameToUse": {
                    "type": "string"
                  },
                  "resourceName": {
                    "type": "string"
                  },
                  "logAnalytics": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  }
                },
                "variables": {},
                "resources": [
                  {
                    "type": "Microsoft.OperationalInsights/Workspaces/providers/diagnosticSettings",
                    "apiVersion": "2017-05-01-preview",
                    "name": "[concat(parameters('resourceName'), '/', 'Microsoft.Insights/', parameters('diagnosticsSettingNameToUse'))]",
                    "location": "[parameters('location')]",
                    "dependsOn": [],
                    "properties": {
                      "workspaceId": "[parameters('logAnalytics')]",
                      "metrics": [
                        {
                          "category": "AllMetrics",
                          "timeGrain": null,
                          "enabled": true,
                          "retentionPolicy": {
                            "enabled": false,
                            "days": 0
                          }
                        }
                      ],
                      "logs": [
                        {
                          "category": "Audit",
                          "enabled": true
                        }
                      ]
                    }
                  }
                ],
                "outputs": {}
              },
              "parameters": {
                "diagnosticsSettingNameToUse": {
                  "value": "[parameters('diagnosticsSettingNameToUse')]"
                },
                "logAnalytics": {
                  "value": "[parameters('logAnalytics')]"
                },
                "location": {
                  "value": "[field('location')]"
                },
                "resourceName": {
                  "value": "[field('name')]"
                }
              }
            }
          }
        }
      }
    }
  },
  "excludedScopes": [

  ],
  "nonComplianceMessage": ""
}

正如我在原来的帖子中提到的,我的 PowerShell 充其量只是基本的,如果有任何支持,我们将不胜感激。

最佳答案

处理失败的 JSON 文件包含 null 值,当通过 ConvertFrom-Json 将 JSON 文件转换为对象图时,这些值会在 PowerShell 中变成 $null 值.

问题中所示的 Get-Node 函数不支持将 $null 绑定(bind)到其管道绑定(bind) -InputObject 参数,每当以下语句中 $_.Value 恰好为 $null 时,就会导致错误:
$_.Value | Get-Node -Where $Where -Depth ($Depth - 1)

解决方案很简单:通过添加 [AllowNull()] 允许 -InputObject 参数接受 $null属性为 original function :

function Get-Node {
  [CmdletBinding()][OutputType([Object[]])] param(
    [ScriptBlock]$Where,
    [AllowNull()]   # <- now $null may be passed too
    [Parameter(ValueFromPipeLine = $True, Mandatory = $True)]$InputObject,
    [Int]$Depth = 10
  )
  process {
    if ($_ -isnot [String] -and $Depth -gt 0) {
      if ($_ -is [Collections.IDictionary]) {
        if (& $Where) { $_ }
        $_.get_Values() | Get-Node -Where $Where -Depth ($Depth - 1)
      }
      elseif ($_ -is [Collections.IEnumerable]) {
        for ($i = 0; $i -lt $_.get_Count(); $i++) { $_[$i] | Get-Node -Where $Where -Depth ($Depth - 1) }
      }
      elseif ($Nodes = $_.PSObject.Properties.Where{ $_.MemberType -eq 'NoteProperty' }) {
        $Nodes.ForEach{
          if (& $Where) { $_ }
          $_.Value | Get-Node -Where $Where -Depth ($Depth - 1)
        }
      }
    }
  }
}

关于某些 JSON 文件出现 PowerShell FilterScript 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74510152/

相关文章:

powershell - 使用 Powershell 脚本开始调试 Visual Studio 项目

azure - 无法通过 Azure 门户中的 Powershell 运行命令启用/禁用 VM 的网络接口(interface)

powershell - 使用Powershell向现有CSV添加新行?

google-chrome - 用于启动 Chrome 等的 Powershell 脚本

azure - 无法在 PowerShell 中安装 Azure 模块

powershell - 密码过期前的天数

python - 从 PowerShell 运行 Python 函数

powershell - 如何删除或替换 powershell 中的内置别名?

file - 如何复制某些文件(无文件夹层次结构),但不覆盖现有文件?

function - powershell 中 "x"秒后停止函数