From 833976c7c847fe05d4021594c977f6f5dbfacc64 Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Wed, 23 Oct 2024 11:52:36 +0530 Subject: [PATCH 01/16] added get,export and test target resource --- ...SFT_AADNetworkAccessForwardingProfile.psm1 | 546 ++++++++++++++++++ ...DNetworkAccessForwardingProfile.schema.mof | 25 + .../readme.md | 7 + .../settings.json | 33 ++ .../Dependencies/Manifest.psd1 | 4 + 5 files changed, 615 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/settings.json diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 new file mode 100644 index 0000000000..c0f158cd0f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 @@ -0,0 +1,546 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $State, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Policies, + + #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 + if (-not [System.String]::IsNullOrEmpty($Id)) + { + $getValue = Get-MgBetaNetworkAccessForwardingProfile -ForwardingProfileId $Id -ErrorAction SilentlyContinue + } + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Azure AD Network Access Forwarding Profile with Id:{$Id}" + + if (-not [System.String]::IsNullOrEmpty($Name)) + { + $getValue = Get-MgBetaNetworkAccessForwardingProfile -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $Name } + } + } + + + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Azure AD Network Access Forwarding Profile with {$Name}." + return $nullResult + } + + Write-Verbose -Message "An Azure AD Network Access Forwarding Profile with {$Id} and {$Name} was found" + + $forwardingProfilePolicies = Get-MgBetaNetworkAccessForwardingProfilePolicy -ForwardingProfileId $getValue.Id -ErrorAction SilentlyContinue + if ($null -ne $forwardingProfilePolicies) + { + Write-Verbose -Message "An Azure AD Network Access Forwarding Profile Policy with $($forwardingProfilePolicies.Id) and $($forwardingProfilePolicies.Name) was found" + } + + $complexPolicies = @() + foreach ($currentPolicy in $forwardingProfilePolicies) + { + $myPolicies = @{} + $myPolicies.Add('Name', $currentPolicy.Policy.Name) + $myPolicies.Add('State', $currentPolicy.State) + $myPolicies.Add('Id', $currentPolicy.Id) + if ($myPolicies.values.Where({ $null -ne $_ }).Count -gt 0) + { + $complexPolicies += $myPolicies + } + } + + + $results = @{ + Name = $getValue.Name + Id = $getValue.Id + State = $getValue.State + Policies = $complexPolicies + # 'Policies@Odata.Context' = $getValue.AdditionalProperties['policies@odata.context'] + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + } + + 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(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $State, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Policies, + + #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 + + + # if ( $Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + # { + # Write-Warning -Message "Can not create the Azure AD Network Access Forwarding Profile with {$($currentInstance.Name)}." + # } + # elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + # { + # Write-Verbose -Message "Updating the Azure AD Network Access Forwarding Profile with {$($currentInstance.Id)}" + + # $updateParameters = ([Hashtable]$BoundParameters).Clone() + # $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters + + # $updateParameters.Remove('Id') | Out-Null + + # $keys = (([Hashtable]$updateParameters).Clone()).Keys + # foreach ($key in $keys) + # { + # if ($null -ne $updateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') + # { + # $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.$key + # } + # } + + # #region resource generator code + # Update-MgBetaNetworkAccessForwardingProfile ` + # -ForwardingProfileId $Id ` + # -BodyParameter $UpdateParameters + # #endregion + # } + # elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + # { + # Write-Warning -Message "Can not remove the Azure AD Network Access Forwarding Profile with {$($currentInstance.Name)}." + # } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + + #region resource generator code + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $State, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Policies, + + #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 Azure AD Network Access Forwarding Profile with Id:{$Id} and Name:{$Name}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + + 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 $ValuesToCheck)" + + 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 + [array]$getValue = Get-MgBetaNetworkAccessForwardingProfile ` + -Filter $Filter ` + -All ` + -ErrorAction Stop + #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.name)) + { + $displayedKey = $config.name + } + Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline + $params = @{ + Id = $config.Id + Name = $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 ($Results.Policies.Count -gt 0) + { + $Results.Policies = Get-PoliciesAsString $Results.Policies + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + + if ($null -ne $Results.Policies) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'Policies' + } + $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 '' + } +} + +function Get-PoliciesAsString +{ + [CmdletBinding()] + [OutputType([System.String])] + param( + [Parameter(Mandatory = $true)] + [System.Collections.ArrayList] + $Policies + ) + + $StringContent = '@(' + foreach ($policy in $Policies) + { + $StringContent += "MSFT_MicrosoftGraphNetworkaccessPolicyLink {`r`n" + $StringContent += " State = '" + $policy.State + "'`r`n" + $StringContent += " Id = '" + $policy.Id + "'`r`n" + $StringContent += " Name = '" + $policy.Name + "'`r`n" + $StringContent += " }`r`n" + } + $StringContent += ' )' + return $StringContent +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof new file mode 100644 index 0000000000..939b48bdb3 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof @@ -0,0 +1,25 @@ + +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphNetworkaccessPolicyLink +{ + [Write, Description("Policy Name. Required")] String Name; + [Write, Description("A Unique Identifier")] String Id; + [Write, Description("status")] String state; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("AADNetworkAccessForwardingProfile")] +class MSFT_AADNetworkAccessForwardingProfile : OMI_BaseResource +{ + [Key, Description("Profile Name. Required.")] String Name; + [Write, Description("Id of the profile. Unique Identifier")] String Id; + [Write, Description("status of the profile")] String State; + [Write, Description("Traffic forwarding policies associated with this profile."), EmbeddedInstance("MSFT_MicrosoftGraphNetworkaccessPolicyLink")] String Policies[]; + [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_AADNetworkAccessForwardingProfile/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/readme.md new file mode 100644 index 0000000000..385d36537f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/readme.md @@ -0,0 +1,7 @@ + +# AADNetworkAccessForwardingProfile + +## Description + +This resource configure the Azure AD Network Access Forwarding Profile + diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/settings.json new file mode 100644 index 0000000000..4a473ad41b --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/settings.json @@ -0,0 +1,33 @@ + +{ + "resourceName": "AADNetworkAccessForwardingProfile", + "description": "This resource configures an Azure AD Network Access Forwarding Profile.", + "permissions": { + "graph": { + "delegated": { + "read": [ + { + "name": "NetworkAccess.Read.All" + } + ], + "update": [ + { + "name": "NetworkAccess.ReadWrite.All" + } + ] + }, + "application": { + "read": [ + { + "name": "NetworkAccess.Read.All" + } + ], + "update": [ + { + "name": "NetworkAccess.ReadWrite.All" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 index 7fd6bbe7fe..288104b127 100644 --- a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 +++ b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 @@ -56,6 +56,10 @@ ModuleName = 'Microsoft.Graph.Beta.DeviceManagement.Enrollment' RequiredVersion = '2.23.0' }, + @{ + ModuleName = 'Microsoft.Graph.Beta.NetworkAccess' + RequiredVersion = '2.23.0' + }, @{ ModuleName = 'Microsoft.Graph.Beta.Identity.DirectoryManagement' RequiredVersion = '2.23.0' From 1cdc364e865f39545967049b368ec3016bcc4763 Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Wed, 23 Oct 2024 20:05:10 +0530 Subject: [PATCH 02/16] removed ensure --- ...SFT_AADNetworkAccessForwardingProfile.psm1 | 127 ++++++++---------- ...DNetworkAccessForwardingProfile.schema.mof | 3 +- 2 files changed, 59 insertions(+), 71 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 index c0f158cd0f..c06ba0ed46 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 @@ -22,12 +22,6 @@ function Get-TargetResource $Policies, #endregion - - [Parameter()] - [System.String] - [ValidateSet('Absent', 'Present')] - $Ensure = 'Present', - [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -75,7 +69,6 @@ function Get-TargetResource #endregion $nullResult = $PSBoundParameters - $nullResult.Ensure = 'Absent' $getValue = $null #region resource generator code @@ -83,6 +76,7 @@ function Get-TargetResource { $getValue = Get-MgBetaNetworkAccessForwardingProfile -ForwardingProfileId $Id -ErrorAction SilentlyContinue } + if ($null -eq $getValue) { Write-Verbose -Message "Could not find an Azure AD Network Access Forwarding Profile with Id:{$Id}" @@ -97,7 +91,7 @@ function Get-TargetResource #endregion if ($null -eq $getValue) { - Write-Verbose -Message "Could not find an Azure AD Network Access Forwarding Profile with {$Name}." + Write-Verbose -Message "Could not find an Azure AD Network Access Forwarding Profile with name {$Name}." return $nullResult } @@ -115,7 +109,7 @@ function Get-TargetResource $myPolicies = @{} $myPolicies.Add('Name', $currentPolicy.Policy.Name) $myPolicies.Add('State', $currentPolicy.State) - $myPolicies.Add('Id', $currentPolicy.Id) + $myPolicies.Add('PolicyLinkId', $currentPolicy.Id) if ($myPolicies.values.Where({ $null -ne $_ }).Count -gt 0) { $complexPolicies += $myPolicies @@ -129,7 +123,6 @@ function Get-TargetResource State = $getValue.State Policies = $complexPolicies # 'Policies@Odata.Context' = $getValue.AdditionalProperties['policies@odata.context'] - Ensure = 'Present' Credential = $Credential ApplicationId = $ApplicationId TenantId = $TenantId @@ -175,11 +168,6 @@ function Set-TargetResource $Policies, #endregion - [Parameter()] - [System.String] - [ValidateSet('Absent', 'Present')] - $Ensure = 'Present', - [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -212,52 +200,59 @@ function Set-TargetResource # 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 - - - # if ( $Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') - # { - # Write-Warning -Message "Can not create the Azure AD Network Access Forwarding Profile with {$($currentInstance.Name)}." - # } - # elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') - # { - # Write-Verbose -Message "Updating the Azure AD Network Access Forwarding Profile with {$($currentInstance.Id)}" - - # $updateParameters = ([Hashtable]$BoundParameters).Clone() - # $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters - - # $updateParameters.Remove('Id') | Out-Null - - # $keys = (([Hashtable]$updateParameters).Clone()).Keys - # foreach ($key in $keys) - # { - # if ($null -ne $updateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') - # { - # $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.$key - # } - # } - - # #region resource generator code - # Update-MgBetaNetworkAccessForwardingProfile ` - # -ForwardingProfileId $Id ` - # -BodyParameter $UpdateParameters - # #endregion - # } - # elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') - # { - # Write-Warning -Message "Can not remove the Azure AD Network Access Forwarding Profile with {$($currentInstance.Name)}." - # } + #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 + + if ($null -ne $currentInstance) + { + Write-Verbose -Message "Updating the Azure AD Network Access Forwarding Profile with {$($currentInstance.Id)}" + + $updateParameters = ([Hashtable]$BoundParameters).Clone() + $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters + + $updateParameters.Remove('Id') | Out-Null + + $keys = (([Hashtable]$updateParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $updateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') + { + $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.$key + } + } + Write-Verbose -Message "Updating the Azure AD Network Access Forwarding Profile with {$($currentInstance.Id)} {$($currentInstance.Name)} State" + Update-MgBetaNetworkAccessForwardingProfile ` + -ForwardingProfileId $currentInstance.Id ` + -State $updateParameters.State + + $currentPolicies = $currentInstance.Policies + $updatedPolicies = $updateParameters.Policies + + # update the current policy's state with the updated policy's state. + foreach ($currentPolicy in $currentPolicies) + { + $updatedPolicy = $updatedPolicies | Where-Object { $_.Name -eq $currentPolicy.Name } + if ($null -ne $updatedPolicy) + { + Write-Verbose -Message "Updating the Azure AD Network Access Forwarding Profile Policy with Id {$($currentPolicy.PolicyLinkId)} {$($currentPolicy.Name)}" + Update-MgBetaNetworkAccessForwardingProfilePolicy ` + -ForwardingProfileId $currentInstance.Id ` + -PolicyLinkId $currentPolicy.PolicyLinkId ` + -State $updatedPolicy.State + } + } + #endregion + } } function Test-TargetResource @@ -286,11 +281,6 @@ function Test-TargetResource #endregion - [Parameter()] - [System.String] - [ValidateSet('Absent', 'Present')] - $Ensure = 'Present', - [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -337,7 +327,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -ne $Ensure) + if ($null -eq $CurrentValues) { Write-Verbose -Message "Test-TargetResource returned $false" return $false @@ -467,7 +457,6 @@ function Export-TargetResource $params = @{ Id = $config.Id Name = $config.Name - Ensure = 'Present' Credential = $Credential ApplicationId = $ApplicationId TenantId = $TenantId @@ -535,7 +524,7 @@ function Get-PoliciesAsString { $StringContent += "MSFT_MicrosoftGraphNetworkaccessPolicyLink {`r`n" $StringContent += " State = '" + $policy.State + "'`r`n" - $StringContent += " Id = '" + $policy.Id + "'`r`n" + $StringContent += " PolicyLinkId = '" + $policy.PolicyLinkId + "'`r`n" $StringContent += " Name = '" + $policy.Name + "'`r`n" $StringContent += " }`r`n" } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof index 939b48bdb3..4bd1149ec8 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.schema.mof @@ -3,7 +3,7 @@ class MSFT_MicrosoftGraphNetworkaccessPolicyLink { [Write, Description("Policy Name. Required")] String Name; - [Write, Description("A Unique Identifier")] String Id; + [Write, Description("Policy Link Id")] String PolicyLinkId; [Write, Description("status")] String state; }; @@ -14,7 +14,6 @@ class MSFT_AADNetworkAccessForwardingProfile : OMI_BaseResource [Write, Description("Id of the profile. Unique Identifier")] String Id; [Write, Description("status of the profile")] String State; [Write, Description("Traffic forwarding policies associated with this profile."), EmbeddedInstance("MSFT_MicrosoftGraphNetworkaccessPolicyLink")] String Policies[]; - [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; From 04f0c1cd243c96ee11dd83ed2f3fa2c15f61984a Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Wed, 23 Oct 2024 22:29:42 +0530 Subject: [PATCH 03/16] Added UTs --- ...SFT_AADNetworkAccessForwardingProfile.psm1 | 2 +- ...ADNetworkAccessForwardingProfile.Tests.ps1 | 222 +++++++++++ Tests/Unit/Stubs/Microsoft365.psm1 | 357 ++++++++++++++++++ 3 files changed, 580 insertions(+), 1 deletion(-) create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNetworkAccessForwardingProfile.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 index c06ba0ed46..346290bfd6 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 @@ -87,7 +87,6 @@ function Get-TargetResource } } - #endregion if ($null -eq $getValue) { @@ -98,6 +97,7 @@ function Get-TargetResource Write-Verbose -Message "An Azure AD Network Access Forwarding Profile with {$Id} and {$Name} was found" $forwardingProfilePolicies = Get-MgBetaNetworkAccessForwardingProfilePolicy -ForwardingProfileId $getValue.Id -ErrorAction SilentlyContinue + if ($null -ne $forwardingProfilePolicies) { Write-Verbose -Message "An Azure AD Network Access Forwarding Profile Policy with $($forwardingProfilePolicies.Id) and $($forwardingProfilePolicies.Name) was found" diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNetworkAccessForwardingProfile.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNetworkAccessForwardingProfile.Tests.ps1 new file mode 100644 index 0000000000..45026a3cb0 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADNetworkAccessForwardingProfile.Tests.ps1 @@ -0,0 +1,222 @@ +[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 'AADNetworkAccessForwardingProfile' -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-MgBetaNetworkAccessForwardingProfile -MockWith { + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfile -MockWith { + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfilePolicy -MockWith { + } + + Mock -CommandName Update-MgBetaNetworkAccessForwardingProfilePolicy -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 + } + # Test contexts + Context -Name 'The AADNetworkAccessForwardingProfile Exists and Values are already in the desired state' -Fixture { + BeforeAll { + $testParams = @{ + Name = 'Microsoft 365 traffic forwarding profile' + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'enabled' + Policies = @( + New-CimInstance -ClassName MSFT_MicrosoftGraphNetworkaccessPolicyLink -Property @{ + Name = 'Custom Bypass' + PolicyLinkId = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'enabled' + } -ClientOnly + New-CimInstance -ClassName MSFT_MicrosoftGraphNetworkaccessPolicyLink -Property @{ + Name = 'Default Bypass' + PolicyLinkId = '12345678-1234-1234-1234-123456789012' + State = 'enabled' + } -ClientOnly + ) + Credential = $Credential + + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfile -MockWith { + return @{ + Name = 'Microsoft 365 traffic forwarding profile' + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'enabled' + } + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfilePolicy -MockWith { + return @( + @{ + Policy = @{ + Name = 'Custom Bypass' + } + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'enabled' + }, + @{ + Policy = @{ + Name = 'Default Bypass' + } + Id = '12345678-1234-1234-1234-123456789012' + State = 'enabled' + } + ) + } + } + + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name 'The AADNetworkAccessForwardingProfile exists and values are NOT in the desired state' -Fixture { + BeforeAll { + $testParams = @{ + Name = 'Microsoft 365 traffic forwarding profile' + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'disabled' + Policies = @( + New-CimInstance -ClassName MSFT_MicrosoftGraphNetworkaccessPolicyLink -Property @{ + Name = 'Custom Bypass' + PolicyLinkId = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'enabled' + } -ClientOnly + New-CimInstance -ClassName MSFT_MicrosoftGraphNetworkaccessPolicyLink -Property @{ + Name = 'Default Bypass' + PolicyLinkId = '12345678-1234-1234-1234-123456789012' + State = 'disabled' + } -ClientOnly + ) + Credential = $Credential + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfile -MockWith { + return @{ + Name = 'Microsoft 365 traffic forwarding profile' + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'disabled' + } + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfilePolicy -MockWith { + return @( + @{ + Policy = @{ + Name = 'Custom Bypass' + } + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'disabled' + }, + @{ + Policy = @{ + Name = 'Default Bypass' + } + Id = '12345678-1234-1234-1234-123456789012' + State = 'enabled' + } + ) + } + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set Update-MgBetaNetworkAccessForwardingProfile method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Update-MgBetaNetworkAccessForwardingProfile -Exactly 1 + } + + It 'Should call the Set Update-MgBetaNetworkAccessForwardingProfilePolicy method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Update-MgBetaNetworkAccessForwardingProfilePolicy -Exactly 2 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfile -MockWith { + return @{ + Name = 'Microsoft 365 traffic forwarding profile' + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'disabled' + } + } + + Mock -CommandName Get-MgBetaNetworkAccessForwardingProfilePolicy -MockWith { + return @( + @{ + Policy = @{ + Name = 'Custom Bypass' + } + Id = '58847306-0ae2-4f65-91ee-d6587e9bebda' + State = 'disabled' + }, + @{ + Policy = @{ + Name = 'Default Bypass' + } + Id = '12345678-1234-1234-1234-123456789012' + State = 'enabled' + } + ) + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index cdcf592740..b89f560fb5 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -97638,3 +97638,360 @@ function Invoke-PnPSPRestMethod $Content ) } +#region MgBetaNetworkAccessForwardingProfile +function Get-MgBetaNetworkAccessForwardingProfile +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $ForwardingProfileId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String[]] + $ExpandProperty, + + [Parameter()] + [System.String[]] + $Property, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.String] + $Search, + + [Parameter()] + [System.Int32] + $Skip, + + [Parameter()] + [System.String[]] + $Sort, + + [Parameter()] + [System.Int32] + $Top, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Int32] + $PageSize, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $All, + + [Parameter()] + [System.String] + $CountVariable + ) +} + +function Update-MgBetaNetworkAccessForwardingProfile +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $ForwardingProfileId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [PSObject[]] + $Associations, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.DateTime] + $LastModifiedDateTime, + + [Parameter()] + [System.String] + $Name, + + [Parameter()] + [PSObject[]] + $Policies, + + [Parameter()] + [System.Int32] + $Priority, + + [Parameter()] + [PSObject] + $ServicePrincipal, + + [Parameter()] + [System.String] + $State, + + [Parameter()] + [System.String] + $TrafficForwardingType, + + [Parameter()] + [System.String] + $Version, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +#endregion + +#region MgBetaNetworkAccessForwardingProfilePolicy +function Get-MgBetaNetworkAccessForwardingProfilePolicy +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $ForwardingProfileId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String[]] + $ExpandProperty, + + [Parameter()] + [System.String[]] + $Property, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.String] + $Search, + + [Parameter()] + [System.Int32] + $Skip, + + [Parameter()] + [System.String[]] + $Sort, + + [Parameter()] + [System.Int32] + $Top, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Int32] + $PageSize, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $All, + + [Parameter()] + [System.String] + $CountVariable + ) +} + +function Update-MgBetaNetworkAccessForwardingProfilePolicy +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $ForwardingProfileId, + + [Parameter()] + [System.String] + $PolicyLinkId , + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $State, + + [Parameter()] + [System.String] + $Version, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +#endregion From 10574d5e7ae4fbd1787d6c5724ee1b45dd117cb1 Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Wed, 23 Oct 2024 22:34:31 +0530 Subject: [PATCH 04/16] added changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 855ee044d2..b6f223b1bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * AADAccessReviewDefinition * Initial release. +* AADNetworkAccessForwardingProfile + * Initial release. * AADAuthenticationMethodPolicyExternal * Initial release. * AADCustomSecurityAttributeDefinition From 39a48c0c66c795a0ec3dd7396c1fb324c475dfcb Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Wed, 23 Oct 2024 23:08:32 +0000 Subject: [PATCH 05/16] Updated Resources and Cmdlet documentation pages --- docs/docs/resources/intune/IntuneDerivedCredential.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/resources/intune/IntuneDerivedCredential.md b/docs/docs/resources/intune/IntuneDerivedCredential.md index c43b79bec9..b42c76a61e 100644 --- a/docs/docs/resources/intune/IntuneDerivedCredential.md +++ b/docs/docs/resources/intune/IntuneDerivedCredential.md @@ -9,7 +9,7 @@ | **HelpUrl** | Write | String | The URL that will be accessible to end users as they retrieve a derived credential using the Company Portal. | | | **RenewalThresholdPercentage** | Write | UInt32 | The nominal percentage of time before certificate renewal is initiated by the client. | | | **Issuer** | Write | String | Supported values for the derived credential issuer. | `intercede`, `entrustDatacard`, `purebred` | -| **NotificationType** | Write | String | Supported values for the notification type to use. | `none`, `email`, `companyPortal` | +| **NotificationType** | Write | String | Supported values for the notification type to use. | `none`, `email`, `companyPortal`, `companyPortal,email` | | **Ensure** | Write | String | Supported values for the notification type to use. | `Present`, `Absent` | | **Credential** | Write | PSCredential | Credentials of the Intune Admin | | | **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | From dd6a3be921c908e4f83f01798bfc359b865dbbec Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Thu, 24 Oct 2024 10:14:45 +0530 Subject: [PATCH 06/16] added example --- .../Update.ps1 | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Modules/Microsoft365DSC/Examples/Resources/AADNetworkAccessForwardingProfile/Update.ps1 diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADNetworkAccessForwardingProfile/Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADNetworkAccessForwardingProfile/Update.ps1 new file mode 100644 index 0000000000..2a7431f519 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADNetworkAccessForwardingProfile/Update.ps1 @@ -0,0 +1,50 @@ +# Generated with Microsoft365DSC version 1.24.1016.1 +# For additional information on how to use Microsoft365DSC, please visit https://aka.ms/M365DSC + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + + Import-DscResource -ModuleName 'Microsoft365DSC' + + Node localhost + { + AADNetworkAccessForwardingProfile "AADNetworkAccessForwardingProfile-Internet traffic forwarding profile" + { + + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Name = "Internet traffic forwarding profile"; + Policies = @(MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'disabled' + PolicyLinkId = 'f8a43f3f-3f44-4738-8025-088bb095a711' + Name = 'Custom Bypass' + } +MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'enabled' + PolicyLinkId = 'b45d1db0-9965-487b-afb1-f4d25174e9db' + Name = 'Default Bypass' + } +MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'enabled' + PolicyLinkId = 'dfd9cd59-90ca-44fc-b997-7cc71f08e438' + Name = 'Default Acquire' + } + ); + State = "disabled"; + } + } +} From 22f5da9fde693049ce470c45e3993b514040e015 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Thu, 24 Oct 2024 10:41:17 +0530 Subject: [PATCH 07/16] first commit --- CHANGELOG.md | 2 + .../MSFT_AADAccessReviewPolicy.psm1 | 330 ++++++++++++++++++ .../MSFT_AADAccessReviewPolicy.schema.mof | 13 + .../MSFT_AADAccessReviewPolicy/readme.md | 6 + .../MSFT_AADAccessReviewPolicy/settings.json | 28 ++ .../AADAccessReviewPolicy/2-Update.ps1 | 34 ++ ...soft365DSC.AADAccessReviewPolicy.Tests.ps1 | 118 +++++++ Tests/Unit/Stubs/Microsoft365.psm1 | 110 ++++++ 8 files changed, 641 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json create mode 100644 Modules/Microsoft365DSC/Examples/Resources/AADAccessReviewPolicy/2-Update.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAccessReviewPolicy.Tests.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 046e476c01..741bb95188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * AADAccessReviewDefinition * Initial release. +* AADAccessReviewPolicy + * Initial release. * AADCustomSecurityAttributeDefinition * Fixed missing permissions in settings.json * AADIdentityB2XUserFlow diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.psm1 new file mode 100644 index 0000000000..226e9f3c22 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.psm1 @@ -0,0 +1,330 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $IsSingleInstance, + + [Parameter()] + [System.Boolean] + $IsGroupOwnerManagementEnabled, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -InboundParameters $PSBoundParameters | Out-Null + + #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 + try + { + $instance = Get-MgBetaPolicyAccessReviewPolicy -ErrorAction Stop + if ($null -eq $instance) + { + throw 'Could not retrieve the Access Review Policy' + } + + $results = @{ + IsSingleInstance = 'Yes' + IsGroupOwnerManagementEnabled = $instance.IsGroupOwnerManagementEnabled + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + return [System.Collections.Hashtable] $results + } + catch + { + Write-Verbose -Message $_ + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $IsSingleInstance, + + [Parameter()] + [System.Boolean] + $IsGroupOwnerManagementEnabled, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [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 + + $updateParameters = @{ + IsGroupOwnerManagementEnabled = $IsGroupOwnerManagementEnabled + } + + $updateJSON = ConvertTo-Json $updateParameters + Write-Verbose -Message "Updating the Entra Id Access Review Policy with values: $updateJSON" + Update-MgBetaPolicyAccessReviewPolicy -BodyParameter $updateParameters +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $IsSingleInstance, + + [Parameter()] + [System.Boolean] + $IsGroupOwnerManagementEnabled, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [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 + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $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] + $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 + { + $Script:ExportMode = $true + [array] $Script:exportedInstances = Get-MgBetaPolicyAccessReviewPolicy -ErrorAction Stop + + $i = 1 + $dscContent = '' + if ($Script:exportedInstances.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $Script:exportedInstances) + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + + $displayedKey = 'Access Review Policy' + Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline + $params = @{ + IsSingleInstance = 'Yes' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + $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_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.schema.mof new file mode 100644 index 0000000000..a5ddb2612b --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/MSFT_AADAccessReviewPolicy.schema.mof @@ -0,0 +1,13 @@ +[ClassVersion("1.0.0.0"), FriendlyName("AADAccessReviewPolicy")] +class MSFT_AADAccessReviewPolicy : OMI_BaseResource +{ + [Key, Description("Only valid value is 'Yes'."), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; + [Write, Description("If true, group owners can create and manage access reviews on groups they own.")] Boolean IsGroupOwnerManagementEnabled; + + [Write, Description("Credentials of the workload's 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("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_AADAccessReviewPolicy/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/readme.md new file mode 100644 index 0000000000..70b59b7f25 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/readme.md @@ -0,0 +1,6 @@ + +# AADAccessReviewPolicy + +## Description + +Use this resource to monitor the access review policy object. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json new file mode 100644 index 0000000000..9dd2ddf441 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json @@ -0,0 +1,28 @@ +{ + "resourceName": "AADAccessReviewPolicy", + "description": "Use this resource to monitor the access review policy object.", + "roles": { + "read": [], + "update": [] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [ + { + "name": "Policy.ReadWrite.AccessReview" + } + ], + "update": [ + { + "name": "Policy.ReadWrite.AccessReview" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADAccessReviewPolicy/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADAccessReviewPolicy/2-Update.ps1 new file mode 100644 index 0000000000..f69b86add3 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADAccessReviewPolicy/2-Update.ps1 @@ -0,0 +1,34 @@ +<# +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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + AADAccessReviewPolicy "AADAccessReviewPolicy" + { + ApplicationId = $ConfigurationData.NonNodeData.ApplicationId; + CertificateThumbprint = $ConfigurationData.NonNodeData.CertificateThumbprint; + IsGroupOwnerManagementEnabled = $False; + IsSingleInstance = "Yes"; + TenantId = $OrganizationName; + } + + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAccessReviewPolicy.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAccessReviewPolicy.Tests.ps1 new file mode 100644 index 0000000000..76d5306bcf --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAccessReviewPolicy.Tests.ps1 @@ -0,0 +1,118 @@ +[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) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -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 New-M365DSCConnection -MockWith { + return "Credentials" + } + + Mock -Command Get-MgBetaPolicyAccessReviewPolicy -MockWith { + } + + Mock -Command Update-MgBetaPolicyAccessReviewPolicy -MockWith { + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + # Test contexts + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + IsSingleInstance = 'Yes' + IsGroupOwnerManagementEnabled = $True; + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyAccessReviewPolicy -MockWith { + return @{ + IsGroupOwnerManagementEnabled = $True; + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + IsSingleInstance = 'Yes' + IsGroupOwnerManagementEnabled = $True; + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyAccessReviewPolicy -MockWith { + return @{ + IsGroupOwnerManagementEnabled = $False; + } + } + } + + 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-MgBetaPolicyAccessReviewPolicy -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyAccessReviewPolicy -MockWith { + return @{ + IsGroupOwnerManagementEnabled = $True; + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index 7d0f828598..4faabd95d5 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -34965,6 +34965,51 @@ function Get-MgBetaIdentityConditionalAccessPolicy $HttpPipelineAppend ) } +function Get-MgBetaPolicyAccessReviewPolicy +{ + [CmdletBinding()] + param( + [Parameter()] + [PSObject] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.String[]] + $ExpandProperty, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [PSObject] + $HttpPipelineAppend, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [System.String[]] + $Property, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break + ) +} function Get-MgBetaIdentityProvider { [CmdletBinding()] @@ -37466,6 +37511,71 @@ function Update-MgBetaPolicyAuthenticationStrengthPolicyAllowedCombination $Break ) } +function Update-MgBetaPolicyAccessReviewPolicy +{ + [CmdletBinding()] + param( + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IsGroupOwnerManagementEnabled, + + [Parameter()] + [System.String] + $DisplayName, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [PSObject] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject] + $HttpPipelineAppend + ) +} function Update-MgBetaPolicyAuthorizationPolicy { [CmdletBinding()] From 4c1de0410ef855c3c8329f10b05d86767576a8cc Mon Sep 17 00:00:00 2001 From: Riyansh Goyal Date: Thu, 24 Oct 2024 10:46:29 +0530 Subject: [PATCH 08/16] minor change --- .../MSFT_AADNetworkAccessForwardingProfile.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 index 346290bfd6..a1e6c27217 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADNetworkAccessForwardingProfile/MSFT_AADNetworkAccessForwardingProfile.psm1 @@ -122,7 +122,6 @@ function Get-TargetResource Id = $getValue.Id State = $getValue.State Policies = $complexPolicies - # 'Policies@Odata.Context' = $getValue.AdditionalProperties['policies@odata.context'] Credential = $Credential ApplicationId = $ApplicationId TenantId = $TenantId From 290e4dd334ad25f77f7b870c60c5e9e17bb932ef Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Thu, 24 Oct 2024 10:59:15 +0530 Subject: [PATCH 09/16] minor --- .../DSCResources/MSFT_AADAccessReviewPolicy/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json index 9dd2ddf441..64be16a4f7 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAccessReviewPolicy/settings.json @@ -14,7 +14,7 @@ "application": { "read": [ { - "name": "Policy.ReadWrite.AccessReview" + "name": "Policy.Read.All" } ], "update": [ From c93afb835b6c342de808ab6fcd25509549ea3dbc Mon Sep 17 00:00:00 2001 From: Ricardo Mestre Date: Thu, 24 Oct 2024 11:27:59 +0100 Subject: [PATCH 10/16] Fix Test-TargetResource --- CHANGELOG.md | 2 ++ .../MSFT_EXOTenantAllowBlockListItems.psm1 | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 394b4af421..bfe3d92853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ * Fixed missing permissions in settings.json * EXOMailboxAuditBypassAssociation * Initial release. +* EXOTenantAllowBlockListItems + * Fixed `Test-TargetResource` to correctly mark when this resource is removed * IntuneDerivedCredential * Fixed export and deployment when `NotificationType` had more than one option selected diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOTenantAllowBlockListItems/MSFT_EXOTenantAllowBlockListItems.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOTenantAllowBlockListItems/MSFT_EXOTenantAllowBlockListItems.psm1 index 08fd6b85e3..01778e9c2b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOTenantAllowBlockListItems/MSFT_EXOTenantAllowBlockListItems.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOTenantAllowBlockListItems/MSFT_EXOTenantAllowBlockListItems.psm1 @@ -378,18 +378,21 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() - $ValuesToCheck.Remove('Entries') | Out-Null - if ($null -ne $ValuesToCheck.ExpirationDate -and $ValuesToCheck.ExpirationDate.Kind -eq 'Local') - { - $ValuesToCheck.ExpirationDate = $ValuesToCheck.ExpirationDate.ToUniversalTime().ToString() - } - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false } + if ($null -ne $ValuesToCheck.ExpirationDate -and $ValuesToCheck.ExpirationDate.Kind -eq 'Local') + { + $ValuesToCheck.ExpirationDate = $ValuesToCheck.ExpirationDate.ToUniversalTime().ToString() + } + + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + $ValuesToCheck.Remove('Entries') | Out-Null + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" From 755ad91a547d95b1cd947ec7d150eb87b1e47507 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Thu, 24 Oct 2024 10:44:44 +0000 Subject: [PATCH 11/16] Updated Resources and Cmdlet documentation pages --- .../azure-ad/AADAccessReviewPolicy.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/docs/resources/azure-ad/AADAccessReviewPolicy.md diff --git a/docs/docs/resources/azure-ad/AADAccessReviewPolicy.md b/docs/docs/resources/azure-ad/AADAccessReviewPolicy.md new file mode 100644 index 0000000000..51e25ff402 --- /dev/null +++ b/docs/docs/resources/azure-ad/AADAccessReviewPolicy.md @@ -0,0 +1,85 @@ +# AADAccessReviewPolicy + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **IsSingleInstance** | Key | String | Only valid value is 'Yes'. | `Yes` | +| **IsGroupOwnerManagementEnabled** | Write | Boolean | If true, group owners can create and manage access reviews on groups they own. | | +| **Credential** | Write | PSCredential | Credentials of the workload's Admin | | +| **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | +| **TenantId** | Write | String | Id of the Azure Active Directory tenant used for authentication. | | +| **CertificateThumbprint** | Write | String | Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication. | | +| **ManagedIdentity** | Write | Boolean | Managed ID being used for authentication. | | +| **AccessTokens** | Write | StringArray[] | Access token used for authentication. | | + + +## Description + +Use this resource to monitor the access review policy object. + +## Permissions + +### Microsoft Graph + +To authenticate with the Microsoft Graph API, this resource required the following permissions: + +#### Delegated permissions + +- **Read** + + - None + +- **Update** + + - None + +#### Application permissions + +- **Read** + + - Policy.Read.All + +- **Update** + + - Policy.ReadWrite.AccessReview + +## Examples + +### Example 1 + +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. + +```powershell +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + AADAccessReviewPolicy "AADAccessReviewPolicy" + { + ApplicationId = $ConfigurationData.NonNodeData.ApplicationId; + CertificateThumbprint = $ConfigurationData.NonNodeData.CertificateThumbprint; + IsGroupOwnerManagementEnabled = $False; + IsSingleInstance = "Yes"; + TenantId = $OrganizationName; + } + + } +} +``` + From 40feb76cefaf8f341a7935aa39359a8c1ef823ca Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Thu, 24 Oct 2024 10:45:11 +0000 Subject: [PATCH 12/16] Updated {Update} AAD Integration Tests --- .../M365DSCIntegration.AAD.Update.Tests.ps1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 index a7082349e2..cfc7c836f5 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 @@ -125,6 +125,14 @@ TenantId = $TenantId CertificateThumbprint = $CertificateThumbprint } + AADAccessReviewPolicy 'AADAccessReviewPolicy' + { + ApplicationId = $ConfigurationData.NonNodeData.ApplicationId; + CertificateThumbprint = $ConfigurationData.NonNodeData.CertificateThumbprint; + IsGroupOwnerManagementEnabled = $False; + IsSingleInstance = "Yes"; + TenantId = $OrganizationName; + } AADAdminConsentRequestPolicy 'AADAdminConsentRequestPolicy' { ApplicationId = $ApplicationId; From 10c5cdad22509994af705c3047d57057360678e5 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Thu, 24 Oct 2024 10:47:15 +0000 Subject: [PATCH 13/16] Updated Schema Definition --- Modules/Microsoft365DSC/SchemaDefinition.json | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index b1d3c54e71..d2055bd85f 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -339,6 +339,51 @@ } ] }, + { + "ClassName": "MSFT_AADAccessReviewPolicy", + "Parameters": [ + { + "CIMType": "String", + "Name": "IsSingleInstance", + "Option": "Key" + }, + { + "CIMType": "Boolean", + "Name": "IsGroupOwnerManagementEnabled", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_AADActivityBasedTimeoutPolicy", "Parameters": [ From e04eaa151935460a057d228f808d3684ff269155 Mon Sep 17 00:00:00 2001 From: RiyanshGoyal <159444353+RiyanshGoyal@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:14:18 +0530 Subject: [PATCH 14/16] Update Manifest.psd1 --- Modules/Microsoft365DSC/Dependencies/Manifest.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 index ad88da500b..a1205e2187 100644 --- a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 +++ b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 @@ -58,7 +58,7 @@ }, @{ ModuleName = 'Microsoft.Graph.Beta.NetworkAccess' - RequiredVersion = '2.23.0' + RequiredVersion = '2.24.0' }, @{ ModuleName = 'Microsoft.Graph.Beta.Identity.DirectoryManagement' From 1865b5fd6ba0b72aa6e97fc55ad2843ea1d53785 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Thu, 24 Oct 2024 12:36:25 +0000 Subject: [PATCH 15/16] Updated Resources and Cmdlet documentation pages --- .../AADNetworkAccessForwardingProfile.md | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 docs/docs/resources/azure-ad/AADNetworkAccessForwardingProfile.md diff --git a/docs/docs/resources/azure-ad/AADNetworkAccessForwardingProfile.md b/docs/docs/resources/azure-ad/AADNetworkAccessForwardingProfile.md new file mode 100644 index 0000000000..6f14c1d50b --- /dev/null +++ b/docs/docs/resources/azure-ad/AADNetworkAccessForwardingProfile.md @@ -0,0 +1,115 @@ +# AADNetworkAccessForwardingProfile + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **Name** | Key | String | Profile Name. Required. | | +| **Id** | Write | String | Id of the profile. Unique Identifier | | +| **State** | Write | String | status of the profile | | +| **Policies** | Write | MSFT_MicrosoftGraphNetworkaccessPolicyLink[] | Traffic forwarding policies associated with this profile. | | +| **Credential** | Write | PSCredential | Credentials of the Admin | | +| **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | +| **TenantId** | Write | String | Id of the Azure Active Directory tenant used for authentication. | | +| **ApplicationSecret** | Write | PSCredential | Secret of the Azure Active Directory tenant used for authentication. | | +| **CertificateThumbprint** | Write | String | Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication. | | +| **ManagedIdentity** | Write | Boolean | Managed ID being used for authentication. | | +| **AccessTokens** | Write | StringArray[] | Access token used for authentication. | | + +### MSFT_MicrosoftGraphNetworkaccessPolicyLink + +#### Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **Name** | Write | String | Policy Name. Required | | +| **PolicyLinkId** | Write | String | Policy Link Id | | +| **state** | Write | String | status | | + + +## Description + +This resource configure the Azure AD Network Access Forwarding Profile + + +## Permissions + +### Microsoft Graph + +To authenticate with the Microsoft Graph API, this resource required the following permissions: + +#### Delegated permissions + +- **Read** + + - NetworkAccess.Read.All + +- **Update** + + - NetworkAccess.ReadWrite.All + +#### Application permissions + +- **Read** + + - NetworkAccess.Read.All + +- **Update** + + - NetworkAccess.ReadWrite.All + +## Examples + +### Example 1 + + +```powershell +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + + Import-DscResource -ModuleName 'Microsoft365DSC' + + Node localhost + { + AADNetworkAccessForwardingProfile "AADNetworkAccessForwardingProfile-Internet traffic forwarding profile" + { + + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Name = "Internet traffic forwarding profile"; + Policies = @(MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'disabled' + PolicyLinkId = 'f8a43f3f-3f44-4738-8025-088bb095a711' + Name = 'Custom Bypass' + } +MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'enabled' + PolicyLinkId = 'b45d1db0-9965-487b-afb1-f4d25174e9db' + Name = 'Default Bypass' + } +MSFT_MicrosoftGraphNetworkaccessPolicyLink { + State = 'enabled' + PolicyLinkId = 'dfd9cd59-90ca-44fc-b997-7cc71f08e438' + Name = 'Default Acquire' + } + ); + State = "disabled"; + } + } +} +``` + From 2cf778afe3e4a94b71ff4b9314f033dfd03a874e Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Thu, 24 Oct 2024 12:41:56 +0000 Subject: [PATCH 16/16] Updated Schema Definition --- Modules/Microsoft365DSC/SchemaDefinition.json | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index d2055bd85f..cb4353ab47 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -6229,6 +6229,86 @@ } ] }, + { + "ClassName": "MSFT_MicrosoftGraphNetworkaccessPolicyLink", + "Parameters": [ + { + "CIMType": "String", + "Name": "Name", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "PolicyLinkId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "state", + "Option": "Write" + } + ] + }, + { + "ClassName": "MSFT_AADNetworkAccessForwardingProfile", + "Parameters": [ + { + "CIMType": "String", + "Name": "Name", + "Option": "Key" + }, + { + "CIMType": "String", + "Name": "Id", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "State", + "Option": "Write" + }, + { + "CIMType": "MSFT_MicrosoftGraphNetworkaccessPolicyLink[]", + "Name": "Policies", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "ApplicationSecret", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_MicrosoftGraphCertificateAuthority", "Parameters": [