diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ace44af07..3331a3505f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change log for Microsoft365DSC +# 1.21.127.1 + +* AADNamedLocation + * Initial Release; +* DEPENDENCIES + * Updated PnP.PowerShell to version 1.2.0; + * Updated Microsoft.PowerApps.Administration.PowerShell to + 1.0.208; + # 1.21.120.1 * DEPENDENCIES diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.psm1 new file mode 100644 index 0000000000..108e74339e --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.psm1 @@ -0,0 +1,390 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter()] + [ValidateSet('#microsoft.graph.countryNamedLocation', '#microsoft.graph.ipNamedLocation')] + [System.String] + $OdataType, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String[]] + $IpRanges, + + [Parameter()] + [System.Boolean] + $IsTrusted, + + [Parameter()] + [System.String[]] + $CountriesAndRegions, + + [Parameter()] + [System.Boolean] + $IncludeUnknownCountriesAndRegions, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + + Write-Verbose -Message "Getting configuration of AAD Named Location" + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace("MSFT_", "") + $data = [System.Collections.Generic.Dictionary[[String], [String]]]::new() + $data.Add("Resource", $ResourceName) + $data.Add("Method", $MyInvocation.MyCommand) + $data.Add("Principal", $GlobalAdminAccount.UserName) + $data.Add("TenantId", $TenantId) + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $ConnectionMode = New-M365DSCConnection -Platform 'AzureAD' -InboundParameters $PSBoundParameters + + try + { + $nullReturn = $PSBoundParameters + $nullReturn.Ensure = "Absent" + try + { + if ($null -ne $Id) + { + $NamedLocation = Get-AzureADMSNamedLocationPolicy -PolicyId $Id + } + } + catch + { + Write-Verbose -Message "Could not retrieve AAD Named Location by ID {$Id}" + } + if ($null -eq $NamedLocation) + { + try + { + $NamedLocation = Get-AzureADMSNamedLocationPolicy -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_.DisplayName -eq $DisplayName } + } + catch + { + Write-Verbose -Message $_ + Add-M365DSCEvent -Message $_ -EntryType 'Error' ` + -EventID 1 -Source $($MyInvocation.MyCommand.Source) + } + } + if ($null -eq $NamedLocation) + { + return $nullReturn + } + else + { + Write-Verbose "Found existing AAD Named Location {$($NamedLocation.DisplayName)}" + $Result = @{ + OdataType = $NamedLocation.OdataType + Id = $NamedLocation.Id + DisplayName = $NamedLocation.DisplayName + IpRanges = $NamedLocation.IpRanges.CidrAddress + IsTrusted = $NamedLocation.IsTrusted + CountriesAndRegions = [String[]]$NamedLocation.CountriesAndRegions + IncludeUnknownCountriesAndRegions = $NamedLocation.IncludeUnknownCountriesAndRegions + Ensure = "Present" + GlobalAdminAccount = $GlobalAdminAccount + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + } + + Write-Verbose -Message "Get-TargetResource Result: `n $(Convert-M365DscHashtableToString -Hashtable $result)" + return $result + } + } + catch + { + Write-Verbose -Message $_ + Add-M365DSCEvent -Message $_ -EntryType 'Error' ` + -EventID 1 -Source $($MyInvocation.MyCommand.Source) + return $nullReturn + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateSet('#microsoft.graph.countryNamedLocation', '#microsoft.graph.ipNamedLocation')] + [System.String] + $OdataType, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String[]] + $IpRanges, + + [Parameter()] + [System.Boolean] + $IsTrusted, + + [Parameter()] + [System.String[]] + $CountriesAndRegions, + + [Parameter()] + [System.Boolean] + $IncludeUnknownCountriesAndRegions, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + + Write-Verbose -Message "Setting configuration of AAD Named Location" + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace("MSFT_", "") + $data = [System.Collections.Generic.Dictionary[[String], [String]]]::new() + $data.Add("Resource", $ResourceName) + $data.Add("Method", $MyInvocation.MyCommand) + $data.Add("Principal", $GlobalAdminAccount.UserName) + $data.Add("TenantId", $TenantId) + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentAADNamedLocation = Get-TargetResource @PSBoundParameters + $currentParameters = $PSBoundParameters + $currentParameters.Remove("ApplicationId") | Out-Null + $currentParameters.Remove("TenantId") | Out-Null + $currentParameters.Remove("CertificateThumbprint") | Out-Null + $currentParameters.Remove("GlobalAdminAccount") | Out-Null + $currentParameters.Remove("Ensure") | Out-Null + + # Named Location should exist but it doesn't + if ($Ensure -eq 'Present' -and $currentAADNamedLocation.Ensure -eq "Absent") + { + $currentParameters.Remove("Id") | Out-Null + $VerboseAttributes = ($currentParameters | Out-String) + Write-Verbose -Message "Creating New AAD Named Location {$Displayname)} with attributes: $VerboseAttributes" + New-AzureADMSNamedLocationPolicy @currentParameters + } + # Named Location should exist and will be configured to desired state + elseif ($Ensure -eq 'Present' -and $CurrentAADNamedLocation.Ensure -eq 'Present') + { + $currentParameters["PolicyId"] = $currentAADNamedLocation.ID + $currentParameters.Remove("Id") | Out-Null + $VerboseAttributes = ($currentParameters | Out-String) + Write-Verbose -Message "Updating existing AAD Named Location {$Displayname)} with attributes: $VerboseAttributes" + Set-AzureADMSNamedLocationPolicy @currentParameters + } + # Named Location exist but should not + elseif ($Ensure -eq 'Absent' -and $CurrentAADNamedLocation.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing AAD Named Location {$Displayname)}" + Remove-AzureADMSNamedLocationPolicy -PolicyId $currentAADNamedLocation.ID + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [ValidateSet('#microsoft.graph.countryNamedLocation', '#microsoft.graph.ipNamedLocation')] + [System.String] + $OdataType, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String[]] + $IpRanges, + + [Parameter()] + [System.Boolean] + $IsTrusted, + + [Parameter()] + [System.String[]] + $CountriesAndRegions, + + [Parameter()] + [System.Boolean] + $IncludeUnknownCountriesAndRegions, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + + Write-Verbose -Message "Testing configuration of AAD Named Location" + + $CurrentValues = Get-TargetResource @PSBoundParameters + + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + + $ValuesToCheck = $PSBoundParameters + $ValuesToCheck.Remove('GlobalAdminAccount') | Out-Null + $ValuesToCheck.Remove("Id") | Out-Null + $ValuesToCheck.Remove("ApplicationId") | Out-Null + $ValuesToCheck.Remove("TenantId") | Out-Null + $ValuesToCheck.Remove("CertificateThumbprint") | Out-Null + + $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.Management.Automation.PSCredential] + $GlobalAdminAccount, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace("MSFT_", "") + $data = [System.Collections.Generic.Dictionary[[String], [String]]]::new() + $data.Add("Resource", $ResourceName) + $data.Add("Method", $MyInvocation.MyCommand) + $data.Add("Principal", $GlobalAdminAccount.UserName) + $data.Add("TenantId", $TenantId) + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $dscContent = '' + $ConnectionMode = New-M365DSCConnection -Platform 'AzureAD' -InboundParameters $PSBoundParameters + $i = 1 + Write-Host "`r`n" -NoNewline + try + { + $AADNamedLocations = Get-AzureADMSNamedLocationPolicy -ErrorAction Stop + foreach ($AADNamedLocation in $AADNamedLocations) + { + Write-Host " |---[$i/$($AADNamedLocations.Count)] $($AADNamedLocation.DisplayName)" -NoNewline + $Params = @{ + GlobalAdminAccount = $GlobalAdminAccount + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + DisplayName = $AADNamedLocation.DisplayName + ID = $AADNamedLocation.ID + } + $Results = Get-TargetResource @Params + + if ($Results.Ensure -eq 'Present') + { + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + $dscContent += Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -GlobalAdminAccount $GlobalAdminAccount + Write-Host $Global:M365DSCEmojiGreenCheckMark + $i++ + } + } + return $dscContent + } + catch + { + Write-Verbose -Message $_ + Add-M365DSCEvent -Message $_ -EntryType 'Error' ` + -EventID 1 -Source $($MyInvocation.MyCommand.Source) + return "" + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.schema.mof new file mode 100644 index 0000000000..8c31b16f72 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/MSFT_AADNamedLocationPolicy.schema.mof @@ -0,0 +1,17 @@ +[ClassVersion("1.0.0.0"), FriendlyName("AADNamedLocationPolicy")] +class MSFT_AADNamedLocationPolicy : OMI_BaseResource +{ + [Write, Description("Specifies the Odata Type of a Named Location policy object in Azure Active Directory"), ValueMap{"#microsoft.graph.countryNamedLocation","#microsoft.graph.ipNamedLocation"}, Values{"#microsoft.graph.countryNamedLocation","#microsoft.graph.ipNamedLocation"}] string OdataType; + [Write, Description("Specifies the ID of a Named Location policy in Azure Active Directory.")] String Id; + [Key, Description("Specifies the Display Name of a Named Location policy in Azure Active Directory")] string DisplayName; + [Write, Description("Specifies the IP ranges of the Named Location policy in Azure Active Directory")] String IpRanges[]; + [Write, Description("Specifies the isTrusted value for the Named Location policy in Azure Active Directory")] Boolean IsTrusted; + [Write, Description("Specifies the countries and regions for the Named Location policy in Azure Active Directory")] String CountriesAndRegions[]; + [Write, Description("Specifies the includeUnknownCountriesAndRegions value for the Named Location policy in Azure Active Directory")] Boolean IncludeUnknownCountriesAndRegions; + [Write, Description("Specify if the Azure AD Named Location should exist or not."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Write, Description("Credentials of the Azure AD Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; + [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("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; + +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/readme.md new file mode 100644 index 0000000000..5ca4b845a0 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNamedLocationPolicy/readme.md @@ -0,0 +1,16 @@ +# AADNamedLocationPolicy + +## Description + +This resource configures the Azure AD Named Location Policies in Azure Active Directory + +## Azure AD Permissions + +To authenticate via Azure Active Directory, this resource required the following Application permissions: + +* **Automate** + * Policy.Read.All,Policy.ReadWrite.ApplicationConfiguration +* **Export** + * Policy.Read.All + +NOTE: All permisions listed above require admin consent. diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADNamedLocationPolicy/1-ConfigureAADNamedLocationPolicy.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADNamedLocationPolicy/1-ConfigureAADNamedLocationPolicy.ps1 new file mode 100644 index 0000000000..afd7d27942 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADNamedLocationPolicy/1-ConfigureAADNamedLocationPolicy.ps1 @@ -0,0 +1,38 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $credsGlobalAdmin + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + AADNamedLocationPolicy CompanyNetwork + { + DisplayName = "Company Network"; + Ensure = "Present"; + IpRanges = @("2.1.1.1/32", "1.2.2.2/32"); + IsTrusted = $True; + OdataType = "#microsoft.graph.ipNamedLocation"; + TenantId = $ConfigurationData.NonNodeData.TenantId; + GlobalAdminAccount = $credsGlobalAdmin; + } + AADNamedLocationPolicy AllowedCountries + { + CountriesAndRegions = @("GH", "AX", "DZ", "AI", "AM"); + DisplayName = "Allowed Countries"; + Ensure = "Present"; + IncludeUnknownCountriesAndRegions = $False; + OdataType = "#microsoft.graph.countryNamedLocation"; + TenantId = $ConfigurationData.NonNodeData.TenantId; + GlobalAdminAccount = $credsGlobalAdmin; + } + } +} diff --git a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 index 9c7b4c362c..aa6f7a947f 100644 --- a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 +++ b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 @@ -3,7 +3,7 @@ # # Generated by: Microsoft Corporation # -# Generated on: 2021-01-20 +# Generated on: 2021-01-27 @{ @@ -11,7 +11,7 @@ # RootModule = '' # Version number of this module. - ModuleVersion = '1.21.120.1' + ModuleVersion = '1.21.127.1' # Supported PSEditions # CompatiblePSEditions = @() @@ -26,7 +26,7 @@ CompanyName = 'Microsoft Corporation' # Copyright statement for this module - Copyright = '(c) 2020 Microsoft Corporation. All rights reserved.' + Copyright = '(c) 2021 Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module Description = 'This DSC module is used to configure and monitor Microsoft tenants, including SharePoint Online, Exchange, Teams, etc.' @@ -89,7 +89,7 @@ }, @{ ModuleName = "Microsoft.PowerApps.Administration.PowerShell" - RequiredVersion = "2.0.104" + RequiredVersion = "2.0.108" }, @{ ModuleName = "MicrosoftTeams" @@ -101,7 +101,7 @@ }, @{ ModuleName = "PnP.PowerShell" - RequiredVersion = "1.1.0" + RequiredVersion = "1.2.0" }, @{ ModuleName = "ReverseDSC" @@ -180,10 +180,13 @@ IconUri = 'https://github.com/microsoft/Microsoft365DSC/blob/Dev/Modules/Microsoft365DSC/Dependencies/Images/Logo.png?raw=true' # ReleaseNotes of this module - ReleaseNotes = "* DEPENDENCIES - * Updated MSCloudLoginAssistant to version 1.0.45; - * Replaced the SharePointPnPPowerShellOnline dependency by the new - PnP.PowerShell core module;" + ReleaseNotes = " + * AADNamedLocation + * Initial Release; + * DEPENDENCIES + * Updated PnP.PowerShell to version 1.2.0; + * Updated Microsoft.PowerApps.Administration.PowerShell to + 1.0.208;" # Flag to indicate whether the module requires explicit user acceptance for install/update # RequireLicenseAcceptance = $false diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNamedLocationPolicy.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNamedLocationPolicy.Tests.ps1 new file mode 100644 index 0000000000..4204339825 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNamedLocationPolicy.Tests.ps1 @@ -0,0 +1,226 @@ +[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 "AADNamedLocationPolicy" -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 "test@password1" -AsPlainText -Force + $GlobalAdminAccount = New-Object System.Management.Automation.PSCredential ("tenantadmin", $secpasswd) + + Mock -CommandName Update-M365DSCExportAuthenticationResults -MockWith { + return @{} + } + + Mock -CommandName Get-M365DSCExportContentForResource -MockWith { + + } + + Mock -CommandName Get-PSSession -MockWith { + + } + + Mock -CommandName Remove-PSSession -MockWith { + + } + + Mock -CommandName Set-AzureADMSNamedLocationPolicy -MockWith { + + } + + Mock -CommandName Remove-AzureADMSNamedLocationPolicy -MockWith { + + } + + Mock -CommandName New-AzureADMSNamedLocationPolicy -MockWith { + + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credential" + } + } + + # Test contexts + Context -Name "The Policy should exist but it does not" -Fixture { + BeforeAll { + $testParams = @{ + DisplayName = "Company Network" + Ensure = "Present" + IpRanges = @("2.1.1.1/32", "1.2.2.2/32") + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + GlobalAdminAccount = $credsGlobalAdmin + } + + Mock -CommandName Get-AzureADMSNamedLocationPolicy -MockWith { + return $null + } + } + + It "Should return values from the get method" { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + Should -Invoke -CommandName "Get-AzureADMSNamedLocationPolicy" -Exactly 2 + } + It 'Should return false from the test method' { + Test-TargetResource @testParams | Should -Be $false + } + It 'Should create the Policy from the set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName "New-AzureADMSNamedLocationPolicy" -Exactly 1 + } + } + Context -Name "The Policy exists but it should not" -Fixture { + BeforeAll { + $testParams = @{ + DisplayName = "Company Network" + Ensure = "Absent" + IpRanges = @("2.1.1.1/32", "1.2.2.2/32") + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + GlobalAdminAccount = $credsGlobalAdmin + } + + Mock -CommandName Get-AzureADMSNamedLocationPolicy -MockWith { + return @{ + DisplayName = "Company Network" + Id = "046956df-2367-4dd4-b7fd-c6175ec11cd5" + IpRanges = @(@{CidrAddress = "2.1.1.1/32" }, @{CidrAddress = "1.2.2.2/32" }) + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + CountriesAndRegions = $null + IncludeUnknownCountriesAndRegions = $null + } + } + } + + It "Should return values from the get method" { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + Should -Invoke -CommandName "Get-AzureADMSNamedLocationPolicy" -Exactly 1 + } + + It 'Should return false from the test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should remove the app from the set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName "Remove-AzureADMSNamedLocationPolicy" -Exactly 1 + } + } + + Context -Name "The Policy exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + DisplayName = "Company Network" + Ensure = "Present" + IpRanges = @("2.1.1.1/32", "1.2.2.2/32") + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + GlobalAdminAccount = $credsGlobalAdmin + } + + Mock -CommandName Get-AzureADMSNamedLocationPolicy -MockWith { + return @{ + DisplayName = "Company Network" + Id = "046956df-2367-4dd4-b7fd-c6175ec11cd5" + IpRanges = @(@{CidrAddress = "2.1.1.1/32" }, @{CidrAddress = "1.2.2.2/32" }) + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + CountriesAndRegions = $null + IncludeUnknownCountriesAndRegions = $null + } + } + } + + It "Should return Values from the get method" { + Get-TargetResource @testParams + Should -Invoke -CommandName "Get-AzureADMSNamedLocationPolicy" -Exactly 1 + } + + It 'Should return true from the test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "Values are not in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + DisplayName = "Company Network" + Ensure = "Present" + IpRanges = @("2.1.1.1/32", "1.2.2.2/32") + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + GlobalAdminAccount = $credsGlobalAdmin + } + + Mock -CommandName Get-AzureADMSNamedLocationPolicy -MockWith { + return @{ + DisplayName = "Company Network" + Id = "046956df-2367-4dd4-b7fd-c6175ec11cd5" + IpRanges = @(@{CidrAddress = "1.1.1.1/32" }, @{CidrAddress = "2.2.2.2/32" }) + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + CountriesAndRegions = $null + IncludeUnknownCountriesAndRegions = $null + } + } + } + + It "Should return values from the get method" { + Get-TargetResource @testParams + Should -Invoke -CommandName "Get-AzureADMSNamedLocationPolicy" -Exactly 1 + } + + 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 "Set-AzureADMSNamedLocationPolicy" -Exactly 1 + } + } + + Context -Name "ReverseDSC tests" -Fixture { + BeforeAll { + $testParams = @{ + GlobalAdminAccount = $GlobalAdminAccount + } + + Mock -CommandName Get-AzureADMSNamedLocationPolicy -MockWith { + return @{ + DisplayName = "Company Network" + Id = "046956df-2367-4dd4-b7fd-c6175ec11cd5" + IpRanges = @(@{CidrAddress = "2.1.1.1/32" }, @{CidrAddress = "1.2.2.2/32" }) + IsTrusted = $True + OdataType = "#microsoft.graph.ipNamedLocation" + CountriesAndRegions = $null + IncludeUnknownCountriesAndRegions = $null + } + } + } + + It "Should reverse engineer resource from the export method" { + Export-TargetResource @testParams + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope