From 463bc40ae7eb0f63b87a1ff6fc3048ae63e67e8d Mon Sep 17 00:00:00 2001 From: Bernie White Date: Fri, 17 Jan 2025 03:11:13 +1000 Subject: [PATCH] WAF rule updates #3102 (#3225) --- docs/CHANGELOG-v1.md | 5 + docs/deprecations.md | 1 + docs/en/rules/Azure.AKS.CNISubnetSize.md | 4 +- docs/en/rules/Azure.APIM.ProductTerms.md | 9 +- docs/en/rules/Azure.APIM.SampleProducts.md | 23 ++- .../rules/Azure.LogicApp.LimitHTTPTrigger.md | 90 ++++++++++- docs/en/rules/Azure.VM.Agent.md | 144 +++++++++++++++++- .../resources/logic-app-consumption.bicep | 32 ++++ .../resources/logic-app-consumption.json | 50 ++++++ docs/examples/resources/vm.bicep | 4 + docs/examples/resources/vm.json | 10 +- .../rules/Azure.APIM.Rule.ps1 | 4 +- .../Azure.Baseline.Tests.ps1 | 36 ++--- 13 files changed, 368 insertions(+), 44 deletions(-) create mode 100644 docs/examples/resources/logic-app-consumption.bicep create mode 100644 docs/examples/resources/logic-app-consumption.json diff --git a/docs/CHANGELOG-v1.md b/docs/CHANGELOG-v1.md index 71cb09e1b5e..1d3c0491e2a 100644 --- a/docs/CHANGELOG-v1.md +++ b/docs/CHANGELOG-v1.md @@ -44,6 +44,11 @@ What's changed since v1.40.0: - Updated documentation and promoted `Azure.ACR.AnonymousAccess` to GA by @BernieWhite. [#3119](https://github.com/Azure/PSRule.Rules.Azure/issues/3119) - Bumped rule set to `2024_12`. +- General improvements: + - **Important change**: Deprecated rules with no clear WAF alignment by @BernieWhite. + [#3102](https://github.com/Azure/PSRule.Rules.Azure/issues/3102) + - The following rules are deprecated: + - `Azure.APIM.ProductTerms` - Engineering: - Updated resource providers and policy aliases by @BernieWhite. [#3166](https://github.com/Azure/PSRule.Rules.Azure/pull/3166) diff --git a/docs/deprecations.md b/docs/deprecations.md index a569b03486a..0fa70914801 100644 --- a/docs/deprecations.md +++ b/docs/deprecations.md @@ -40,6 +40,7 @@ The following rules are deprecated and will be removed in v2: Reference ID | Name | Deprecated from | Reason ------------ | ---- | --------------- | ------ +AZR-000050 | Azure.APIM.ProductTerms | v1.41.0 | No clear linkage to WAF. AZR-000217 | Azure.Template.UseParameters | v1.36.0 | Linting already handled by Bicep linter. No clear linkage to WAF. AZR-000219 | Azure.Template.UseVariables | v1.36.0 | Linting already handled by Bicep linter. No clear linkage to WAF. AZR-000218 | Azure.Template.DefineParameters | v1.36.0 | No applicable to Bicep. No clear linkage to WAF. diff --git a/docs/en/rules/Azure.AKS.CNISubnetSize.md b/docs/en/rules/Azure.AKS.CNISubnetSize.md index d30c936731e..06525910bcf 100644 --- a/docs/en/rules/Azure.AKS.CNISubnetSize.md +++ b/docs/en/rules/Azure.AKS.CNISubnetSize.md @@ -1,7 +1,7 @@ --- severity: Important pillar: Reliability -category: Scalability +category: PE:05 Scaling and partitioning resource: Azure Kubernetes Service online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AKS.CNISubnetSize/ --- @@ -43,7 +43,7 @@ configuration: ## LINKS -- [Plan for growth](https://learn.microsoft.com/azure/architecture/framework/scalability/design-scale#plan-for-growth) +- [PE:05 Scaling and partitioning](https://learn.microsoft.com/azure/well-architected/performance-efficiency/scale-partition#configure-scaling) - [Configure Azure CNI networking in Azure Kubernetes Service (AKS)](https://learn.microsoft.com/azure/aks/configure-azure-cni) - [Use kubenet networking with your own IP address ranges in Azure Kubernetes Service (AKS)](https://learn.microsoft.com/azure/aks/configure-kubenet) - [Tutorial: Configure Azure CNI networking in Azure Kubernetes Service (AKS) using Ansible](https://learn.microsoft.com/azure/developer/ansible/aks-configure-cni-networking) diff --git a/docs/en/rules/Azure.APIM.ProductTerms.md b/docs/en/rules/Azure.APIM.ProductTerms.md index f4a28ea0990..bc02871cc11 100644 --- a/docs/en/rules/Azure.APIM.ProductTerms.md +++ b/docs/en/rules/Azure.APIM.ProductTerms.md @@ -1,4 +1,5 @@ --- +deprecated: true severity: Important pillar: Operational Excellence category: Configuration @@ -6,7 +7,7 @@ resource: API Management online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.APIM.ProductTerms/ --- -# Use API product legal terms +# API Management products do not have legal terms set ## SYNOPSIS @@ -25,6 +26,12 @@ Acceptance of legal terms is bypassed when an administrator creates a subscripti Consider configuring legal terms for all products to declare acceptable use of included APIs. +## NOTES + +This rule is deprecated from v1.41.0. +By default, PSRule will not evaluate this rule unless explicitly enabled. +See https://aka.ms/ps-rule-azure/deprecations. + ## LINKS - [Create and publish a product](https://learn.microsoft.com/azure/api-management/api-management-howto-add-products) diff --git a/docs/en/rules/Azure.APIM.SampleProducts.md b/docs/en/rules/Azure.APIM.SampleProducts.md index 0afdc0e11a5..f5067cb78ac 100644 --- a/docs/en/rules/Azure.APIM.SampleProducts.md +++ b/docs/en/rules/Azure.APIM.SampleProducts.md @@ -1,26 +1,37 @@ --- severity: Awareness -pillar: Operational Excellence -category: Configuration +pillar: Security +category: SE:08 Hardening resources resource: API Management online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.APIM.SampleProducts/ --- -# Remove default products +# API Management Service has default products present ## SYNOPSIS -Remove starter and unlimited sample products. +API Management Services with default products configured may expose more APIs than intended. ## DESCRIPTION API Management includes two sample products _Starter_ and _Unlimited_. -Accidentally adding APIs to these sample products may expose APIs more than intended. +These products are created by default when an API Management Service using V1 plans is created. + +In both cases, these products are created with a default set of developer permissions that may be too permissive. +Accidentally adding APIs to these sample products may expose API metadata to unauthorized users. + +Before publishing APIs, plan access control for API development and usage. +Additional products or workspaces can be created to manage discovery of APIs and enforce usage policies. ## RECOMMENDATION -Consider removing starter and unlimited sample products from API Management. +Consider removing starter and unlimited products from API Management to reduce the risk of unauthorized API discovery. + +## NOTES + +This rule applies when analyzing API Management Services (in-flight) and running within Azure. ## LINKS +- [SE:08 Hardening resources](https://learn.microsoft.com/azure/well-architected/security/harden-resources) - [Create and publish a product](https://learn.microsoft.com/azure/api-management/api-management-howto-add-products) diff --git a/docs/en/rules/Azure.LogicApp.LimitHTTPTrigger.md b/docs/en/rules/Azure.LogicApp.LimitHTTPTrigger.md index 513ac2ccb7a..fd9f14c3b78 100644 --- a/docs/en/rules/Azure.LogicApp.LimitHTTPTrigger.md +++ b/docs/en/rules/Azure.LogicApp.LimitHTTPTrigger.md @@ -1,27 +1,105 @@ --- +reviewed: 2025-01-17 severity: Critical pillar: Security -category: Network security and containment +category: SE:06 Network controls resource: Logic App online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.LogicApp.LimitHTTPTrigger/ --- -# Limit Logic App HTTP request triggers +# Logic App HTTP request trigger is not restricted ## SYNOPSIS -Limit HTTP request trigger access to trusted IP addresses. +Logic Apps using HTTP triggers without restrictions can be accessed from any network location including the Internet. ## DESCRIPTION -When a Logic App uses a HTTP request trigger by default any source IP address can trigger the workflow. -Logic Apps can be configured to limit the IP addresses that are accepted to trigger the workflow. +Logic Apps are workflows that integrate services and systems across cloud services and on-premises systems. +Logic Apps can be triggered by a variety of events including HTTP requests. + +When HTTP request trigger is configured, +by default the Logic App in a consumption plan may receive requests from any source IP address. +This can expose the Logic App to unauthorized access or exfiltration attempts. + +Logic Apps can be secured by restricting access to trusted IP addresses. ## RECOMMENDATION -Consider limiting Logic Apps with HTTP request triggers to trusted IP addresses. +Consider restricting HTTP triggers to trusted IP addresses to harden against unauthorized access or exfiltration attempts. + +## EXAMPLES + +### Configure with Azure template + +To deploy Logic Apps that pass this rule: + +- Set the `allowedCallerIpAddresses` property to a list of IP address ranges. + +For example: + +```json +{ + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "properties": { + "definition": "", + "parameters": {}, + "accessControl": { + "contents": { + "allowedCallerIpAddresses": [ + { + "addressRange": "192.168.12.0/23" + }, + { + "addressRange": "2001:0db8::/64" + } + ] + } + } + } +} +``` + +### Configure with Bicep + +To deploy Logic Apps that pass this rule: + +- Set the `allowedCallerIpAddresses` property to a list of IP address ranges. + +For example: + +```bicep +resource app 'Microsoft.Logic/workflows@2019-05-01' = { + name: name + location: location + properties: { + definition: '' + parameters: {} + accessControl: { + contents: { + allowedCallerIpAddresses: [ + { + addressRange: '192.168.12.0/23' + } + { + addressRange: '2001:0db8::/64' + } + ] + } + } + } +} +``` + +## NOTES + +This rule currently only applies to Logic Apps using consumption plans. ## LINKS +- [SE:06 Network controls](https://learn.microsoft.com/azure/well-architected/security/networking) - [Secure access and data in Azure Logic Apps](https://learn.microsoft.com/azure/logic-apps/logic-apps-securing-a-logic-app) - [Azure security baseline for Logic Apps](https://learn.microsoft.com/azure/logic-apps/security-baseline#network-security) diff --git a/docs/en/rules/Azure.VM.Agent.md b/docs/en/rules/Azure.VM.Agent.md index 6cef4dd1d03..c3a33f091e3 100644 --- a/docs/en/rules/Azure.VM.Agent.md +++ b/docs/en/rules/Azure.VM.Agent.md @@ -1,29 +1,161 @@ --- severity: Important pillar: Operational Excellence -category: Monitoring +category: OE:10 Automation design resource: Virtual Machine online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.VM.Agent/ ms-content-id: e4f6f6e7-593c-4507-811d-778ee8ec9ac4 --- -# VM agent is provisioned automatically +# Virtual Machine agent is not provisioned ## SYNOPSIS -Ensure the VM agent is provisioned automatically. +Virtual Machines (VMs) without an agent provisioned are unable to use monitoring, management, and security extensions. ## DESCRIPTION The virtual machine (VM) agent is required for most functionality that interacts with the guest operating system. +This includes any VMs extensions such as Azure monitoring, management, and security features. -VM extensions help reduce management overhead by providing an entry point to bootstrap monitoring and configuration of the guest operating system. -The VM agent is required to use any VM extensions. +Extensions help reduce management overhead by providing an entry point to bootstrap VM monitoring and configuration. + +By default, the VM agent is provisioned for all supported operating systems. ## RECOMMENDATION -Automatically provision the VM agent for all supported operating systems, this is the default. +Consider automatically provisioning the VM agent for all supported operating systems to reduce management overhead of VMs. + +## EXAMPLES + +### Configure with Azure template + +To deploy VMs that pass this rule: + +- Set the `properties.osProfile.linuxConfiguration.provisionVMAgent` property to `true` for Linux VMs. +- Set the `properties.osProfile.windowsConfiguration.provisionVMAgent` property to `true` for Windows VMs. + +For example: + +```json +{ + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2024-03-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "hardwareProfile": { + "vmSize": "Standard_D8d_v5" + }, + "osProfile": { + "computerName": "[parameters('name')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "provisionVMAgent": true, + "disablePasswordAuthentication": true + } + }, + "storageProfile": { + "imageReference": { + "publisher": "MicrosoftCblMariner", + "offer": "Cbl-Mariner", + "sku": "cbl-mariner-2-gen2", + "version": "latest" + }, + "osDisk": { + "name": "[format('{0}-disk0', parameters('name'))]", + "caching": "ReadWrite", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" + } + ] + } + }, + "zones": [ + "1" + ], + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" + ] +} +``` + +### Configure with Bicep + +To deploy VMs that pass this rule: + +- Set the `properties.osProfile.linuxConfiguration.provisionVMAgent` property to `true` for Linux VMs. +- Set the `properties.osProfile.windowsConfiguration.provisionVMAgent` property to `true` for Windows VMs. + +For example: + +```bicep +resource linux 'Microsoft.Compute/virtualMachines@2024-03-01' = { + name: name + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + hardwareProfile: { + vmSize: 'Standard_D8d_v5' + } + osProfile: { + computerName: name + adminUsername: adminUsername + linuxConfiguration: { + provisionVMAgent: true + disablePasswordAuthentication: true + } + } + storageProfile: { + imageReference: { + publisher: 'MicrosoftCblMariner' + offer: 'Cbl-Mariner' + sku: 'cbl-mariner-2-gen2' + version: 'latest' + } + osDisk: { + name: '${name}-disk0' + caching: 'ReadWrite' + createOption: 'FromImage' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + } + networkProfile: { + networkInterfaces: [ + { + id: nic.id + } + ] + } + } + zones: [ + '1' + ] +} +``` + +## NOTES + +In general provisioning the VM agent is recommended for all supported operating systems. +For network virtual appliances (NVAs) or specialized unsupported OS images installed from the Azure Marketplace, +the VM agent may be disabled by the publisher. ## LINKS +- [OE:10 Automation design](https://learn.microsoft.com/azure/well-architected/operational-excellence/enable-automation) - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.compute/virtualmachines) diff --git a/docs/examples/resources/logic-app-consumption.bicep b/docs/examples/resources/logic-app-consumption.bicep new file mode 100644 index 00000000000..2248b2f06d4 --- /dev/null +++ b/docs/examples/resources/logic-app-consumption.bicep @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// Bicep documentation examples + +@description('The name of the resource.') +param name string + +@description('The location resources will be deployed.') +param location string = resourceGroup().location + +// An example Logic App with IP restrictions. +resource app 'Microsoft.Logic/workflows@2019-05-01' = { + name: name + location: location + properties: { + definition: '' + parameters: {} + accessControl: { + contents: { + allowedCallerIpAddresses: [ + { + addressRange: '192.168.12.0/23' + } + { + addressRange: '2001:0db8::/64' + } + ] + } + } + } +} diff --git a/docs/examples/resources/logic-app-consumption.json b/docs/examples/resources/logic-app-consumption.json new file mode 100644 index 00000000000..a96931c3d9b --- /dev/null +++ b/docs/examples/resources/logic-app-consumption.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "470250706748108541" + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the resource." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location resources will be deployed." + } + } + }, + "resources": [ + { + "type": "Microsoft.Logic/workflows", + "apiVersion": "2019-05-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "properties": { + "definition": "", + "parameters": {}, + "accessControl": { + "contents": { + "allowedCallerIpAddresses": [ + { + "addressRange": "192.168.12.0/23" + }, + { + "addressRange": "2001:0db8::/64" + } + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/docs/examples/resources/vm.bicep b/docs/examples/resources/vm.bicep index 4859774f8b4..900f9c05ef7 100644 --- a/docs/examples/resources/vm.bicep +++ b/docs/examples/resources/vm.bicep @@ -41,6 +41,9 @@ resource vm 'Microsoft.Compute/virtualMachines@2024-03-01' = { computerName: name adminUsername: adminUsername adminPassword: adminPassword + windowsConfiguration: { + provisionVMAgent: true + } } storageProfile: { imageReference: { @@ -224,6 +227,7 @@ resource linux 'Microsoft.Compute/virtualMachines@2024-03-01' = { computerName: name adminUsername: adminUsername linuxConfiguration: { + provisionVMAgent: true disablePasswordAuthentication: true } } diff --git a/docs/examples/resources/vm.json b/docs/examples/resources/vm.json index ba0f2b05a36..2dd590c05e0 100644 --- a/docs/examples/resources/vm.json +++ b/docs/examples/resources/vm.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.92.45157", - "templateHash": "1657333872264934230" + "version": "0.32.4.45862", + "templateHash": "13775676563717028722" } }, "parameters": { @@ -77,7 +77,10 @@ "osProfile": { "computerName": "[parameters('name')]", "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]" + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVMAgent": true + } }, "storageProfile": { "imageReference": { @@ -269,6 +272,7 @@ "computerName": "[parameters('name')]", "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": { + "provisionVMAgent": true, "disablePasswordAuthentication": true } }, diff --git a/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 index eeae178ccf1..c6ba27144ea 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Azure.APIM.Rule.ps1 @@ -129,7 +129,7 @@ Rule 'Azure.APIM.ProductApproval' -Ref 'AZR-000047' -Type 'Microsoft.ApiManageme } # Synopsis: Remove sample products -Rule 'Azure.APIM.SampleProducts' -Ref 'AZR-000048' -Type 'Microsoft.ApiManagement/service', 'Microsoft.ApiManagement/service/products' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { +Rule 'Azure.APIM.SampleProducts' -Ref 'AZR-000048' -Type 'Microsoft.ApiManagement/service', 'Microsoft.ApiManagement/service/products' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } { $products = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.ApiManagement/service') { $products = @(GetSubResources -ResourceType 'Microsoft.ApiManagement/service/products'); @@ -162,7 +162,7 @@ Rule 'Azure.APIM.ProductDescriptors' -Ref 'AZR-000049' -Level Warning -Type 'Mic } # Synopsis: Use product terms -Rule 'Azure.APIM.ProductTerms' -Ref 'AZR-000050' -Type 'Microsoft.ApiManagement/service', 'Microsoft.ApiManagement/service/products' -Tag @{ release = 'GA'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { +Rule 'Azure.APIM.ProductTerms' -Ref 'AZR-000050' -Type 'Microsoft.ApiManagement/service', 'Microsoft.ApiManagement/service/products' -Tag @{ release = 'deprecated'; ruleSet = '2020_09'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { $products = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.ApiManagement/service') { $products = @(GetSubResources -ResourceType 'Microsoft.ApiManagement/service/products'); diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.Baseline.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.Baseline.Tests.ps1 index 3a7aefd2440..d2842cb32d8 100644 --- a/tests/PSRule.Rules.Azure.Tests/Azure.Baseline.Tests.ps1 +++ b/tests/PSRule.Rules.Azure.Tests/Azure.Baseline.Tests.ps1 @@ -66,35 +66,35 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2020_09' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 149; + $filteredResult.Length | Should -Be 148; } It 'With Azure.GA_2020_12' { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2020_12' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 171; + $filteredResult.Length | Should -Be 170; } It 'With Azure.GA_2021_03' { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2021_03' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 185; + $filteredResult.Length | Should -Be 184; } It 'With Azure.GA_2021_06' { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2021_06' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 199; + $filteredResult.Length | Should -Be 198; } It 'With Azure.GA_2021_09' { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2021_09' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 217; + $filteredResult.Length | Should -Be 216; } It 'With Azure.Preview_2021_09' { @@ -108,7 +108,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2021_12' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 242; + $filteredResult.Length | Should -Be 241; } It 'With Azure.Preview_2021_12' { @@ -122,7 +122,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2022_03' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 258; + $filteredResult.Length | Should -Be 257; } It 'With Azure.Preview_2022_03' { @@ -136,7 +136,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2022_06' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 262; + $filteredResult.Length | Should -Be 261; } It 'With Azure.Preview_2022_06' { @@ -150,7 +150,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2022_09' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 293; + $filteredResult.Length | Should -Be 292; } It 'With Azure.Preview_2022_09' { @@ -164,7 +164,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2022_12' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 329; + $filteredResult.Length | Should -Be 328; } It 'With Azure.Preview_2022_12' { @@ -178,7 +178,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2023_03' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 349; + $filteredResult.Length | Should -Be 348; } It 'With Azure.Preview_2023_03' { @@ -192,7 +192,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2023_06' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 364; + $filteredResult.Length | Should -Be 363; } It 'With Azure.Preview_2023_06' { @@ -206,7 +206,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2023_09' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 375; + $filteredResult.Length | Should -Be 374; } It 'With Azure.Preview_2023_09' { @@ -220,7 +220,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2023_12' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 384; + $filteredResult.Length | Should -Be 383; } It 'With Azure.Preview_2023_12' { @@ -234,7 +234,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_03' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 394; + $filteredResult.Length | Should -Be 393; } It 'With Azure.Preview_2024_03' { @@ -248,7 +248,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_06' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 415; + $filteredResult.Length | Should -Be 414; } It 'With Azure.Preview_2024_06' { @@ -262,7 +262,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_09' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 432; + $filteredResult.Length | Should -Be 431; } It 'With Azure.Preview_2024_09' { @@ -276,7 +276,7 @@ Describe 'Baselines' -Tag Baseline { $result = @(Get-PSRule -Module PSRule.Rules.Azure -Baseline 'Azure.GA_2024_12' -WarningAction Ignore); $filteredResult = @($result | Where-Object { $_.Tag.release -in 'GA'}); $filteredResult | Should -Not -BeNullOrEmpty; - $filteredResult.Length | Should -Be 435; + $filteredResult.Length | Should -Be 434; } It 'With Azure.Preview_2024_12' {