From 3ddde67d66e71e88b351631f7f60d4eaf7afcf0b Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Fri, 8 Nov 2024 14:02:38 +0100 Subject: [PATCH] Add Intune Firewall rules policy for Windows10 --- CHANGELOG.md | 3 + ...FT_IntuneFirewallRulesPolicyWindows10.psm1 | 657 ++++++++++++++++++ ...uneFirewallRulesPolicyWindows10.schema.mof | 54 ++ .../readme.md | 6 + .../settings.json | 44 ++ .../1-Create.ps1 | 56 ++ .../2-Update.ps1 | 56 ++ .../3-Remove.ps1 | 34 + ResourceGenerator/UnitTest.Template.ps1 | 4 +- ...tuneFirewallRulesPolicyWindows10.Tests.ps1 | 584 ++++++++++++++++ 10 files changed, 1497 insertions(+), 1 deletion(-) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/settings.json create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/1-Create.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/2-Update.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/3-Remove.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneFirewallRulesPolicyWindows10.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index a702020fe7..635851d6dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ # UNRELEASED +* IntuneFirewallRulesPolicyWindows10 + * Initial release. + # 1.24.1106.1 * AADAccessReviewDefinition diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.psm1 new file mode 100644 index 0000000000..bf0f395f72 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.psm1 @@ -0,0 +1,657 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $FirewallRuleName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + try + { + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + + $getValue = $null + #region resource generator code + $getValue = Get-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $Id -ErrorAction SilentlyContinue + + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune Firewall Rules Policy for Windows10 with Id {$Id}" + + if (-not [System.String]::IsNullOrEmpty($DisplayName)) + { + $getValue = Get-MgBetaDeviceManagementConfigurationPolicy ` + -Filter "Name eq '$DisplayName'" ` + -All ` + -ErrorAction SilentlyContinue + } + } + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune Firewall Rules Policy for Windows10 with Name {$DisplayName}." + return $nullResult + } + $Id = $getValue.Id + Write-Verbose -Message "An Intune Firewall Rules Policy for Windows10 with Id {$Id} and Name {$DisplayName} was found" + + # Retrieve policy specific settings + [array]$settings = Get-MgBetaDeviceManagementConfigurationPolicySetting ` + -DeviceManagementConfigurationPolicyId $Id ` + -ExpandProperty 'settingDefinitions' ` + -All ` + -ErrorAction Stop + + $policySettings = @{} + $policySettings = Export-IntuneSettingCatalogPolicySettings -Settings $settings -ReturnHashtable $policySettings + + #region resource generator code + $complexFirewallRuleName = @() + foreach ($currentFirewallRuleName in $policySettings.firewallRuleName) + { + $myFirewallRuleName = @{} + $myFirewallRuleName.Add('Enabled', $currentFirewallRuleName.enabled) + $myFirewallRuleName.Add('Name', $currentFirewallRuleName.name) + $myFirewallRuleName.Add('InterfaceTypes', $currentFirewallRuleName.interfaceTypes) + $myFirewallRuleName.Add('FilePath', $currentFirewallRuleName.filePath) + $myFirewallRuleName.Add('RemotePortRanges', $currentFirewallRuleName.remotePortRanges) + $myFirewallRuleName.Add('EdgeTraversal', $currentFirewallRuleName.edgeTraversal) + $myFirewallRuleName.Add('LocalUserAuthorizedList', $currentFirewallRuleName.localUserAuthorizedList) + $myFirewallRuleName.Add('Profiles', $currentFirewallRuleName.profiles) + $myFirewallRuleName.Add('LocalPortRanges', $currentFirewallRuleName.localPortRanges) + $myFirewallRuleName.Add('Description', $currentFirewallRuleName.description) + $myFirewallRuleName.Add('PolicyAppId', $currentFirewallRuleName.policyAppId) + $myFirewallRuleName.Add('PackageFamilyName', $currentFirewallRuleName.packageFamilyName) + $myFirewallRuleName.Add('LocalAddressRanges', $currentFirewallRuleName.localAddressRanges) + $myFirewallRuleName.Add('Direction', $currentFirewallRuleName.direction) + $myFirewallRuleName.Add('ServiceName', $currentFirewallRuleName.serviceName) + $myFirewallRuleName.Add('RemoteAddressRanges', $currentFirewallRuleName.remoteAddressRanges) + $myFirewallRuleName.Add('Type', $currentFirewallRuleName.type) + $myFirewallRuleName.Add('RemoteAddressDynamicKeywords', $currentFirewallRuleName.remoteAddressDynamicKeywords) + $myFirewallRuleName.Add('Protocol', $currentFirewallRuleName.protocol) + $myFirewallRuleName.Add('IcmpTypesAndCodes', $currentFirewallRuleName.icmpTypesAndCodes) + if ($myFirewallRuleName.values.Where({$null -ne $_}).Count -gt 0) + { + $complexFirewallRuleName += $myFirewallRuleName + } + } + $policySettings.Remove('FirewallRuleName') | Out-Null + #endregion + + $results = @{ + #region resource generator code + Description = $getValue.Description + DisplayName = $getValue.Name + RoleScopeTagIds = $getValue.RoleScopeTagIds + Id = $getValue.Id + FirewallRuleName = $complexFirewallRuleName + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + #endregion + } + $results += $policySettings + + $assignmentsValues = Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $Id + $assignmentResult = @() + if ($assignmentsValues.Count -gt 0) + { + $assignmentResult += ConvertFrom-IntunePolicyAssignment -Assignments $assignmentsValues -IncludeDeviceFilter $true + } + $results.Add('Assignments', $assignmentResult) + + return [System.Collections.Hashtable] $results + } + catch + { + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $FirewallRuleName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentInstance = Get-TargetResource @PSBoundParameters + + $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + $templateReferenceId = '19c8aa67-f286-4861-9aa0-f23541d31680_1' + $platforms = 'windows10' + $technologies = 'mdm,microsoftSense' + + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating an Intune Firewall Rules Policy for Windows10 with Name {$DisplayName}" + $BoundParameters.Remove("Assignments") | Out-Null + + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` + -TemplateId $templateReferenceId + + $createParameters = @{ + Name = $DisplayName + Description = $Description + TemplateReference = @{ templateId = $templateReferenceId } + Platforms = $platforms + Technologies = $technologies + Settings = $settings + } + + #region resource generator code + $policy = New-MgBetaDeviceManagementConfigurationPolicy -BodyParameter $createParameters + + if ($policy.Id) + { + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $policy.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' + } + #endregion + } + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating the Intune Firewall Rules Policy for Windows10 with Id {$($currentInstance.Id)}" + $BoundParameters.Remove("Assignments") | Out-Null + + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` + -TemplateId $templateReferenceId + + Update-IntuneDeviceConfigurationPolicy ` + -DeviceConfigurationPolicyId $currentInstance.Id ` + -Name $DisplayName ` + -Description $Description ` + -TemplateReferenceId $templateReferenceId ` + -Platforms $platforms ` + -Technologies $technologies ` + -Settings $settings + + #region resource generator code + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $currentInstance.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' + #endregion + } + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing the Intune Firewall Rules Policy for Windows10 with Id {$($currentInstance.Id)}" + #region resource generator code + Remove-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $currentInstance.Id + #endregion + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $FirewallRuleName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + Write-Verbose -Message "Testing configuration of the Intune Firewall Rules Policy for Windows10 with Id {$Id} and Name {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + [Hashtable]$ValuesToCheck = @{} + $MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { + if ($_.Key -notlike '*Variable' -or $_.Key -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction')) + { + if ($null -ne $CurrentValues[$_.Key] -or $null -ne $PSBoundParameters[$_.Key]) + { + $ValuesToCheck.Add($_.Key, $null) + if (-not $PSBoundParameters.ContainsKey($_.Key)) + { + $PSBoundParameters.Add($_.Key, $null) + } + } + } + } + + if ($CurrentValues.Ensure -ne $Ensure) + { + Write-Verbose -Message "Test-TargetResource returned $false" + return $false + } + $testResult = $true + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) + { + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-not $testResult) + { + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } + } + + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + + if ($testResult) + { + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + } + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + #region resource generator code + $policyTemplateID = "19c8aa67-f286-4861-9aa0-f23541d31680_1" + [array]$getValue = Get-MgBetaDeviceManagementConfigurationPolicy ` + -Filter $Filter ` + -All ` + -ErrorAction Stop | Where-Object ` + -FilterScript { + $_.TemplateReference.TemplateId -eq $policyTemplateID + } + #endregion + + $i = 1 + $dscContent = '' + if ($getValue.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $getValue) + { + $displayedKey = $config.Id + if (-not [String]::IsNullOrEmpty($config.displayName)) + { + $displayedKey = $config.displayName + } + elseif (-not [string]::IsNullOrEmpty($config.name)) + { + $displayedKey = $config.name + } + Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline + $params = @{ + Id = $config.Id + DisplayName = $config.Name + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + if ($null -ne $Results.FirewallRuleName) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.FirewallRuleName ` + -CIMInstanceName 'MicrosoftGraphIntuneSettingsCatalogFirewallRuleName' + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.FirewallRuleName = $complexTypeStringResult + } + else + { + $Results.Remove('FirewallRuleName') | Out-Null + } + } + + if ($Results.Assignments) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName DeviceManagementConfigurationPolicyAssignments + if ($complexTypeStringResult) + { + $Results.Assignments = $complexTypeStringResult + } + else + { + $Results.Remove('Assignments') | Out-Null + } + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + if ($Results.FirewallRuleName) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "FirewallRuleName" -IsCIMArray:$True + } + + if ($Results.Assignments) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "Assignments" -IsCIMArray:$true + } + + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.schema.mof new file mode 100644 index 0000000000..f0471b26fe --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/MSFT_IntuneFirewallRulesPolicyWindows10.schema.mof @@ -0,0 +1,54 @@ +[ClassVersion("1.0.0.0")] +class MSFT_DeviceManagementConfigurationPolicyAssignments +{ + [Write, Description("The type of the target assignment."), ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}, Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}] String dataType; + [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are:none, include, exclude."), ValueMap{"none","include","exclude"}, Values{"none","include","exclude"}] String deviceAndAppManagementAssignmentFilterType; + [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; + [Write, Description("The group Id that is the target of the assignment.")] String groupId; + [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; + [Write, Description("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; +}; + +[ClassVersion("1.0.0.0")] +class MSFT_MicrosoftGraphIntuneSettingsCatalogFirewallRuleName +{ + [Write, Description("Enabled - Depends on FirewallRuleName (0: Disabled, 1: Enabled)"), ValueMap{"0", "1"}, Values{"0", "1"}] String Enabled; + [Write, Description("Name - Depends on FirewallRuleName")] String Name; + [Write, Description("Interface Types - Depends on FirewallRuleName (remoteaccess: RemoteAccess, wireless: Wireless, lan: Lan, mobilebroadband: MobileBroadband, mbb: MBB, all: All)"), ValueMap{"remoteaccess", "wireless", "lan", "mobilebroadband", "mbb", "all"}, Values{"remoteaccess", "wireless", "lan", "mobilebroadband", "mbb", "all"}] String InterfaceTypes[]; + [Write, Description("File Path - Depends on FirewallRuleName")] String FilePath; + [Write, Description("Remote Port Ranges - Depends on FirewallRuleName")] String RemotePortRanges[]; + [Write, Description("Edge Traversal - Depends on FirewallRuleName (0: Disabled, 1: Enabled)"), ValueMap{"0", "1"}, Values{"0", "1"}] String EdgeTraversal; + [Write, Description("Local User Authorized List - Depends on FirewallRuleName")] String LocalUserAuthorizedList[]; + [Write, Description("Network Types - Depends on FirewallRuleName (1: FW_PROFILE_TYPE_DOMAIN: This value represents the profile for networks that are connected to domains., 2: FW_PROFILE_TYPE_STANDARD: This value represents the standard profile for networks. These networks are classified as private by the administrators in the server host. The classification happens the first time the host connects to the network. Usually these networks are behind Network Address Translation (NAT) devices, routers, and other edge devices, and they are in a private location, such as a home or an office. AND FW_PROFILE_TYPE_PRIVATE: This value represents the profile for private networks, which is represented by the same value as that used for FW_PROFILE_TYPE_STANDARD., 4: FW_PROFILE_TYPE_PUBLIC: This value represents the profile for public networks. These networks are classified as public by the administrators in the server host. The classification happens the first time the host connects to the network. Usually these networks are those at airports, coffee shops, and other public places where the peers in the network or the network administrator are not trusted., 2147483647: FW_PROFILE_TYPE_ALL: This value represents all these network sets and any future network sets., -2147483648: FW_PROFILE_TYPE_CURRENT: This value represents the current profiles to which the firewall and advanced security components determine the host is connected at the moment of the call. This value can be specified only in method calls, and it cannot be combined with other flags.)"), ValueMap{"1", "2", "4", "2147483647", "-2147483648"}, Values{"1", "2", "4", "2147483647", "-2147483648"}] SInt32 Profiles[]; + [Write, Description("Local Port Ranges - Depends on FirewallRuleName")] String LocalPortRanges[]; + [Write, Description("Description - Depends on FirewallRuleName")] String Description; + [Write, Description("Policy App Id - Depends on FirewallRuleName")] String PolicyAppId; + [Write, Description("Package Family Name - Depends on FirewallRuleName")] String PackageFamilyName; + [Write, Description("Local Address Ranges - Depends on FirewallRuleName")] String LocalAddressRanges[]; + [Write, Description("Direction - Depends on FirewallRuleName (in: The rule applies to inbound traffic., out: The rule applies to outbound traffic.)"), ValueMap{"in", "out"}, Values{"in", "out"}] String Direction; + [Write, Description("Service Name - Depends on FirewallRuleName")] String ServiceName; + [Write, Description("Remote Address Ranges - Depends on FirewallRuleName")] String RemoteAddressRanges[]; + [Write, Description("Action - Depends on FirewallRuleName (0: Block, 1: Allow)"), ValueMap{"0", "1"}, Values{"0", "1"}] String Type; + [Write, Description("Reusable groups - Depends on FirewallRuleName")] String RemoteAddressDynamicKeywords[]; + [Write, Description("Protocol - Depends on FirewallRuleName")] SInt32 Protocol; + [Write, Description("ICMP Types And Codes - Depends on FirewallRuleName")] String IcmpTypesAndCodes[]; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("IntuneFirewallRulesPolicyWindows10")] +class MSFT_IntuneFirewallRulesPolicyWindows10 : OMI_BaseResource +{ + [Write, Description("Policy description")] String Description; + [Key, Description("Policy name")] String DisplayName; + [Write, Description("List of Scope Tags for this Entity instance.")] String RoleScopeTagIds[]; + [Write, Description("The unique identifier for an entity. Read-only.")] String Id; + [Write, Description("Firewall Rules"), EmbeddedInstance("MSFT_MicrosoftGraphIntuneSettingsCatalogFirewallRuleName")] String FirewallRuleName[]; + [Write, Description("Represents the assignment to the Intune policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; + [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Write, Description("Credentials of the Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; + [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; + [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; + [Write, Description("Secret of the Azure Active Directory tenant used for authentication."), EmbeddedInstance("MSFT_Credential")] String ApplicationSecret; + [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; + [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; + [Write, Description("Access token used for authentication.")] String AccessTokens[]; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/readme.md new file mode 100644 index 0000000000..9678849531 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/readme.md @@ -0,0 +1,6 @@ + +# IntuneFirewallRulesPolicyWindows10 + +## Description + +Intune Firewall Rules Policy for Windows10 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/settings.json new file mode 100644 index 0000000000..b586b4a5a3 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneFirewallRulesPolicyWindows10/settings.json @@ -0,0 +1,44 @@ +{ + "resourceName":"IntuneFirewallRulesPolicyWindows10", + "description":"This resource configures an Intune Firewall Rules Policy for Windows10.", + "permissions":{ + "graph":{ + "delegated":{ + "read":[ + { + "name":"DeviceManagementConfiguration.Read.All" + }, + { + "name":"Group.Read.All" + } + ], + "update":[ + { + "name":"DeviceManagementConfiguration.ReadWrite.All" + }, + { + "name":"Group.Read.All" + } + ] + }, + "application":{ + "read":[ + { + "name":"DeviceManagementConfiguration.Read.All" + }, + { + "name":"Group.Read.All" + } + ], + "update":[ + { + "name":"DeviceManagementConfiguration.ReadWrite.All" + }, + { + "name":"Group.Read.All" + } + ] + } + } + } +} \ No newline at end of file diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/1-Create.ps1 new file mode 100644 index 0000000000..603aa5a22f --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/1-Create.ps1 @@ -0,0 +1,56 @@ +<# +This example creates a new Intune Firewall Policy for Windows10. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneFirewallRulesPolicyWindows10 'myIntuneFirewallRulesPolicyWindows10' + { + Assignments = @( + MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } + ); + FirewallRuleName = @( + MicrosoftGraphIntuneSettingsCatalogFirewallRuleName{ + Direction = 'out' + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = 'Rule1' + FilePath = 'C:\Temp' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } + ) + Description = 'Description' + DisplayName = "Intune Firewall Rules Policy Windows10"; + Ensure = "Present"; + Id = '00000000-0000-0000-0000-000000000000' + RoleScopeTagIds = @("0"); + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/2-Update.ps1 new file mode 100644 index 0000000000..bbf0fcd6cc --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/2-Update.ps1 @@ -0,0 +1,56 @@ +<# +This example updates a Intune Firewall Policy for Windows10. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneFirewallRulesPolicyWindows10 'myIntuneFirewallRulesPolicyWindows10' + { + Assignments = @( + MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } + ); + FirewallRuleName = @( + MicrosoftGraphIntuneSettingsCatalogFirewallRuleName{ + Direction = 'in' # Updated property + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = 'Rule1' + FilePath = 'C:\Temp' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } + ) + Description = 'Description' + DisplayName = "Intune Firewall Rules Policy Windows10"; + Ensure = "Present"; + Id = '00000000-0000-0000-0000-000000000000' + RoleScopeTagIds = @("0"); + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/3-Remove.ps1 new file mode 100644 index 0000000000..7c63d62b15 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneFirewallRulesPolicyWindows10/3-Remove.ps1 @@ -0,0 +1,34 @@ +<# +This example removes a Device Control Policy. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneFirewallRulesPolicyWindows10 'myIntuneFirewallRulesPolicyWindows10' + { + Id = '00000000-0000-0000-0000-000000000000' + DisplayName = 'Intune Firewall Rules Policy Windows10' + Ensure = 'Absent' + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/ResourceGenerator/UnitTest.Template.ps1 b/ResourceGenerator/UnitTest.Template.ps1 index 482d5a8912..456efa2ffb 100644 --- a/ResourceGenerator/UnitTest.Template.ps1 +++ b/ResourceGenerator/UnitTest.Template.ps1 @@ -52,6 +52,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { $Script:exportedInstances =$null $Script:ExportMode = $false } + # Test contexts Context -Name "The should exist but it DOES NOT" -Fixture { BeforeAll { @@ -103,6 +104,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Should -Invoke -CommandName -Exactly 1 } } + Context -Name "The Exists and Values are already in the desired state" -Fixture { BeforeAll { $testParams = @{ @@ -117,7 +119,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } } - It 'Should return true from the Test method' { Test-TargetResource @testParams | Should -Be $true } @@ -164,6 +165,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } } } + It 'Should Reverse Engineer resource from the Export method' { $result = Export-TargetResource @testParams $result | Should -Not -BeNullOrEmpty diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneFirewallRulesPolicyWindows10.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneFirewallRulesPolicyWindows10.Tests.ps1 new file mode 100644 index 0000000000..48be0166e9 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneFirewallRulesPolicyWindows10.Tests.ps1 @@ -0,0 +1,584 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "IntuneFirewallRulesPolicyWindows10" -GenericStubModule $GenericStubPath +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + BeforeAll { + + $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force + $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) + + Mock -CommandName Confirm-M365DSCDependencies -MockWith { + } + + Mock -CommandName Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + + Mock -CommandName Update-MgBetaDeviceManagementConfigurationPolicy -MockWith { + } + + Mock -CommandName New-MgBetaDeviceManagementConfigurationPolicy -MockWith { + return @{ + Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' + } + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { + return @{ + Id = '12345-12345-12345-12345-12345' + Description = 'My Test' + Name = 'My Test' + RoleScopeTagIds = @("FakeStringValue") + TemplateReference = @{ + TemplateId = '19c8aa67-f286-4861-9aa0-f23541d31680_1' + } + } + } + + Mock -CommandName Remove-MgBetaDeviceManagementConfigurationPolicy -MockWith { + } + + Mock -CommandName Update-IntuneDeviceConfigurationPolicy -MockWith { + } + + Mock -CommandName Get-IntuneSettingCatalogPolicySetting -MockWith { + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { + return @( + @{ + Id = '0' + SettingDefinitions = @( + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + Name = '{FirewallRuleName}' + OffsetUri = '/MdmStore/FirewallRules/{0}' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSettingGroupCollectionDefinition' + minimumCount = 0 + maximumCount = 150 + childIds = @( + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_firewallrulename' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_direction' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_interfacetypes' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_remoteportranges' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_name' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_filepath' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_protocol' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_servicename' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_enabled' + 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_action_type' + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_firewallrulename' + Name = 'FirewallRuleName' + OffsetUri = '/MdmStore/FirewallRules/{0}/FirewallRuleName' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_direction' + Name = 'Direction' + OffsetUri = '/MdmStore/FirewallRules/{0}/Direction' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + options = @( + @{ + itemId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_direction_out' + name = 'The rule applies to outbound traffic.' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_interfacetypes' + Name = 'InterfaceTypes' + OffsetUri = '/MdmStore/FirewallRules/{0}/InterfaceTypes' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingCollectionDefinition' + minimumCount = 0 + maximumCount = 100 + options = @( + @{ + itemId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_interfacetypes_lan' + name = 'Lan' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_remoteportranges' + Name = 'RemotePortRanges' + OffsetUri = '/MdmStore/FirewallRules/{0}/RemotePortRanges' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionDefinition' + minimumCount = 0 + maximumCount = 600 + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_name' + Name = 'Name' + OffsetUri = '/MdmStore/FirewallRules/{0}/Name' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_filepath' + Name = 'FilePath' + OffsetUri = '/MdmStore/FirewallRules/{0}/App/FilePath' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_protocol' + Name = 'Protocol' + OffsetUri = '/MdmStore/FirewallRules/{0}/Protocol' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_servicename' + Name = 'ServiceName' + OffsetUri = '/MdmStore/FirewallRules/{0}/App/ServiceName' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_enabled' + Name = 'Enabled' + OffsetUri = '/MdmStore/FirewallRules/{0}/Enabled' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + options = @( + @{ + itemId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_enabled_0' + name = 'Enabled' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + ) + } + }, + @{ + Id = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_action_type' + Name = 'Type' + OffsetUri = '/MdmStore/FirewallRules/{0}/Action/Type' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + options = @( + @{ + itemId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_action_type_1' + name = 'Allow' + dependentOn = @( + @{ + dependentOn = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + parentSettingId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + } + ) + } + ) + } + } + ) + SettingInstance = @{ + SettingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + SettingInstanceTemplateReference = @{ + SettingInstanceTemplateId = '76c7a8be-67d2-44bf-81a5-38c94926b1a1' + } + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}' + groupSettingCollectionValue = @( + @{ + children = @( + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_enabled' + choiceSettingValue = @{ + children = @() + value = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_enabled_1' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_name' + simpleSettingValue = @{ + value = '__Test' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingCollectionInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_interfacetypes' + choiceSettingCollectionValue = @( + @{ + children = @() + value = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_interfacetypes_lan' + } + ) + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_filepath' + simpleSettingValue = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationStringSettingValue' + value = 'C:\Temp\bla2' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_remoteportranges' + simpleSettingCollectionValue = @( + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationStringSettingValue' + value = '0-100' + } + ) + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_direction' + choiceSettingValue = @{ + children = @() + value = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_direction_out' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_app_servicename' + simpleSettingValue = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationStringSettingValue' + value = 'mysvc' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_action_type' + choiceSettingValue = @{ + children = @() + value = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_action_type_1' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + settingDefinitionId = 'vendor_msft_firewall_mdmstore_firewallrules_{firewallrulename}_protocol' + simpleSettingValue = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationIntegerSettingValue' + value = 80 + } + } + ) + } + ) + } + } + } + ) + } + + Mock -CommandName Update-DeviceConfigurationPolicyAssignment -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicyAssignment -MockWith { + return @(@{ + Id = '12345-12345-12345-12345-12345' + Source = 'direct' + SourceId = '12345-12345-12345-12345-12345' + Target = @{ + DeviceAndAppManagementAssignmentFilterId = '12345-12345-12345-12345-12345' + DeviceAndAppManagementAssignmentFilterType = 'none' + AdditionalProperties = @( + @{ + '@odata.type' = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + } + ) + } + }) + } + } + + # Test contexts + Context -Name "The IntuneFirewallRulesPolicyWindows10 should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + Description = "My Test" + FirewallRuleName = [CimInstance[]]@( + (New-CimInstance -ClassName MicrosoftGraphIntuneSettingsCatalogFirewallRuleName -Property @{ + Direction = 'out' + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = '__Test' + FilePath = 'C:\Temp\bla2' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } -ClientOnly) + ) + Id = "619bd4a4-3b3b-4441-bd6f-3f4c0c444870" + DisplayName = "My Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Present" + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { + return $null + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + It 'Should Create the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName New-MgBetaDeviceManagementConfigurationPolicy -Exactly 1 + } + } + + Context -Name "The IntuneFirewallRulesPolicyWindows10 exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + Description = "My Test" + FirewallRuleName = [CimInstance[]]@( + (New-CimInstance -ClassName MicrosoftGraphIntuneSettingsCatalogFirewallRuleName -Property @{ + Direction = 'out' + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = '__Test' + FilePath = 'C:\Temp\bla2' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } -ClientOnly) + ) + Id = "619bd4a4-3b3b-4441-bd6f-3f4c0c444870" + DisplayName = "My Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Absent" + Credential = $Credential; + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should Remove the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Remove-MgBetaDeviceManagementConfigurationPolicy -Exactly 1 + } + } + + Context -Name "The IntuneFirewallRulesPolicyWindows10 Exists and Values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + Description = "My Test" + FirewallRuleName = [CimInstance[]]@( + (New-CimInstance -ClassName MicrosoftGraphIntuneSettingsCatalogFirewallRuleName -Property @{ + Direction = 'out' + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = '__Test' + FilePath = 'C:\Temp\bla2' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } -ClientOnly) + ) + Id = "619bd4a4-3b3b-4441-bd6f-3f4c0c444870" + DisplayName = "My Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Present" + Credential = $Credential; + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The IntuneFirewallRulesPolicyWindows10 exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + Description = "My Test" + FirewallRuleName = [CimInstance[]]@( + (New-CimInstance -ClassName MicrosoftGraphIntuneSettingsCatalogFirewallRuleName -Property @{ + Direction = 'out' + InterfaceTypes = @('lan') + RemotePortRanges = @('0-100') + Name = '__Test' + FilePath = 'C:\Temp\bla2' + Protocol = 80 + ServiceName = 'mysvc' + Enabled = '1' + Type = '1' + } -ClientOnly) + ) + Id = "619bd4a4-3b3b-4441-bd6f-3f4c0c444870" + DisplayName = "My Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Present" + Credential = $Credential; + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Update-IntuneDeviceConfigurationPolicy -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + } + + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope