diff --git a/BestPracticeAnalyser_OrchestrationStarter/run.ps1 b/BestPracticeAnalyser_OrchestrationStarter/run.ps1 index aba14651622b..0afc6fdc07e0 100644 --- a/BestPracticeAnalyser_OrchestrationStarter/run.ps1 +++ b/BestPracticeAnalyser_OrchestrationStarter/run.ps1 @@ -32,7 +32,6 @@ $InputObject = [PSCustomObject]@{ Batch = @($BPAReports) OrchestratorName = 'BPAOrchestrator' SkipLog = $true - DurableMode = 'Sequence' } Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Compress -Depth 5) diff --git a/BestPracticeAnalyser_OrchestrationStarterTimer/run.ps1 b/BestPracticeAnalyser_OrchestrationStarterTimer/run.ps1 index 6c34fc501c62..f111844160d4 100644 --- a/BestPracticeAnalyser_OrchestrationStarterTimer/run.ps1 +++ b/BestPracticeAnalyser_OrchestrationStarterTimer/run.ps1 @@ -31,6 +31,5 @@ $InputObject = [PSCustomObject]@{ Batch = @($BPAReports) OrchestratorName = 'BPAOrchestrator' SkipLog = $true - DurableMode = 'Sequence' } Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Compress -Depth 5) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAdminPassword.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAdminPassword.ps1 index 2b92dc01a0ab..27e911fe98b0 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAdminPassword.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAdminPassword.ps1 @@ -7,7 +7,8 @@ function Get-CIPPAlertAdminPassword { [CmdletBinding()] param( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertApnCertExpiry.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertApnCertExpiry.ps1 index 25d63b23ebcd..bf6086581cf6 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertApnCertExpiry.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertApnCertExpiry.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertApnCertExpiry { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAppSecretExpiry.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAppSecretExpiry.ps1 index cc4884df294b..cef5ba03ba14 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAppSecretExpiry.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertAppSecretExpiry.ps1 @@ -6,30 +6,28 @@ function Get-CIPPAlertAppSecretExpiry { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { Write-Host "Checking app expire for $($TenantFilter)" $appList = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/applications?`$select=appId,displayName,passwordCredentials" -tenantid $TenantFilter - $AlertData = foreach ($App in $applist) { - Write-Host "checking $($App.displayName)" - if ($App.passwordCredentials) { - foreach ($Credential in $App.passwordCredentials) { - if ($Credential.endDateTime -lt (Get-Date).AddDays(30) -and $Credential.endDateTime -gt (Get-Date).AddDays(-7)) { - Write-Host ("Application '{0}' has secrets expiring on {1}" -f $App.displayName, $Credential.endDateTime) - @{ DisplayName = $App.displayName; Expires = $Credential.endDateTime } - } + } catch { + return + } + + $AlertData = foreach ($App in $applist) { + Write-Host "checking $($App.displayName)" + if ($App.passwordCredentials) { + foreach ($Credential in $App.passwordCredentials) { + if ($Credential.endDateTime -lt (Get-Date).AddDays(30) -and $Credential.endDateTime -gt (Get-Date).AddDays(-7)) { + Write-Host ("Application '{0}' has secrets expiring on {1}" -f $App.displayName, $Credential.endDateTime) + @{ DisplayName = $App.displayName; Expires = $Credential.endDateTime } } } - Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData - - } else { - Write-Host "Skipping app expire for $($TenantFilter)" } - } catch { - #Write-AlertMessage -tenant $($TenantFilter) -message "Failed to check App registration expiry for $($TenantFilter): $(Get-NormalizedError -message $_.Exception.message)" } + Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData } - diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderMalware.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderMalware.ps1 index 6129c3b6ab3f..ea4812c62548 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderMalware.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderMalware.ps1 @@ -7,7 +7,8 @@ function Get-CIPPAlertDefenderMalware { [CmdletBinding()] param( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderStatus.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderStatus.ps1 index cccb46f13f5b..8dca902b18a5 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderStatus.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDefenderStatus.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertDefenderStatus { [CmdletBinding()] param( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDepTokenExpiry.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDepTokenExpiry.ps1 index c67ff7bc39d0..1bf1e9c4463e 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDepTokenExpiry.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertDepTokenExpiry.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertDepTokenExpiry { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) @@ -22,7 +23,7 @@ function Get-CIPPAlertDepTokenExpiry { } catch {} - + } catch { Write-AlertMessage -tenant $($TenantFilter) -message "Failed to check Apple Device Enrollment Program token expiry for $($TenantFilter): $(Get-NormalizedError -message $_.Exception.message)" } diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertExpiringLicenses.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertExpiringLicenses.ps1 index bf41dbc3e74c..1c8046934429 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertExpiringLicenses.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertExpiringLicenses.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertExpiringLicenses { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAdmins.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAdmins.ps1 index d1eb7df2c93a..411e3c96a806 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAdmins.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAdmins.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertMFAAdmins { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAlertUsers.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAlertUsers.ps1 index 386dbde00c5f..0b59055ed560 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAlertUsers.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAlertUsers.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertMFAAlertUsers { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 index 9fe0dc66271d..3708942b4759 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 @@ -7,7 +7,8 @@ function Get-CIPPAlertNewAppApproval { [CmdletBinding()] param( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewRole.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewRole.ps1 index 65fc84b35315..04beb6a6d523 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewRole.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewRole.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertNewRole { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) $Deltatable = Get-CIPPTable -Table DeltaCompare diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNoCAConfig.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNoCAConfig.ps1 index 2875b082fa6a..2bbc9e5a55a5 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNoCAConfig.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNoCAConfig.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertNoCAConfig { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertOverusedLicenses.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertOverusedLicenses.ps1 index dedead01d535..b02a8bb00676 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertOverusedLicenses.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertOverusedLicenses.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertOverusedLicenses { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1 index 675dbeb8251e..32b63925c02a 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1 @@ -6,22 +6,25 @@ function Get-CIPPAlertQuotaUsed { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) - try { - $AlertData = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/getMailboxUsageDetail(period='D7')?`$format=application/json" -tenantid $TenantFilter | ForEach-Object { - if ($_.StorageUsedInBytes -eq 0) { return } - $PercentLeft = [math]::round($_.StorageUsedInBytes / $_.prohibitSendReceiveQuotaInBytes * 100) - if ($Input) { $Value = $input } else { $Value = 90 } - if ($PercentLeft -gt $Value) { - "$($_.UserPrincipalName): Mailbox is more than $($value)% full. Mailbox is $PercentLeft% full" - } - - } - Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData + $AlertData = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/getMailboxUsageDetail(period='D7')?`$format=application/json" -tenantid $TenantFilter } catch { + return + } + $AlertData | ForEach-Object { + if ($_.StorageUsedInBytes -eq 0) { return } + $PercentLeft = [math]::round(($_.storageUsedInBytes / $_.prohibitSendReceiveQuotaInBytes) * 100) + if ($InputValue) { $Value = [int]$InputValue } else { $Value = 90 } + if ($PercentLeft -gt $Value) { + "$($_.userPrincipalName): Mailbox is more than $($value)% full. Mailbox is $PercentLeft% full" + } + } + Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData + } diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSecDefaultsUpsell.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSecDefaultsUpsell.ps1 index 8f3ff0fd48c2..c560d47329cb 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSecDefaultsUpsell.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSecDefaultsUpsell.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertSecDefaultsUpsell { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 index db33c5a1a4f1..4cb04042f495 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 @@ -7,7 +7,8 @@ function Get-CIPPAlertSharepointQuota { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) Try { @@ -15,16 +16,15 @@ function Get-CIPPAlertSharepointQuota { $sharepointToken = (Get-GraphToken -scope "https://$($tenantName)-admin.sharepoint.com/.default" -tenantid $TenantFilter) $sharepointToken.Add('accept', 'application/json') $sharepointQuota = (Invoke-RestMethod -Method 'GET' -Headers $sharepointToken -Uri "https://$($tenantName)-admin.sharepoint.com/_api/StorageQuotas()?api-version=1.3.2" -ErrorAction Stop).value - if ($sharepointQuota) { - if ($input -Is [Boolean]) { $Value = 90 } else { $Value = $input } - $UsedStoragePercentage = [int](($sharepointQuota.GeoUsedStorageMB / $sharepointQuota.TenantStorageMB) * 100) - if ($UsedStoragePercentage -gt $Value) { - $AlertData = "SharePoint Storage is at $($UsedStoragePercentage)%. Your alert threshold is $($Value)%" - Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData - } - } } catch { + return + } + if ($sharepointQuota) { + if ($InputValue -Is [Boolean]) { $Value = 90 } else { $Value = $InputValue } + $UsedStoragePercentage = [int](($sharepointQuota.GeoUsedStorageMB / $sharepointQuota.TenantStorageMB) * 100) + if ($UsedStoragePercentage -gt $Value) { + $AlertData = "SharePoint Storage is at $($UsedStoragePercentage)%. Your alert threshold is $($Value)%" + Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData + } } - - } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertUnusedLicenses.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertUnusedLicenses.ps1 index 5344c17d9ce3..d8fc1dd69e2c 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertUnusedLicenses.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertUnusedLicenses.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertUnusedLicenses { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertVppTokenExpiry.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertVppTokenExpiry.ps1 index 6fb0c2695d57..224d23857005 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertVppTokenExpiry.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertVppTokenExpiry.ps1 @@ -6,7 +6,8 @@ function Get-CIPPAlertVppTokenExpiry { [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] - $input, + [Alias('input')] + $InputValue, $TenantFilter ) try { @@ -23,7 +24,7 @@ function Get-CIPPAlertVppTokenExpiry { Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData } catch {} - + } catch { # Error handling } diff --git a/Modules/CIPPCore/Public/Assert-CippVersion.ps1 b/Modules/CIPPCore/Public/Assert-CippVersion.ps1 new file mode 100644 index 000000000000..83f77f43edd0 --- /dev/null +++ b/Modules/CIPPCore/Public/Assert-CippVersion.ps1 @@ -0,0 +1,27 @@ +function Assert-CippVersion { + <# + .SYNOPSIS + Compare the local version of CIPP with the latest version. + + .DESCRIPTION + Retrieves the local version of CIPP and compares it with the latest version in GitHub. + + .PARAMETER CIPPVersion + Local version of CIPP frontend + + #> + Param($CIPPVersion) + $APIVersion = (Get-Content 'version_latest.txt' -Raw).trim() + + $RemoteAPIVersion = (Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP-API/master/version_latest.txt').trim() + $RemoteCIPPVersion = (Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP/master/public/version_latest.txt').trim() + + [PSCustomObject]@{ + LocalCIPPVersion = $CIPPVersion + RemoteCIPPVersion = $RemoteCIPPVersion + LocalCIPPAPIVersion = $APIVersion + RemoteCIPPAPIVersion = $RemoteAPIVersion + OutOfDateCIPP = ([version]$RemoteCIPPVersion -gt [version]$CIPPVersion) + OutOfDateCIPPAPI = ([version]$RemoteAPIVersion -gt [version]$APIVersion) + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Authentication/Get-CIPPHttpFunctions.ps1 b/Modules/CIPPCore/Public/Authentication/Get-CIPPHttpFunctions.ps1 new file mode 100644 index 000000000000..968fa5f70b9a --- /dev/null +++ b/Modules/CIPPCore/Public/Authentication/Get-CIPPHttpFunctions.ps1 @@ -0,0 +1,37 @@ +function Get-CIPPHttpFunctions { + Param( + [switch]$ByRole, + [switch]$ByRoleGroup + ) + + try { + $Functions = Get-Command -Module CippCore | Where-Object { $_.Visibility -eq 'Public' -and $_.Name -match 'Invoke-*' } + $Results = foreach ($Function in $Functions) { + $Help = Get-Help $Function + if ($Help.Functionality -ne 'Entrypoint') { continue } + [PSCustomObject]@{ + Function = $Function.Name + Role = $Help.Role + } + } + + if ($ByRole.IsPresent -or $ByRoleGroup.IsPresent) { + $Results = $Results | Group-Object -Property Role | Select-Object -Property @{l = 'Permission'; e = { $_.Name -eq '' ? 'None' : $_.Name } }, Count, @{l = 'Functions'; e = { $_.Group.Function -replace 'Invoke-' } } | Sort-Object -Property Permission + + if ($ByRoleGroup.IsPresent) { + $RoleGroup = @{} + foreach ($Permission in $Results) { + $PermSplit = $Permission.Permission -split '\.' + if ($PermSplit.Count -ne 3) { continue } + if ($RoleGroup[$PermSplit[0]] -eq $null) { $RoleGroup[$PermSplit[0]] = @{} } + if ($RoleGroup[$PermSplit[0]][$PermSplit[1]] -eq $null) { $RoleGroup[$PermSplit[0]][$PermSplit[1]] = @{} } + $RoleGroup[$PermSplit[0]][$PermSplit[1]][$PermSplit[2]] = @($Permission.Functions) + } + $Results = $RoleGroup + } + } + $Results + } catch { + "Function Error $($_.Exception.Message): $($_.InvocationInfo.PositionMessage)" + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Authentication/Get-CIPPRolePermissions.ps1 b/Modules/CIPPCore/Public/Authentication/Get-CIPPRolePermissions.ps1 new file mode 100644 index 000000000000..0f932ee7f842 --- /dev/null +++ b/Modules/CIPPCore/Public/Authentication/Get-CIPPRolePermissions.ps1 @@ -0,0 +1,29 @@ +function Get-CIPPRolePermissions { + <# + .SYNOPSIS + Get the permissions associated with a role. + .PARAMETER RoleName + The role to get the permissions for. + .EXAMPLE + Get-CIPPRolePermissions -RoleName 'mycustomrole' + #> + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$RoleName + ) + + $Table = Get-CippTable -tablename 'CustomRoles' + $Filter = "RowKey eq '$RoleName'" + $Role = Get-CIPPAzDataTableEntity @Table -Filter $Filter + if ($Role) { + $Permissions = $Role.Permissions | ConvertFrom-Json + [PSCustomObject]@{ + Role = $Role.RowKey + Permissions = $Permissions.PSObject.Properties.Value + AllowedTenants = $Role.AllowedTenants | ConvertFrom-Json + } + } else { + throw "Role $RoleName not found." + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 b/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 new file mode 100644 index 000000000000..5fcd0395a783 --- /dev/null +++ b/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 @@ -0,0 +1,93 @@ +function Test-CIPPAccess { + param( + $Request, + [switch]$TenantList + ) + + if (!$Request.Headers.'x-ms-client-principal') { + # Direct API Access + $CustomRoles = @('CIPP-API') + } else { + $DefaultRoles = @('admin', 'editor', 'readonly', 'anonymous', 'authenticated') + $User = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Request.Headers.'x-ms-client-principal')) | ConvertFrom-Json + if ($User.userRoles -contains 'admin' -or $User.userRoles -contains 'superadmin') { + if ($TenantList.IsPresent) { + return @('AllTenants') + } + return $true + } + + $CustomRoles = $User.userRoles | ForEach-Object { + if ($DefaultRoles -notcontains $_) { + $_ + } + } + } + if (($CustomRoles | Measure-Object).Count -gt 0 ) { + $Tenants = Get-Tenants -IncludeErrors + $PermissionSet = foreach ($CustomRole in $CustomRoles) { + try { + Get-CIPPRolePermissions -Role $CustomRole + } catch { + Write-Information $_.Exception.Message + } + } + if ($TenantList.IsPresent) { + $AllowedTenants = foreach ($Permission in $PermissionSet) { + foreach ($Tenant in $Permission.AllowedTenants) { + $Tenant + } + } + return $AllowedTenants + } + + if (($PermissionSet | Measure-Object).Count -eq 0) { + return $true + } else { + $FunctionName = 'Invoke-{0}' -f $Request.Params.CIPPEndpoint + $Help = Get-Help $FunctionName + # Check API for required role + $APIRole = $Help.Role + foreach ($Role in $PermissionSet) { + # Loop through each custom role permission and check API / Tenant access + $TenantAllowed = $false + $APIAllowed = $false + foreach ($Perm in $Role.Permissions) { + if ($Perm -match $APIRole) { + $APIAllowed = $true + break + } + } + if ($APIAllowed) { + # Check tenant level access + if ($Role.AllowedTenants -contains 'AllTenants') { + $TenantAllowed = $true + } elseif ($Request.Query.TenantFilter -eq 'AllTenants' -or $Request.Body.TenantFilter -eq 'AllTenants') { + $TenantAllowed = $false + } else { + $Tenant = ($Tenants | Where-Object { $Request.Query.TenantFilter -eq $_.customerId -or $Request.Body.TenantFilter -eq $_.customerId -or $Request.Query.TenantFilter -eq $_.defaultDomainName -or $Request.Body.TenantFilter -eq $_.defaultDomainName }).customerId + + if ($Tenant) { + $TenantAllowed = $Role.AllowedTenants -contains $Tenant + if (!$TenantAllowed) { continue } + break + } else { + $TenantAllowed = $true + break + } + } + } + } + if (!$APIAllowed) { + throw "Access to this CIPP API endpoint is not allowed, the '$($Role.Role)' custom role does not have the required permission: $APIRole" + } + if (!$TenantAllowed) { + throw 'Access to this tenant is not allowed' + } else { + return $true + } + } + } else { + return $true + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1 b/Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1 index d04193b88d3a..ef4357efefd5 100644 --- a/Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1 +++ b/Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1 @@ -2,6 +2,8 @@ function Invoke-ListCippQueue { <# .FUNCTIONALITY Entrypoint + .ROLE + CIPP.Core.Read #> param($Request = $null, $TriggerMetadata = $null) diff --git a/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 b/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 index 32c577f6d356..656aa592c8a7 100644 --- a/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 +++ b/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 @@ -2,6 +2,8 @@ function Invoke-RemoveCippQueue { <# .FUNCTIONALITY Entrypoint + .ROLE + CIPP.Core.ReadWrite #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 index 78223a4bdf93..3e597fab6553 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 @@ -278,7 +278,7 @@ Function Push-ExecOnboardTenantQueue { $Tenant = Get-Tenants -TriggerRefresh -IncludeAll | Where-Object { $_.customerId -eq $Relationship.customer.tenantId } | Select-Object -First 1 $y++ Start-Sleep -Seconds 20 - } while (!$Tenant -and $y -le 4) + } while (!$Tenant -and $y -le 10) if ($Tenant) { $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = 'Tenant found in customer list' }) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 index b75de4bd1d4d..20746f57fa52 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 @@ -4,16 +4,17 @@ function Push-ExecScheduledCommand { Entrypoint #> param($Item) - Write-Host "We are going to be running a scheduled task: $($Item.TaskInfo | ConvertTo-Json)" + Write-Host "We are going to be running a scheduled task: $($Item.TaskInfo | ConvertTo-Json -Depth 10)" $Table = Get-CippTable -tablename 'ScheduledTasks' $task = $Item.TaskInfo - $commandParameters = $Item.Parameters | ConvertTo-Json | ConvertFrom-Json -AsHashtable + $commandParameters = $Item.Parameters | ConvertTo-Json -Depth 10 | ConvertFrom-Json -AsHashtable $tenant = $Item.Parameters['TenantFilter'] Write-Host "Started Task: $($Item.Command) for tenant: $tenant" try { try { + Write-Host "Starting task: $($Item.Command) with parameters: " $results = & $Item.Command @commandParameters } catch { $results = "Task Failed: $($_.Exception.Message)" @@ -53,7 +54,7 @@ function Push-ExecScheduledCommand { Results = "$errorMessage" TaskState = $State } - Write-LogMessage -API 'Scheduler_UserTasks' -tenant $tenant -message "Failed to execute task $($task.Name): $errorMessage" -sev Error + Write-LogMessage -API 'Scheduler_UserTasks' -tenant $tenant -message "Failed to execute task $($task.Name): $errorMessage" -sev Error -LogData (Get-CippExceptionData -Exception $_.Exception) } Write-Host 'Sending task results to target. Updating the task state.' @@ -79,7 +80,8 @@ function Push-ExecScheduledCommand { } Write-Host 'Sent the results to the target. Updating the task state.' - if ($task.Recurrence -eq '0' -or $task.Recurrence -eq $null) { + if ($task.Recurrence -eq '0' -or [string]::IsNullOrEmpty($task.Recurrence)) { + Write-Host 'Recurrence empty or 0. Task is not recurring. Setting task state to completed.' Update-AzDataTableEntity @Table -Entity @{ PartitionKey = $task.PartitionKey RowKey = $task.RowKey diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecAddAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecAddAlert.ps1 index 1e1ecbfc0fcc..81a079c2401d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecAddAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecAddAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAddAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 index 6028762273c6..c2c194438e96 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 @@ -2,6 +2,8 @@ function Invoke-ExecDurableFunctions { <# .FUNCTIONALITY Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding(SupportsShouldProcess = $true)] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecEditTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecEditTemplate.ps1 index 4998a8447406..053395d7d293 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecEditTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecEditTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecEditTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,7 +13,7 @@ Function Invoke-ExecEditTemplate { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - try { + try { $Table = Get-CippTable -tablename 'templates' $Table.Force = $true $guid = $request.body.guid @@ -33,7 +35,7 @@ Function Invoke-ExecEditTemplate { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Edited template $($Request.body.name) with GUID $GUID" -Sev 'Debug' } $body = [pscustomobject]@{ 'Results' = 'Successfully saved the template' } - + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to edit template: $($_.Exception.Message)" -Sev 'Error' $body = [pscustomobject]@{'Results' = "Editing template failed: $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecGeoIPLookup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecGeoIPLookup.ps1 index 3410320f99a8..6c252b12c28c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecGeoIPLookup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecGeoIPLookup.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGeoIPLookup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 index d6efbbe307f0..5a235ee7cb7d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 @@ -2,6 +2,8 @@ function Invoke-ExecPartnerWebhook { <# .FUNCTIONALITY Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> Param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 index d0bbaea27dfc..1ec68eb1a7c7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 @@ -3,60 +3,48 @@ using namespace System.Net Function Invoke-GetCippAlerts { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - $Alerts = [System.Collections.ArrayList]@() + $Alerts = [System.Collections.Generic.List[object]]::new() $Table = Get-CippTable -tablename CippAlerts $PartitionKey = Get-Date -UFormat '%Y%m%d' $Filter = "PartitionKey eq '{0}'" -f $PartitionKey $Rows = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Sort-Object TableTimestamp -Descending | Select-Object -First 10 $role = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userRoles - $APIVersion = Get-Content 'version_latest.txt' | Out-String - $CIPPVersion = $request.query.localversion - - $RemoteAPIVersion = Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP-API/master/version_latest.txt' - $RemoteCIPPVersion = Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP/master/public/version_latest.txt' - - $version = [PSCustomObject]@{ - LocalCIPPVersion = $CIPPVersion - RemoteCIPPVersion = $RemoteCIPPVersion - LocalCIPPAPIVersion = $APIVersion - RemoteCIPPAPIVersion = $RemoteAPIVersion - OutOfDateCIPP = ([version]$RemoteCIPPVersion -gt [version]$CIPPVersion) - OutOfDateCIPPAPI = ([version]$RemoteAPIVersion -gt [version]$APIVersion) - } - if ($version.outOfDateCIPP) { - $Alerts.add(@{Alert = 'Your CIPP Frontend is out of date. Please update to the latest version. Find more on the following '; link = 'https://docs.cipp.app/setup/installation/updating'; type = 'warning' }) + $CIPPVersion = $Request.Query.localversion + $Version = Assert-CippVersion -CIPPVersion $CIPPVersion + if ($Version.OutOfDateCIPP) { + $Alerts.Add(@{Alert = 'Your CIPP Frontend is out of date. Please update to the latest version. Find more on the following '; link = 'https://docs.cipp.app/setup/installation/updating'; type = 'warning' }) Write-LogMessage -message 'Your CIPP Frontend is out of date. Please update to the latest version' -API 'Updates' -tenant 'All Tenants' -sev Alert } - if ($version.outOfDateCIPPAPI) { - $Alerts.add(@{Alert = 'Your CIPP API is out of date. Please update to the latest version. Find more on the following'; link = 'https://docs.cipp.app/setup/installation/updating'; type = 'warning' }) + if ($Version.OutOfDateCIPPAPI) { + $Alerts.Add(@{Alert = 'Your CIPP API is out of date. Please update to the latest version. Find more on the following'; link = 'https://docs.cipp.app/setup/installation/updating'; type = 'warning' }) Write-LogMessage -message 'Your CIPP API is out of date. Please update to the latest version' -API 'Updates' -tenant 'All Tenants' -sev Alert } - - if ($env:ApplicationID -eq 'LongApplicationID' -or $null -eq $ENV:ApplicationID) { $Alerts.add(@{Alert = 'You have not yet setup your SAM Setup. Please go to the SAM Wizard in settings to finish setup'; link = '/cipp/setup'; type = 'warning' }) } - if ($role -like '*superadmin*') { $Alerts.add(@{Alert = 'You are logged in under a superadmin account. This account should not be used for normal usage.'; link = 'https://docs.cipp.app/setup/installation/owntenant'; type = 'danger' }) } - if ($env:WEBSITE_RUN_FROM_PACKAGE -ne '1') { - $Alerts.add( + if ($env:ApplicationID -eq 'LongApplicationID' -or $null -eq $ENV:ApplicationID) { $Alerts.Add(@{Alert = 'You have not yet completed your SAM Setup. Please go to the SAM Setup Wizard in settings to connect CIPP to your tenant.'; link = '/cipp/setup'; type = 'warning' }) } + if ($role -like '*superadmin*') { $Alerts.Add(@{Alert = 'You are logged in under a superadmin account. This account should not be used for normal usage.'; link = 'https://docs.cipp.app/setup/installation/owntenant'; type = 'danger' }) } + if ($env:WEBSITE_RUN_FROM_PACKAGE -ne '1' -and $env:AzureWebJobsStorage -ne 'UseDevelopmentStorage=true') { + $Alerts.Add( @{Alert = 'Your Function App is running in write mode. This will cause performance issues and increase cost. Please check this ' - link = 'https://docs.cipp.app/setup/installation/runfrompackage' - type = 'warning' - }) + link = 'https://docs.cipp.app/setup/installation/runfrompackage' + type = 'warning' + }) } - if ($Rows) { $Rows | ForEach-Object { $alerts.add($_) } } + if ($Rows) { $Rows | ForEach-Object { $Alerts.Add($_) } } $Alerts = @($Alerts) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetVersion.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetVersion.ps1 index b92ecb48d6e6..61df91438485 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetVersion.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetVersion.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-GetVersion { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,20 +13,9 @@ Function Invoke-GetVersion { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $APIVersion = Get-Content 'version_latest.txt' | Out-String $CIPPVersion = $request.query.localversion - $RemoteAPIVersion = Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP-API/master/version_latest.txt' - $RemoteCIPPVersion = Invoke-RestMethod -Uri 'https://raw.githubusercontent.com/KelvinTegelaar/CIPP/master/public/version_latest.txt' - - $version = [PSCustomObject]@{ - LocalCIPPVersion = $CIPPVersion - RemoteCIPPVersion = $RemoteCIPPVersion - LocalCIPPAPIVersion = $APIVersion - RemoteCIPPAPIVersion = $RemoteAPIVersion - OutOfDateCIPP = ([version]$RemoteCIPPVersion -gt [version]$CIPPVersion) - OutOfDateCIPPAPI = ([version]$RemoteAPIVersion -gt [version]$APIVersion) - } + $Version = Assert-CippVersion -CIPPVersion $CIPPVersion # Write to the Azure Functions log stream. # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 index 44dbfa761030..50860f6e034b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddScheduledItem { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Scheduler.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 index 71aa6aa536fe..98e51126ed22 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListScheduledItems { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Scheduler.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -17,6 +19,10 @@ Function Invoke-ListScheduledItems { $HiddenTasks = $true } $Tasks = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'ScheduledTask'" | Where-Object { $_.Hidden -ne $HiddenTasks } + $AllowedTenants = Test-CIPPAccess -Request $Request -TenantList + if ($AllowedTenants -notcontains 'AllTenants') { + $Tasks = $Tasks | Where-Object -Property TenantId -In $AllowedTenants + } $ScheduledTasks = foreach ($Task in $tasks) { $Task.Parameters = $Task.Parameters | ConvertFrom-Json $Task diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 index 629760a2ca68..257902f03726 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveScheduledItem { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Scheduler.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -21,7 +23,7 @@ Function Invoke-RemoveScheduledItem { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK - Body = @{ Results = 'Task removed successfully.' } + Body = @{ Results = 'Task removed successfully.' } }) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAPIPermissionList.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAPIPermissionList.ps1 new file mode 100644 index 000000000000..a877e4b829d2 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAPIPermissionList.ps1 @@ -0,0 +1,17 @@ +function Invoke-ExecAPIPermissionList { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + CIPP.SuperAdmin.Read + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $Roles = Get-CIPPHttpFunctions -ByRoleGroup | ConvertTo-Json -Depth 10 + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Roles + }) +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 index 93a72e2e296d..019e3af0997e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAccessChecks { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAddTrustedIP.ps1 index db587ae67959..4613ea2c3c68 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAddTrustedIP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAddTrustedIP.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAddTrustedIP { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 4a29002ad122..4c0adc7368e8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecBackendURLs { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 index 4703972094e4..db0bae59c71b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecCPVPermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 new file mode 100644 index 000000000000..45b0e6931d89 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 @@ -0,0 +1,52 @@ +function Invoke-ExecCustomRole { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + CIPP.SuperAdmin.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $Table = Get-CippTable -tablename 'CustomRoles' + switch ($Request.Query.Action) { + 'AddUpdate' { + $Role = @{ + 'PartitionKey' = 'CustomRoles' + 'RowKey' = "$($Request.Body.RoleName)" + 'Permissions' = "$($Request.Body.Permissions | ConvertTo-Json -Compress)" + 'AllowedTenants' = "$($Request.Body.AllowedTenants | ConvertTo-Json -Compress)" + } + Add-CIPPAzDataTableEntity @Table -Entity $Role -Force | Out-Null + $Body = @{Results = 'Custom role saved' } + } + 'Delete' { + $Role = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$($Request.Body.RoleName)'" -Property RowKey, PartitionKey + Remove-AzDataTableEntity @Table -Entity $Role + $Body = @{Results = 'Custom role deleted' } + } + default { + $Body = Get-CIPPAzDataTableEntity @Table + + if (!$Body) { + $Body = @( + @{ + RowKey = 'No custom roles found' + } + ) + } else { + $Body = foreach ($Role in $Body) { + $Role.Permissions = $Role.Permissions | ConvertFrom-Json + $Role.AllowedTenants = @($Role.AllowedTenants | ConvertFrom-Json) + $Role + } + $Body = @($Body) + } + } + } + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Body + }) +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 index 41768a704af5..147855eab44c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecDnsConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 index c20795dcb97c..8b18bb186e4a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecExcludeLicenses { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 index ca3e85feed9a..76c414414905 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecExcludeTenant { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionMapping.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionMapping.ps1 index e848d7df1669..77b8e277c780 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionMapping.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionMapping.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecExtensionMapping { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionSync.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionSync.ps1 index 3abce0100b91..2f069988996a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionSync.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionSync.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecExtensionSync { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionTest.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionTest.ps1 index afbdfacc402c..7c2f271c13a5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionTest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionTest.ps1 @@ -1,50 +1,51 @@ - using namespace System.Net +using namespace System.Net - Function Invoke-ExecExtensionTest { +Function Invoke-ExecExtensionTest { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" -$Table = Get-CIPPTable -TableName Extensionsconfig -$Configuration = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json) -# Interact with query parameters or the body of the request. -try { - switch ($Request.query.extensionName) { - "HaloPSA" { - $token = Get-HaloToken -configuration $Configuration.HaloPSA - $Results = [pscustomobject]@{"Results" = "Successfully Connected to HaloPSA" } + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Table = Get-CIPPTable -TableName Extensionsconfig + $Configuration = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json) + # Interact with query parameters or the body of the request. + try { + switch ($Request.query.extensionName) { + 'HaloPSA' { + $token = Get-HaloToken -configuration $Configuration.HaloPSA + $Results = [pscustomobject]@{'Results' = 'Successfully Connected to HaloPSA' } } - "Gradient" { - $GradientToken = Get-GradientToken -Configuration $Configuration.Gradient - $ExistingIntegrations = Invoke-RestMethod -Uri 'https://app.usegradient.com/api/vendor-api/organization' -Method GET -Headers $GradientToken - if ($ExistingIntegrations.Status -ne "active") { - $ActivateRequest = Invoke-RestMethod -Uri 'https://app.usegradient.com/api/vendor-api/organization/status/active' -Method PATCH -Headers $GradientToken - } - $Results = [pscustomobject]@{"Results" = "Succesfully Connected to Gradient" } + 'Gradient' { + $GradientToken = Get-GradientToken -Configuration $Configuration.Gradient + $ExistingIntegrations = Invoke-RestMethod -Uri 'https://app.usegradient.com/api/vendor-api/organization' -Method GET -Headers $GradientToken + if ($ExistingIntegrations.Status -ne 'active') { + $ActivateRequest = Invoke-RestMethod -Uri 'https://app.usegradient.com/api/vendor-api/organization/status/active' -Method PATCH -Headers $GradientToken + } + $Results = [pscustomobject]@{'Results' = 'Succesfully Connected to Gradient' } } - "CIPP-API" { - $Results = [pscustomobject]@{"Results" = "You cannot test the CIPP-API from CIPP. Please check the documentation on how to test the CIPP-API." } + 'CIPP-API' { + $Results = [pscustomobject]@{'Results' = 'You cannot test the CIPP-API from CIPP. Please check the documentation on how to test the CIPP-API.' } } - "NinjaOne" { - $token = Get-NinjaOneToken -configuration $Configuration.NinjaOne - $Results = [pscustomobject]@{"Results" = "Succesfully Connected to NinjaOne" } + 'NinjaOne' { + $token = Get-NinjaOneToken -configuration $Configuration.NinjaOne + $Results = [pscustomobject]@{'Results' = 'Succesfully Connected to NinjaOne' } } - } -} -catch { - $Results = [pscustomobject]@{"Results" = "Failed to connect: $($_.Exception.Message) $($_.InvocationInfo.ScriptLineNumber)" } -} + } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed to connect: $($_.Exception.Message) $($_.InvocationInfo.ScriptLineNumber)" } + } -# Associate values to output bindings by calling 'Push-OutputBinding'. -Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = $Results - }) + }) - } +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionsConfig.ps1 index 50675339a8f8..fd3b8764959d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExtensionsConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecExtensionsConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 index 567e6dc3a1c4..fe01aed3123e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecMaintenanceScripts { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -17,7 +19,7 @@ Function Invoke-ExecMaintenanceScripts { $ReplacementStrings = @{ '##TENANTID##' = $env:TenantID '##RESOURCEGROUP##' = $env:WEBSITE_RESOURCE_GROUP - '##FUNCTIONAPP##' = $env:WEBSITE_SITE_NAME + '##FUNCTIONAPP##' = $env:WEBSITE_SITE_NAME '##SUBSCRIPTION##' = (($env:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1) '##TOKENIP##' = $AccessTokenDetails.IPAddress } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 index f1f39d9bcc90..411400303392 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecNotificationConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPartnerMode.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPartnerMode.ps1 index b7a2a621fb64..a7d2ba3511bb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPartnerMode.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPartnerMode.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecPartnerMode { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.SuperAdmin.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -29,7 +31,7 @@ Function Invoke-ExecPartnerMode { }) } - + if ($request.query.action -eq 'ListCurrent') { $CurrentState = Get-CIPPAzDataTableEntity @Table $CurrentState = if (!$CurrentState) { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 index 78e27e7f01f3..9f4815e3f25d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecPasswordConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-ExecPasswordConfig { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' - $results = try { + $results = try { if ($Request.Query.List) { @{ passwordType = $PasswordType.passwordType } } else { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 index 0342d10f68c5..b9820352bfdd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 @@ -3,14 +3,16 @@ using namespace System.Net Function Invoke-ExecRestoreBackup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - try { + try { foreach ($line in ($Request.body | ConvertFrom-Json | Select-Object * -ExcludeProperty ETag)) { Write-Host ($line) $Table = Get-CippTable -tablename $line.table @@ -23,7 +25,7 @@ Function Invoke-ExecRestoreBackup { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Created backup' -Sev 'Debug' $body = [pscustomobject]@{ - 'Results' = 'Succesfully restored backup.' + 'Results' = 'Succesfully restored backup.' } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create backup: $($_.Exception.Message)" -Sev 'Error' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRunBackup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRunBackup.ps1 index a237798e8e01..5dd1070a2c49 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRunBackup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRunBackup.ps1 @@ -3,14 +3,16 @@ using namespace System.Net Function Invoke-ExecRunBackup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - try { + try { if ($request.query.Selected) { $BackupTables = $request.query.Selected -split ',' } else { @@ -31,7 +33,7 @@ Function Invoke-ExecRunBackup { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Created backup' -Sev 'Debug' $body = [pscustomobject]@{ - 'Results' = 'Created backup' + 'Results' = 'Created backup' backup = $CSVfile } } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 index 97e293d285ce..e61a272a80ac 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSAMSetup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddContact.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddContact.ps1 index ebd0d9be935b..c52e2e60ffbd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddContact.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddContact.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddContact { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Contact.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -31,8 +33,7 @@ Function Invoke-AddContact { $body = [pscustomobject]@{'Results' = 'Successfully added a contact.' } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($contactobj.tenantid) -message "Created contact $($contactobj.displayname) with id $($GraphRequest.id) for " -Sev 'Info' - } - catch { + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($contactobj.tenantid) -message "Contact creation API failed. $($_.Exception.Message)" -Sev 'Error' $body = [pscustomobject]@{'Results' = "Failed to create contact. $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnector.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnector.ps1 index b3246cea773d..d1a29a85a67d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnector.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnector.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddExConnector { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -17,7 +19,7 @@ Function Invoke-AddExConnector { $Tenants = ($Request.body | Select-Object Select_*).psobject.properties.value $Result = foreach ($Tenantfilter in $tenants) { try { - $GraphRequest = New-ExoRequest -tenantid $Tenantfilter -cmdlet "New-$($ConnectorType)connector" -cmdParams $RequestParams + $GraphRequest = New-ExoRequest -tenantid $Tenantfilter -cmdlet "New-$($ConnectorType)connector" -cmdParams $RequestParams "Successfully created Connector for $Tenantfilter." Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Tenantfilter -message "Created Connector for $($Tenantfilter)" -sev 'Info' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnectorTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnectorTemplate.ps1 index 73cf56b8d910..222c01f420ff 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnectorTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddExConnectorTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddExConnectorTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -15,8 +17,8 @@ Function Invoke-AddExConnectorTemplate { try { $GUID = (New-Guid).GUID - $Select = if ($Request.body.cippconnectortype -eq 'outbound') { - @( + $Select = if ($Request.body.cippconnectortype -eq 'outbound') { + @( 'name', 'AllAcceptedDomains', 'CloudServicesMailEnabled', 'Comment', 'Confirm', 'ConnectorSource', 'ConnectorType', 'Enabled', 'IsTransportRuleScoped', 'RecipientDomains', 'RouteAllMessagesViaOnPremises', 'SenderRewritingEnabled', 'SmartHosts', 'TestMode', 'TlsDomain', 'TlsSettings', 'UseMXRecord' ) } @@ -28,7 +30,7 @@ Function Invoke-AddExConnectorTemplate { $JSON = ([pscustomobject]$Request.body | Select-Object $Select) | ForEach-Object { $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name - $_ | Select-Object -Property $NonEmptyProperties + $_ | Select-Object -Property $NonEmptyProperties } $JSON = ($JSON | Select-Object @{n = 'name'; e = { $_.name } }, * | ConvertTo-Json -Depth 10) $Table = Get-CippTable -tablename 'templates' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 index c3017c7cf881..20af9ebdd475 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddSharedMailbox { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -40,7 +42,7 @@ Function Invoke-AddSharedMailbox { try { if ($Aliases) { - + Start-Sleep 3 # Sleep since there is apparently a race condition with the mailbox creation if we don't delay for a lil bit $AliasBodyToShip = [pscustomobject] @{ 'Identity' = $AddSharedRequest.Guid diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilter.ps1 index 789b3eaffe9d..deb78b344897 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilter.ps1 @@ -3,12 +3,14 @@ using namespace System.Net Function Invoke-AddSpamFilter { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) - + $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilterTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilterTemplate.ps1 index 9aeef51f243c..37cf34b88916 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilterTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSpamFilterTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddSpamFilterTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Spamfilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -12,7 +14,7 @@ Function Invoke-AddSpamFilterTemplate { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' Write-Host ($request | ConvertTo-Json -Compress) - try { + try { $GUID = (New-Guid).GUID $JSON = if ($request.body.PowerShellCommand) { Write-Host 'PowerShellCommand' @@ -21,7 +23,7 @@ Function Invoke-AddSpamFilterTemplate { else { ([pscustomobject]$Request.body | Select-Object name, AddXHeaderValue, AdminDisplayName, AllowedSenderDomains, AllowedSenders, BlockedSenderDomains, BlockedSenders, BulkQuarantineTag, BulkSpamAction, BulkThreshold, Confirm, DownloadLink, EnableEndUserSpamNotifications, EnableLanguageBlockList, EnableRegionBlockList, EndUserSpamNotificationCustomFromAddress, EndUserSpamNotificationCustomFromName, EndUserSpamNotificationCustomSubject, EndUserSpamNotificationFrequency, EndUserSpamNotificationLanguage, EndUserSpamNotificationLimit, HighConfidencePhishAction, HighConfidencePhishQuarantineTag, HighConfidenceSpamAction, HighConfidenceSpamQuarantineTag, IncreaseScoreWithBizOrInfoUrls, IncreaseScoreWithImageLinks, IncreaseScoreWithNumericIps, IncreaseScoreWithRedirectToOtherPort, InlineSafetyTipsEnabled, LanguageBlockList, MarkAsSpamBulkMail, MarkAsSpamEmbedTagsInHtml, MarkAsSpamEmptyMessages, MarkAsSpamFormTagsInHtml, MarkAsSpamFramesInHtml, MarkAsSpamFromAddressAuthFail, MarkAsSpamJavaScriptInHtml, MarkAsSpamNdrBackscatter, MarkAsSpamObjectTagsInHtml, MarkAsSpamSensitiveWordList, MarkAsSpamSpfRecordHardFail, MarkAsSpamWebBugsInHtml, ModifySubjectValue, PhishQuarantineTag, PhishSpamAction, PhishZapEnabled, QuarantineRetentionPeriod, RecommendedPolicyType, RedirectToRecipients, RegionBlockList, SpamAction, SpamQuarantineTag, SpamZapEnabled, TestModeAction, TestModeBccToRecipients ) | ForEach-Object { $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name - $_ | Select-Object -Property $NonEmptyProperties + $_ | Select-Object -Property $NonEmptyProperties } } $JSON = ($JSON | Select-Object @{n = 'name'; e = { $_.name } }, @{n = 'comments'; e = { $_.comments } }, * | ConvertTo-Json -Depth 10) @@ -34,7 +36,7 @@ Function Invoke-AddSpamFilterTemplate { } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created Spam Filter Template $($Request.body.name) with GUID $GUID" -Sev 'Debug' $body = [pscustomobject]@{'Results' = 'Successfully added template' } - + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create Spam Filter Template: $($_.Exception.Message)" -Sev 'Error' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportRule.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportRule.ps1 index 64c394ee2852..acd265572aa5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportRule.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportRule.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddTransportRule { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,7 +13,7 @@ Function Invoke-AddTransportRule { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $RequestParams = $Request.Body.PowerShellCommand | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty GUID, Comments, HasSenderOverride, ExceptIfHasSenderOverride, ExceptIfMessageContainsDataClassifications, MessageContainsDataClassifications + $RequestParams = $Request.Body.PowerShellCommand | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty GUID, Comments, HasSenderOverride, ExceptIfHasSenderOverride, ExceptIfMessageContainsDataClassifications, MessageContainsDataClassifications $Tenants = ($Request.body | Select-Object Select_*).psobject.properties.value $Result = foreach ($Tenantfilter in $tenants) { @@ -28,7 +30,7 @@ Function Invoke-AddTransportRule { $GraphRequest = New-ExoRequest -tenantid $Tenantfilter -cmdlet 'New-TransportRule' -cmdParams $RequestParams -useSystemMailbox $true "Successfully created transport rule for $tenantfilter." } - + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenantfilter -message "Created transport rule for $($tenantfilter)" -sev Info } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportTemplate.ps1 index 6028c15578b6..0f7fb738e6ff 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddTransportTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddTransportTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -12,7 +14,7 @@ Function Invoke-AddTransportTemplate { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' Write-Host ($request | ConvertTo-Json -Compress) - try { + try { $GUID = (New-Guid).GUID $JSON = if ($request.body.PowerShellCommand) { Write-Host 'PowerShellCommand' @@ -21,7 +23,7 @@ Function Invoke-AddTransportTemplate { else { ([pscustomobject]$Request.body | Select-Object Name, ActivationDate, ADComparisonAttribute, ADComparisonOperator, AddManagerAsRecipientType, AddToRecipients, AnyOfCcHeader, AnyOfCcHeaderMemberOf, AnyOfRecipientAddressContainsWords, AnyOfRecipientAddressMatchesPatterns, AnyOfToCcHeader, AnyOfToCcHeaderMemberOf, AnyOfToHeader, AnyOfToHeaderMemberOf, ApplyClassification, ApplyHtmlDisclaimerFallbackAction, ApplyHtmlDisclaimerLocation, ApplyHtmlDisclaimerText, ApplyOME, ApplyRightsProtectionCustomizationTemplate, ApplyRightsProtectionTemplate, AttachmentContainsWords, AttachmentExtensionMatchesWords, AttachmentHasExecutableContent, AttachmentIsPasswordProtected, AttachmentIsUnsupported, AttachmentMatchesPatterns, AttachmentNameMatchesPatterns, AttachmentProcessingLimitExceeded, AttachmentPropertyContainsWords, AttachmentSizeOver, BetweenMemberOf1, BetweenMemberOf2, BlindCopyTo, Comments, Confirm, ContentCharacterSetContainsWords, CopyTo, DeleteMessage, DlpPolicy, DomainController, Enabled, ExceptIfADComparisonAttribute, ExceptIfADComparisonOperator, ExceptIfAnyOfCcHeader, ExceptIfAnyOfCcHeaderMemberOf, ExceptIfAnyOfRecipientAddressContainsWords, ExceptIfAnyOfRecipientAddressMatchesPatterns, ExceptIfAnyOfToCcHeader, ExceptIfAnyOfToCcHeaderMemberOf, ExceptIfAnyOfToHeader, ExceptIfAnyOfToHeaderMemberOf, ExceptIfAttachmentContainsWords, ExceptIfAttachmentExtensionMatchesWords, ExceptIfAttachmentHasExecutableContent, ExceptIfAttachmentIsPasswordProtected, ExceptIfAttachmentIsUnsupported, ExceptIfAttachmentMatchesPatterns, ExceptIfAttachmentNameMatchesPatterns, ExceptIfAttachmentProcessingLimitExceeded, ExceptIfAttachmentPropertyContainsWords, ExceptIfAttachmentSizeOver, ExceptIfBetweenMemberOf1, ExceptIfBetweenMemberOf2, ExceptIfContentCharacterSetContainsWords, ExceptIfFrom, ExceptIfFromAddressContainsWords, ExceptIfFromAddressMatchesPatterns, ExceptIfFromMemberOf, ExceptIfFromScope, ExceptIfHasClassification, ExceptIfHasNoClassification, ExceptIfHasSenderOverride, ExceptIfHeaderContainsMessageHeader, ExceptIfHeaderContainsWords, ExceptIfHeaderMatchesMessageHeader, ExceptIfHeaderMatchesPatterns, ExceptIfManagerAddresses, ExceptIfManagerForEvaluatedUser, ExceptIfMessageContainsDataClassifications, ExceptIfMessageSizeOver, ExceptIfMessageTypeMatches, ExceptIfRecipientADAttributeContainsWords, ExceptIfRecipientADAttributeMatchesPatterns, ExceptIfRecipientAddressContainsWords, ExceptIfRecipientAddressMatchesPatterns, ExceptIfRecipientDomainIs, ExceptIfRecipientInSenderList, ExceptIfSCLOver, ExceptIfSenderADAttributeContainsWords, ExceptIfSenderADAttributeMatchesPatterns, ExceptIfSenderDomainIs, ExceptIfSenderInRecipientList, ExceptIfSenderIpRanges, ExceptIfSenderManagementRelationship, ExceptIfSentTo, ExceptIfSentToMemberOf, ExceptIfSentToScope, ExceptIfSubjectContainsWords, ExceptIfSubjectMatchesPatterns, ExceptIfSubjectOrBodyContainsWords, ExceptIfSubjectOrBodyMatchesPatterns, ExceptIfWithImportance, ExpiryDate, From, FromAddressContainsWords, FromAddressMatchesPatterns, FromMemberOf, FromScope, GenerateIncidentReport, GenerateNotification, HasClassification, HasNoClassification, HasSenderOverride, HeaderContainsMessageHeader, HeaderContainsWords, HeaderMatchesMessageHeader, HeaderMatchesPatterns, IncidentReportContent, IncidentReportOriginalMail, LogEventText, ManagerAddresses, ManagerForEvaluatedUser, MessageContainsDataClassifications, MessageSizeOver, MessageTypeMatches, Mode, ModerateMessageByManager, ModerateMessageByUser, NotifySender, PrependSubject, Quarantine, RecipientADAttributeContainsWords, RecipientADAttributeMatchesPatterns, RecipientAddressContainsWords, RecipientAddressMatchesPatterns, RecipientAddressType, RecipientDomainIs, RecipientInSenderList, RedirectMessageTo, RejectMessageEnhancedStatusCode, RejectMessageReasonText, RemoveHeader, RemoveOME, RemoveOMEv2, RemoveRMSAttachmentEncryption, RouteMessageOutboundConnector, RouteMessageOutboundRequireTls, RuleErrorAction, RuleSubType, SCLOver, SenderADAttributeContainsWords, SenderADAttributeMatchesPatterns, SenderAddressLocation, SenderDomainIs, SenderInRecipientList, SenderIpRanges, SenderManagementRelationship, SentTo, SentToMemberOf, SentToScope, SetAuditSeverity, SetHeaderName, SetHeaderValue, SetSCL, SmtpRejectMessageRejectStatusCode, SmtpRejectMessageRejectText, StopRuleProcessing, SubjectContainsWords, SubjectMatchesPatterns, SubjectOrBodyContainsWords, SubjectOrBodyMatchesPatterns, UseLegacyRegex, WithImportance ) | ForEach-Object { $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name - $_ | Select-Object -Property $NonEmptyProperties + $_ | Select-Object -Property $NonEmptyProperties } } $JSON = ($JSON | Select-Object @{n = 'name'; e = { $_.name } }, @{n = 'comments'; e = { $_.comments } }, * | ConvertTo-Json -Depth 10) @@ -34,7 +36,7 @@ Function Invoke-AddTransportTemplate { } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created Transport Rule Template $($Request.body.name) with GUID $GUID" -Sev 'Debug' $body = [pscustomobject]@{'Results' = 'Successfully added template' } - + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create Transport Rule Template: $($_.Exception.Message)" -Sev 'Error' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditExConnector.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditExConnector.ps1 index 9042e7fdfa0a..b1c622f621fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditExConnector.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditExConnector.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditExConnector { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditSpamFilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditSpamFilter.ps1 index 9f98d280f511..1c638ab96ea1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditSpamFilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditSpamFilter.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditSpamFilter { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditTransportRule.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditTransportRule.ps1 index 20f93fd4014f..8d968077db70 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditTransportRule.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-EditTransportRule.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditTransportRule { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecConverttoSharedMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecConverttoSharedMailbox.ps1 index cb16432e8937..ed59a074c1ac 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecConverttoSharedMailbox.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecConverttoSharedMailbox.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecConverttoSharedMailbox { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecCopyForSent.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecCopyForSent.ps1 index a039be57dfba..4aadbd74c563 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecCopyForSent.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecCopyForSent.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecCopyForSent { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecDisableEmailForward.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecDisableEmailForward.ps1 index 12c57868e68d..d2894b583ee4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecDisableEmailForward.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecDisableEmailForward.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecDisableEmailForward { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 index 346deef09dcc..eebb7139649d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecEditCalendarPermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditMailboxPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditMailboxPermissions.ps1 index 97200abfc763..d017f8ae65a4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditMailboxPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditMailboxPermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecEditMailboxPermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -17,11 +19,11 @@ Function Invoke-ExecEditMailboxPermissions { $Results = [System.Collections.ArrayList]@() $RemoveFullAccess = ($Request.body.RemoveFullAccess).value - foreach ($RemoveUser in $RemoveFullAccess) { + foreach ($RemoveUser in $RemoveFullAccess) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-mailboxpermission' -cmdParams @{Identity = $userid; user = $RemoveUser; accessRights = @('FullAccess'); } $results.add("Removed $($removeuser) from $($username) Shared Mailbox permissions") - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Removed $($RemoveUser) from $($username) Shared Mailbox permission" -Sev 'Info' -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Removed $($RemoveUser) from $($username) Shared Mailbox permission" -Sev 'Info' -tenant $TenantFilter } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not remove mailbox permissions for $($removeuser) on $($username)" -Sev 'Error' -tenant $TenantFilter $results.add("Could not remove $($removeuser) shared mailbox permissions for $($username). Error: $($_.Exception.Message)") @@ -29,7 +31,7 @@ Function Invoke-ExecEditMailboxPermissions { } $AddFullAccess = ($Request.body.AddFullAccess).value - foreach ($UserAutomap in $AddFullAccess) { + foreach ($UserAutomap in $AddFullAccess) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-MailboxPermission' -cmdParams @{Identity = $userid; user = $UserAutomap; accessRights = @('FullAccess'); automapping = $true } $results.add( "Granted $($UserAutomap) access to $($username) Mailbox with automapping") @@ -42,7 +44,7 @@ Function Invoke-ExecEditMailboxPermissions { } $AddFullAccessNoAutoMap = ($Request.body.AddFullAccessNoAutoMap).value - foreach ($UserNoAutomap in $AddFullAccessNoAutoMap) { + foreach ($UserNoAutomap in $AddFullAccessNoAutoMap) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-MailboxPermission' -cmdParams @{Identity = $userid; user = $UserNoAutomap; accessRights = @('FullAccess'); automapping = $false } $results.add( "Granted $UserNoAutomap access to $($username) Mailbox without automapping") @@ -55,7 +57,7 @@ Function Invoke-ExecEditMailboxPermissions { $AddSendAS = ($Request.body.AddSendAs).value - foreach ($UserSendAs in $AddSendAS) { + foreach ($UserSendAs in $AddSendAS) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Add-RecipientPermission' -cmdParams @{Identity = $userid; Trustee = $UserSendAs; accessRights = @('SendAs') } $results.add( "Granted $UserSendAs access to $($username) with Send As permissions") @@ -68,7 +70,7 @@ Function Invoke-ExecEditMailboxPermissions { $RemoveSendAs = ($Request.body.RemoveSendAs).value - foreach ($UserSendAs in $RemoveSendAs) { + foreach ($UserSendAs in $RemoveSendAs) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Remove-RecipientPermission' -cmdParams @{Identity = $userid; Trustee = $UserSendAs; accessRights = @('SendAs') } $results.add( "Removed $UserSendAs from $($username) with Send As permissions") @@ -81,7 +83,7 @@ Function Invoke-ExecEditMailboxPermissions { $AddSendOnBehalf = ($Request.body.AddSendOnBehalf).value - foreach ($UserSendOnBehalf in $AddSendOnBehalf) { + foreach ($UserSendOnBehalf in $AddSendOnBehalf) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-Mailbox' -cmdParams @{Identity = $userid; GrantSendonBehalfTo = @{'@odata.type' = '#Exchange.GenericHashTable'; add = $UserSendOnBehalf }; } $results.add( "Granted $UserSendOnBehalf access to $($username) with Send On Behalf Permissions") @@ -94,7 +96,7 @@ Function Invoke-ExecEditMailboxPermissions { $RemoveSendOnBehalf = ($Request.body.RemoveSendOnBehalf).value - foreach ($UserSendOnBehalf in $RemoveSendOnBehalf) { + foreach ($UserSendOnBehalf in $RemoveSendOnBehalf) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet 'Set-Mailbox' -cmdParams @{Identity = $userid; GrantSendonBehalfTo = @{'@odata.type' = '#Exchange.GenericHashTable'; remove = $UserSendOnBehalf }; } $results.add( "Removed $UserSendOnBehalf from $($username) Send on Behalf Permissions") diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEmailForward.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEmailForward.ps1 index f9b05a8f662a..9ddf5aa7b523 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEmailForward.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEmailForward.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecEmailForward { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -23,12 +25,12 @@ Function Invoke-ExecEmailForward { $results = "Forwarding all email for $($username) to $($ForwardingAddress) and not keeping a copy" } elseif ($request.body.KeepCopy) { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Set Forwarding for $($username) to $($ForwardingAddress) and keeping a copy" -Sev 'Info' -tenant $TenantFilter - $results = "Forwarding all email for $($username) to $($ForwardingAddress) and keeping a copy" + $results = "Forwarding all email for $($username) to $($ForwardingAddress) and keeping a copy" } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not add forwarding for $($username)" -Sev 'Error' -tenant $TenantFilter $results = "Could not add forwarding for $($username). Error: $($_.Exception.Message)" - + } } @@ -40,12 +42,12 @@ Function Invoke-ExecEmailForward { $results = "Forwarding all email for $($username) to $($ForwardingSMTPAddress) and not keeping a copy" } elseif ($request.body.KeepCopy) { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Set forwarding for $($username) to $($ForwardingSMTPAddress) and keeping a copy" -Sev 'Info' -tenant $TenantFilter - $results = "Forwarding all email for $($username) to $($ForwardingSMTPAddress) and keeping a copy" + $results = "Forwarding all email for $($username) to $($ForwardingSMTPAddress) and keeping a copy" } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not add forwarding for $($username)" -Sev 'Error' -tenant $TenantFilter $results = "Could not add forwarding for $($username). Error: $($_.Exception.Message)" - + } } @@ -58,7 +60,7 @@ Function Invoke-ExecEmailForward { } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not disable Email forwarding for $($username)" -Sev 'Error' -tenant $TenantFilter $results = "Could not disable Email forwarding for $($username). Error: $($_.Exception.Message)" - + } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEnableArchive.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEnableArchive.ps1 index ac4cf5f8686b..f1dfb475b1cd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEnableArchive.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEnableArchive.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecEnableArchive { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDelete.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDelete.ps1 index c4f5be9d67f7..d66af4964171 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDelete.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDelete.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGroupsDelete { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDeliveryManagement.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDeliveryManagement.ps1 index d77c8a56d6e7..1f096507bd61 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDeliveryManagement.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsDeliveryManagement.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGroupsDeliveryManagement { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,7 +20,7 @@ Function Invoke-ExecGroupsDeliveryManagement { # Interact with query parameters or the body of the request. Try { - $SetResults = Set-CIPPGroupAuthentication -ID $Request.query.id -GroupType $Request.query.GroupType -OnlyAllowInternalString $Request.query.OnlyAllowInternal -tenantFilter $Request.query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' + $SetResults = Set-CIPPGroupAuthentication -ID $Request.query.id -GroupType $Request.query.GroupType -OnlyAllowInternalString $Request.query.OnlyAllowInternal -tenantFilter $Request.query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' $Results = [pscustomobject]@{'Results' = $SetResults } } catch { $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsHideFromGAL.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsHideFromGAL.ps1 index 6307f2ef898d..caf559918240 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsHideFromGAL.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecGroupsHideFromGAL.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGroupsHideFromGAL { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -13,7 +15,7 @@ Function Invoke-ExecGroupsHideFromGAL { # Interact with query parameters or the body of the request. Try { - $GroupStatus = Set-CIPPGroupGAL -Id $Request.query.id -tenantFilter $Request.query.TenantFilter -GroupType $Request.query.groupType -HiddenString $Request.query.HidefromGAL -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' + $GroupStatus = Set-CIPPGroupGAL -Id $Request.query.id -tenantFilter $Request.query.TenantFilter -GroupType $Request.query.groupType -HiddenString $Request.query.HidefromGAL -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' $Results = [pscustomobject]@{'Results' = $GroupStatus } } catch { $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecHideFromGAL.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecHideFromGAL.ps1 index 787bdd798e36..7dac7da9c2fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecHideFromGAL.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecHideFromGAL.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecHideFromGAL { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailTest.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailTest.ps1 index 483594d83889..a80a812b45d6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailTest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailTest.ps1 @@ -2,7 +2,9 @@ using namespace System.Net Function Invoke-ExecMailTest { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxMobileDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxMobileDevices.ps1 index 15f96d33503a..7b58b76afc7c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxMobileDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxMobileDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecMailboxMobileDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxRestore.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxRestore.ps1 index 8dc0bf5981f6..fb66074d979d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxRestore.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecMailboxRestore.ps1 @@ -1,7 +1,9 @@ function Invoke-ExecMailboxRestore { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> Param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecQuarantineManagement.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecQuarantineManagement.ps1 index 7f85df715207..e22301a7629c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecQuarantineManagement.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecQuarantineManagement.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecQuarantineManagement { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,9 +20,9 @@ Function Invoke-ExecQuarantineManagement { # Interact with query parameters or the body of the request. Try { - $tenantfilter = $Request.Query.TenantFilter + $tenantfilter = $Request.Query.TenantFilter $params = @{ - Identity = $request.query.ID + Identity = $request.query.ID AllowSender = [boolean]$Request.query.AllowSender ReleasetoAll = [boolean]$Request.query.type ActionType = $Request.query.type diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetMailboxQuota.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetMailboxQuota.ps1 index f2059365139c..a55f1a420a1b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetMailboxQuota.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetMailboxQuota.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSetMailboxQuota { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetOoO.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetOoO.ps1 index c0a004791254..fab2212d888c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetOoO.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecSetOoO.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSetOoO { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMailQuarantine.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMailQuarantine.ps1 index 4b1a1c68b57f..fcdf05d199fb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMailQuarantine.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMailQuarantine.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailQuarantine { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMessageTrace.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMessageTrace.ps1 index 5ec6203892c4..25a5e57b1e59 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMessageTrace.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListMessageTrace.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMessageTrace { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,10 +20,10 @@ Function Invoke-ListMessageTrace { StartDate = (Get-Date).AddDays( - $($request.query.days)).ToString('s') EndDate = (Get-Date).ToString('s') } - + if ($null -ne $request.query.recipient) { $Searchparams.Add('RecipientAddress', $($request.query.recipient)) } if ($null -ne $request.query.sender) { $Searchparams.Add('SenderAddress', $($request.query.sender)) } - $type = $request.query.Tracedetail + $type = $request.query.Tracedetail $trace = if ($Request.Query.Tracedetail) { New-ExoRequest -tenantid $Tenantfilter -cmdlet 'Get-MessageTraceDetail' -cmdParams $Searchparams Get-MessageTraceDetail -MessageTraceId $Request.Query.ID -RecipientAddress $request.query.recipient -erroraction stop | Select-Object Event, Action, Detail, @{ Name = 'Date'; Expression = { $_.Date.Tostring('s') } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListOoO.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListOoO.ps1 index b83c74d7dd42..dc3a35d2201c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListOoO.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListOoO.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListOoO { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListPhishPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListPhishPolicies.ps1 index 1b3d767f85fd..28e46a3b88c4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListPhishPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListPhishPolicies.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListPhishPolicies { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListRecipients.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListRecipients.ps1 index 29bc8bd8a01a..e995daa9231c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListRecipients.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListRecipients.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListRecipients { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -26,9 +28,9 @@ Function Invoke-ListRecipients { Select = $select } - $GraphRequest = (New-ExoRequest @ExoRequest) | Select-Object id, ExchangeGuid, ArchiveGuid, - @{ Name = 'UPN'; Expression = { $_.'PrimarySmtpAddress' } }, - @{ Name = 'mail'; Expression = { $_.'PrimarySmtpAddress' } }, + $GraphRequest = (New-ExoRequest @ExoRequest) | Select-Object id, ExchangeGuid, ArchiveGuid, + @{ Name = 'UPN'; Expression = { $_.'PrimarySmtpAddress' } }, + @{ Name = 'mail'; Expression = { $_.'PrimarySmtpAddress' } }, @{ Name = 'displayName'; Expression = { $_.'DisplayName' } } $StatusCode = [HttpStatusCode]::OK } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamFilterTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamFilterTemplates.ps1 index 9782073ffb25..e38c63bbedbf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamFilterTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamFilterTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSpamFilterTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -14,12 +16,12 @@ Function Invoke-ListSpamFilterTemplates { #List new policies $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'SpamfilterTemplate'" + $Filter = "PartitionKey eq 'SpamfilterTemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $GUID = $_.RowKey - $data = $_.JSON | ConvertFrom-Json + $data = $_.JSON | ConvertFrom-Json $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $GUID - $data + $data } if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property RowKey -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamfilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamfilter.ps1 index 3e705b9f46a5..cb58d1a378f2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamfilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListSpamfilter.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSpamfilter { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRules.ps1 index 18e9fb3959d2..283afe12e1ee 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRules.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRules.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTransportRules { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRulesTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRulesTemplates.ps1 index 1c42c21d9470..31fe9e6b04a9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRulesTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ListTransportRulesTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTransportRulesTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -13,7 +15,7 @@ Function Invoke-ListTransportRulesTemplates { $Table = Get-CippTable -tablename 'templates' $Templates = Get-ChildItem 'Config\*.TransportRuleTemplate.json' | ForEach-Object { - + $Entity = @{ JSON = "$(Get-Content $_)" RowKey = "$($_.name)" @@ -26,12 +28,12 @@ Function Invoke-ListTransportRulesTemplates { #List new policies $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'TransportTemplate'" + $Filter = "PartitionKey eq 'TransportTemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $GUID = $_.RowKey - $data = $_.JSON | ConvertFrom-Json + $data = $_.JSON | ConvertFrom-Json $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $GUID - $data + $data } if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property RowKey -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 index 7c94dbe33d81..f554fd228f7b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddChocoApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 index 5ecd0a49fcb9..663a490927e9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddMSPApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -21,37 +23,37 @@ Function Invoke-AddMSPApp { $Results = foreach ($Tenant in $tenants) { $InstallParams = [pscustomobject]$RMMApp.params switch ($rmmapp.RMMName.value) { - 'datto' { + 'datto' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -URL $($InstallParams.DattoURL) -GUID $($InstallParams.DattoGUID["$($tenant.customerId)"])" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } - 'ninja' { + 'ninja' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } - 'Huntress' { + 'Huntress' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -OrgKey $($InstallParams.Orgkey["$($tenant.customerId)"]) -acctkey $($InstallParams.AccountKey)" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\install.ps1 -Uninstall' } - 'Immybot' { + 'Immybot' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -url $($InstallParams.ClientURL["$($tenant.customerId)"])" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } - 'syncro' { + 'syncro' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -URL $($InstallParams.ClientURL["$($tenant.customerId)"])" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } - 'NCentral' { + 'NCentral' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } - 'automate' { + 'automate' { $installcommandline = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -executionpolicy bypass .\install.ps1 -Server $($InstallParams.Server) -InstallerToken $($InstallParams.InstallerToken["$($tenant.customerId)"]) -LocationID $($InstallParams.LocationID["$($tenant.customerId)"])" $UninstallCommandLine = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -executionpolicy bypass .\uninstall.ps1 -Server $($InstallParams.Server)" $DetectionScript = (Get-Content 'AddMSPApp\automate.detection.ps1' -Raw) -replace '##SERVER##', $InstallParams.Server $intuneBody.detectionRules[0].scriptContent = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($DetectionScript)) } - 'cwcommand' { + 'cwcommand' { $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -Url $($InstallParams.ClientURL["$($tenant.customerId)"])" $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 index 865449257a89..e5a73e7dcb6c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddOfficeApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -61,14 +63,14 @@ Function Invoke-AddOfficeApp { 'updateChannel' = $request.body.updateChannel.value 'useSharedComputerActivation' = [bool]$request.body.SharedComputerActivation 'productIds' = $products - 'largeIcon' = @{ + 'largeIcon' = @{ 'type' = 'image/png' 'value' = 'iVBORw0KGgoAAAANSUhEUgAAAF0AAAAeCAMAAAEOZNKlAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJhUExURf////7z7/i9qfF1S/KCW/i+qv3q5P/9/PrQwfOMae1RG+s8AOxGDfBtQPWhhPvUx/759/zg1vWgg+9fLu5WIvKFX/rSxP728/nCr/FyR+tBBvOMaO1UH+1RHOs+AvSScP3u6f/+/v3s5vzg1+xFDO9kNPOOa/i7pvzj2/vWyes9Af76+Pzh2PrTxf/6+f7y7vOGYexHDv3t5+1SHfi8qPOIZPvb0O1NFuxDCe9hMPSVdPnFs/3q4/vaz/STcu5VIe5YJPWcfv718v/9/e1MFfF4T/F4TvF2TP3o4exECvF0SexIEPONavzn3/vZze1QGvF3Te5dK+5cKvrPwPrQwvKAWe1OGPexmexKEveulfezm/BxRfamiuxLE/apj/zf1e5YJfSXd/OHYv3r5feznPakiPze1P7x7f739f3w6+xJEfnEsvWdf/Wfge1LFPe1nu9iMvnDsfBqPOs/BPOIY/WZevJ/V/zl3fnIt/vTxuxHD+xEC+9mN+5ZJv749vBpO/KBWvBwRP/8+/SUc/etlPjArP/7+vOLZ/F7UvWae/708e1OF/aihvSWdvi8p+tABfSZefvVyPWihfSVde9lNvami+9jM/zi2fKEXvBuQvOKZvalifF5UPJ/WPSPbe9eLfrKuvvd0uxBB/7w7Pzj2vrRw/rOv+1PGfi/q/eymu5bKf3n4PnJuPBrPf3t6PWfgvWegOxCCO9nOO9oOfaskvSYePi5pPi2oPnGtO5eLPevlvKDXfrNvv739Pzd0/708O9gL+9lNfJ9VfrLu/OPbPnDsPBrPus+A/nArfarkQAAAGr5HKgAAADLdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AvuakogAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAz5JREFUOE+tVTtu4zAQHQjppmWzwIJbEVCzpTpjbxD3grQHSOXKRXgCAT6EC7UBVAmp3KwBnmvfzNCyZTmxgeTZJsXx43B+HBHRE34ZkXgkerXFTheeiCkRrbB4UXmp4wSWz5raaQEMTM5TZwuiXoaKgV+6FsmkZQcSy0kA71yMTMGHanX+AzMMGLAQCxU1F/ZwjULPugazl82GM0NEKm/U8EqFwEkO3/EAT4grgl0nucwlk9pcpTTJ4VPA4g/Rb3yIRhhp507e9nTQmZ1OS5RO4sS7nIRPEeHXCHdkw9ZEW2yVE5oIS7peD58Avs7CN+PVCmHh21oOqBdjDzIs+FldPJ74TFESUSJEfVzy9U/dhu+AuOT6eBp6gGKyXEx8euO450ZE4CMfstMFT44broWw/itkYErWXRx+fFArt9Ca9os78TFed0LVIUsmIHrwbwaw3BEOnOk94qVpQ6Ka2HjxewJnfyd6jUtGDQLdWlzmYNYLeKbbGOucJsNabCq1Yub0o92rtR+i30V2dapxYVEePXcOjeCKPnYyit7BtKeNlZqHbr+gt7i+AChWA9RsRs03pxTQc67ouWpxyESvjK5Vs3DVSy3IpkxPm5X+wZoBi+MFHWW69/w8FRhc7VBe6HAhMB2b8Q0XqDzTNZtXUMnKMjwKVaCrB/CSUL7WSx/HsdJC86lFGXwnioTeOMPjV+szlFvrZLA5VMVK4y+41l4e1xfx7Z88o4hkilRUH/qKqwNVlgDgpvYCpH3XwAy5eMCRnezIUxffVXoDql2rTHFDO+pjWnTWzAfrYXn6BFECblUpWGrvPZvBipETjS5ydM7tdXpH41ZCEbBNy/+wFZu71QO2t9pgT+iZEf657Q1vpN94PQNDxUHeKR103LV9nPVOtDikcNKO+2naCw7yKBhOe9Hm79pe8C4/CfC2wDjXnqC94kEeBU3WwN7dt/2UScXas7zDl5GpkY+M8WKv2J7fd4Ib2rGTk+jsC2cleEM7jI9veF7B0MBJrsZqfKd/81q9pR2NZfwJK2JzsmIT1Ns8jUH0UusQBpU8d2JzsHiXg1zXGLqxfitUNTDT/nUUeqDBp2HZVr+Ocqi/Ty3Rf4Jn82xxfSNtAAAAAElFTkSuQmCC' } } Write-Host ($ObjBody | ConvertTo-Json -Compress) $OfficeAppID = New-graphPostRequest -Uri 'https://graph.microsoft.com/beta/deviceAppManagement/mobileApps' -tenantid $tenant -Body (ConvertTo-Json -InputObject $ObjBody -Depth 10) -type POST - } else { + } else { "Office deployment already exists for $($Tenant)" Continue } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddWinGetApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddWinGetApp.ps1 index d59307524615..8097c6d328e2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddWinGetApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddWinGetApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddWinGetApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 index 4825fc8a9f81..74a83ce92927 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAssignApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -24,7 +26,7 @@ Function Invoke-ExecAssignApp { 'AllUsers' { @' {"mobileAppAssignments":[{"@odata.type":"#microsoft.graph.mobileAppAssignment","target":{"@odata.type":"#microsoft.graph.allLicensedUsersAssignmentTarget"},"intent":"Required","settings":null}]} -'@ +'@ } 'AllDevices' { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApplicationQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApplicationQueue.ps1 index 13e945aa16ed..0aa432beff14 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApplicationQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApplicationQueue.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListApplicationQueue { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 index aca3cafdcd2f..d5c13112058f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 @@ -1,35 +1,37 @@ using namespace System.Net Function Invoke-ListApps { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?`$top=999&`$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName&" -tenantid $TenantFilter - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + try { + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?`$top=999&`$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName&" -tenantid $TenantFilter + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = $ErrorMessage + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListAppsRepository.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListAppsRepository.ps1 index e85a43e1740b..4f9d60aa52df 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListAppsRepository.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListAppsRepository.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAppsRepository { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -39,7 +41,7 @@ Function Invoke-ListAppsRepository { description = $RepoPackage.summary.'#text' customRepo = $Repository created = Get-Date -Date $RepoPackage.properties.Created.'#text' -Format 'MM/dd/yyyy HH:mm:ss' - } + } } } else { $IsError = $true diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 index 262bb17f79bc..b9ff114c5ffd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddAPDevice { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,25 +18,32 @@ Function Invoke-AddAPDevice { Write-Host 'PowerShell HTTP trigger function processed a request.' $TenantFilter = (Get-Tenants | Where-Object { $_.defaultDomainName -eq $Request.body.TenantFilter }).customerId $GroupName = if ($Request.body.Groupname) { $Request.body.Groupname } else { (New-Guid).GUID } + Write-Host $GroupName $rawDevices = $request.body.autopilotData $Devices = ConvertTo-Json @($rawDevices) - Write-Host $Devices $Result = try { $CurrentStatus = (New-GraphgetRequest -uri "https://api.partnercenter.microsoft.com/v1/customers/$tenantfilter/DeviceBatches" -scope 'https://api.partnercenter.microsoft.com/user_impersonation') - if ($groupname -in $CurrentStatus.items.id) { throw 'This device batch name already exists. Please try with another name.' } + if ($groupname -in $CurrentStatus.items.id) { throw 'This device batch name already exists. The batch name must be unique.' } $body = '{"batchId":"' + $($GroupName) + '","devices":' + $Devices + '}' - $GraphRequest = (New-GraphPostRequest -uri "https://api.partnercenter.microsoft.com/v1/customers/$TenantFilter/DeviceBatches" -body $body -scope 'https://api.partnercenter.microsoft.com/user_impersonation') - Write-Host ($GraphRequest | ConvertTo-Json) - Start-Sleep 5 - $NewStatus = New-GraphgetRequest -uri "https://api.partnercenter.microsoft.com/v1/customers/$tenantfilter/DeviceBatches" -scope 'https://api.partnercenter.microsoft.com/user_impersonation' - Write-Host $($Newstatus | ConvertTo-Json) - if ($Newstatus.totalcount -eq $CurrentStatus.totalcount) { throw 'We could not find the new autopilot device. Please check if your input is correct.' } - Write-Host $CurrentStatus.Items + $GraphRequest = (New-GraphPostRequest -returnHeaders $true -uri "https://api.partnercenter.microsoft.com/v1/customers/$TenantFilter/DeviceBatches" -body $body -scope 'https://api.partnercenter.microsoft.com/user_impersonation') + $Amount = 0 + do { + Write-Host "Checking status of import job for $GroupName" + $amount ++ + Start-Sleep 1 + $NewStatus = New-GraphgetRequest -uri "https://api.partnercenter.microsoft.com/v1/$($GraphRequest.Location)" -scope 'https://api.partnercenter.microsoft.com/user_impersonation' + } until ($Newstatus.status -eq 'finished' -or $amount -eq 4) + if ($NewStatus.status -ne 'finished') { throw 'Could not retrieve status of import - This job might still be running. Check the autopilot device list in 10 minutes for the latest status.' } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APIName -tenant $($Request.body.TenantFilter) -message "Created Autopilot devices group. Group ID is $GroupName" -Sev 'Info' - "Created Autopilot devices group for $($Request.body.TenantFilter). Group ID is $GroupName" - } - catch { - "$($Request.body.TenantFilter): Failed to create autopilot devices. $($_.Exception.Message)" + [PSCustomObject]@{ + Status = 'Import Job Completed' + Devices = @($NewStatus.devicesStatus) + } + } catch { + [PSCustomObject]@{ + Status = "$($Request.body.TenantFilter): Failed to create autopilot devices. $($_.Exception.Message)" + Devices = @() + } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APIName -tenant $($Request.body.TenantFilter) -message "Failed to create autopilot devices. $($_.Exception.Message)" -Sev 'Error' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 index 96208b3674f8..38c9161bbabd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddAutopilotConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 index f74ce07857d1..eaed0e5aba15 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddEnrollment { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecAssignAPDevice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecAssignAPDevice.ps1 index 450e93ef642b..0ae4d1f13cb0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecAssignAPDevice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecAssignAPDevice.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAssignAPDevice { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -15,7 +17,7 @@ Function Invoke-ExecAssignAPDevice { UserPrincipalName = $Request.body.UserPrincipalName addressableUserName = $Request.body.addressableUserName } | ConvertTo-Json - New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($request.body.Device)/UpdateDeviceProperties" -tenantid $TenantFilter -body $body -method POST + New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($request.body.Device)/UpdateDeviceProperties" -tenantid $TenantFilter -body $body -method POST $Results = "Successfully assigned device to $($Request.body.UserPrincipalName) for $($tenantfilter)" } catch { $Results = "Could not $($Request.body.UserPrincipalName) to $($Request.body.device) for $($tenantfilter) Error: $($_.Exception.Message)" diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 index c2ec2c1f497b..ab840b320596 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAPDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,7 +20,7 @@ Function Invoke-ListAPDevices { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities?`$top=999" -tenantid $TenantFilter + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities?`$top=999" -tenantid $TenantFilter $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 index e38a8fd67769..7bb3f446bd11 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddDefenderDeployment { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -38,7 +40,7 @@ Function Invoke-AddDefenderDeployment { $Settings = switch ($PolicySettings) { { $_.ScanArchives } { - @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting'; settingInstance = @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance'; settingDefinitionId = 'device_vendor_msft_policy_config_defender_allowarchivescanning'; choiceSettingValue = @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingValue'; value = 'device_vendor_msft_policy_config_defender_allowarchivescanning_1'; settingValueTemplateReference = @{settingValueTemplateId = '9ead75d4-6f30-4bc5-8cc5-ab0f999d79f0' } }; settingInstanceTemplateReference = @{settingInstanceTemplateId = '7c5c9cde-f74d-4d11-904f-de4c27f72d89' } } } + @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting'; settingInstance = @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance'; settingDefinitionId = 'device_vendor_msft_policy_config_defender_allowarchivescanning'; choiceSettingValue = @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingValue'; value = 'device_vendor_msft_policy_config_defender_allowarchivescanning_1'; settingValueTemplateReference = @{settingValueTemplateId = '9ead75d4-6f30-4bc5-8cc5-ab0f999d79f0' } }; settingInstanceTemplateReference = @{settingInstanceTemplateId = '7c5c9cde-f74d-4d11-904f-de4c27f72d89' } } } } { $_.AllowBehavior } { @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting'; settingInstance = @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' ; settingDefinitionId = 'device_vendor_msft_policy_config_defender_allowbehaviormonitoring' ; choiceSettingValue = @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingValue'; value = 'device_vendor_msft_policy_config_defender_allowbehaviormonitoring_1'; settingValueTemplateReference = @{settingValueTemplateId = '905921da-95e2-4a10-9e30-fe5540002ce1' } }; settingInstanceTemplateReference = @{settingInstanceTemplateId = '8eef615a-1aa0-46f4-a25a-12cbe65de5ab' } } } } { $_.AllowCloudProtection } { @@ -87,7 +89,7 @@ Function Invoke-AddDefenderDeployment { roleScopeTagIds = @('0') templateReference = @{templateId = '804339ad-1553-4478-a742-138fb5807418_1' } settings = $Settings - } + } $PolicyRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/configurationPolicies' -tenantid $tenant -type POST -body $PolBody if ($PolicySettings.AssignTo -ne 'None') { $AssignBody = if ($PolicySettings.AssignTo -ne 'AllDevicesAndUsers') { '{"assignments":[{"id":"","target":{"@odata.type":"#microsoft.graph.' + $($PolicySettings.AssignTo) + 'AssignmentTarget"}}]}' } else { '{"assignments":[{"id":"","target":{"@odata.type":"#microsoft.graph.allDevicesAssignmentTarget"}},{"id":"","target":{"@odata.type":"#microsoft.graph.allLicensedUsersAssignmentTarget"}}]}' } @@ -150,7 +152,7 @@ Function Invoke-AddDefenderDeployment { } $EDRSettings = switch ($EDR) { - { $_.SampleSharing } { + { $_.SampleSharing } { @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting' settingInstance = @{ @@ -163,9 +165,9 @@ Function Invoke-AddDefenderDeployment { } settingInstanceTemplateReference = @{settingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' } } - } + } } - { $_.Telemetry } { + { $_.Telemetry } { @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting' settingInstance = @{ @@ -178,10 +180,10 @@ Function Invoke-AddDefenderDeployment { } settingInstanceTemplateReference = @{settingInstanceTemplateId = '03de6095-07c4-4f35-be38-c1cd3bae4484' } } - } - + } + } - { $_.Config } { + { $_.Config } { @{ '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting' settingInstance = @{ @@ -193,11 +195,11 @@ Function Invoke-AddDefenderDeployment { settingValueTemplateReference = @{settingValueTemplateId = 'e5c7c98c-c854-4140-836e-bd22db59d651' } children = @(@{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' ; settingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_onboarding_fromconnector' ; simpleSettingValue = @{'@odata.type' = '#microsoft.graph.deviceManagementConfigurationSecretSettingValue' ; value = 'Microsoft ATP connector enabled'; valueState = 'NotEncrypted' } } ) } - + settingInstanceTemplateReference = @{settingInstanceTemplateId = '23ab0ea3-1b12-429a-8ed0-7390cf699160' } } - } - + } + } } $EDRbody = ConvertTo-Json -Depth 15 -Compress -InputObject @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddIntuneTemplate.ps1 index b4c3471b4fca..d01025dc080a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddIntuneTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddIntuneTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -44,18 +46,18 @@ Function Invoke-AddIntuneTemplate { $Type = 'deviceCompliancePolicies' $Template = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$($urlname)/$($ID)?`$expand=scheduledActionsForRule(`$expand=scheduledActionConfigurations)" -tenantid $tenantfilter $DisplayName = $Template.displayName - $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 10 -Compress + $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress } 'managedAppPolicies' { $Type = 'AppProtection' $Template = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceAppManagement/$($urlname)('$($ID)')" -tenantid $tenantfilter $DisplayName = $Template.displayName - $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 10 -Compress + $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress } 'configurationPolicies' { $Type = 'Catalog' $Template = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$($urlname)('$($ID)')?`$expand=settings" -tenantid $tenantfilter | Select-Object name, description, settings, platforms, technologies, templateReference - $TemplateJson = $Template | ConvertTo-Json -Depth 10 + $TemplateJson = $Template | ConvertTo-Json -Depth 100 $DisplayName = $Template.name @@ -65,7 +67,7 @@ Function Invoke-AddIntuneTemplate { $Template = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$($urlname)/$($ID)" -tenantid $tenantfilter | Select-Object * -ExcludeProperty id, lastModifiedDateTime, '@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime' Write-Host ($Template | ConvertTo-Json) $DisplayName = $Template.displayName - $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 10 -Compress + $TemplateJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress } 'groupPolicyConfigurations' { $Type = 'Admin' @@ -100,7 +102,7 @@ Function Invoke-AddIntuneTemplate { } - $TemplateJson = (ConvertTo-Json -InputObject $inputvar -Depth 15 -Compress) + $TemplateJson = (ConvertTo-Json -InputObject $inputvar -Depth 100 -Compress) } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 index ac6648f814dc..a00bc8c60e64 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 index e30d3971cb00..066e83cf11df 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-EditPolicy { $displayname = $request.body.Displayname $description = $request.body.Description $AssignTo = if ($request.body.Assignto -ne 'on') { $request.body.Assignto } - + $results = try { $CreateBody = '{"description":"' + $description + '","displayName":"' + $displayname + '","roleScopeTagIds":["0"]}' $Request = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/groupPolicyConfigurations('$ID')" -tenantid $tenant -type PATCH -body $CreateBody diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecAssignPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecAssignPolicy.ps1 index ae866ed3f485..8000d6f46d2f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecAssignPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecAssignPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAssignPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -15,7 +17,7 @@ Function Invoke-ExecAssignPolicy { $ID = $request.query.id $displayname = $request.query.Displayname $AssignTo = if ($request.query.Assignto -ne 'on') { $request.query.Assignto } - + $results = try { if ($AssignTo) { $assign = Set-CIPPAssignedPolicy -PolicyId $ID -TenantFilter $tenant -GroupName $AssignTo -Type $Request.query.Type diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 index 90f9e86d4c6d..ca788cb979da 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecDeviceAction { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -14,10 +16,10 @@ Function Invoke-ExecDeviceAction { # Interact with query parameters or the body of the request. - try { + try { if ($Request.Query.Action -eq 'setDeviceName') { $ActionBody = @{ deviceName = $Request.Body.input } | ConvertTo-Json -Compress - } + } $ActionResult = New-CIPPDeviceAction -Action $Request.Query.Action -ActionBody $ActionBody -DeviceFilter $Request.Query.GUID -TenantFilter $Request.Query.TenantFilter -ExecutingUser $request.headers.'x-ms-client-principal' -APINAME $APINAME $body = [pscustomobject]@{'Results' = "$ActionResult" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetLocalAdminPassword.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetLocalAdminPassword.ps1 index c58267717c20..f2850548e8c2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetLocalAdminPassword.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetLocalAdminPassword.ps1 @@ -1,30 +1,31 @@ - using namespace System.Net +using namespace System.Net - Function Invoke-ExecGetLocalAdminPassword { +Function Invoke-ExecGetLocalAdminPassword { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Device.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName + $APIName = $TriggerMetadata.FunctionName -try { - $GraphRequest = Get-CIPPLapsPassword -device $($request.query.guid) -tenantFilter $Request.Query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' - $Body = [pscustomobject]@{"Results" = $GraphRequest } + try { + $GraphRequest = Get-CIPPLapsPassword -device $($request.query.guid) -tenantFilter $Request.Query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' + $Body = [pscustomobject]@{'Results' = $GraphRequest } -} -catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $Body = [pscustomobject]@{"Results" = "Failed. $ErrorMessage" } + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $Body = [pscustomobject]@{'Results' = "Failed. $ErrorMessage" } -} + } -# Associate values to output bindings by calling 'Push-OutputBinding'. -Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Body - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Body + }) - } +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetRecoveryKey.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetRecoveryKey.ps1 index 7190225450a5..46df4d780496 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetRecoveryKey.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecGetRecoveryKey.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGetRecoveryKey { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Device.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 index 8587a32155e3..d4ed67595239 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Device.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,7 +20,7 @@ Function Invoke-ListDevices { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter try { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/managedDevices' -Tenantid $tenantfilter + $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/managedDevices' -Tenantid $tenantfilter $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Devices/Invoke-ExecDeviceDelete.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Devices/Invoke-ExecDeviceDelete.ps1 index 25e64be478b3..14101947635f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Devices/Invoke-ExecDeviceDelete.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Devices/Invoke-ExecDeviceDelete.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecDeviceDelete { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Device.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroup.ps1 index 2a9d176a365e..f4dda9d8f50a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroup.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddGroup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -46,14 +48,14 @@ Function Invoke-AddGroup { $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/beta/groups' -tenantid $tenant -type POST -body (ConvertTo-Json -InputObject $BodyToship -Depth 10) -verbose } else { if ($groupobj.groupType -eq 'dynamicdistribution') { - $Params = @{ + $Params = @{ Name = $groupobj.Displayname RecipientFilter = $groupobj.membershipRules PrimarySmtpAddress = $email } $GraphRequest = New-ExoRequest -tenantid $tenant -cmdlet 'New-DynamicDistributionGroup' -cmdParams $params } else { - $Params = @{ + $Params = @{ Name = $groupobj.Displayname Alias = $groupobj.username Description = $groupobj.Description diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 index 85d10812a9c8..83d8e9a64743 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddGroupTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -12,7 +14,7 @@ Function Invoke-AddGroupTemplate { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $GUID = (New-Guid).GUID - try { + try { if (!$Request.body.displayname) { throw 'You must enter a displayname' } $object = [PSCustomObject]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 index 6990f6baa46f..122c4f118739 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditGroup { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -23,13 +25,13 @@ Function Invoke-EditGroup { $AddMembers | ForEach-Object { try { $member = $_ - + if ($member -like '*#EXT#*') { $member = [System.Web.HttpUtility]::UrlEncode($member) } - $MemberIDs = 'https://graph.microsoft.com/v1.0/directoryObjects/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($member)" -tenantid $Userobj.tenantid).id + $MemberIDs = 'https://graph.microsoft.com/v1.0/directoryObjects/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($member)" -tenantid $Userobj.tenantid).id $addmemberbody = "{ `"members@odata.bind`": $(ConvertTo-Json @($MemberIDs)) }" if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') { $Params = @{ Identity = $userobj.groupid; Member = $member; BypassSecurityGroupManagerCheck = $true } - New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true + New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true } else { New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)" -tenantid $Userobj.tenantid -type patch -body $addmemberbody -Verbose } @@ -67,7 +69,7 @@ Function Invoke-EditGroup { $RemoveMembers = ($userobj.Removemember).value try { if ($RemoveMembers) { - $RemoveMembers | ForEach-Object { + $RemoveMembers | ForEach-Object { $member = $_ if ($member -like '*#EXT#*') { $member = [System.Web.HttpUtility]::UrlEncode($member) } if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') { @@ -75,11 +77,11 @@ Function Invoke-EditGroup { New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true } else { $MemberInfo = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($_)" -tenantid $Userobj.tenantid) - New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/members/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE + New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/members/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE } Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Removed $member from $($userobj.groupName) group" -Sev 'Info' $null = $results.add("Success. Member $member has been removed from $($userobj.groupName)") - } + } } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to remove $RemoveMembers from $($userobj.groupName). Error:$($_.Exception.Message)" -Sev 'Error' @@ -89,7 +91,7 @@ Function Invoke-EditGroup { $AddOwners = $userobj.Addowner.value try { if ($AddOwners) { - $AddOwners | ForEach-Object { + $AddOwners | ForEach-Object { try { $ID = 'https://graph.microsoft.com/beta/users/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($_)" -tenantid $Userobj.tenantid).id Write-Host $ID @@ -110,16 +112,16 @@ Function Invoke-EditGroup { $RemoveOwners = ($userobj.RemoveOwner).value try { if ($RemoveOwners) { - $RemoveOwners | ForEach-Object { + $RemoveOwners | ForEach-Object { try { $MemberInfo = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($_)" -tenantid $Userobj.tenantid) - New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/owners/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE + New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/owners/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Removed $($MemberInfo.UserPrincipalname) from $($userobj.displayname) group" -Sev 'Info' $null = $results.add("Success. Member $_ has been removed from $($userobj.groupName)") } catch { $null = $results.add("Failed to remove $_ from $($userobj.groupName): $($_.Exception.Message)") } - } + } } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to remove $RemoveMembers from $($userobj.groupName). Error:$($_.Exception.Message)" -Sev 'Error' @@ -157,7 +159,7 @@ Function Invoke-EditGroup { $subscriberParams = @{ Identity = $userobj.Groupid; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses) } New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-UnifiedGrouplinks' -cmdParams $subscriberParams -Anchor $userobj.mail - + $body = $results.add("Send Copies of team emails and events to team members inboxes for $($userobj.mail) enabled.") Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Send Copies of team emails and events to team members inboxes for $($userobj.mail) enabled." -Sev 'Info' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddGuest.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddGuest.ps1 index 462ba7df0545..43e1dc49d393 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddGuest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddGuest.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddGuest { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -22,7 +24,7 @@ Function Invoke-AddGuest { 'InvitedUserEmailAddress' = $($userobj.mail) 'inviteRedirectUrl' = $($userobj.RedirectURL) 'sendInvitationMessage' = [boolean]$userobj.SendInvite - } + } } else { $BodyToship = [pscustomobject] @{ @@ -31,14 +33,14 @@ Function Invoke-AddGuest { 'sendInvitationMessage' = [boolean]$userobj.SendInvite 'inviteRedirectUrl' = 'https://myapps.microsoft.com' } - } + } $bodyToShip = ConvertTo-Json -Depth 10 -InputObject $BodyToship -Compress $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/beta/invitations' -tenantid $Userobj.tenantid -type POST -body $BodyToship -verbose - if ($Userobj.sendInvite -eq 'true') { + if ($Userobj.sendInvite -eq 'true') { $results.add('Invited Guest. Invite Email sent') Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($userobj.tenantid) -message "Invited Guest $($userobj.displayname) with Email Invite " -Sev 'Info' } - else { + else { $results.add('Invited Guest. No Invite Email was sent') Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($userobj.tenantid) -message "Invited Guest $($userobj.displayname) with no Email Invite " -Sev 'Info' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUser.ps1 index 861ea01e85c4..5a4b4f95e08c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUser.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddUser { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 index 31c3fbbaa687..8169512aaeee 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddUserBulk { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -37,7 +39,7 @@ Function Invoke-AddUserBulk { } } $body = [pscustomobject] @{ - 'Results' = @($results) + 'Results' = @($results) 'Username' = $UserprincipalName 'Password' = $password 'CopyFrom' = $copyFromResults diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 index cb925b1cda70..39e018d223df 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditUser { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECCheck.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECCheck.ps1 index 7413636f7061..52aab6d770f5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECCheck.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECCheck.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecBECCheck { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 index b863aeac8f06..cfbf2078aa27 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecBECRemediate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -24,9 +26,9 @@ Function Invoke-ExecBECRemediate { $RuleDisabled = 0 New-ExoRequest -anchor $username -tenantid $TenantFilter -cmdlet 'get-inboxrule' -cmdParams @{Mailbox = $username } | ForEach-Object { $null = New-ExoRequest -anchor $username -tenantid $TenantFilter -cmdlet 'Disable-InboxRule' -cmdParams @{Confirm = $false; Identity = $_.Identity } - "Disabled Inbox Rule $($_.Identity) for $username" + "Disabled Inbox Rule $($_.Identity) for $username" $RuleDisabled ++ - } + } if ($RuleDisabled) { "Disabled $RuleDisabled Inbox Rules for $username" } else { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecClrImmId.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecClrImmId.ps1 index 3506522f2c8c..9241f5feae7d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecClrImmId.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecClrImmId.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecClrImmId { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 index 9919b0564510..3ae22c37ffa7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 @@ -1,28 +1,30 @@ using namespace System.Net Function Invoke-ExecCreateTAP { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - try { - $TAP = New-CIPPTAP -userid $Request.query.ID -TenantFilter $Request.query.tenantfilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' - $Results = [pscustomobject]@{'Results' = "$TAP" } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + # Interact with query parameters or the body of the request. + try { + $TAP = New-CIPPTAP -userid $Request.query.ID -TenantFilter $Request.query.tenantfilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' + $Results = [pscustomobject]@{'Results' = "$TAP" } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecDisableUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecDisableUser.ps1 index 3e32878e726d..69ac4dd83ec8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecDisableUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecDisableUser.ps1 @@ -1,26 +1,28 @@ using namespace System.Net Function Invoke-ExecDisableUser { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - try { + $APIName = $TriggerMetadata.FunctionName + try { ([System.Convert]::ToBoolean($Request.Query.Enable)) - $State = Set-CIPPSignInState -userid $Request.query.ID -TenantFilter $Request.Query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' -AccountEnabled ([System.Convert]::ToBoolean($Request.Query.Enable)) - $Results = [pscustomobject]@{'Results' = "$State" } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + $State = Set-CIPPSignInState -userid $Request.query.ID -TenantFilter $Request.Query.TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' -AccountEnabled ([System.Convert]::ToBoolean($Request.Query.Enable)) + $Results = [pscustomobject]@{'Results' = "$State" } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 index 02516f3148bf..0bf9feaf3dff 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecOffboardUser { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -22,9 +24,10 @@ Function Invoke-ExecOffboardUser { value = 'Invoke-CIPPOffboardingJob' } Parameters = @{ - Username = $Username - APIName = 'Scheduled Offboarding' - options = $request.body + Username = $Username + APIName = 'Scheduled Offboarding' + options = $request.body + RunScheduled = $true } ScheduledTime = $Request.body.scheduled.date PostExecution = @{ @@ -38,7 +41,7 @@ Function Invoke-ExecOffboardUser { Invoke-CIPPOffboardingJob -Username $Username -TenantFilter $Tenantfilter -Options $Request.body -APIName $APIName -ExecutingUser $request.headers.'x-ms-client-principal' } $StatusCode = [HttpStatusCode]::OK - + } catch { $StatusCode = [HttpStatusCode]::Forbidden $body = $_.Exception.message @@ -48,6 +51,6 @@ Function Invoke-ExecOffboardUser { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode Body = $Body - }) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboard_Mailboxpermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboard_Mailboxpermissions.ps1 index 18e70672635d..02e60ca462d0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboard_Mailboxpermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboard_Mailboxpermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecOffboard_Mailboxpermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 index 2f820ab4a068..ddc282908b68 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecOneDriveShortCut { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 index 457e8abcba1c..1667958aa7a1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecResetMFA { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -29,7 +31,7 @@ Function Invoke-ExecResetMFA { http://provisioning.microsoftonline.com/IProvisioningWebService/SetUserurn:uuid:$TrackingGuidhttp://www.w3.org/2005/08/addressing/anonymous$($AADGraphtoken['Authorization'])$($DataBlob)9450afce61-c917-435b-8c6d-60aa5a8b8aa71.2.183.57Version47$TrackingGuidhttps://provisioningapi.microsoftonline.com/provisioningwebservice.svcVersion16$($tenantid)$($Request.query.id)*0001-01-01T00:00:00Enabled "@ $SetMFA = (Invoke-RestMethod -Uri 'https://provisioningapi.microsoftonline.com/provisioningwebservice.svc' -Method post -Body $MSOLXML -ContentType 'application/soap+xml; charset=utf-8') - + $Results = [pscustomobject]@{'Results' = 'Successfully completed request. User must supply MFA at next logon' } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Reset Multi factor authentication settings for $($Request.query.id)" -Sev 'Info' } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 index 0d16795f9104..c9be1da38759 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecResetPass { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 index bab48ef09239..5c5c56fe568f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 @@ -1,29 +1,31 @@ using namespace System.Net Function Invoke-ExecRevokeSessions { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - try { - $RevokeSessions = Revoke-CIPPSessions -userid $Request.Query.id -tenantFilter $TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' - $Results = [pscustomobject]@{'Results' = $RevokeSessions } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + try { + $RevokeSessions = Revoke-CIPPSessions -userid $Request.Query.id -tenantFilter $TenantFilter -APIName $APINAME -ExecutingUser $request.headers.'x-ms-client-principal' + $Results = [pscustomobject]@{'Results' = $RevokeSessions } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 index aeeb61d4f9c8..3970db4890e6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSendPush { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -46,7 +48,7 @@ Function Invoke-ExecSendPush { # Create a serivce principal if needed if (!$SPID) { - + $SPBody = [pscustomobject]@{ appId = $MFAAppID } @@ -107,7 +109,7 @@ Function Invoke-ExecSendPush { $Body = "Authentication Failed! Does the user have Push/Phone call MFA configured? Errorcode: $($obj.BeginTwoWayAuthenticationResponse.result.value | Out-String)" $colour = 'danger' } - + } $Results = [pscustomobject]@{'Results' = $Body; colour = $colour } @@ -117,6 +119,6 @@ Function Invoke-ExecSendPush { StatusCode = [HttpStatusCode]::OK Body = $Results }) - + } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 index 1557184a8bb6..dd0ced4e4e68 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserConditionalAccessPolicies { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -41,7 +43,7 @@ Function Invoke-ListUserConditionalAccessPolicies { # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK - Body = @($GraphRequest) + Body = @($GraphRequest) }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 index 137a9c8cc902..d67251b461e0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 @@ -1,45 +1,47 @@ using namespace System.Net Function Invoke-ListUserCounts { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - if ($Request.Query.TenantFilter -eq 'AllTenants') { - $users = 'Not Supported' - $LicUsers = 'Not Supported' - $GAs = 'Not Supported' - $Guests = 'Not Supported' - } else { - try { $Users = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Users = 'Not available' } - try { $LicUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1&`$filter=assignedLicenses/`$count ne 0" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Licusers = 'Not available' } - try { $GAs = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190-012177145e10/members?`$count=true" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Gas = 'Not available' } - try { $guests = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1&`$filter=userType eq 'Guest'" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Guests = 'Not available' } - } - $StatusCode = [HttpStatusCode]::OK - $Counts = @{ - Users = $users - LicUsers = $LicUsers - Gas = $Gas - Guests = $guests - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + if ($Request.Query.TenantFilter -eq 'AllTenants') { + $users = 'Not Supported' + $LicUsers = 'Not Supported' + $GAs = 'Not Supported' + $Guests = 'Not Supported' + } else { + try { $Users = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Users = 'Not available' } + try { $LicUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1&`$filter=assignedLicenses/`$count ne 0" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Licusers = 'Not available' } + try { $GAs = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190-012177145e10/members?`$count=true" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Gas = 'Not available' } + try { $guests = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$count=true&`$top=1&`$filter=userType eq 'Guest'" -CountOnly -ComplexFilter -tenantid $TenantFilter } catch { $Guests = 'Not available' } + } + $StatusCode = [HttpStatusCode]::OK + $Counts = @{ + Users = $users + LicUsers = $LicUsers + Gas = $Gas + Guests = $guests + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = $Counts - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = $Counts + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 index 0bbcb27b4422..0c36e75712fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 index fff7eb222d9c..26676aec5623 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserGroups { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -20,7 +22,7 @@ Function Invoke-ListUserGroups { $UserID = $Request.Query.UserID - $URI = "https://graph.microsoft.com/beta/users/$UserID/memberOf/$/microsoft.graph.group?`$select=id,displayName,mailEnabled,securityEnabled,groupTypes,onPremisesSyncEnabled,mail,isAssignableToRole`&$orderby=displayName asc" + $URI = "https://graph.microsoft.com/beta/users/$UserID/memberOf/$/microsoft.graph.group?`$select=id,displayName,mailEnabled,securityEnabled,groupTypes,onPremisesSyncEnabled,mail,isAssignableToRole`&$orderby=displayName asc" Write-Host $URI $GraphRequest = New-GraphGetRequest -uri $URI -tenantid $TenantFilter -noPagination $true -verbose | Select-Object id, @{ Name = 'DisplayName'; Expression = { $_.displayName } }, diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxDetails.ps1 index 22f5665696c4..152323e21b4e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxDetails.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxDetails.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserMailboxDetails { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -23,7 +25,7 @@ Function Invoke-ListUserMailboxDetails { $TenantFilter = $Request.Query.TenantFilter try { $Bytes = [System.Text.Encoding]::UTF8.GetBytes($Request.Query.UserID) - $base64IdentityParam = [Convert]::ToBase64String($Bytes) + $base64IdentityParam = [Convert]::ToBase64String($Bytes) $CASRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/CasMailbox('$UserID')" -Tenantid $tenantfilter -scope ExchangeOnline -noPagination $true $MailRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Mailbox('$UserID')" -Tenantid $tenantfilter -scope ExchangeOnline -noPagination $true $FetchParam = @{ @@ -32,7 +34,7 @@ Function Invoke-ListUserMailboxDetails { $MailboxDetailedRequest = New-ExoRequest -TenantID $TenantFilter -cmdlet 'Get-Mailbox' -cmdParams $FetchParam try { if ($MailboxDetailedRequest.ArchiveStatus -eq 'Active') { - $ArchiveEnabled = $True + $ArchiveEnabled = $True } else { $ArchiveEnabled = $False } @@ -68,7 +70,7 @@ Function Invoke-ListUserMailboxDetails { } $StatsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Mailbox('$($MailRequest.PrimarySmtpAddress)')/Exchange.GetMailboxStatistics()" -Tenantid $tenantfilter -scope ExchangeOnline -noPagination $true $PermsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Mailbox('$($MailRequest.PrimarySmtpAddress)')/MailboxPermission" -Tenantid $tenantfilter -scope ExchangeOnline -noPagination $true - $PermsRequest2 = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Recipient('$base64IdentityParam')?`$expand=RecipientPermission&isEncoded=true" -Tenantid $tenantfilter -scope ExchangeOnline + $PermsRequest2 = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Recipient('$base64IdentityParam')?`$expand=RecipientPermission&isEncoded=true" -Tenantid $tenantfilter -scope ExchangeOnline } catch { Write-Error "Failed Fetching Data $($_.Exception.message): $($_.InvocationInfo.ScriptLineNumber)" @@ -79,16 +81,16 @@ Function Invoke-ListUserMailboxDetails { if ($perm.Trustee) { $perm | Where-Object Trustee | ForEach-Object { [PSCustomObject]@{ User = $_.Trustee - AccessRights = $_.accessRights -join ', ' + AccessRights = $_.accessRights -join ', ' } } - + } if ($perm.PermissionList) { $perm | Where-Object User | ForEach-Object { [PSCustomObject]@{ User = $_.User AccessRights = $_.PermissionList.accessRights -join ', ' - } + } } } } @@ -98,10 +100,10 @@ Function Invoke-ListUserMailboxDetails { } elseif ($MailboxDetailedRequest.ForwardingSmtpAddress -and $MailboxDetailedRequest.ForwardingAddress) { $MailboxDetailedRequest.ForwardingAddress + ' ' + $MailboxDetailedRequest.ForwardingSmtpAddress } else { - $MailboxDetailedRequest.ForwardingSmtpAddress + $MailboxDetailedRequest.ForwardingSmtpAddress } - if ($ArchiveSize) { + if ($ArchiveSize) { $GraphRequest = [ordered]@{ ForwardAndDeliver = $MailboxDetailedRequest.DeliverToMailboxAndForward ForwardingAddress = $ForwardingAddress diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 index 4a0a433fc1d4..eade83ccee64 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserMailboxRules { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserPhoto.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserPhoto.ps1 index bd596e0a379a..757784ad320d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserPhoto.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserPhoto.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserPhoto { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 index 50781d922e7b..85b59ec479fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 @@ -3,7 +3,9 @@ using namespace System.Net function Invoke-ListUserSettings { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 index d421b79441d5..32c2cc24f28a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUserSigninLogs { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -19,7 +21,7 @@ Function Invoke-ListUserSigninLogs { $TenantFilter = $Request.Query.TenantFilter $UserID = $Request.Query.UserID try { - $URI = "https://graph.microsoft.com/beta/auditLogs/signIns?`$filter=(userId eq '$UserID')&`$top=50&`$orderby=createdDateTime desc" + $URI = "https://graph.microsoft.com/beta/auditLogs/signIns?`$filter=(userId eq '$UserID')&`$top=50&`$orderby=createdDateTime desc" Write-Host $URI $GraphRequest = New-GraphGetRequest -uri $URI -tenantid $TenantFilter -noPagination $true -verbose | Select-Object @{ Name = 'Date'; Expression = { $(($_.createdDateTime | Out-String) -replace '\r\n') } }, id, diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 index 8431d441a320..b85dde08e21f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListUsers { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -72,11 +74,11 @@ Function Invoke-ListUsers { Id = $AuditlogsLogon.errorNumber Status = $AuditlogsLogon.ResultStatus } - $GraphRequest = $GraphRequest | Select-Object *, + $GraphRequest = $GraphRequest | Select-Object *, @{ Name = 'LastSigninApplication'; Expression = { $LastSignIn.AppDisplayName } }, @{ Name = 'LastSigninDate'; Expression = { $($LastSignIn.CreatedDateTime | Out-String) } }, @{ Name = 'LastSigninStatus'; Expression = { $AuditlogsLogon.operation } }, - @{ Name = 'LastSigninResult'; Expression = { $LastSignIn.status } }, + @{ Name = 'LastSigninResult'; Expression = { $LastSignIn.status } }, @{ Name = 'LastSigninFailureReason'; Expression = { if ($LastSignIn.Id -eq 0) { 'Sucessfully signed in' } else { $LastSignIn.Id } } } } # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuth.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuth.ps1 index bf831b65cc9b..9cdbce1b86c8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuth.ps1 @@ -3,12 +3,14 @@ using namespace System.Net Function Invoke-ListBasicAuth { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.AuditLog.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - + # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' @@ -25,7 +27,7 @@ Function Invoke-ListBasicAuth { $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/auditLogs/signIns?api-version=beta&filter=$($filters)" -tenantid $TenantFilter -erroraction stop | Select-Object userPrincipalName, clientAppUsed, Status | Sort-Object -Unique -Property userPrincipalName $response = $GraphRequest Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Retrieved basic authentication report' -Sev 'Debug' -tenant $TenantFilter - + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuthAllTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuthAllTenants.ps1 index e4be4bafbb02..26d93e02b387 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuthAllTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Reports/Invoke-ListBasicAuthAllTenants.ps1 @@ -3,13 +3,15 @@ using namespace System.Net Function Invoke-ListBasicAuthAllTenants { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.AuditLog.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - - Get-Tenants | ForEach-Object -Parallel { + + Get-Tenants | ForEach-Object -Parallel { $domainName = $_.defaultDomainName Import-Module '.\Modules\AzBobbyTables' Import-Module '.\Modules\CIPPCore' @@ -36,7 +38,7 @@ Function Invoke-ListBasicAuthAllTenants { RowKey = $domainName PartitionKey = 'basicauth' } - } + } $Table = Get-CIPPTable -TableName cachebasicauth Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Invoke-Z_CIPPHttpTrigger.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Invoke-Z_CIPPHttpTrigger.ps1 deleted file mode 100644 index 9f0083676d1e..000000000000 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Invoke-Z_CIPPHttpTrigger.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -function Invoke-Z_CIPPHttpTrigger { - <# - .FUNCTIONALITY - Entrypoint - #> - Param( - $Request, - $TriggerMetadata - ) - - $FunctionName = 'Invoke-{0}' -f $Request.Params.CIPPEndpoint - - Write-Host "Function: $($Request.Params.CIPPEndpoint)" - - $HttpTrigger = @{ - Request = $Request - TriggerMetadata = $TriggerMetadata - } - - if (Get-Command -Name $FunctionName -ErrorAction SilentlyContinue) { - & $FunctionName @HttpTrigger - } else { - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::NotFound - Body = 'Endpoint not found' - }) - } -} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ExecAlertsList.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 similarity index 97% rename from Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ExecAlertsList.ps1 rename to Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 index 1b6141e1fcda..f3580ec3fc19 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ExecAlertsList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAlertsList { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Alert.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -26,7 +28,7 @@ Function Invoke-ExecAlertsList { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter $GraphRequest = if ($TenantFilter -ne 'AllTenants') { - $Alerts = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/alerts' -tenantid $TenantFilter + $Alerts = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/alerts' -tenantid $TenantFilter $AlertsObj = foreach ($Alert In $alerts) { @{ Tenant = $TenantFilter @@ -42,7 +44,7 @@ Function Invoke-ExecAlertsList { } } - $DisplayableAlerts = New-FlatArray $AlertsObj | Where-Object { $_.Id -ne $null } | Sort-Object -Property EventDateTime -Descending + $DisplayableAlerts = New-FlatArray $AlertsObj | Where-Object { $_.Id -ne $null } | Sort-Object -Property EventDateTime -Descending [PSCustomObject]@{ NewAlertsCount = $DisplayableAlerts | Where-Object { $_.Status -eq 'newAlert' } | Measure-Object | Select-Object -ExpandProperty Count @@ -79,7 +81,7 @@ Function Invoke-ExecAlertsList { InvolvedUsers = $AlertInfo.userStates } } - $DisplayableAlerts = New-FlatArray $AlertsObj | Where-Object { $_.Id -ne $null } | Sort-Object -Property EventDateTime -Descending + $DisplayableAlerts = New-FlatArray $AlertsObj | Where-Object { $_.Id -ne $null } | Sort-Object -Property EventDateTime -Descending [PSCustomObject]@{ NewAlertsCount = $DisplayableAlerts | Where-Object { $_.Status -eq 'newAlert' } | Measure-Object | Select-Object -ExpandProperty Count InProgressAlertsCount = $DisplayableAlerts | Where-Object { $_.Status -eq 'inProgress' } | Measure-Object | Select-Object -ExpandProperty Count @@ -103,6 +105,6 @@ Function Invoke-ExecAlertsList { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode Body = $Body - }) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsListAllTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsListAllTenants.ps1 index fc14d337dc28..cbab4f74d8ad 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsListAllTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsListAllTenants.ps1 @@ -3,20 +3,22 @@ using namespace System.Net Function Invoke-ExecAlertsListAllTenants { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Alert.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - - Get-Tenants | ForEach-Object -Parallel { + + Get-Tenants | ForEach-Object -Parallel { $domainName = $_.defaultDomainName Import-Module '.\Modules\AzBobbyTables' Import-Module '.\Modules\CIPPCore' $Table = Get-CIPPTable -TableName 'cachealertsandincidents' try { - $Alerts = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/alerts' -tenantid $domainName + $Alerts = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/alerts' -tenantid $domainName foreach ($Alert in $Alerts) { $GUID = (New-Guid).Guid $alertJson = $Alert | ConvertTo-Json @@ -33,7 +35,7 @@ Function Invoke-ExecAlertsListAllTenants { } catch { $GUID = (New-Guid).Guid $AlertText = ConvertTo-Json -InputObject @{ - Title = "Could not connect to tenant to retrieve data: $($_.Exception.Message)" + Title = "Could not connect to tenant to retrieve data: $($_.Exception.Message)" Id = '' Category = '' EventDateTime = '' @@ -46,7 +48,7 @@ Function Invoke-ExecAlertsListAllTenants { } } $GraphRequest = @{ - Alert = [string]$AlertText + Alert = [string]$AlertText RowKey = [string]$GUID PartitionKey = 'alert' Tenant = $domainName diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsList.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsList.ps1 index e3bb573809ef..184f629f2b2c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsList.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecIncidentsList { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Incident.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-ExecIncidentsList { $GraphRequest = if ($TenantFilter -ne 'AllTenants') { $incidents = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/incidents' -tenantid $Request.Query.TenantFilter -AsApp $true - foreach ($incident in $incidents) { + foreach ($incident in $incidents) { [PSCustomObject]@{ Tenant = $Request.Query.TenantFilter Id = $incident.id @@ -33,7 +35,7 @@ Function Invoke-ExecIncidentsList { Tags = ($IncidentObj.tags -join ', ') Comments = $incident.comments } - } + } } else { $Table = Get-CIPPTable -TableName cachealertsandincidents $Filter = "PartitionKey eq 'Incident'" @@ -45,8 +47,8 @@ Function Invoke-ExecIncidentsList { } } else { $incidents = $Rows - foreach ($incident in $incidents) { - $IncidentObj = $incident.Incident | ConvertFrom-Json + foreach ($incident in $incidents) { + $IncidentObj = $incident.Incident | ConvertFrom-Json [PSCustomObject]@{ Tenant = $incident.Tenant Id = $IncidentObj.id @@ -63,7 +65,7 @@ Function Invoke-ExecIncidentsList { Tags = ($IncidentObj.tags -join ', ') Comments = @($IncidentObj.comments) } - } + } } } } catch { @@ -79,6 +81,6 @@ Function Invoke-ExecIncidentsList { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode Body = $Body - }) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsListAllTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsListAllTenants.ps1 index 25e24aa519ec..73421bb577fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsListAllTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecIncidentsListAllTenants.ps1 @@ -3,13 +3,15 @@ using namespace System.Net Function Invoke-ExecIncidentsListAllTenants { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Incident.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - - Get-Tenants | ForEach-Object -Parallel { + + Get-Tenants | ForEach-Object -Parallel { $domainName = $_.defaultDomainName Import-Module '.\Modules\AzBobbyTables' Import-Module '.\Modules\CIPPCore' @@ -17,7 +19,7 @@ Function Invoke-ExecIncidentsListAllTenants { try { $incidents = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/incidents' -tenantid $domainName -AsApp $true - $GraphRequest = foreach ($incident in $incidents) { + $GraphRequest = foreach ($incident in $incidents) { $GUID = (New-Guid).Guid $GraphRequest = @{ Incident = [string]($incident | ConvertTo-Json -Depth 10) @@ -26,7 +28,7 @@ Function Invoke-ExecIncidentsListAllTenants { Tenant = [string]$domainName } Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null - } + } } catch { $GUID = (New-Guid).Guid @@ -43,7 +45,7 @@ Function Invoke-ExecIncidentsListAllTenants { severity = 'CIPP' } $GraphRequest = @{ - Incident = [string]$AlertText + Incident = [string]$AlertText RowKey = [string]$GUID PartitionKey = 'Incident' Tenant = [string]$domainName diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityAlert.ps1 index 1a13261e7c03..da3bc31ab858 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSetSecurityAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Alert.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-ExecSetSecurityAlert { $AlertFilter = $Request.Query.GUID $Status = $Request.Query.Status $AssignBody = '{"status":"' + $Status + '","vendorInformation":{"provider":"' + $Request.query.provider + '","vendor":"' + $Request.query.vendor + '"}}' - try { + try { $GraphRequest = New-Graphpostrequest -uri "https://graph.microsoft.com/beta/security/alerts/$AlertFilter" -type PATCH -tenantid $TenantFilter -body $Assignbody Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Set alert $AlertFilter to status $Status" -Sev 'Info' $body = [pscustomobject]@{'Results' = "Set status for alert to $Status" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityIncident.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityIncident.ps1 index 64b2ad0b6bcf..b1065f721a29 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityIncident.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecSetSecurityIncident.ps1 @@ -1,79 +1,81 @@ using namespace System.Net Function Invoke-ExecSetSecurityIncident { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Security.Incident.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $first = '' - # Interact with query parameters or the body of the request. - $tenantfilter = $Request.Query.TenantFilter - $IncidentFilter = $Request.Query.GUID - $Status = $Request.Query.Status - $Assigned = $Request.Query.Assigned - $Classification = $Request.Query.Classification - $Determination = $Request.Query.Determination - $Redirected = $Request.Query.Redirected -as [int] - $BodyBuild - $AssignBody = '{' + $first = '' + # Interact with query parameters or the body of the request. + $tenantfilter = $Request.Query.TenantFilter + $IncidentFilter = $Request.Query.GUID + $Status = $Request.Query.Status + $Assigned = $Request.Query.Assigned + $Classification = $Request.Query.Classification + $Determination = $Request.Query.Determination + $Redirected = $Request.Query.Redirected -as [int] + $BodyBuild + $AssignBody = '{' - try { - # We won't update redirected incidents because the incident it is redirected to should instead be updated - if ($Redirected -lt 1) { - # Set received status - if ($null -ne $Status) { - $AssignBody += $first + '"status":"' + $Status + '"' - $BodyBuild += $first + 'Set status for incident to ' + $Status - $first = ', ' - } + try { + # We won't update redirected incidents because the incident it is redirected to should instead be updated + if ($Redirected -lt 1) { + # Set received status + if ($null -ne $Status) { + $AssignBody += $first + '"status":"' + $Status + '"' + $BodyBuild += $first + 'Set status for incident to ' + $Status + $first = ', ' + } - # Set received classification and determination - if ($null -ne $Classification) { - if ($null -eq $Determination) { - # Maybe some poindexter tries to send a classification without a determination - throw - } + # Set received classification and determination + if ($null -ne $Classification) { + if ($null -eq $Determination) { + # Maybe some poindexter tries to send a classification without a determination + throw + } - $AssignBody += $first + '"classification":"' + $Classification + '", "determination":"' + $Determination + '"' - $BodyBuild += $first + 'Set classification & determination for incident to ' + $Classification + ' ' + $Determination - $first = ', ' - } + $AssignBody += $first + '"classification":"' + $Classification + '", "determination":"' + $Determination + '"' + $BodyBuild += $first + 'Set classification & determination for incident to ' + $Classification + ' ' + $Determination + $first = ', ' + } - # Set received asignee - if ($null -ne $Assigned) { - $AssignBody += $first + '"assignedTo":"' + $Assigned + '"' - if ($null -eq $Status) { - $BodyBuild += $first + 'Set assigned for incident to ' + $Assigned - } - $first = ', ' - } + # Set received asignee + if ($null -ne $Assigned) { + $AssignBody += $first + '"assignedTo":"' + $Assigned + '"' + if ($null -eq $Status) { + $BodyBuild += $first + 'Set assigned for incident to ' + $Assigned + } + $first = ', ' + } - $AssignBody += '}' + $AssignBody += '}' - $ResponseBody = [pscustomobject]@{'Results' = $BodyBuild } - New-Graphpostrequest -uri "https://graph.microsoft.com/beta/security/incidents/$IncidentFilter" -type PATCH -tenantid $TenantFilter -body $Assignbody -asApp $true - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Update incident $IncidentFilter with values $Assignbody" -Sev 'Info' - } else { - $ResponseBody = [pscustomobject]@{'Results' = 'Cannot update redirected incident' } - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Refuse to pdate incident $IncidentFilter with values $Assignbody because it is redirected to another incident" -Sev 'Info' - } + $ResponseBody = [pscustomobject]@{'Results' = $BodyBuild } + New-Graphpostrequest -uri "https://graph.microsoft.com/beta/security/incidents/$IncidentFilter" -type PATCH -tenantid $TenantFilter -body $Assignbody -asApp $true + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Update incident $IncidentFilter with values $Assignbody" -Sev 'Info' + } else { + $ResponseBody = [pscustomobject]@{'Results' = 'Cannot update redirected incident' } + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Refuse to pdate incident $IncidentFilter with values $Assignbody because it is redirected to another incident" -Sev 'Info' + } - $body = $ResponseBody - } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Failed to update alert $($AlertFilter): $($_.Exception.Message)" -Sev 'Error' - $body = [pscustomobject]@{'Results' = "Failed to update incident: $($_.Exception.Message)" } - } + $body = $ResponseBody + } catch { + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantfilter) -message "Failed to update alert $($AlertFilter): $($_.Exception.Message)" -Sev 'Error' + $body = [pscustomobject]@{'Results' = "Failed to update incident: $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $body - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 index 34b9bda58208..ea3412dd22b4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddTeam { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Teams.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,7 +20,7 @@ Function Invoke-AddTeam { $Owners = ($userobj.owner).Split([Environment]::NewLine) | Where-Object { $_ -ne $null -or $_ -ne '' } try { - + $Owners = $Owners | ForEach-Object { $OwnerID = "https://graph.microsoft.com/beta/users('" + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$_" -tenantid $Userobj.tenantid).id + "')" @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSetSharePointMember.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSetSharePointMember.ps1 index 0a031a0af5d3..c52f4c1b1409 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSetSharePointMember.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSetSharePointMember.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSetSharePointMember { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Sharepoint.Site.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSharePointOwner.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSharePointOwner.ps1 index 398f070db9ee..542dfb665b9f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSharePointOwner.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecSharePointOwner.ps1 @@ -1,26 +1,28 @@ using namespace System.Net Function Invoke-ExecSharePointOwner { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Sharepoint.Site.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - $tenantFilter = $Request.Body.TenantFilter - try { - $State = Set-CIPPSharePointOwner -tenantFilter $tenantFilter -userid $request.body.UPN -OnedriveAccessUser $request.body.input -ExecutingUser $ExecutingUser -APIName $APIName -RemovePermission $request.body.RemovePermission -URL $Request.Body.URL - $Results = [pscustomobject]@{'Results' = "$State" } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + $APIName = $TriggerMetadata.FunctionName + $tenantFilter = $Request.Body.TenantFilter + try { + $State = Set-CIPPSharePointOwner -tenantFilter $tenantFilter -userid $request.body.UPN -OnedriveAccessUser $request.body.input -ExecutingUser $ExecutingUser -APIName $APIName -RemovePermission $request.body.RemovePermission -URL $Request.Body.URL + $Results = [pscustomobject]@{'Results' = "$State" } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 index e769c7ee9879..2b04807cd4e1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSharepointSettings { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Sharepoint.Admin.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -21,7 +23,7 @@ Function Invoke-ListSharepointSettings { $USERToGet = $Request.query.usertoGet $body = '{"isResharingByExternalUsersEnabled": "False"}' $Request = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -Type patch -Body $body -ContentType 'application/json' - + Write-LogMessage -API 'Standards' -tenant $tenantFilter -message 'Disabled Password Expiration' -sev Info # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSites.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSites.ps1 index 48f3f8badb80..7b5ac0cd37b7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSites.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSites.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSites { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Sharepoint.Site.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -20,7 +22,7 @@ Function Invoke-ListSites { $type = $request.query.Type $UserUPN = $request.query.UserUPN try { - $Result = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/get$($type)Detail(period='D7')" -tenantid $TenantFilter | ConvertFrom-Csv + $Result = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/get$($type)Detail(period='D7')" -tenantid $TenantFilter | ConvertFrom-Csv if ($UserUPN) { $ParsedRequest = $Result | Where-Object { $_.'Owner Principal Name' -eq $UserUPN } @@ -37,7 +39,7 @@ Function Invoke-ListSites { @{ Name = 'Template'; Expression = { $_.'Root Web Template' } }, @{ Name = 'siteid'; Expression = { $_.'site Id' } } - #Temporary workaround for url as report is broken. + #Temporary workaround for url as report is broken. #This API is so stupid its great. $URLs = (New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/sites/getAllSites?$select=SharePointIds' -asapp $true -tenantid $TenantFilter).SharePointIds diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 index c5969ad1d8ae..743568fe8bed 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTeams { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Teams.Group.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -37,7 +39,7 @@ Function Invoke-ListTeams { Members = @($Members) Owners = @($owners) InstalledApps = @($AppsList) - } + } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 index 944fb90c7bf7..426131cc047d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 @@ -3,12 +3,14 @@ using namespace System.Net Function Invoke-ListTeamsActivity { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Teams.Activity.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - + # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 index ef5e1ca9d3d2..ec33ee67e86e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTeamsVoice { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Teams.Voice.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -24,11 +26,11 @@ Function Invoke-ListTeamsVoice { $CompleteRequest = $_ | Select-Object *, 'AssignedTo' $CompleteRequest.AcquisitionDate = $CompleteRequest.AcquisitionDate -split 'T' | Select-Object -First 1 - if ($CompleteRequest.TargetId -eq '00000000-0000-0000-0000-000000000000') { + if ($CompleteRequest.TargetId -eq '00000000-0000-0000-0000-000000000000') { $CompleteRequest.AssignedTo = 'Unassigned' } else { $CompleteRequest.AssignedTo = ($users | Where-Object -Property Id -EQ $CompleteRequest.TargetId).userPrincipalName - + } $CompleteRequest } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 index ab279d752d81..2cbba9b5fa42 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 index 4cbcff576e97..9b0e5aab48bb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAlertsQueue { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -15,29 +17,42 @@ Function Invoke-ListAlertsQueue { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' $WebhookTable = Get-CIPPTable -TableName 'WebhookRules' - $WebhookRules = Get-CIPPAzDataTableEntity @WebhookTable + $WebhookRules = Get-CIPPAzDataTableEntity @WebhookTable $ScheduledTasks = Get-CIPPTable -TableName 'ScheduledTasks' $ScheduledTasks = Get-CIPPAzDataTableEntity @ScheduledTasks | Where-Object { $_.hidden -eq $true } + $AllowedTenants = Test-CIPPAccess -Request $Request -TenantList + $TenantList = Get-Tenants -IncludeErrors $AllTasksArrayList = [system.collections.generic.list[object]]::new() foreach ($Task in $WebhookRules) { $Conditions = $Task.Conditions | ConvertFrom-Json -ErrorAction SilentlyContinue $TranslatedConditions = ($Conditions | ForEach-Object { "When $($_.Property.label) is $($_.Operator.label) $($_.input.value)" }) -join ' and ' $TranslatedActions = ($Task.Actions | ConvertFrom-Json -ErrorAction SilentlyContinue).label -join ',' + $Tenants = ($Task.Tenants | ConvertFrom-Json -ErrorAction SilentlyContinue).fullValue $TaskEntry = [PSCustomObject]@{ - Tenants = ($Task.Tenants | ConvertFrom-Json -ErrorAction SilentlyContinue).fullValue.defaultDomainName -join ',' + Tenants = $Tenants.defaultDomainName -join ',' Conditions = $TranslatedConditions - Actions = $TranslatedActions + Actions = $TranslatedActions LogType = $Task.type EventType = 'Audit log Alert' RowKey = $Task.RowKey PartitionKey = $Task.PartitionKey RepeatsEvery = 'When received' } - $AllTasksArrayList.Add($TaskEntry) - } + + if ($AllowedTenants -notcontains 'AllTenants') { + foreach ($Tenant in $Tenants) { + if ($AllowedTenants -contains $Tenant.customerId) { + $AllTasksArrayList.Add($TaskEntry) + break + } + } + } else { + $AllTasksArrayList.Add($TaskEntry) + } + } foreach ($Task in $ScheduledTasks) { $TaskEntry = [PSCustomObject]@{ @@ -50,7 +65,14 @@ Function Invoke-ListAlertsQueue { EventType = 'Scheduled Task' RepeatsEvery = $Task.Recurrence } - $AllTasksArrayList.Add($TaskEntry) + if ($AllowedTenants -notcontains 'AllTenants') { + $Tenant = $TenantList | Where-Object -Property defaultDomainName -EQ $Task.Tenant + if ($AllowedTenants -contains $Tenant.customerId) { + $AllTasksArrayList.Add($TaskEntry) + } + } else { + $AllTasksArrayList.Add($TaskEntry) + } } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 index d585504f4254..1741ed98fcaf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListWebhookAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-PublicWebhooks.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-PublicWebhooks.ps1 index a65084e28bdc..d4633158b895 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-PublicWebhooks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-PublicWebhooks.ps1 @@ -79,7 +79,7 @@ function Invoke-PublicWebhooks { Conditions = $_.Conditions Actions = $_.Actions LogType = $_.Type - } + } } if (!$Configuration.Tenants) { Write-Host 'No tenants found for this webhook, probably an old entry. Skipping.' @@ -99,22 +99,22 @@ function Invoke-PublicWebhooks { $ProcessedData = foreach ($Data in $PreProccessedData) { if ($Data.ExtendedProperties) { $Data.CIPPExtendedProperties = ($Data.ExtendedProperties | ConvertTo-Json) - $Data.ExtendedProperties | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } + $Data.ExtendedProperties | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } } - if ($Data.DeviceProperties) { + if ($Data.DeviceProperties) { $Data.CIPPDeviceProperties = ($Data.DeviceProperties | ConvertTo-Json) - $Data.DeviceProperties | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } + $Data.DeviceProperties | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } } - if ($Data.parameters) { + if ($Data.parameters) { $Data.CIPPParameters = ($Data.parameters | ConvertTo-Json) - $Data.parameters | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } + $Data.parameters | ForEach-Object { $data | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force -ErrorAction SilentlyContinue } } - if ($Data.ModifiedProperties) { + if ($Data.ModifiedProperties) { $Data.CIPPModifiedProperties = ($Data.ModifiedProperties | ConvertTo-Json) - $Data.ModifiedProperties | ForEach-Object { $data | Add-Member -NotePropertyName "$($_.Name)" -NotePropertyValue "$($_.NewValue)" -Force -ErrorAction SilentlyContinue } + $Data.ModifiedProperties | ForEach-Object { $data | Add-Member -NotePropertyName "$($_.Name)" -NotePropertyValue "$($_.NewValue)" -Force -ErrorAction SilentlyContinue } } if ($Data.ModifiedProperties) { $Data.ModifiedProperties | ForEach-Object { $data | Add-Member -NotePropertyName $("Previous_Value_$($_.Name)") -NotePropertyValue "$($_.OldValue)" -Force -ErrorAction SilentlyContinue } } - + if ($data.clientip) { if ($data.clientip -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { $data.clientip = $data.clientip -replace ':\d+$', '' # Remove the port number if present @@ -150,7 +150,7 @@ function Invoke-PublicWebhooks { $null = Add-CIPPAzDataTableEntity @LocationTable -Entity $LocationInfo -Force } catch { Write-Host "Webhook: Failed to add location info for $($data.clientip) to cache: $($_.Exception.Message)" - + } } $Data.CIPPGeoLocation = $Country @@ -165,12 +165,12 @@ function Invoke-PublicWebhooks { #Filter data based on conditions. $Where = $Configuration | ForEach-Object { $conditions = $_.Conditions | ConvertFrom-Json | Where-Object { $_.Input.value -ne '' } - $actions = $_.Actions + $actions = $_.Actions $conditionStrings = foreach ($condition in $conditions) { - $value = if ($condition.Input.value -is [array]) { + $value = if ($condition.Input.value -is [array]) { $arrayAsString = $condition.Input.value | ForEach-Object { - "'$_'" - } + "'$_'" + } "@($($arrayAsString -join ', '))" } else { "'$($condition.Input.value)'" } "`$(`$_.$($condition.Property.label)) -$($condition.Operator.value) $value" @@ -184,9 +184,9 @@ function Invoke-PublicWebhooks { clause = $finalCondition expectedAction = $actions } - + } - Write-Host "Webhook: The list of operations in the data are $($ProcessedData.operation -join ', ')" + Write-Host "Webhook: The list of operations in the data are $($ProcessedData.operation -join ', ')" $DataToProcess = foreach ($clause in $Where) { Write-Host "Webhook: Processing clause: $($clause.clause)" diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 index 7552c2afe222..3a52f5dacdfd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveQueuedAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -24,7 +26,7 @@ Function Invoke-RemoveQueuedAlert { $Alert = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey Remove-AzDataTableEntity @Table -Entity $Alert Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Removed application queue for $ID." -Sev 'Info' - + $body = [pscustomobject]@{'Results' = 'Successfully removed from queue.' } } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to remove from queue $ID. $($_.Exception.Message)" -Sev 'Error' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 index ef76692431bb..08124ad41683 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 @@ -4,6 +4,8 @@ function Invoke-ExecAddMultiTenantApp { <# .FUNCTIONALITY Entrypoint + .ROLE + Tenant.Application.ReadWrite #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 index 561d060eb99b..b79ef41afb72 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecAppApproval { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Application.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-ExecAppApproval { Write-Host "$($Request.query.ID)" # Interact with query parameters or the body of the request. - $applicationid = if ($request.query.applicationid) { $request.query.applicationid } else { $env:ApplicationID } + $applicationid = if ($request.query.applicationid) { $request.query.applicationid } else { $env:ApplicationID } $Results = get-tenants | ForEach-Object { [PSCustomObject]@{ defaultDomainName = $_.defaultDomainName diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 index de779bfe083d..b52867e7f0da 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 @@ -1,29 +1,31 @@ using namespace System.Net Function Invoke-ExecAddSPN { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - $Body = if ($Request.Query.Enable) { '{"accountEnabled":"true"}' } else { '{"accountEnabled":"false"}' } - try { - $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -tenantid $ENV:TenantID -type POST -Body "{ `"appId`": `"2832473f-ec63-45fb-976f-5d45a7d4bb91`" }" -NoAuthCheck $true - $Results = [pscustomobject]@{'Results' = "Successfully completed request. Add your GDAP migration permissions to your SAM application here: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnAPI/appId/$($ENV:ApplicationID)/isMSAApp/ " } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed to add SPN. Please manually execute 'New-AzureADServicePrincipal -AppId 2832473f-ec63-45fb-976f-5d45a7d4bb91' The error was $($_.Exception.Message)" } - } + # Interact with query parameters or the body of the request. + $Body = if ($Request.Query.Enable) { '{"accountEnabled":"true"}' } else { '{"accountEnabled":"false"}' } + try { + $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -tenantid $ENV:TenantID -type POST -Body "{ `"appId`": `"2832473f-ec63-45fb-976f-5d45a7d4bb91`" }" -NoAuthCheck $true + $Results = [pscustomobject]@{'Results' = "Successfully completed request. Add your GDAP migration permissions to your SAM application here: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnAPI/appId/$($ENV:ApplicationID)/isMSAApp/ " } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed to add SPN. Please manually execute 'New-AzureADServicePrincipal -AppId 2832473f-ec63-45fb-976f-5d45a7d4bb91' The error was $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 index 7b02b9aa1f74..adcb580e45cf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecOffboardTenant { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -23,7 +25,7 @@ Function Invoke-ExecOffboardTenant { try { try { $domains = (New-GraphGETRequest -Uri "https://graph.microsoft.com/v1.0/domains?`$select=id" -tenantid $env:TenantID -NoAuthCheck:$true).id - $CSPGuestUsers = (New-GraphGETRequest -Uri "https://graph.microsoft.com/v1.0/users?`$select=id,mail&`$filter=userType eq 'Guest' and $(($domains | ForEach-Object { "endswith(mail, '$_')" }) -join ' or ')&`$count=true" -tenantid $Tenantfilter -ComplexFilter) + $CSPGuestUsers = (New-GraphGETRequest -Uri "https://graph.microsoft.com/v1.0/users?`$select=id,mail&`$filter=userType eq 'Guest' and $(($domains | ForEach-Object { "endswith(mail, '$_')" }) -join ' or ')&`$count=true" -tenantid $Tenantfilter -ComplexFilter) } catch { $errors.Add("Failed to retrieve guest users: $($_.Exception.message)") } @@ -57,28 +59,28 @@ Function Invoke-ExecOffboardTenant { } catch { throw "Failed to retrieve CSP domains: $($_.Exception.message)" } - + try { # Get /organization data $orgContacts = New-GraphGETRequest -Uri "https://graph.microsoft.com/v1.0/organization?`$select=id,marketingNotificationEmails,securityComplianceNotificationMails,technicalNotificationMails" -tenantid $TenantFilter - + } catch { throw "Failed to retrieve CSP domains: $($_.Exception.message)" } } catch { $errors.Add("$($_.Exception.message)") } - + # foreach through the properties we want to check/update @('marketingNotificationEmails','securityComplianceNotificationMails','technicalNotificationMails') | ForEach-Object { $property = $_ $propertyContacts = $orgContacts.($($property)) - + if ($propertyContacts -AND ($domains -notcontains ($propertyContacts | ForEach-Object { $_.Split("@")[1] }))) { $newPropertyContent = [System.Collections.Generic.List[object]]($propertyContacts | Where-Object { $domains -notcontains $_.Split("@")[1] }) - + $patchContactBody = if (!($newPropertyContent)) { "{ `"$($property)`" : [] }" } else { [pscustomobject]@{ $property = $newPropertyContent } | ConvertTo-Json } - + try { New-GraphPostRequest -type PATCH -body $patchContactBody -Uri "https://graph.microsoft.com/v1.0/organization/$($orgContacts.id)" -tenantid $Tenantfilter -ContentType "application/json" $results.Add("Succesfully removed notification contacts from $($property): $(($propertyContacts | Where-Object { $domains -contains $_.Split("@")[1] }))") @@ -91,9 +93,9 @@ Function Invoke-ExecOffboardTenant { } } # Add logic for privacyProfile later - rvdwegen - + } - + if ($request.body.RemoveVendorApps) { $request.body.RemoveVendorApps | ForEach-Object { try { @@ -104,7 +106,7 @@ Function Invoke-ExecOffboardTenant { #$results.Add("Failed to removed app $($_.displayName)") $errors.Add("Failed to removed app $($_.label)") } - } + } } # All customer tenant specific actions ALWAYS have to be completed before this action! diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 index 84492fe68a70..10c11f90575a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 @@ -4,6 +4,8 @@ function Invoke-ExecOnboardTenant { <# .FUNCTIONALITY Entrypoint + .ROLE + Tenant.Administration.ReadWrite #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListAppConsentRequests.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListAppConsentRequests.ps1 index 9cfc10853e23..7e8a8603896d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListAppConsentRequests.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListAppConsentRequests.ps1 @@ -3,14 +3,16 @@ using namespace System.Net function Invoke-ListAppConsentRequests { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.Read #> param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName $TenantFilter = $Request.Query.TenantFilter Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - + try { if ($Request.Query.TenantFilter -eq 'AllTenants') { throw 'AllTenants is not yet supported' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListTenantOnboarding.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListTenantOnboarding.ps1 index c3fbd33947af..f8821c051a8a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListTenantOnboarding.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListTenantOnboarding.ps1 @@ -1,4 +1,10 @@ function Invoke-ListTenantOnboarding { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Tenant.Administration.Read + #> Param( $Request, $TriggerMetadata diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-UpdateSecureScore.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-UpdateSecureScore.ps1 index b1ffb9bee098..26bc7332a928 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-UpdateSecureScore.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-UpdateSecureScore.ps1 @@ -1,33 +1,35 @@ using namespace System.Net Function Invoke-ExecUpdateSecureScore { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - $Body = @{ - comment = $request.body.reason - state = $request.body.resolutionType - vendorInformation = $request.body.vendorInformation - } - try { - $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/security/secureScoreControlProfiles/$($Request.body.ControlName)" -tenantid $Request.body.TenantFilter -type PATCH -Body $($Body | ConvertTo-Json -Compress) - $Results = [pscustomobject]@{'Results' = "Succesfully set control to $($body.state) " } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed to set Control to $($body.state) $($_.Exception.Message)" } - } + # Interact with query parameters or the body of the request. + $Body = @{ + comment = $request.body.reason + state = $request.body.resolutionType + vendorInformation = $request.body.vendorInformation + } + try { + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/security/secureScoreControlProfiles/$($Request.body.ControlName)" -tenantid $Request.body.TenantFilter -type PATCH -Body $($Body | ConvertTo-Json -Compress) + $Results = [pscustomobject]@{'Results' = "Succesfully set control to $($body.state) " } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed to set Control to $($body.state) $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 index 77db47a5ff51..fe98eae2eee1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditTenant { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -30,11 +32,11 @@ Function Invoke-EditTenant { if ($tenantObjectId) { try { $bodyToPatch = '{"displayName":"' + $tenantDisplayName + '","defaultDomainName":"' + $tenantDefaultDomainName + '"}' - $patchTenant = (Invoke-RestMethod -Method PATCH -Uri "https://graph.windows.net/myorganization/contracts/$($tenantObjectId.objectId)?api-version=1.6" -Body $bodyToPatch -ContentType 'application/json' -Headers $AADGraphtoken -ErrorAction Stop) + $patchTenant = (Invoke-RestMethod -Method PATCH -Uri "https://graph.windows.net/myorganization/contracts/$($tenantObjectId.objectId)?api-version=1.6" -Body $bodyToPatch -ContentType 'application/json' -Headers $AADGraphtoken -ErrorAction Stop) $Filter = "PartitionKey eq 'Tenants' and defaultDomainName eq '{0}'" -f $tenantDefaultDomainName try { $TenantsTable = Get-CippTable -tablename Tenants - $Tenant = Get-CIPPAzDataTableEntity @TenantsTable -Filter $Filter + $Tenant = Get-CIPPAzDataTableEntity @TenantsTable -Filter $Filter $Tenant.displayName = $tenantDisplayName Update-AzDataTableEntity @TenantsTable -Entity $Tenant } @@ -44,7 +46,7 @@ Function Invoke-EditTenant { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenantDisplayName -message "Edited tenant $tenantDisplayName" -Sev 'Info' $results = "Successfully amended details for $($Tenant.displayName) $AddedText" } - catch { + catch { $results = "Failed to amend details for $tenantDisplayName : $($_.Exception.Message)" Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenantDisplayName -message "Failed amending details $tenantDisplayName. Error:$($_.Exception.Message)" -Sev 'Error' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenantDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenantDetails.ps1 index 9aa191e2e44f..001c8ac2cbcd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenantDetails.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenantDetails.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTenantDetails { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -44,6 +46,6 @@ Function Invoke-ListTenantDetails { StatusCode = [HttpStatusCode]::OK Body = $Body }) - + } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenants.ps1 index 3c183a98af86..67b0d6562ec7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-ListTenants.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTenants { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,7 +13,13 @@ Function Invoke-ListTenants { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $TenantAccess = Test-CIPPAccess -Request $Request -TenantList + if ($TenantAccess -notcontains 'AllTenants') { + $AllTenantSelector = $false + } else { + $AllTenantSelector = $Request.Query.AllTenantSelector + } # Clear Cache if ($request.Query.ClearCache -eq 'true') { @@ -30,10 +38,13 @@ Function Invoke-ListTenants { try { $tenantfilter = $Request.Query.TenantFilter $Tenants = Get-Tenants -IncludeErrors -SkipDomains + if ($TenantAccess -notcontains 'AllTenants') { + $Tenants = $Tenants | Where-Object -Property customerId -In $TenantAccess + } if ($null -eq $TenantFilter -or $TenantFilter -eq 'null') { $TenantList = [system.collections.generic.list[object]]::new() - if ($Request.Query.AllTenantSelector -eq $true) { + if ($AllTenantSelector -eq $true) { $TenantList.Add(@{ customerId = 'AllTenants' defaultDomainName = 'AllTenants' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 index 547828a337f4..7ced88078c10 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddCAPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 index b6de2ac40ed3..b0f64582c5c4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddCATemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -12,14 +14,14 @@ Function Invoke-AddCATemplate { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $Request.Query.TenantFilter - try { + try { $GUID = (New-Guid).GUID $JSON = if ($request.body.rawjson) { ConvertFrom-Json -InputObject ([pscustomobject]$request.body.rawjson) } else { ([pscustomobject]$Request.body) | ForEach-Object { $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name - $_ | Select-Object -Property $NonEmptyProperties + $_ | Select-Object -Property $NonEmptyProperties } } @@ -85,7 +87,7 @@ Function Invoke-AddCATemplate { } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created CA Template $($Request.body.name) with GUID $GUID" -Sev 'Debug' $body = [pscustomobject]@{'Results' = 'Successfully added template' } - + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create CA Template: $($_.Exception.Message)" -Sev 'Error' $body = [pscustomobject]@{'Results' = "Intune Template Deployment failed: $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 index 578b196ed014..47dd98aa75dd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddNamedLocation { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 index fb804f8fbfe1..e3baf6e4a607 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-EditCAPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 index 137c55a9c28b..9bdd61686269 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecCaCheck { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -42,7 +44,7 @@ Function Invoke-ExecCaCheck { $JSONBody = $ConditionalAccessWhatIfDefinition | ConvertTo-Json -Depth 10 Write-Host $JSONBody $Request = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/evaluate' -tenantid $tenant -type POST -body $JsonBody -AsApp $true - $Request + $Request } catch { "Failed to execute check: $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 index 4dafed5af25a..86d06bf95796 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecCAExclusion { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -46,6 +48,6 @@ Function Invoke-ExecCAExclusion { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = $Body - }) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 index 14ec616c0616..7f4be467dd3a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListCAtemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -29,11 +31,11 @@ Function Invoke-ListCAtemplates { #List new policies $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'CATemplate'" + $Filter = "PartitionKey eq 'CATemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $data = $_.JSON | ConvertFrom-Json -Depth 100 $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force - $data + $data } | Sort-Object -Property displayName if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property GUID -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 index c093a8c4f009..337fc9c46ace 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 @@ -1,458 +1,455 @@ - using namespace System.Net +using namespace System.Net - Function Invoke-ListConditionalAccessPolicies { +Function Invoke-ListConditionalAccessPolicies { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' -function Get-LocationNameFromId { - [CmdletBinding()] - param ( - [Parameter()] - $ID, - - [Parameter(Mandatory = $true)] - $Locations - ) - if ($id -eq 'All') { - return 'All' - } - $DisplayName = $Locations | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName - if ([string]::IsNullOrEmpty($displayName)) { - return $ID - } - else { - return $DisplayName - } -} - -function Get-RoleNameFromId { - [CmdletBinding()] - param ( - [Parameter()] - $ID, - - [Parameter(Mandatory = $true)] - $RoleDefinitions - ) - if ($id -eq 'All') { - return 'All' - } - $DisplayName = $RoleDefinitions | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName - if ([string]::IsNullOrEmpty($displayName)) { - return $ID - } - else { - return $DisplayName - } -} + function Get-LocationNameFromId { + [CmdletBinding()] + param ( + [Parameter()] + $ID, -function Get-UserNameFromId { - [CmdletBinding()] - param ( - [Parameter()] - $ID, - - [Parameter(Mandatory = $true)] - $Users - ) - if ($id -eq 'All') { - return 'All' - } - $DisplayName = $Users | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName - if ([string]::IsNullOrEmpty($displayName)) { - return $ID - } - else { - return $DisplayName + [Parameter(Mandatory = $true)] + $Locations + ) + if ($id -eq 'All') { + return 'All' + } + $DisplayName = $Locations | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName + if ([string]::IsNullOrEmpty($displayName)) { + return $ID + } else { + return $DisplayName + } } -} -function Get-GroupNameFromId { - param ( - [Parameter()] - $ID, + function Get-RoleNameFromId { + [CmdletBinding()] + param ( + [Parameter()] + $ID, - [Parameter(Mandatory = $true)] - $Groups - ) - if ($id -eq 'All') { - return 'All' - } - $DisplayName = $Groups | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName - if ([string]::IsNullOrEmpty($displayName)) { - return "No Data" - } - else { - return $DisplayName + [Parameter(Mandatory = $true)] + $RoleDefinitions + ) + if ($id -eq 'All') { + return 'All' + } + $DisplayName = $RoleDefinitions | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName + if ([string]::IsNullOrEmpty($displayName)) { + return $ID + } else { + return $DisplayName + } } -} -function Get-ApplicationNameFromId { - [CmdletBinding()] - param ( - [Parameter()] - $ID, - - [Parameter(Mandatory = $true)] - $Applications - ) - if ($id -eq 'All') { - return 'All' - } - switch ($id) { - 00000004-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Lync' } - 00000006-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Office365Portal' } - 00000003-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.SharePoint ' } - 00000005-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.Workflow' } - 00000009-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.AnalysisServices' } - 00000002-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Exchange' } - 00000007-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.ExchangeOnlineProtection' } - 00000002-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.ActiveDirectory' } - 8fca0a66-c008-4564-a876-ab3ae0fd5cff { $return = 'Microsoft.SMIT' } - 0000000b-0000-0000-c000-000000000000 { $return = 'Microsoft.SellerDashboard' } - 0000000f-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.GraphExplorer' } - 0000000c-0000-0000-c000-000000000000 { $return = 'Microsoft App Access Panel' } - 00000013-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.Portal' } - 00000010-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.GraphStore' } - 93ee9413-cf4c-4d4e-814b-a91ff20a01bd { $return = 'Workflow' } - aa9ecb1e-fd53-4aaa-a8fe-7a54de2c1334 { $return = 'Microsoft.Office365.Configure' } - 797f4846-ba00-4fd7-ba43-dac1f8f63013 { $return = 'Windows Azure Service Management API' } - 00000005-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.YammerEnterprise' } - 601d4e27-7bb3-4dee-8199-90d47d527e1c { $return = 'Microsoft.Office365.ChangeManagement' } - 6f82282e-0070-4e78-bc23-e6320c5fa7de { $return = 'Microsoft.DiscoveryService' } - 0f698dd4-f011-4d23-a33e-b36416dcb1e6 { $return = 'Microsoft.OfficeClientService' } - 67e3df25-268a-4324-a550-0de1c7f97287 { $return = 'Microsoft.OfficeWebAppsService' } - ab27a73e-a3ba-4e43-8360-8bcc717114d8 { $return = 'Microsoft.OfficeModernCalendar' } - aedca418-a84d-430d-ab84-0b1ef06f318f { $return = 'Workflow' } - 595d87a1-277b-4c0a-aa7f-44f8a068eafc { $return = 'Microsoft.SupportTicketSubmission' } - e3583ad2-c781-4224-9b91-ad15a8179ba0 { $return = 'Microsoft.ExtensibleRealUserMonitoring' } - b645896d-566e-447e-8f7f-e2e663b5d182 { $return = 'OpsDashSharePointApp' } - 48229a4a-9f1d-413a-8b96-4c02462c0360 { $return = 'OpsDashSharePointApp' } - 48717084-a59c-4306-9dc4-3f618dbecdf9 { $return = '"Napa" Office 365 Development Tools' } - c859ff33-eb41-4ba6-8093-a2c5153bbd7c { $return = 'Workflow' } - 67cad61c-3411-48d7-ab73-561c64f11ed6 { $return = 'Workflow' } - 914ed757-9257-4200-b68e-a2bed2f12c5a { $return = 'RbacBackfill' } - 499b84ac-1321-427f-aa17-267ca6975798 { $return = 'Microsoft.VisualStudio.Online' } - b2590339-0887-4e94-93aa-13357eb510d7 { $return = 'Workflow' } - 0000001b-0000-0000-c000-000000000000 { $return = 'Microsoft Power BI Information Service' } - 89f80565-bfac-4c01-9535-9f0eba332ffe { $return = 'Power BI' } - 433895fb-4ec7-45c3-a53c-c44d10f80d5b { $return = 'Compromised Account Service' } - d7c17728-4f1e-4a1e-86cf-7e0adf3fe903 { $return = 'Workflow' } - 17ef6d31-381f-4783-b186-7b440a3c85c1 { $return = 'Workflow' } - 00000012-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.RMS' } - 81ce94d4-9422-4c0d-a4b9-3250659366ce { $return = 'Workflow' } - 8d3a7d3c-c034-4f19-a2ef-8412952a9671 { $return = 'MicrosoftOffice' } - 0469d4cd-df37-4d93-8a61-f8c75b809164 { $return = 'Microsoft Policy Administration Service' } - 31d3f3f5-7267-45a8-9549-affb00110054 { $return = 'Windows Azure RemoteApp Service' } - 4e004241-32db-46c2-a86f-aaaba29bea9c { $return = 'Workflow' } - 748d098e-7a3b-436d-8b0a-006a58b29647 { $return = 'Workflow' } - dbf08535-1d3b-4f89-bf54-1d48dd613a61 { $return = 'Workflow' } - ed9fe1ef-25a4-482f-9981-2b60f91e2448 { $return = 'Workflow' } - 8ad28d50-ee26-42fc-8a29-e41ea38461f2 { $return = 'Office365RESTAPIExplorer.Office365App' } - 38285dce-a13d-4107-9b04-3016b941bb3a { $return = 'BasicDataOperationsREST' } - 92bb96c8-321c-47f9-bcc5-8849490c2b07 { $return = 'BasicSelfHostedAppREST' } - 488a57a0-00e2-4817-8c8d-cf8a15a994d2 { $return = 'WindowsFormsApplication2.Office365App' } - 11c174dc-1945-4a9a-a36b-c79a0f246b9b { $return = 'AzureApplicationInsights' } - e6acb561-0d94-4287-bd3a-3169f421b112 { $return = 'Tutum' } - 7b77b3a2-8490-49e1-8842-207cd0899af9 { $return = 'Nearpod' } - 0000000a-0000-0000-c000-000000000000 { $return = 'Microsoft.Intune' } - 93625bc8-bfe2-437a-97e0-3d0060024faa { $return = 'SelfServicePasswordReset' } - dee7ba80-6a55-4f3b-a86c-746a9231ae49 { $return = 'MicrosoftAppPlatEMA' } - 803ee9ca-3f7f-4824-bd6e-0b99d720c35c { $return = 'Azure Media Service' } - 2d4d3d8e-2be3-4bef-9f87-7875a61c29de { $return = 'OneNote' } - 8d40666e-5abf-45f6-a5e7-b7192d6d56ed { $return = 'Workflow' } - 262044b1-e2ce-469f-a196-69ab7ada62d3 { $return = 'Backup Management Service' } - 087a2c70-c89e-463f-8dd3-e3959eabb1a9 { $return = 'Microsoft Profile Service Platform Service' } - 7cd684f4-8a78-49b0-91ec-6a35d38739ba { $return = 'Azure Logic Apps' } - c5393580-f805-4401-95e8-94b7a6ef2fc2 { $return = 'Office 365 Management APIs' } - 96231a05-34ce-4eb4-aa6a-70759cbb5e83 { $return = 'MicrosoftAzureRedisCache' } - b8340c3b-9267-498f-b21a-15d5547fd85e { $return = 'Hyper-V Recovery Manager' } - abfa0a7c-a6b6-4736-8310-5855508787cd { $return = 'Microsoft.Azure.WebSites' } - c44b4083-3bb0-49c1-b47d-974e53cbdf3c { $return = 'IbizaPortal' } - 905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba { $return = 'Sway' } - b10686fd-6ba8-49f2-a3cd-67e4d2f52ac8 { $return = 'NovoEd' } - c606301c-f764-4e6b-aa45-7caaaea93c9a { $return = 'OfficeStore' } - 569e8598-685b-4ba2-8bff-5bced483ac46 { $return = 'Evercontact' } - 20a23a2f-8c32-4de7-8063-8c8f909602c0 { $return = 'Workflow' } - aaf214cc-8013-4b95-975f-13203ae36039 { $return = 'Power BI Tiles' } - d88a361a-d488-4271-a13f-a83df7dd99c2 { $return = 'IDML Graph Resolver Service and CAD' } - dff9b531-6290-4620-afce-26826a62a4e7 { $return = 'DocuSign' } - 01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9 { $return = 'Device Registration Service' } - 3290e3f7-d3ac-4165-bcef-cf4874fc4270 { $return = 'Smartsheet' } - a4ee6867-8640-4495-b1fd-8b26037a5bd3 { $return = 'Workflow' } - aa0e3dd4-df02-478d-869e-fc61dd71b6e8 { $return = 'Workflow' } - 0f6edad5-48f2-4585-a609-d252b1c52770 { $return = 'AIGraphClient' } - 0c8139b5-d545-4448-8d2b-2121bb242680 { $return = 'BillingExtension' } - 475226c6-020e-4fb2-8a90-7a972cbfc1d4 { $return = 'KratosAppsService' } - 39624784-6cbe-4a60-afbe-9f46d10fdb27 { $return = 'SkypeForBusinessRemotePowershell' } - 8bdebf23-c0fe-4187-a378-717ad86f6a53 { $return = 'ResourceHealthRP' } - c161e42e-d4df-4a3d-9b42-e7a3c31f59d4 { $return = 'MicrosoftIntuneAPI' } - 9cb77803-d937-493e-9a3b-4b49de3f5a74 { $return = 'MicrosoftIntuneServiceDiscovery' } - ddbf3205-c6bd-46ae-8127-60eb93363864 { $return = 'Microsoft Azure Batch' } - 80ccca67-54bd-44ab-8625-4b79c4dc7775 { $return = 'ComplianceCenter' } - 0a5f63c0-b750-4f38-a71c-4fc0d58b89e2 { $return = 'Microsoft Mobile Application Management' } - e1335bb1-2aec-4f92-8140-0e6e61ae77e5 { $return = 'CIWebService' } - 75018fbe-21fe-4a57-b63c-83252b5eaf16 { $return = 'TeamImprover - Team Organization Chart' } - a393296b-5695-4463-97cb-9fa8638a494a { $return = 'My SharePoint Sites' } - fe217466-5583-431c-9531-14ff7268b7b3 { $return = 'Microsoft Education' } - 5bfe8a29-054e-4348-9e7a-3981b26b125f { $return = 'Bing Places for Business' } - eaf8a961-f56e-47eb-9ffd-936e22a554ef { $return = 'DevilFish' } - 4b4b1d56-1f03-47d9-a0a3-87d4afc913c9 { $return = 'Wunderlist' } - 00000003-0000-0000-c000-000000000000 { $return = 'Microsoft Graph' } - 60e6cd67-9c8c-4951-9b3c-23c25a2169af { $return = 'Compute Resource Provider' } - 507bc9da-c4e2-40cb-96a7-ac90df92685c { $return = 'Office365Reports' } - 09abbdfd-ed23-44ee-a2d9-a627aa1c90f3 { $return = 'ProjectWorkManagement' } - 28ec9756-deaf-48b2-84d5-a623b99af263 { $return = 'Office Personal Assistant at Work Service' } - 9e4a5442-a5c9-4f6f-b03f-5b9fcaaf24b1 { $return = 'OfficeServicesManager' } - 3138fe80-4087-4b04-80a6-8866c738028a { $return = 'SharePoint Notification Service' } - d2a0a418-0aac-4541-82b2-b3142c89da77 { $return = 'MicrosoftAzureOperationalInsights' } - 2cf9eb86-36b5-49dc-86ae-9a63135dfa8c { $return = 'AzureTrafficManagerandDNS' } - 32613fc5-e7ac-4894-ac94-fbc39c9f3e4a { $return = 'OAuth Sandbox' } - 925eb0d0-da50-4604-a19f-bd8de9147958 { $return = 'Groupies Web Service' } - e4ab13ed-33cb-41b4-9140-6e264582cf85 { $return = 'Azure SQL Database Backup To Azure Backup Vault' } - ad230543-afbe-4bb4-ac4f-d94d101704f8 { $return = 'Apiary for Power BI' } - 11cd3e2e-fccb-42ad-ad00-878b93575e07 { $return = 'Automated Call Distribution' } - de17788e-c765-4d31-aba4-fb837cfff174 { $return = 'Skype for Business Management Reporting and Analytics' } - 65d91a3d-ab74-42e6-8a2f-0add61688c74 { $return = 'Microsoft Approval Management' } - 5225545c-3ebd-400f-b668-c8d78550d776 { $return = 'Office Agent Service' } - 1cda9b54-9852-4a5a-96d4-c2ab174f9edf { $return = 'O365Account' } - 4747d38e-36c5-4bc3-979b-b0ef74df54d1 { $return = 'PushChannel' } - b97b6bd4-a49f-4a0c-af18-af507d1da76c { $return = 'Office Shredding Service' } - d4ebce55-015a-49b5-a083-c84d1797ae8c { $return = 'Microsoft Intune Enrollment' } - 5b20c633-9a48-4a5f-95f6-dae91879051f { $return = 'Azure Information Protection' } - 441509e5-a165-4363-8ee7-bcf0b7d26739 { $return = 'EnterpriseAgentPlatform' } - e691bce4-6612-4025-b94c-81372a99f77e { $return = 'Boomerang' } - 8edd93e1-2103-40b4-bd70-6e34e586362d { $return = 'Windows Azure Security Resource Provider' } - 94c63fef-13a3-47bc-8074-75af8c65887a { $return = 'Office Delve' } - e95d8bee-4725-4f59-910d-94d415da51b9 { $return = 'Skype for Business Name Dictionary Service' } - e3c5dbcd-bb5f-4bda-b943-adc7a5bbc65e { $return = 'Workflow' } - 8602e328-9b72-4f2d-a4ae-1387d013a2b3 { $return = 'Azure API Management' } - 8b3391f4-af01-4ee8-b4ea-9871b2499735 { $return = 'O365 Secure Score' } - c26550d6-bc82-4484-82ca-ac1c75308ca3 { $return = 'Office 365 YammerOnOls' } - 33be1cef-03fb-444b-8fd3-08ca1b4d803f { $return = 'OneDrive Web' } - dcad865d-9257-4521-ad4d-bae3e137b345 { $return = 'Microsoft SharePoint Online - SharePoint Home' } - b2cc270f-563e-4d8a-af47-f00963a71dcd { $return = 'OneProfile Service' } - 4660504c-45b3-4674-a709-71951a6b0763 { $return = 'Microsoft Invitation Acceptance Portal' } - ba23cd2a-306c-48f2-9d62-d3ecd372dfe4 { $return = 'OfficeGraph' } - d52485ee-4609-4f6b-b3a3-68b6f841fa23 { $return = 'On-Premises Data Gateway Connector' } - 996def3d-b36c-4153-8607-a6fd3c01b89f { $return = 's 365 for Financials' } - b6b84568-6c01-4981-a80f-09da9a20bbed { $return = 'Microsoft Invoicing' } - 9d3e55ba-79e0-4b7c-af50-dc460b81dca1 { $return = 'Microsoft Azure Data Catalog' } - 4345a7b9-9a63-4910-a426-35363201d503 { $return = 'O365 Suite UX' } - ac815d4a-573b-4174-b38e-46490d19f894 { $return = 'Workflow' } - bb8f18b0-9c38-48c9-a847-e1ef3af0602d { $return = 'Microsoft.Azure.ActiveDirectoryIUX' } - cc15fd57-2c6c-4117-a88c-83b1d56b4bbe { $return = 'Microsoft Teams Services' } - 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 { $return = 'Skype Teams' } - 1fec8e78-bce4-4aaf-ab1b-5451cc387264 { $return = 'Microsoft Teams' } - 6d32b7f8-782e-43e0-ac47-aaad9f4eb839 { $return = 'Permission Service O365' } - cdccd920-384b-4a25-897d-75161a4b74c1 { $return = 'Skype Teams Firehose' } - 1c0ae35a-e2ec-4592-8e08-c40884656fa5 { $return = 'Skype Team Substrate connector' } - cf6c77f8-914f-4078-baef-e39a5181158b { $return = 'Skype Teams Settings Store' } - 64f79cb9-9c82-4199-b85b-77e35b7dcbcb { $return = 'Microsoft Teams Bots' } - b7912db9-aa33-4820-9d4f-709830fdd78f { $return = 'ConnectionsService' } - 82f77645-8a66-4745-bcdf-9706824f9ad0 { $return = 'PowerApps Runtime Service' } - 6204c1d1-4712-4c46-a7d9-3ed63d992682 { $return = 'Microsoft Flow Portal' } - 7df0a125-d3be-4c96-aa54-591f83ff541c { $return = 'Microsoft Flow Service' } - 331cc017-5973-4173-b270-f0042fddfd75 { $return = 'PowerAppsService' } - 0a0e9e37-25e3-47d4-964c-5b8237cad19a { $return = 'CloudSponge' } - df09ff61-2178-45d8-888c-4210c1c7b0b2 { $return = 'O365 UAP Processor' } - 8338dec2-e1b3-48f7-8438-20c30a534458 { $return = 'ViewPoint' } - 00000001-0000-0000-c000-000000000000 { $return = 'Azure ESTS Service' } - 394866fc-eedb-4f01-8536-3ff84b16be2a { $return = 'Microsoft People Cards Service' } - 0a0a29f9-0a25-49c7-94bf-c53c3f8fa69d { $return = 'Cortana Experience with O365' } - bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4 { $return = 'CPIM Service' } - 0004c632-673b-4105-9bb6-f3bbd2a927fe { $return = 'PowerApps and Flow' } - d3ce4cf8-6810-442d-b42e-375e14710095 { $return = 'Graph Explorer' } - 3aa5c166-136f-40eb-9066-33ac63099211 { $return = 'O365 Customer Monitoring' } - d6fdaa33-e821-4211-83d0-cf74736489e1 { $return = 'Microsoft Service Trust' } - ef4a2a24-4b4e-4abf-93ba-cc11c5bd442c { $return = 'Edmodo' } - b692184e-b47f-4706-b352-84b288d2d9ee { $return = 'Microsoft.MileIQ.RESTService' } - a25dbca8-4e60-48e5-80a2-0664fdb5c9b6 { $return = 'Microsoft.MileIQ' } - f7069a8d-9edc-4300-b365-ae53c9627fc4 { $return = 'Microsoft.MileIQ.Dashboard' } - 02e3ae74-c151-4bda-b8f0-55fbf341de08 { $return = 'Application Registration Portal' } - 1f5530b3-261a-47a9-b357-ded261e17918 { $return = 'Azure Multi-Factor Auth Connector' } - 981f26a1-7f43-403b-a875-f8b09b8cd720 { $return = 'Azure Multi-Factor Auth Client' } - 6ea8091b-151d-447a-9013-6845b83ba57b { $return = 'AD Hybrid Health' } - fc68d9e5-1f76-45ef-99aa-214805418498 { $return = 'Azure AD Identity Protection' } - 01fc33a7-78ba-4d2f-a4b7-768e336e890e { $return = 'MS-PIM' } - a6aa9161-5291-40bb-8c5c-923b567bee3b { $return = 'Storage Resource Provider' } - 4e9b8b9a-1001-4017-8dd1-6e8f25e19d13 { $return = 'Adobe Acrobat' } - 159b90bb-bb28-4568-ad7c-adad6b814a2f { $return = 'LastPass' } - b4bddae8-ab25-483e-8670-df09b9f1d0ea { $return = 'Signup' } - aa580612-c342-4ace-9055-8edee43ccb89 { $return = 'Microsoft StaffHub' } - 51133ff5-8e0d-4078-bcca-84fb7f905b64 { $return = 'Microsoft Teams Mailhook' } - ab3be6b7-f5df-413d-ac2d-abf1e3fd9c0b { $return = 'Microsoft Teams Graph Service' } - b1379a75-ce5e-4fa3-80c6-89bb39bf646c { $return = 'Microsoft Teams Chat Aggregator' } - 48af08dc-f6d2-435f-b2a7-069abd99c086 { $return = 'Connectors' } - d676e816-a17b-416b-ac1a-05ad96f43686 { $return = 'Workflow' } - cfa8b339-82a2-471a-a3c9-0fc0be7a4093 { $return = 'Azure Key Vault' } - c2f89f53-3971-4e09-8656-18eed74aee10 { $return = 'calendly' } - 6da466b6-1d13-4a2c-97bd-51a99e8d4d74 { $return = 'Exchange Office Graph Client for AAD - Interactive' } - 0eda3b13-ddc9-4c25-b7dd-2f6ea073d6b7 { $return = 'Microsoft Flow CDS Integration Service' } - eacba838-453c-4d3e-8c6a-eb815d3469a3 { $return = 'Microsoft Flow CDS Integration Service TIP1' } - 4ac7d521-0382-477b-b0f8-7e1d95f85ca2 { $return = 'SQL Server Analysis Services Azure' } - b4114287-89e4-4209-bd99-b7d4919bcf64 { $return = 'OfficeDelve' } - 4580fd1d-e5a3-4f56-9ad1-aab0e3bf8f76 { $return = 'Call Recorder' } - a855a166-fd92-4c76-b60d-a791e0762432 { $return = 'Microsoft Teams VSTS' } - c37c294f-eec8-47d2-b3e2-fc3daa8f77d3 { $return = 'Workflow' } - fc75330b-179d-49af-87dd-3b1acf6827fa { $return = 'AzureAutomationAADPatchS2S' } - 766d89a4-d6a6-444d-8a5e-e1a18622288a { $return = 'OneDrive' } - f16c4a38-5aff-4549-8199-ee7d3c5bd8dc { $return = 'Workflow' } - 4c4f550b-42b2-4a16-93f9-fdb9e01bb6ed { $return = 'Targeted Messaging Service' } - 765fe668-04e7-42ba-aec0-2c96f1d8b652 { $return = 'Exchange Office Graph Client for AAD - Noninteractive' } - 0130cc9f-7ac5-4026-bd5f-80a08a54e6d9 { $return = 'Azure Data Warehouse Polybase' } - a1cf9e0a-fe14-487c-beb9-dd3360921173 { $return = 'Meetup' } - 76cd24bf-a9fc-4344-b1dc-908275de6d6d { $return = 'Azure SQL Virtual Network to Network Resource Provider' } - 9f505dbd-a32c-4685-b1c6-72e4ef704cb0 { $return = 'Amazon Alexa' } - 1e2ca66a-c176-45ea-a877-e87f7231e0ee { $return = 'Microsoft B2B Admin Worker' } - 2634dd23-5e5a-431c-81ca-11710d9079f4 { $return = 'Microsoft Stream Service' } - cf53fce8-def6-4aeb-8d30-b158e7b1cf83 { $return = 'Microsoft Stream Portal' } - c9a559d2-7aab-4f13-a6ed-e7e9c52aec87 { $return = 'Microsoft Forms' } - 978877ea-b2d6-458b-80c7-05df932f3723 { $return = 'Microsoft Teams AuditService' } - dbc36ae1-c097-4df9-8d94-343c3d091a76 { $return = 'Service Encryption' } - fa7ff576-8e31-4a58-a5e5-780c1cd57caa { $return = 'OneNote' } - cb4dc29f-0bf4-402a-8b30-7511498ed654 { $return = 'Power BI Premium' } - f5aeb603-2a64-4f37-b9a8-b544f3542865 { $return = 'Microsoft Teams RetentionHook Service' } - da109bdd-abda-4c06-8808-4655199420f8 { $return = 'Glip Contacts' } - 76c7f279-7959-468f-8943-3954880e0d8c { $return = 'Azure SQL Managed Instance to Microsoft.Network' } - 3a9ddf38-83f3-4ea1-a33a-ecf934644e2d { $return = 'Protected Message Viewer' } - 5635d99c-c364-4411-90eb-764a511b5fdf { $return = 'Responsive Banner Slider' } - a43e5392-f48b-46a4-a0f1-098b5eeb4757 { $return = 'Cloudsponge' } - d73f4b35-55c9-48c7-8b10-651f6f2acb2e { $return = 'MCAPI Authorization Prod' } - 166f1b03-5b19-416f-a94b-1d7aa2d247dc { $return = 'Office Hive' } - b815ce1c-748f-4b1e-9270-a42c1fa4485a { $return = 'Workflow' } - bd7b778b-4aa8-4cde-8d90-8aeb821c0bd2 { $return = 'Workflow' } - 9d06afd9-66c9-49a6-b385-ea7509332b0b { $return = 'O365SBRM Service' } - 9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7 { $return = 'Bing' } - 57fb890c-0dab-4253-a5e0-7188c88b2bb4 { $return = 'SharePoint Online Client' } - 45c10911-200f-4e27-a666-9e9fca147395 { $return = 'drawio' } - b73f62d0-210b-4396-a4c5-ea50c4fab79b { $return = 'Skype Business Voice Fraud Detection and Prevention' } - bc59ab01-8403-45c6-8796-ac3ef710b3e3 { $return = 'Outlook Online Add-in App' } - 035f9e1d-4f00-4419-bf50-bf2d87eb4878 { $return = 'Azure Monitor Restricted' } - 7c33bfcb-8d33-48d6-8e60-dc6404003489 { $return = 'Network Watcher' } - a0be0c72-870e-46f0-9c49-c98333a996f7 { $return = 'AzureDnsFrontendApp' } - 1e3e4475-288f-4018-a376-df66fd7fac5f { $return = 'NetworkTrafficAnalyticsService' } - 7557eb47-c689-4224-abcf-aef9bd7573df { $return = 'Skype for Business' } - c39c9bac-9d1f-4dfb-aa29-27f6365e5cb7 { $return = 'Azure Advisor' } - 2087bd82-7206-4c0a-b305-1321a39e5926 { $return = 'Microsoft To-Do' } - f8d98a96-0999-43f5-8af3-69971c7bb423 { $return = 'iOS Accounts' } - c27373d3-335f-4b45-8af9-fe81c240d377 { $return = 'P2P Server' } - 5c2ffddc-f1d7-4dc3-926e-3c1bd98e32bd { $return = 'RITS Dev' } - 982bda36-4632-4165-a46a-9863b1bbcf7d { $return = 'O365 Demeter' } - 98c8388a-4e86-424f-a176-d1288462816f { $return = 'OfficeFeedProcessors' } - bf9fc203-c1ff-4fd4-878b-323642e462ec { $return = 'Jarvis Transaction Service' } - 257601fd-462f-4a21-b623-7f719f0f90f4 { $return = 'Centralized Deployment' } - 2a486b53-dbd2-49c0-a2bc-278bdfc30833 { $return = 'Cortana at Work Service' } - 22d7579f-06c2-4baa-89d2-e844486adb9d { $return = 'Cortana at Work Bing Services' } - 4c8f074c-e32b-4ba7-b072-0f39d71daf51 { $return = 'IPSubstrate' } - a164aee5-7d0a-46bb-9404-37421d58bdf7 { $return = 'Microsoft Teams AuthSvc' } - 354b5b6d-abd6-4736-9f51-1be80049b91f { $return = 'Microsoft Mobile Application Management Backend' } - 82b293b2-d54d-4d59-9a95-39c1c97954a7 { $return = 'Tasks in a Box' } - fdc83783-b652-4258-a622-66bc85f1a871 { $return = 'FedExPackageTracking' } - d0597157-f0ae-4e23-b06c-9e65de434c4f { $return = 'Microsoft Teams Task Service' } - f5c26e74-f226-4ae8-85f0-b4af0080ac9e { $return = 'Application Insights API' } - 57c0fc58-a83a-41d0-8ae9-08952659bdfd { $return = 'Azure Cosmos DB Virtual Network To Network Resource Provider' } - 744e50be-c4ff-4e90-8061-cd7f1fabac0b { $return = 'LinkedIn Microsoft Graph Connector' } - 823dfde0-1b9a-415a-a35a-1ad34e16dd44 { $return = 'Microsoft Teams Wiki Images Migration' } - 3ab9b3bc-762f-4d62-82f7-7e1d653ce29f { $return = 'Microsoft Volume Licensing' } - 44eb7794-0e11-42b6-800b-dc31874f9f60 { $return = 'Alignable' } - c58637bb-e2e1-4312-8a00-04b5ffcd3403 { $return = 'SharePoint Online Client Extensibility' } - 62b732f7-fc71-40bc-b27d-35efcb0509de { $return = 'Microsoft Teams AadSync' } - 07978fee-621a-42df-82bb-3eabc6511c26 { $return = 'SurveyMonkey' } - 47ee738b-3f1a-4fc7-ab11-37e4822b007e { $return = 'Azure AD Application Proxy' } - 00000007-0000-0000-c000-000000000000 { $return = 'Dynamics CRM Online' } - 913c6de4-2a4a-4a61-a9ce-945d2b2ce2e0 { $return = 'Dynamics Lifecycle services' } - f217ad13-46b8-4c5b-b661-876ccdf37302 { $return = 'Attach OneDrive files to Asana' } - 00000008-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.DataMarket' } - 9b06ebd4-9068-486b-bdd2-dac26b8a5a7a { $return = 'Microsoft.DynamicsMarketing' } - e8ab36af-d4be-4833-a38b-4d6cf1cfd525 { $return = 'Microsoft Social Engagement' } - 8909aac3-be91-470c-8a0b-ff09d669af91 { $return = 'Microsoft Parature Dynamics CRM' } - 71234da4-b92f-429d-b8ec-6e62652e50d7 { $return = 'Microsoft Customer Engagement Portal' } - b861dbcc-a7ef-4219-a005-0e4de4ea7dcf { $return = 'Data Export Service for Microsoft Dynamics 365' } - 2db8cb1d-fb6c-450b-ab09-49b6ae35186b { $return = 'Microsoft Dynamics CRM Learning Path' } - 2e49aa60-1bd3-43b6-8ab6-03ada3d9f08b { $return = 'Dynamics Data Integration' } - } + function Get-UserNameFromId { + [CmdletBinding()] + param ( + [Parameter()] + $ID, - if ([string]::IsNullOrEmpty($return)) { - $return = $Applications | Where-Object { $_.Appid -eq $ID } | Select-Object -ExpandProperty DisplayName + [Parameter(Mandatory = $true)] + $Users + ) + if ($id -eq 'All') { + return 'All' + } + $DisplayName = $Users | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName + if ([string]::IsNullOrEmpty($displayName)) { + return $ID + } else { + return $DisplayName + } } - if ([string]::IsNullOrEmpty($return)) { - $return = $Applications | Where-Object { $_.ID -eq $ID } | Select-Object -ExpandProperty DisplayName - } + function Get-GroupNameFromId { + param ( + [Parameter()] + $ID, - if ([string]::IsNullOrEmpty($return)) { - $return = '' + [Parameter(Mandatory = $true)] + $Groups + ) + if ($id -eq 'All') { + return 'All' + } + $DisplayName = $Groups | Where-Object { $_.id -eq $ID } | Select-Object -ExpandProperty DisplayName + if ([string]::IsNullOrEmpty($displayName)) { + return 'No Data' + } else { + return $DisplayName + } } - return $return -} + function Get-ApplicationNameFromId { + [CmdletBinding()] + param ( + [Parameter()] + $ID, + + [Parameter(Mandatory = $true)] + $Applications + ) + if ($id -eq 'All') { + return 'All' + } + switch ($id) { + 00000004-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Lync' } + 00000006-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Office365Portal' } + 00000003-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.SharePoint ' } + 00000005-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.Workflow' } + 00000009-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.AnalysisServices' } + 00000002-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.Exchange' } + 00000007-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.ExchangeOnlineProtection' } + 00000002-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.ActiveDirectory' } + 8fca0a66-c008-4564-a876-ab3ae0fd5cff { $return = 'Microsoft.SMIT' } + 0000000b-0000-0000-c000-000000000000 { $return = 'Microsoft.SellerDashboard' } + 0000000f-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.GraphExplorer' } + 0000000c-0000-0000-c000-000000000000 { $return = 'Microsoft App Access Panel' } + 00000013-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.Portal' } + 00000010-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.GraphStore' } + 93ee9413-cf4c-4d4e-814b-a91ff20a01bd { $return = 'Workflow' } + aa9ecb1e-fd53-4aaa-a8fe-7a54de2c1334 { $return = 'Microsoft.Office365.Configure' } + 797f4846-ba00-4fd7-ba43-dac1f8f63013 { $return = 'Windows Azure Service Management API' } + 00000005-0000-0ff1-ce00-000000000000 { $return = 'Microsoft.YammerEnterprise' } + 601d4e27-7bb3-4dee-8199-90d47d527e1c { $return = 'Microsoft.Office365.ChangeManagement' } + 6f82282e-0070-4e78-bc23-e6320c5fa7de { $return = 'Microsoft.DiscoveryService' } + 0f698dd4-f011-4d23-a33e-b36416dcb1e6 { $return = 'Microsoft.OfficeClientService' } + 67e3df25-268a-4324-a550-0de1c7f97287 { $return = 'Microsoft.OfficeWebAppsService' } + ab27a73e-a3ba-4e43-8360-8bcc717114d8 { $return = 'Microsoft.OfficeModernCalendar' } + aedca418-a84d-430d-ab84-0b1ef06f318f { $return = 'Workflow' } + 595d87a1-277b-4c0a-aa7f-44f8a068eafc { $return = 'Microsoft.SupportTicketSubmission' } + e3583ad2-c781-4224-9b91-ad15a8179ba0 { $return = 'Microsoft.ExtensibleRealUserMonitoring' } + b645896d-566e-447e-8f7f-e2e663b5d182 { $return = 'OpsDashSharePointApp' } + 48229a4a-9f1d-413a-8b96-4c02462c0360 { $return = 'OpsDashSharePointApp' } + 48717084-a59c-4306-9dc4-3f618dbecdf9 { $return = '"Napa" Office 365 Development Tools' } + c859ff33-eb41-4ba6-8093-a2c5153bbd7c { $return = 'Workflow' } + 67cad61c-3411-48d7-ab73-561c64f11ed6 { $return = 'Workflow' } + 914ed757-9257-4200-b68e-a2bed2f12c5a { $return = 'RbacBackfill' } + 499b84ac-1321-427f-aa17-267ca6975798 { $return = 'Microsoft.VisualStudio.Online' } + b2590339-0887-4e94-93aa-13357eb510d7 { $return = 'Workflow' } + 0000001b-0000-0000-c000-000000000000 { $return = 'Microsoft Power BI Information Service' } + 89f80565-bfac-4c01-9535-9f0eba332ffe { $return = 'Power BI' } + 433895fb-4ec7-45c3-a53c-c44d10f80d5b { $return = 'Compromised Account Service' } + d7c17728-4f1e-4a1e-86cf-7e0adf3fe903 { $return = 'Workflow' } + 17ef6d31-381f-4783-b186-7b440a3c85c1 { $return = 'Workflow' } + 00000012-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.RMS' } + 81ce94d4-9422-4c0d-a4b9-3250659366ce { $return = 'Workflow' } + 8d3a7d3c-c034-4f19-a2ef-8412952a9671 { $return = 'MicrosoftOffice' } + 0469d4cd-df37-4d93-8a61-f8c75b809164 { $return = 'Microsoft Policy Administration Service' } + 31d3f3f5-7267-45a8-9549-affb00110054 { $return = 'Windows Azure RemoteApp Service' } + 4e004241-32db-46c2-a86f-aaaba29bea9c { $return = 'Workflow' } + 748d098e-7a3b-436d-8b0a-006a58b29647 { $return = 'Workflow' } + dbf08535-1d3b-4f89-bf54-1d48dd613a61 { $return = 'Workflow' } + ed9fe1ef-25a4-482f-9981-2b60f91e2448 { $return = 'Workflow' } + 8ad28d50-ee26-42fc-8a29-e41ea38461f2 { $return = 'Office365RESTAPIExplorer.Office365App' } + 38285dce-a13d-4107-9b04-3016b941bb3a { $return = 'BasicDataOperationsREST' } + 92bb96c8-321c-47f9-bcc5-8849490c2b07 { $return = 'BasicSelfHostedAppREST' } + 488a57a0-00e2-4817-8c8d-cf8a15a994d2 { $return = 'WindowsFormsApplication2.Office365App' } + 11c174dc-1945-4a9a-a36b-c79a0f246b9b { $return = 'AzureApplicationInsights' } + e6acb561-0d94-4287-bd3a-3169f421b112 { $return = 'Tutum' } + 7b77b3a2-8490-49e1-8842-207cd0899af9 { $return = 'Nearpod' } + 0000000a-0000-0000-c000-000000000000 { $return = 'Microsoft.Intune' } + 93625bc8-bfe2-437a-97e0-3d0060024faa { $return = 'SelfServicePasswordReset' } + dee7ba80-6a55-4f3b-a86c-746a9231ae49 { $return = 'MicrosoftAppPlatEMA' } + 803ee9ca-3f7f-4824-bd6e-0b99d720c35c { $return = 'Azure Media Service' } + 2d4d3d8e-2be3-4bef-9f87-7875a61c29de { $return = 'OneNote' } + 8d40666e-5abf-45f6-a5e7-b7192d6d56ed { $return = 'Workflow' } + 262044b1-e2ce-469f-a196-69ab7ada62d3 { $return = 'Backup Management Service' } + 087a2c70-c89e-463f-8dd3-e3959eabb1a9 { $return = 'Microsoft Profile Service Platform Service' } + 7cd684f4-8a78-49b0-91ec-6a35d38739ba { $return = 'Azure Logic Apps' } + c5393580-f805-4401-95e8-94b7a6ef2fc2 { $return = 'Office 365 Management APIs' } + 96231a05-34ce-4eb4-aa6a-70759cbb5e83 { $return = 'MicrosoftAzureRedisCache' } + b8340c3b-9267-498f-b21a-15d5547fd85e { $return = 'Hyper-V Recovery Manager' } + abfa0a7c-a6b6-4736-8310-5855508787cd { $return = 'Microsoft.Azure.WebSites' } + c44b4083-3bb0-49c1-b47d-974e53cbdf3c { $return = 'IbizaPortal' } + 905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba { $return = 'Sway' } + b10686fd-6ba8-49f2-a3cd-67e4d2f52ac8 { $return = 'NovoEd' } + c606301c-f764-4e6b-aa45-7caaaea93c9a { $return = 'OfficeStore' } + 569e8598-685b-4ba2-8bff-5bced483ac46 { $return = 'Evercontact' } + 20a23a2f-8c32-4de7-8063-8c8f909602c0 { $return = 'Workflow' } + aaf214cc-8013-4b95-975f-13203ae36039 { $return = 'Power BI Tiles' } + d88a361a-d488-4271-a13f-a83df7dd99c2 { $return = 'IDML Graph Resolver Service and CAD' } + dff9b531-6290-4620-afce-26826a62a4e7 { $return = 'DocuSign' } + 01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9 { $return = 'Device Registration Service' } + 3290e3f7-d3ac-4165-bcef-cf4874fc4270 { $return = 'Smartsheet' } + a4ee6867-8640-4495-b1fd-8b26037a5bd3 { $return = 'Workflow' } + aa0e3dd4-df02-478d-869e-fc61dd71b6e8 { $return = 'Workflow' } + 0f6edad5-48f2-4585-a609-d252b1c52770 { $return = 'AIGraphClient' } + 0c8139b5-d545-4448-8d2b-2121bb242680 { $return = 'BillingExtension' } + 475226c6-020e-4fb2-8a90-7a972cbfc1d4 { $return = 'KratosAppsService' } + 39624784-6cbe-4a60-afbe-9f46d10fdb27 { $return = 'SkypeForBusinessRemotePowershell' } + 8bdebf23-c0fe-4187-a378-717ad86f6a53 { $return = 'ResourceHealthRP' } + c161e42e-d4df-4a3d-9b42-e7a3c31f59d4 { $return = 'MicrosoftIntuneAPI' } + 9cb77803-d937-493e-9a3b-4b49de3f5a74 { $return = 'MicrosoftIntuneServiceDiscovery' } + ddbf3205-c6bd-46ae-8127-60eb93363864 { $return = 'Microsoft Azure Batch' } + 80ccca67-54bd-44ab-8625-4b79c4dc7775 { $return = 'ComplianceCenter' } + 0a5f63c0-b750-4f38-a71c-4fc0d58b89e2 { $return = 'Microsoft Mobile Application Management' } + e1335bb1-2aec-4f92-8140-0e6e61ae77e5 { $return = 'CIWebService' } + 75018fbe-21fe-4a57-b63c-83252b5eaf16 { $return = 'TeamImprover - Team Organization Chart' } + a393296b-5695-4463-97cb-9fa8638a494a { $return = 'My SharePoint Sites' } + fe217466-5583-431c-9531-14ff7268b7b3 { $return = 'Microsoft Education' } + 5bfe8a29-054e-4348-9e7a-3981b26b125f { $return = 'Bing Places for Business' } + eaf8a961-f56e-47eb-9ffd-936e22a554ef { $return = 'DevilFish' } + 4b4b1d56-1f03-47d9-a0a3-87d4afc913c9 { $return = 'Wunderlist' } + 00000003-0000-0000-c000-000000000000 { $return = 'Microsoft Graph' } + 60e6cd67-9c8c-4951-9b3c-23c25a2169af { $return = 'Compute Resource Provider' } + 507bc9da-c4e2-40cb-96a7-ac90df92685c { $return = 'Office365Reports' } + 09abbdfd-ed23-44ee-a2d9-a627aa1c90f3 { $return = 'ProjectWorkManagement' } + 28ec9756-deaf-48b2-84d5-a623b99af263 { $return = 'Office Personal Assistant at Work Service' } + 9e4a5442-a5c9-4f6f-b03f-5b9fcaaf24b1 { $return = 'OfficeServicesManager' } + 3138fe80-4087-4b04-80a6-8866c738028a { $return = 'SharePoint Notification Service' } + d2a0a418-0aac-4541-82b2-b3142c89da77 { $return = 'MicrosoftAzureOperationalInsights' } + 2cf9eb86-36b5-49dc-86ae-9a63135dfa8c { $return = 'AzureTrafficManagerandDNS' } + 32613fc5-e7ac-4894-ac94-fbc39c9f3e4a { $return = 'OAuth Sandbox' } + 925eb0d0-da50-4604-a19f-bd8de9147958 { $return = 'Groupies Web Service' } + e4ab13ed-33cb-41b4-9140-6e264582cf85 { $return = 'Azure SQL Database Backup To Azure Backup Vault' } + ad230543-afbe-4bb4-ac4f-d94d101704f8 { $return = 'Apiary for Power BI' } + 11cd3e2e-fccb-42ad-ad00-878b93575e07 { $return = 'Automated Call Distribution' } + de17788e-c765-4d31-aba4-fb837cfff174 { $return = 'Skype for Business Management Reporting and Analytics' } + 65d91a3d-ab74-42e6-8a2f-0add61688c74 { $return = 'Microsoft Approval Management' } + 5225545c-3ebd-400f-b668-c8d78550d776 { $return = 'Office Agent Service' } + 1cda9b54-9852-4a5a-96d4-c2ab174f9edf { $return = 'O365Account' } + 4747d38e-36c5-4bc3-979b-b0ef74df54d1 { $return = 'PushChannel' } + b97b6bd4-a49f-4a0c-af18-af507d1da76c { $return = 'Office Shredding Service' } + d4ebce55-015a-49b5-a083-c84d1797ae8c { $return = 'Microsoft Intune Enrollment' } + 5b20c633-9a48-4a5f-95f6-dae91879051f { $return = 'Azure Information Protection' } + 441509e5-a165-4363-8ee7-bcf0b7d26739 { $return = 'EnterpriseAgentPlatform' } + e691bce4-6612-4025-b94c-81372a99f77e { $return = 'Boomerang' } + 8edd93e1-2103-40b4-bd70-6e34e586362d { $return = 'Windows Azure Security Resource Provider' } + 94c63fef-13a3-47bc-8074-75af8c65887a { $return = 'Office Delve' } + e95d8bee-4725-4f59-910d-94d415da51b9 { $return = 'Skype for Business Name Dictionary Service' } + e3c5dbcd-bb5f-4bda-b943-adc7a5bbc65e { $return = 'Workflow' } + 8602e328-9b72-4f2d-a4ae-1387d013a2b3 { $return = 'Azure API Management' } + 8b3391f4-af01-4ee8-b4ea-9871b2499735 { $return = 'O365 Secure Score' } + c26550d6-bc82-4484-82ca-ac1c75308ca3 { $return = 'Office 365 YammerOnOls' } + 33be1cef-03fb-444b-8fd3-08ca1b4d803f { $return = 'OneDrive Web' } + dcad865d-9257-4521-ad4d-bae3e137b345 { $return = 'Microsoft SharePoint Online - SharePoint Home' } + b2cc270f-563e-4d8a-af47-f00963a71dcd { $return = 'OneProfile Service' } + 4660504c-45b3-4674-a709-71951a6b0763 { $return = 'Microsoft Invitation Acceptance Portal' } + ba23cd2a-306c-48f2-9d62-d3ecd372dfe4 { $return = 'OfficeGraph' } + d52485ee-4609-4f6b-b3a3-68b6f841fa23 { $return = 'On-Premises Data Gateway Connector' } + 996def3d-b36c-4153-8607-a6fd3c01b89f { $return = 's 365 for Financials' } + b6b84568-6c01-4981-a80f-09da9a20bbed { $return = 'Microsoft Invoicing' } + 9d3e55ba-79e0-4b7c-af50-dc460b81dca1 { $return = 'Microsoft Azure Data Catalog' } + 4345a7b9-9a63-4910-a426-35363201d503 { $return = 'O365 Suite UX' } + ac815d4a-573b-4174-b38e-46490d19f894 { $return = 'Workflow' } + bb8f18b0-9c38-48c9-a847-e1ef3af0602d { $return = 'Microsoft.Azure.ActiveDirectoryIUX' } + cc15fd57-2c6c-4117-a88c-83b1d56b4bbe { $return = 'Microsoft Teams Services' } + 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 { $return = 'Skype Teams' } + 1fec8e78-bce4-4aaf-ab1b-5451cc387264 { $return = 'Microsoft Teams' } + 6d32b7f8-782e-43e0-ac47-aaad9f4eb839 { $return = 'Permission Service O365' } + cdccd920-384b-4a25-897d-75161a4b74c1 { $return = 'Skype Teams Firehose' } + 1c0ae35a-e2ec-4592-8e08-c40884656fa5 { $return = 'Skype Team Substrate connector' } + cf6c77f8-914f-4078-baef-e39a5181158b { $return = 'Skype Teams Settings Store' } + 64f79cb9-9c82-4199-b85b-77e35b7dcbcb { $return = 'Microsoft Teams Bots' } + b7912db9-aa33-4820-9d4f-709830fdd78f { $return = 'ConnectionsService' } + 82f77645-8a66-4745-bcdf-9706824f9ad0 { $return = 'PowerApps Runtime Service' } + 6204c1d1-4712-4c46-a7d9-3ed63d992682 { $return = 'Microsoft Flow Portal' } + 7df0a125-d3be-4c96-aa54-591f83ff541c { $return = 'Microsoft Flow Service' } + 331cc017-5973-4173-b270-f0042fddfd75 { $return = 'PowerAppsService' } + 0a0e9e37-25e3-47d4-964c-5b8237cad19a { $return = 'CloudSponge' } + df09ff61-2178-45d8-888c-4210c1c7b0b2 { $return = 'O365 UAP Processor' } + 8338dec2-e1b3-48f7-8438-20c30a534458 { $return = 'ViewPoint' } + 00000001-0000-0000-c000-000000000000 { $return = 'Azure ESTS Service' } + 394866fc-eedb-4f01-8536-3ff84b16be2a { $return = 'Microsoft People Cards Service' } + 0a0a29f9-0a25-49c7-94bf-c53c3f8fa69d { $return = 'Cortana Experience with O365' } + bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4 { $return = 'CPIM Service' } + 0004c632-673b-4105-9bb6-f3bbd2a927fe { $return = 'PowerApps and Flow' } + d3ce4cf8-6810-442d-b42e-375e14710095 { $return = 'Graph Explorer' } + 3aa5c166-136f-40eb-9066-33ac63099211 { $return = 'O365 Customer Monitoring' } + d6fdaa33-e821-4211-83d0-cf74736489e1 { $return = 'Microsoft Service Trust' } + ef4a2a24-4b4e-4abf-93ba-cc11c5bd442c { $return = 'Edmodo' } + b692184e-b47f-4706-b352-84b288d2d9ee { $return = 'Microsoft.MileIQ.RESTService' } + a25dbca8-4e60-48e5-80a2-0664fdb5c9b6 { $return = 'Microsoft.MileIQ' } + f7069a8d-9edc-4300-b365-ae53c9627fc4 { $return = 'Microsoft.MileIQ.Dashboard' } + 02e3ae74-c151-4bda-b8f0-55fbf341de08 { $return = 'Application Registration Portal' } + 1f5530b3-261a-47a9-b357-ded261e17918 { $return = 'Azure Multi-Factor Auth Connector' } + 981f26a1-7f43-403b-a875-f8b09b8cd720 { $return = 'Azure Multi-Factor Auth Client' } + 6ea8091b-151d-447a-9013-6845b83ba57b { $return = 'AD Hybrid Health' } + fc68d9e5-1f76-45ef-99aa-214805418498 { $return = 'Azure AD Identity Protection' } + 01fc33a7-78ba-4d2f-a4b7-768e336e890e { $return = 'MS-PIM' } + a6aa9161-5291-40bb-8c5c-923b567bee3b { $return = 'Storage Resource Provider' } + 4e9b8b9a-1001-4017-8dd1-6e8f25e19d13 { $return = 'Adobe Acrobat' } + 159b90bb-bb28-4568-ad7c-adad6b814a2f { $return = 'LastPass' } + b4bddae8-ab25-483e-8670-df09b9f1d0ea { $return = 'Signup' } + aa580612-c342-4ace-9055-8edee43ccb89 { $return = 'Microsoft StaffHub' } + 51133ff5-8e0d-4078-bcca-84fb7f905b64 { $return = 'Microsoft Teams Mailhook' } + ab3be6b7-f5df-413d-ac2d-abf1e3fd9c0b { $return = 'Microsoft Teams Graph Service' } + b1379a75-ce5e-4fa3-80c6-89bb39bf646c { $return = 'Microsoft Teams Chat Aggregator' } + 48af08dc-f6d2-435f-b2a7-069abd99c086 { $return = 'Connectors' } + d676e816-a17b-416b-ac1a-05ad96f43686 { $return = 'Workflow' } + cfa8b339-82a2-471a-a3c9-0fc0be7a4093 { $return = 'Azure Key Vault' } + c2f89f53-3971-4e09-8656-18eed74aee10 { $return = 'calendly' } + 6da466b6-1d13-4a2c-97bd-51a99e8d4d74 { $return = 'Exchange Office Graph Client for AAD - Interactive' } + 0eda3b13-ddc9-4c25-b7dd-2f6ea073d6b7 { $return = 'Microsoft Flow CDS Integration Service' } + eacba838-453c-4d3e-8c6a-eb815d3469a3 { $return = 'Microsoft Flow CDS Integration Service TIP1' } + 4ac7d521-0382-477b-b0f8-7e1d95f85ca2 { $return = 'SQL Server Analysis Services Azure' } + b4114287-89e4-4209-bd99-b7d4919bcf64 { $return = 'OfficeDelve' } + 4580fd1d-e5a3-4f56-9ad1-aab0e3bf8f76 { $return = 'Call Recorder' } + a855a166-fd92-4c76-b60d-a791e0762432 { $return = 'Microsoft Teams VSTS' } + c37c294f-eec8-47d2-b3e2-fc3daa8f77d3 { $return = 'Workflow' } + fc75330b-179d-49af-87dd-3b1acf6827fa { $return = 'AzureAutomationAADPatchS2S' } + 766d89a4-d6a6-444d-8a5e-e1a18622288a { $return = 'OneDrive' } + f16c4a38-5aff-4549-8199-ee7d3c5bd8dc { $return = 'Workflow' } + 4c4f550b-42b2-4a16-93f9-fdb9e01bb6ed { $return = 'Targeted Messaging Service' } + 765fe668-04e7-42ba-aec0-2c96f1d8b652 { $return = 'Exchange Office Graph Client for AAD - Noninteractive' } + 0130cc9f-7ac5-4026-bd5f-80a08a54e6d9 { $return = 'Azure Data Warehouse Polybase' } + a1cf9e0a-fe14-487c-beb9-dd3360921173 { $return = 'Meetup' } + 76cd24bf-a9fc-4344-b1dc-908275de6d6d { $return = 'Azure SQL Virtual Network to Network Resource Provider' } + 9f505dbd-a32c-4685-b1c6-72e4ef704cb0 { $return = 'Amazon Alexa' } + 1e2ca66a-c176-45ea-a877-e87f7231e0ee { $return = 'Microsoft B2B Admin Worker' } + 2634dd23-5e5a-431c-81ca-11710d9079f4 { $return = 'Microsoft Stream Service' } + cf53fce8-def6-4aeb-8d30-b158e7b1cf83 { $return = 'Microsoft Stream Portal' } + c9a559d2-7aab-4f13-a6ed-e7e9c52aec87 { $return = 'Microsoft Forms' } + 978877ea-b2d6-458b-80c7-05df932f3723 { $return = 'Microsoft Teams AuditService' } + dbc36ae1-c097-4df9-8d94-343c3d091a76 { $return = 'Service Encryption' } + fa7ff576-8e31-4a58-a5e5-780c1cd57caa { $return = 'OneNote' } + cb4dc29f-0bf4-402a-8b30-7511498ed654 { $return = 'Power BI Premium' } + f5aeb603-2a64-4f37-b9a8-b544f3542865 { $return = 'Microsoft Teams RetentionHook Service' } + da109bdd-abda-4c06-8808-4655199420f8 { $return = 'Glip Contacts' } + 76c7f279-7959-468f-8943-3954880e0d8c { $return = 'Azure SQL Managed Instance to Microsoft.Network' } + 3a9ddf38-83f3-4ea1-a33a-ecf934644e2d { $return = 'Protected Message Viewer' } + 5635d99c-c364-4411-90eb-764a511b5fdf { $return = 'Responsive Banner Slider' } + a43e5392-f48b-46a4-a0f1-098b5eeb4757 { $return = 'Cloudsponge' } + d73f4b35-55c9-48c7-8b10-651f6f2acb2e { $return = 'MCAPI Authorization Prod' } + 166f1b03-5b19-416f-a94b-1d7aa2d247dc { $return = 'Office Hive' } + b815ce1c-748f-4b1e-9270-a42c1fa4485a { $return = 'Workflow' } + bd7b778b-4aa8-4cde-8d90-8aeb821c0bd2 { $return = 'Workflow' } + 9d06afd9-66c9-49a6-b385-ea7509332b0b { $return = 'O365SBRM Service' } + 9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7 { $return = 'Bing' } + 57fb890c-0dab-4253-a5e0-7188c88b2bb4 { $return = 'SharePoint Online Client' } + 45c10911-200f-4e27-a666-9e9fca147395 { $return = 'drawio' } + b73f62d0-210b-4396-a4c5-ea50c4fab79b { $return = 'Skype Business Voice Fraud Detection and Prevention' } + bc59ab01-8403-45c6-8796-ac3ef710b3e3 { $return = 'Outlook Online Add-in App' } + 035f9e1d-4f00-4419-bf50-bf2d87eb4878 { $return = 'Azure Monitor Restricted' } + 7c33bfcb-8d33-48d6-8e60-dc6404003489 { $return = 'Network Watcher' } + a0be0c72-870e-46f0-9c49-c98333a996f7 { $return = 'AzureDnsFrontendApp' } + 1e3e4475-288f-4018-a376-df66fd7fac5f { $return = 'NetworkTrafficAnalyticsService' } + 7557eb47-c689-4224-abcf-aef9bd7573df { $return = 'Skype for Business' } + c39c9bac-9d1f-4dfb-aa29-27f6365e5cb7 { $return = 'Azure Advisor' } + 2087bd82-7206-4c0a-b305-1321a39e5926 { $return = 'Microsoft To-Do' } + f8d98a96-0999-43f5-8af3-69971c7bb423 { $return = 'iOS Accounts' } + c27373d3-335f-4b45-8af9-fe81c240d377 { $return = 'P2P Server' } + 5c2ffddc-f1d7-4dc3-926e-3c1bd98e32bd { $return = 'RITS Dev' } + 982bda36-4632-4165-a46a-9863b1bbcf7d { $return = 'O365 Demeter' } + 98c8388a-4e86-424f-a176-d1288462816f { $return = 'OfficeFeedProcessors' } + bf9fc203-c1ff-4fd4-878b-323642e462ec { $return = 'Jarvis Transaction Service' } + 257601fd-462f-4a21-b623-7f719f0f90f4 { $return = 'Centralized Deployment' } + 2a486b53-dbd2-49c0-a2bc-278bdfc30833 { $return = 'Cortana at Work Service' } + 22d7579f-06c2-4baa-89d2-e844486adb9d { $return = 'Cortana at Work Bing Services' } + 4c8f074c-e32b-4ba7-b072-0f39d71daf51 { $return = 'IPSubstrate' } + a164aee5-7d0a-46bb-9404-37421d58bdf7 { $return = 'Microsoft Teams AuthSvc' } + 354b5b6d-abd6-4736-9f51-1be80049b91f { $return = 'Microsoft Mobile Application Management Backend' } + 82b293b2-d54d-4d59-9a95-39c1c97954a7 { $return = 'Tasks in a Box' } + fdc83783-b652-4258-a622-66bc85f1a871 { $return = 'FedExPackageTracking' } + d0597157-f0ae-4e23-b06c-9e65de434c4f { $return = 'Microsoft Teams Task Service' } + f5c26e74-f226-4ae8-85f0-b4af0080ac9e { $return = 'Application Insights API' } + 57c0fc58-a83a-41d0-8ae9-08952659bdfd { $return = 'Azure Cosmos DB Virtual Network To Network Resource Provider' } + 744e50be-c4ff-4e90-8061-cd7f1fabac0b { $return = 'LinkedIn Microsoft Graph Connector' } + 823dfde0-1b9a-415a-a35a-1ad34e16dd44 { $return = 'Microsoft Teams Wiki Images Migration' } + 3ab9b3bc-762f-4d62-82f7-7e1d653ce29f { $return = 'Microsoft Volume Licensing' } + 44eb7794-0e11-42b6-800b-dc31874f9f60 { $return = 'Alignable' } + c58637bb-e2e1-4312-8a00-04b5ffcd3403 { $return = 'SharePoint Online Client Extensibility' } + 62b732f7-fc71-40bc-b27d-35efcb0509de { $return = 'Microsoft Teams AadSync' } + 07978fee-621a-42df-82bb-3eabc6511c26 { $return = 'SurveyMonkey' } + 47ee738b-3f1a-4fc7-ab11-37e4822b007e { $return = 'Azure AD Application Proxy' } + 00000007-0000-0000-c000-000000000000 { $return = 'Dynamics CRM Online' } + 913c6de4-2a4a-4a61-a9ce-945d2b2ce2e0 { $return = 'Dynamics Lifecycle services' } + f217ad13-46b8-4c5b-b661-876ccdf37302 { $return = 'Attach OneDrive files to Asana' } + 00000008-0000-0000-c000-000000000000 { $return = 'Microsoft.Azure.DataMarket' } + 9b06ebd4-9068-486b-bdd2-dac26b8a5a7a { $return = 'Microsoft.DynamicsMarketing' } + e8ab36af-d4be-4833-a38b-4d6cf1cfd525 { $return = 'Microsoft Social Engagement' } + 8909aac3-be91-470c-8a0b-ff09d669af91 { $return = 'Microsoft Parature Dynamics CRM' } + 71234da4-b92f-429d-b8ec-6e62652e50d7 { $return = 'Microsoft Customer Engagement Portal' } + b861dbcc-a7ef-4219-a005-0e4de4ea7dcf { $return = 'Data Export Service for Microsoft Dynamics 365' } + 2db8cb1d-fb6c-450b-ab09-49b6ae35186b { $return = 'Microsoft Dynamics CRM Learning Path' } + 2e49aa60-1bd3-43b6-8ab6-03ada3d9f08b { $return = 'Dynamics Data Integration' } + } -# Write to the Azure Functions log stream. -Write-Host "PowerShell HTTP trigger function processed a request." + if ([string]::IsNullOrEmpty($return)) { + $return = $Applications | Where-Object { $_.Appid -eq $ID } | Select-Object -ExpandProperty DisplayName + } -# Interact with query parameters or the body of the request. -$TenantFilter = $Request.Query.TenantFilter -try { - $ConditionalAccessPolicyOutput = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies" -tenantid $tenantfilter - $AllNamedLocations = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations" -tenantid $tenantfilter - $AllApplications = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/applications" -tenantid $tenantfilter - $AllRoleDefinitions = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions" -tenantid $tenantfilter - $GroupListOutput = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/groups" -tenantid $tenantfilter - $UserListOutput = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users" -tenantid $tenantfilter | Select-Object * -ExcludeProperty *extensionAttribute* + if ([string]::IsNullOrEmpty($return)) { + $return = $Applications | Where-Object { $_.ID -eq $ID } | Select-Object -ExpandProperty DisplayName + } - $GraphRequest = foreach ($cap in $ConditionalAccessPolicyOutput) { - $temp = [PSCustomObject]@{ - id = $cap.id - displayName = $cap.displayName - customer = $cap.Customer - tenantID = $cap.TenantID - createdDateTime = $(if (![string]::IsNullOrEmpty($cap.createdDateTime)) { [datetime]$cap.createdDateTime | Get-Date -Format "yyyy-MM-dd HH:mm" }else { "" }) - modifiedDateTime = $(if (![string]::IsNullOrEmpty($cap.modifiedDateTime)) { [datetime]$cap.modifiedDateTime | Get-Date -Format "yyyy-MM-dd HH:mm" }else { "" }) - state = $cap.state - clientAppTypes = ($cap.conditions.clientAppTypes) -join "," - includePlatforms = ($cap.conditions.platforms.includePlatforms) -join "," - excludePlatforms = ($cap.conditions.platforms.excludePlatforms) -join "," - includeLocations = (Get-LocationNameFromId -Locations $AllNamedLocations -id $cap.conditions.locations.includeLocations) -join "," - excludeLocations = (Get-LocationNameFromId -Locations $AllNamedLocations -id $cap.conditions.locations.excludeLocations) -join "," - includeApplications = ($cap.conditions.applications.includeApplications | ForEach-Object { Get-ApplicationNameFromId -Applications $AllApplications -id $_ }) -join "," - excludeApplications = ($cap.conditions.applications.excludeApplications | ForEach-Object { Get-ApplicationNameFromId -Applications $AllApplications -id $_ }) -join "," - includeUserActions = ($cap.conditions.applications.includeUserActions | Out-String) - includeAuthenticationContextClassReferences = ($cap.conditions.applications.includeAuthenticationContextClassReferences | Out-String) - includeUsers = ($cap.conditions.users.includeUsers | ForEach-Object { Get-UserNameFromId -Users $UserListOutput -id $_ }) | Out-String - excludeUsers = ($cap.conditions.users.excludeUsers | ForEach-Object { Get-UserNameFromId -Users $UserListOutput -id $_ }) | Out-String - includeGroups = ($cap.conditions.users.includeGroups | ForEach-Object { Get-GroupNameFromId -Groups $GroupListOutput -id $_ }) | Out-String - excludeGroups = ($cap.conditions.users.excludeGroups | ForEach-Object { Get-GroupNameFromId -Groups $GroupListOutput -id $_ }) | Out-String - includeRoles = ($cap.conditions.users.includeRoles | ForEach-Object { Get-RoleNameFromId -RoleDefinitions $AllRoleDefinitions -id $_ }) | Out-String - excludeRoles = ($cap.conditions.users.excludeRoles | ForEach-Object { Get-RoleNameFromId -RoleDefinitions $AllRoleDefinitions -id $_ }) | Out-String - grantControlsOperator = ($cap.grantControls.operator) -join "," - builtInControls = ($cap.grantControls.builtInControls) -join "," - customAuthenticationFactors = ($cap.grantControls.customAuthenticationFactors) -join "," - termsOfUse = ($cap.grantControls.termsOfUse) -join "," - rawjson = ($cap | ConvertTo-Json -Depth 100) + if ([string]::IsNullOrEmpty($return)) { + $return = '' } - $temp + + return $return } - $StatusCode = [HttpStatusCode]::OK -} -catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage -} -# Associate values to output bindings by calling 'Push-OutputBinding'. -Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + try { + $ConditionalAccessPolicyOutput = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/policies' -tenantid $tenantfilter + $AllNamedLocations = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -tenantid $tenantfilter + $AllApplications = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/applications' -tenantid $tenantfilter + $AllRoleDefinitions = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions' -tenantid $tenantfilter + $GroupListOutput = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/groups' -tenantid $tenantfilter + $UserListOutput = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/users' -tenantid $tenantfilter | Select-Object * -ExcludeProperty *extensionAttribute* + + $GraphRequest = foreach ($cap in $ConditionalAccessPolicyOutput) { + $temp = [PSCustomObject]@{ + id = $cap.id + displayName = $cap.displayName + customer = $cap.Customer + tenantID = $cap.TenantID + createdDateTime = $(if (![string]::IsNullOrEmpty($cap.createdDateTime)) { [datetime]$cap.createdDateTime | Get-Date -Format 'yyyy-MM-dd HH:mm' }else { '' }) + modifiedDateTime = $(if (![string]::IsNullOrEmpty($cap.modifiedDateTime)) { [datetime]$cap.modifiedDateTime | Get-Date -Format 'yyyy-MM-dd HH:mm' }else { '' }) + state = $cap.state + clientAppTypes = ($cap.conditions.clientAppTypes) -join ',' + includePlatforms = ($cap.conditions.platforms.includePlatforms) -join ',' + excludePlatforms = ($cap.conditions.platforms.excludePlatforms) -join ',' + includeLocations = (Get-LocationNameFromId -Locations $AllNamedLocations -id $cap.conditions.locations.includeLocations) -join ',' + excludeLocations = (Get-LocationNameFromId -Locations $AllNamedLocations -id $cap.conditions.locations.excludeLocations) -join ',' + includeApplications = ($cap.conditions.applications.includeApplications | ForEach-Object { Get-ApplicationNameFromId -Applications $AllApplications -id $_ }) -join ',' + excludeApplications = ($cap.conditions.applications.excludeApplications | ForEach-Object { Get-ApplicationNameFromId -Applications $AllApplications -id $_ }) -join ',' + includeUserActions = ($cap.conditions.applications.includeUserActions | Out-String) + includeAuthenticationContextClassReferences = ($cap.conditions.applications.includeAuthenticationContextClassReferences | Out-String) + includeUsers = ($cap.conditions.users.includeUsers | ForEach-Object { Get-UserNameFromId -Users $UserListOutput -id $_ }) | Out-String + excludeUsers = ($cap.conditions.users.excludeUsers | ForEach-Object { Get-UserNameFromId -Users $UserListOutput -id $_ }) | Out-String + includeGroups = ($cap.conditions.users.includeGroups | ForEach-Object { Get-GroupNameFromId -Groups $GroupListOutput -id $_ }) | Out-String + excludeGroups = ($cap.conditions.users.excludeGroups | ForEach-Object { Get-GroupNameFromId -Groups $GroupListOutput -id $_ }) | Out-String + includeRoles = ($cap.conditions.users.includeRoles | ForEach-Object { Get-RoleNameFromId -RoleDefinitions $AllRoleDefinitions -id $_ }) | Out-String + excludeRoles = ($cap.conditions.users.excludeRoles | ForEach-Object { Get-RoleNameFromId -RoleDefinitions $AllRoleDefinitions -id $_ }) | Out-String + grantControlsOperator = ($cap.grantControls.operator) -join ',' + builtInControls = ($cap.grantControls.builtInControls) -join ',' + customAuthenticationFactors = ($cap.grantControls.customAuthenticationFactors) -join ',' + termsOfUse = ($cap.grantControls.termsOfUse) -join ',' + rawjson = ($cap | ConvertTo-Json -Depth 100) + } + $temp + } + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = $ErrorMessage } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) + +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicyChanges.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicyChanges.ps1 index 89e2ecfb2bff..22f708cfb080 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicyChanges.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicyChanges.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListConditionalAccessPolicyChanges { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 index 61701c1d51a9..946eaddafaf0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 @@ -1,66 +1,68 @@ using namespace System.Net Function Invoke-ExecAddGDAPRole { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $Groups = $Request.body.gdapRoles - $CustomSuffix = $Request.body.customSuffix - $Table = Get-CIPPTable -TableName 'GDAPRoles' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Groups = $Request.body.gdapRoles + $CustomSuffix = $Request.body.customSuffix + $Table = Get-CIPPTable -TableName 'GDAPRoles' - $Results = [System.Collections.Generic.List[string]]::new() - $ExistingGroups = New-GraphGetRequest -NoAuthCheck $True -uri 'https://graph.microsoft.com/beta/groups' -tenantid $env:TenantID + $Results = [System.Collections.Generic.List[string]]::new() + $ExistingGroups = New-GraphGetRequest -NoAuthCheck $True -uri 'https://graph.microsoft.com/beta/groups' -tenantid $env:TenantID - $RoleMappings = foreach ($group in $Groups) { - if ($CustomSuffix) { - $GroupName = "M365 GDAP $($Group.Name) - $CustomSuffix" - $MailNickname = "M365GDAP$(($Group.Name).replace(' ',''))$($CustomSuffix)" + $RoleMappings = foreach ($group in $Groups) { + if ($CustomSuffix) { + $GroupName = "M365 GDAP $($Group.Name) - $CustomSuffix" + $MailNickname = "M365GDAP$(($Group.Name).replace(' ',''))$($CustomSuffix)" + } else { + $GroupName = "M365 GDAP $($Group.Name)" + $MailNickname = "M365GDAP$(($Group.Name).replace(' ',''))" + } + try { + if ($GroupName -in $ExistingGroups.displayName) { + @{ + PartitionKey = 'Roles' + RowKey = ($ExistingGroups | Where-Object -Property displayName -EQ $GroupName).id + RoleName = $Group.Name + GroupName = $GroupName + GroupId = ($ExistingGroups | Where-Object -Property displayName -EQ $GroupName).id + roleDefinitionId = $group.ObjectId + } + $Results.Add("M365 GDAP $($Group.Name) already exists") } else { - $GroupName = "M365 GDAP $($Group.Name)" - $MailNickname = "M365GDAP$(($Group.Name).replace(' ',''))" + $BodyToship = [pscustomobject] @{'displayName' = $GroupName; 'description' = "This group is used to manage M365 partner tenants at the $($group.name) level."; securityEnabled = $true; mailEnabled = $false; mailNickname = $MailNickname } | ConvertTo-Json + $GraphRequest = New-GraphPostRequest -NoAuthCheck $True -uri 'https://graph.microsoft.com/beta/groups' -tenantid $env:TenantID -type POST -body $BodyToship -verbose + @{ + PartitionKey = 'Roles' + RowKey = $GraphRequest.Id + RoleName = $Group.Name + GroupName = $GroupName + GroupId = $GraphRequest.Id + roleDefinitionId = $group.ObjectId + } + $Results.Add("$GroupName added successfully") } - try { - if ($GroupName -in $ExistingGroups.displayName) { - @{ - PartitionKey = 'Roles' - RowKey = ($ExistingGroups | Where-Object -Property displayName -EQ $GroupName).id - RoleName = $Group.Name - GroupName = $GroupName - GroupId = ($ExistingGroups | Where-Object -Property displayName -EQ $GroupName).id - roleDefinitionId = $group.ObjectId - } - $Results.Add("M365 GDAP $($Group.Name) already exists") - } else { - $BodyToship = [pscustomobject] @{'displayName' = $GroupName; 'description' = "This group is used to manage M365 partner tenants at the $($group.name) level."; securityEnabled = $true; mailEnabled = $false; mailNickname = $MailNickname } | ConvertTo-Json - $GraphRequest = New-GraphPostRequest -NoAuthCheck $True -uri 'https://graph.microsoft.com/beta/groups' -tenantid $env:TenantID -type POST -body $BodyToship -verbose - @{ - PartitionKey = 'Roles' - RowKey = $GraphRequest.Id - RoleName = $Group.Name - GroupName = $GroupName - GroupId = $GraphRequest.Id - roleDefinitionId = $group.ObjectId - } - $Results.Add("$GroupName added successfully") - } - } catch { - $Results.Add("Could not create GDAP group $($GroupName): $($_.Exception.Message)") - } - } + } catch { + $Results.Add("Could not create GDAP group $($GroupName): $($_.Exception.Message)") + } + } - Add-CIPPAzDataTableEntity @Table -Entity $RoleMappings -Force + Add-CIPPAzDataTableEntity @Table -Entity $RoleMappings -Force - $body = @{Results = @($Results) } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $body - }) + $body = @{Results = @($Results) } + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 index d0f1b5385e0c..f57c65330f6f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 @@ -1,23 +1,25 @@ using namespace System.Net Function Invoke-ExecAutoExtendGDAP { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - $Results = Set-CIPPGDAPAutoExtend -RelationShipid $Request.query.ID + # Interact with query parameters or the body of the request. + $Results = Set-CIPPGDAPAutoExtend -RelationShipid $Request.query.ID - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = @{ Results = $Results } - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @{ Results = $Results } + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 index bdfe01455cd4..61164e8968be 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecDeleteGDAPRelationship { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 index 729c327b3528..23426c6f1a14 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 @@ -1,33 +1,35 @@ using namespace System.Net Function Invoke-ExecDeleteGDAPRoleMapping { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $Table = Get-CIPPTable -TableName 'GDAPRoles' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Table = Get-CIPPTable -TableName 'GDAPRoles' - Write-Host $Table - try { - $Filter = "PartitionKey eq 'Roles' and RowKey eq '{0}'" -f $Request.Query.GroupId - $Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter - Remove-AzDataTableEntity @Table -Entity $Entity - $Results = [pscustomobject]@{'Results' = 'Success. GDAP relationship mapping deleted' } - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "GDAP relationship mapping deleted for $($Request.Query.GroupId)" -Sev 'Info' + Write-Host $Table + try { + $Filter = "PartitionKey eq 'Roles' and RowKey eq '{0}'" -f $Request.Query.GroupId + $Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter + Remove-AzDataTableEntity @Table -Entity $Entity + $Results = [pscustomobject]@{'Results' = 'Success. GDAP relationship mapping deleted' } + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "GDAP relationship mapping deleted for $($Request.Query.GroupId)" -Sev 'Info' - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 index 4739df9c2df1..91cfa3388bb2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 @@ -2,12 +2,14 @@ using namespace System.Net Function Invoke-ExecGDAPInvite { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName + $APIName = 'ExecGDAPInvite' Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $RoleMappings = $Request.body.gdapRoles @@ -47,7 +49,7 @@ Function Invoke-ExecGDAPInvite { if ($NewRelationshipRequest.action -eq 'lockForApproval') { $InviteUrl = "https://admin.microsoft.com/AdminPortal/Home#/partners/invitation/granularAdminRelationships/$($NewRelationship.id)" - $Uri = ([System.Uri]$TriggerMetadata.Headers.referer) + $Uri = ([System.Uri]$TriggerMetadata.Headers.Referer) $TableFilter = [System.Web.HttpUtility]::UrlEncode(('Complex: id eq {0}' -f $NewRelationship.id)) $OnboardingUrl = $Uri.AbsoluteUri.Replace($Uri.PathAndQuery, "/tenant/administration/tenant-onboarding-wizard?tableFilter=$TableFilter") @@ -69,8 +71,8 @@ Function Invoke-ExecGDAPInvite { } } catch { $Message = 'Error creating GDAP relationship' - Write-Host "GDAP ERROR: $($_.Exception.Message)" - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $env:TenantID -message "$($Message): $($_.Exception.Message)" -Sev 'Error' + Write-Host "GDAP ERROR: $($_.InvocationInfo.PositionMessage)" + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $env:TenantID -message "$($Message): $($_.Exception.Message)" -Sev 'Error' -LogData (Get-CippException -Exception $_) } $body = @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 index 23565a19602e..7430ff9e1ce5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGDAPInviteApproved { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 index 319118877545..c6a60971f1c6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 @@ -2,7 +2,9 @@ using namespace System.Net Function Invoke-ExecGDAPRemoveGArole { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 index afc2bacfc630..218f0248f2cc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGDAPInvite { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPQueue.ps1 index 94f43d623abe..d3110cadd8ad 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPQueue.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGDAPQueue { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -14,7 +16,7 @@ Function Invoke-ListGDAPQueue { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' - $Table = Get-CIPPTable -TableName 'GDAPMigration' + $Table = Get-CIPPTable -TableName 'GDAPMigration' $QueuedApps = Get-CIPPAzDataTableEntity @Table $CurrentStandards = foreach ($QueueFile in $QueuedApps) { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 index 0102748cb4f8..f39e16ebd1fc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGDAPRoles { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -14,7 +16,7 @@ Function Invoke-ListGDAPRoles { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' - $Table = Get-CIPPTable -TableName 'GDAPRoles' + $Table = Get-CIPPTable -TableName 'GDAPRoles' $Groups = Get-CIPPAzDataTableEntity @Table $MappedGroups = foreach ($Group in $Groups) { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 index 4a43292deba6..091d903054b7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddStandardsDeploy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 index 27c8774bae3c..8e5186727b8f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddStandardsTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -22,7 +24,7 @@ Function Invoke-AddStandardsTemplate { } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created CA Template $($Request.body.name) with GUID $GUID" -Sev 'Debug' $body = [pscustomobject]@{'Results' = 'Successfully added template' } - + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 index e1930a1cbc04..5bf7c40a6741 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-BestPracticeAnalyser_List { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.BestPracticeAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -13,7 +15,7 @@ Function Invoke-BestPracticeAnalyser_List { $Tenants = Get-Tenants $Table = get-cipptable 'cachebpa' - $Results = (Get-CIPPAzDataTableEntity @Table) | ForEach-Object { + $Results = (Get-CIPPAzDataTableEntity @Table) | ForEach-Object { $_.UnusedLicenseList = @(ConvertFrom-Json -ErrorAction silentlycontinue -InputObject $_.UnusedLicenseList) $_ } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 index c205bf24d57b..f200e4729272 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecStandardsRun { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 index 0e632d4fba35..df3e849a19e8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListBPA { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.BestPracticeAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -46,7 +48,12 @@ Function Invoke-ListBPA { $Data = $mergedObject } else { + $AllowedTenants = Test-CIPPAccess -Request $Request -TenantList $Tenants = Get-Tenants -IncludeErrors + if ($AllowedTenants -notcontains 'AllTenants') { + $Tenants = $Tenants | Where-Object -Property customerId -In $AllowedTenants + } + Write-Information ($tenants.defaultDomainName | ConvertTo-Json) $Data = (Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$NAME'") | ForEach-Object { $row = $_ $JSONFields | ForEach-Object { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 index 2185772864cd..7f7c110fcd9f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListBPATemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.BestPracticeAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 index 76fe08536529..95077930211f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 @@ -4,7 +4,9 @@ using namespace System.Net Function Invoke-ListDomainAnalyser { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.DomainAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 index dfbd46514448..fb04e3d547ca 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDomainHealth { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.DomainAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 index acc984d6e0ab..1b17d33131a2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-listStandardTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,11 +13,11 @@ Function Invoke-listStandardTemplates { $APIName = $TriggerMetadata.FunctionName $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'StandardsTemplate'" + $Filter = "PartitionKey eq 'StandardsTemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $data = $_.JSON | ConvertFrom-Json -Depth 100 $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force - $data + $data } | Sort-Object -Property displayName # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/invoke-DomainAnalyser_List.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/invoke-DomainAnalyser_List.ps1 index e1c7c345e511..1682b8b30cd1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/invoke-DomainAnalyser_List.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/invoke-DomainAnalyser_List.ps1 @@ -4,7 +4,9 @@ using namespace System.Net Function Invoke-DomainAnalyser_List { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.DomainAnalyser.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -19,7 +21,7 @@ Function Invoke-DomainAnalyser_List { try { # Extract json from table results $Results = foreach ($DomainAnalyserResult in (Get-CIPPAzDataTableEntity @DomainTable).DomainAnalyser) { - try { + try { if (![string]::IsNullOrEmpty($DomainAnalyserResult)) { $Object = $DomainAnalyserResult | ConvertFrom-Json -ErrorAction SilentlyContinue $Object diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 index f04c365c5ccf..01e72df98868 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecGraphExplorerPreset { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddTenantAllowBlockList.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddTenantAllowBlockList.ps1 index c94b9ecf1ea2..00c2cffc02e7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddTenantAllowBlockList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddTenantAllowBlockList.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-AddTenantAllowBlockList { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -20,10 +22,10 @@ Function Invoke-AddTenantAllowBlockList { tenantid = $Request.body.tenantid cmdlet = 'New-TenantAllowBlockListItems' cmdParams = @{ - Entries = [string[]]$blocklistobj.entries - ListType = [string]$blocklistobj.listType - Notes = [string]$blocklistobj.notes - $blocklistobj.listMethod = [bool]$true + Entries = [string[]]$blocklistobj.entries + ListType = [string]$blocklistobj.listType + Notes = [string]$blocklistobj.notes + $blocklistobj.listMethod = [bool]$true } } @@ -43,10 +45,10 @@ Function Invoke-AddTenantAllowBlockList { # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = @{ - 'Results' = $result - 'Request' = $ExoRequest - } - }) + StatusCode = [HttpStatusCode]::OK + Body = @{ + 'Results' = $result + 'Request' = $ExoRequest + } + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 index 3f78672c9894..5ea8abad3067 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 @@ -3,16 +3,18 @@ using namespace System.Net Function Invoke-ExecExtensionNinjaOneQueue { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) - + Switch ($QueueItem.NinjaAction) { 'StartAutoMapping' { Invoke-NinjaOneOrgMapping } - 'AutoMapTenant' { Invoke-NinjaOneOrgMappingTenant -QueueItem $QueueItem } + 'AutoMapTenant' { Invoke-NinjaOneOrgMappingTenant -QueueItem $QueueItem } 'SyncTenant' { Invoke-NinjaOneTenantSync -QueueItem $QueueItem } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 index d3695a00742f..1adc1799debd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 @@ -1,26 +1,28 @@ using namespace System.Net Function Invoke-ExecListAppId { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $ResponseURL = "$(($Request.headers.'x-ms-original-url').replace('/api/ExecListAppId','/api/ExecSAMSetup'))" + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $ResponseURL = "$(($Request.headers.'x-ms-original-url').replace('/api/ExecListAppId','/api/ExecSAMSetup'))" - $Results = @{ - applicationId = $ENV:ApplicationID - tenantId = $ENV:TenantID - refreshUrl = "https://login.microsoftonline.com/$ENV:TenantID/oauth2/v2.0/authorize?client_id=$ENV:ApplicationID&response_type=code&redirect_uri=$ResponseURL&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default+offline_access+profile+openid&state=1&prompt=select_account" - } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + $Results = @{ + applicationId = $ENV:ApplicationID + tenantId = $ENV:TenantID + refreshUrl = "https://login.microsoftonline.com/$ENV:TenantID/oauth2/v2.0/authorize?client_id=$ENV:ApplicationID&response_type=code&redirect_uri=$ResponseURL&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default+offline_access+profile+openid&state=1&prompt=select_account" + } + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecRestoreDeleted.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecRestoreDeleted.ps1 index a78905f8386a..403e4e3dcdfa 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecRestoreDeleted.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecRestoreDeleted.ps1 @@ -1,30 +1,32 @@ using namespace System.Net Function Invoke-ExecRestoreDeleted { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.ReadWrite #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter - try { - $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/v1.0/directory/deletedItems/$($Request.query.ID)/restore" -tenantid $TenantFilter -type POST -body '{}' -verbose - $Results = [pscustomobject]@{'Results' = 'Successfully completed request.' } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } - } + try { + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/v1.0/directory/deletedItems/$($Request.query.ID)/restore" -tenantid $TenantFilter -type POST -body '{}' -verbose + $Results = [pscustomobject]@{'Results' = 'Successfully completed request.' } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 index 2b4fd7d70190..6c373d6deaf4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSchedulerBillingRun { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Scheduler.Billing.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 index b70f200aae55..e5293d373605 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSendOrgMessage { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -81,7 +83,7 @@ Function Invoke-ExecSendOrgMessage { } }) }) - }) + }) } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSyncAPDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSyncAPDevices.ps1 index 0d5b9b9e253d..98dae4f0f308 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSyncAPDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSyncAPDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecSyncAPDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 index eda323666fa1..f16a350fc2c6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ExecUniversalSearch { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 index ab9092f13c1d..ec1381e24e45 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 @@ -3,7 +3,9 @@ using namespace System.Net function Invoke-ExecUserSettings { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.ReadWrite #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 index d9d49840c7b4..31c3e5dd4675 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAllTenantDeviceCompliance { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.DeviceCompliance.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -19,18 +21,18 @@ Function Invoke-ListAllTenantDeviceCompliance { $TenantFilter = $Request.Query.TenantFilter try { if ($TenantFilter -eq 'AllTenants') { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/tenantRelationships/managedTenants/managedDeviceCompliances' - $StatusCode = [HttpStatusCode]::OK + $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/tenantRelationships/managedTenants/managedDeviceCompliances' + $StatusCode = [HttpStatusCode]::OK } else { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/managedDeviceCompliances?`$top=999&`$filter=organizationId eq '$TenantFilter'" + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/managedDeviceCompliances?`$top=999&`$filter=organizationId eq '$TenantFilter'" $StatusCode = [HttpStatusCode]::OK } - if ($GraphRequest.value.count -lt 1) { + if ($GraphRequest.value.count -lt 1) { $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = 'No data found - This client might not be onboarded in Lighthouse' + $GraphRequest = 'No data found - This client might not be onboarded in Lighthouse' } - } catch { + } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message $StatusCode = [HttpStatusCode]::Forbidden $GraphRequest = "Could not connect to Azure Lighthouse API: $($ErrorMessage)" diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 index 1b6723d21c17..93a95f880983 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAppStatus { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Device.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAutopilotconfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAutopilotconfig.ps1 index 43ae12082452..1b4c8f4a1440 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAutopilotconfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAutopilotconfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAutopilotconfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAzureADConnectStatus.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAzureADConnectStatus.ps1 index f1b1b0592e76..0a02e1814601 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAzureADConnectStatus.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAzureADConnectStatus.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListAzureADConnectStatus { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -41,10 +43,10 @@ Function Invoke-ListAzureADConnectStatus { $GraphRequest = foreach ($Type in $types) { New-GraphGetRequest -uri "https://graph.microsoft.com/beta/$($Type)?`$select=$($selectlist -join ',')" -tenantid $TenantFilter | ForEach-Object { if ($_.id -ne $null) { - $_ | Add-Member -NotePropertyName ObjectType -NotePropertyValue $Type + $_ | Add-Member -NotePropertyName ObjectType -NotePropertyValue $Type $_ } - + } } $ObjectsInError = @($GraphRequest) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCalendarPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCalendarPermissions.ps1 index 3bbefa764b84..9112981dad14 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCalendarPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCalendarPermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListCalendarPermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListContacts.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListContacts.ps1 index 768417a1db23..00a7b0410365 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListContacts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListContacts.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListContacts { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Contact.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderState.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderState.ps1 index 5b5a244c7e72..78a4f1bcbbf0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderState.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderState.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDefenderState { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -19,11 +21,11 @@ Function Invoke-ListDefenderState { $TenantFilter = $Request.Query.TenantFilter try { $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/windowsProtectionStates?`$top=999&`$filter=tenantId eq '$TenantFilter'" - if ($GraphRequest.tenantDisplayName.length -lt 1) { + if ($GraphRequest.tenantDisplayName.length -lt 1) { $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = 'No data found - This client might not be onboarded in Lighthouse' + $GraphRequest = 'No data found - This client might not be onboarded in Lighthouse' } - } catch { + } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message $StatusCode = [HttpStatusCode]::Forbidden $GraphRequest = "Could not connect to Azure Lighthouse API: $($ErrorMessage)" diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderTVM.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderTVM.ps1 index 2011f161abaf..01e7cacb254f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderTVM.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDefenderTVM.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDefenderTVM { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -40,7 +42,7 @@ Function Invoke-ListDefenderTVM { $StatusCode = [HttpStatusCode]::Forbidden $GroupObj = $ErrorMessage } - # Associate values to output bindings by calling 'Push-OutputBinding'. + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode Body = @($GroupObj) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeletedItems.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeletedItems.ps1 index 2f3488655fa0..26d68ac580b7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeletedItems.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeletedItems.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDeletedItems { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -19,7 +21,7 @@ Function Invoke-ListDeletedItems { $TenantFilter = $Request.Query.TenantFilter $Types = 'Application', 'User', 'Device', 'Group' $GraphRequest = foreach ($Type in $Types) { - (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directory/deletedItems/microsoft.graph.$($Type)" -tenantid $TenantFilter) | Where-Object -Property '@odata.context' -NotLike '*graph.microsoft.com*' | Select-Object *, @{ Name = 'TargetType'; Expression = { $Type } } + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directory/deletedItems/microsoft.graph.$($Type)" -tenantid $TenantFilter) | Where-Object -Property '@odata.context' -NotLike '*graph.microsoft.com*' | Select-Object *, @{ Name = 'TargetType'; Expression = { $Type } } } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 index f3a4d9f309c9..1d561c958f65 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListDeviceDetails { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Device.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -28,7 +30,7 @@ Function Invoke-ListDeviceDetails { $Found = $False if ($SeriaNumber -and $DeviceName) { $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices?`$filter=serialnumber eq '$DeviceSerial' and deviceName eq '$DeviceName'" -Tenantid $tenantfilter - + if (($GraphRequest | Measure-Object).count -eq 1 -and $GraphRequest.'@odata.count' -ne 0 ) { $Found = $True } @@ -75,7 +77,7 @@ Function Invoke-ListDeviceDetails { $DeviceGroups = Get-GraphBulkResultByID -Results $BulkResults -ID 'DeviceGroups' -Value $CompliancePolicies = Get-GraphBulkResultByID -Results $BulkResults -ID 'CompliancePolicies' -Value - $DetectedApps = Get-GraphBulkResultByID -Results $BulkResults -ID 'DetectedApps' + $DetectedApps = Get-GraphBulkResultByID -Results $BulkResults -ID 'DetectedApps' $Null = $GraphRequest | Add-Member -NotePropertyName 'DetectedApps' -NotePropertyValue ($DetectedApps.DetectedApps | Select-Object id, displayName, version) $Null = $GraphRequest | Add-Member -NotePropertyName 'CompliancePolicies' -NotePropertyValue ($CompliancePolicies | Select-Object id, displayname, UserPrincipalName, state) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomains.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomains.ps1 index 113b9d53a304..149eb8fa9a04 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomains.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomains.ps1 @@ -1,35 +1,37 @@ using namespace System.Net Function Invoke-ListDomains { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter - try { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $TenantFilter | Select-Object id, isdefault, isinitial | Sort-Object isdefault - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage - } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + try { + $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $TenantFilter | Select-Object id, isdefault, isinitial | Sort-Object isdefault + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = $ErrorMessage + } + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 index 897fcf53b3ed..8c96c119f2f0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListExConnectorTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -14,14 +16,14 @@ Function Invoke-ListExConnectorTemplates { #List new policies $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'ExConnectorTemplate'" + $Filter = "PartitionKey eq 'ExConnectorTemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $GUID = $_.RowKey $Direction = $_.direction - $data = $_.JSON | ConvertFrom-Json + $data = $_.JSON | ConvertFrom-Json $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $GUID $data | Add-Member -NotePropertyName 'cippconnectortype' -NotePropertyValue $Direction - $data + $data } | Sort-Object -Property displayName if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property RowKey -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExchangeConnectors.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExchangeConnectors.ps1 index 35b1863f45f8..95120eab6ac6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExchangeConnectors.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExchangeConnectors.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListExchangeConnectors { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 index 5e9cd48198c8..e2feff0542d7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListExtensionsConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 index 55fb22f3f99e..f5c773792ce2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListExternalTenantInfo { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 index 2be8941920f1..64c465e799e9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 @@ -3,7 +3,9 @@ using namespace System.Net function Invoke-ListFunctionParameters { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 index 7a0ca462e60e..037801e25962 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListFunctionStats { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 index ddb0c55b1444..32afe59ac176 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGenericAllTenants { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 index 80012cd30de9..8cfed503e5cb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGenericTestFunction { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 index 100aa6a450ba..1212c03efee0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGraphExplorerPresets { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 index cd0f73a61f45..4177e3e24368 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 @@ -2,10 +2,9 @@ function Invoke-ListGraphRequest { <# .FUNCTIONALITY - Entrypoint - + Entrypoint .ROLE - Core.Read + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroupTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroupTemplates.ps1 index 205410cd9f92..6a6bc6b12248 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroupTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroupTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGroupTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -17,9 +19,9 @@ Function Invoke-ListGroupTemplates { #List new policies $Table = Get-CippTable -tablename 'templates' - $Filter = "PartitionKey eq 'GroupTemplate'" + $Filter = "PartitionKey eq 'GroupTemplate'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { - $data = $_.JSON | ConvertFrom-Json + $data = $_.JSON | ConvertFrom-Json $data | Add-Member -MemberType NoteProperty -Name GUID -Value $_.RowKey -Force $data } | Sort-Object -Property displayName diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1 index d25ccd2c6d9f..b59ceae2fd06 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListGroups { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -20,16 +22,16 @@ Function Invoke-ListGroups { $TenantFilter = $Request.Query.TenantFilter $selectstring = "id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,grouptypes,onPremisesSyncEnabled,resourceProvisioningOptions,userPrincipalName&`$expand=members(`$select=userPrincipalName)" - if ($Request.Query.GroupID) { + if ($Request.Query.GroupID) { $groupid = $Request.query.groupid $selectstring = 'id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,groupTypes,userPrincipalName' } - if ($Request.Query.members) { + if ($Request.Query.members) { $members = 'members' $selectstring = 'id,userPrincipalName,displayName,hideFromOutlookClients,hideFromAddressLists,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule' } - if ($Request.Query.owners) { + if ($Request.Query.owners) { $members = 'owners' $selectstring = 'id,userPrincipalName,displayName,hideFromOutlookClients,hideFromAddressLists,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule' } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 index 84b1b3cae514..e00ba611aa67 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 @@ -1,49 +1,51 @@ using namespace System.Net Function Invoke-ListHaloClients { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Extension.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - try { - $Table = Get-CIPPTable -TableName Extensionsconfig - $Configuration = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json).HaloPSA - $Token = Get-HaloToken -configuration $Configuration - $i = 1 - $RawHaloClients = do { - $Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } - $Result.clients | Select-Object * -ExcludeProperty logo - $i++ - $pagecount = [Math]::Ceiling($Result.record_count / 999) - } while ($i -le $pagecount) - $HaloClients = $RawHaloClients | ForEach-Object { - [PSCustomObject]@{ - label = $_.name - value = $_.id - } - } - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $HaloClients = $ErrorMessage + # Interact with query parameters or the body of the request. + try { + $Table = Get-CIPPTable -TableName Extensionsconfig + $Configuration = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json).HaloPSA + $Token = Get-HaloToken -configuration $Configuration + $i = 1 + $RawHaloClients = do { + $Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } + $Result.clients | Select-Object * -ExcludeProperty logo + $i++ + $pagecount = [Math]::Ceiling($Result.record_count / 999) + } while ($i -le $pagecount) + $HaloClients = $RawHaloClients | ForEach-Object { + [PSCustomObject]@{ + label = $_.name + value = $_.id + } } + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $HaloClients = $ErrorMessage + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($HaloClients) - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($HaloClients) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 index 985473bc5bb8..bf031cfb22a8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListIPWhitelist { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListInactiveAccounts.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListInactiveAccounts.ps1 index 3ce42719c362..559543a51a67 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListInactiveAccounts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListInactiveAccounts.ps1 @@ -1,36 +1,38 @@ using namespace System.Net Function Invoke-ListInactiveAccounts { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - if ($TenantFilter -eq 'AllTenants') { $TenantFilter = (get-tenants).customerId } - try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/inactiveUsers?`$count=true" -tenantid $env:TenantId | Where-Object { $_.tenantId -in $TenantFilter } - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = "Could not connect to Azure Lighthouse API: $($ErrorMessage)" - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + if ($TenantFilter -eq 'AllTenants') { $TenantFilter = (get-tenants).customerId } + try { + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/inactiveUsers?`$count=true" -tenantid $env:TenantId | Where-Object { $_.tenantId -in $TenantFilter } + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = "Could not connect to Azure Lighthouse API: $($ErrorMessage)" + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 index cb98c87d6e67..b7043311731c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 @@ -1,35 +1,37 @@ using namespace System.Net Function Invoke-ListIntuneIntents { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/Intents?`$expand=settings,categories" -tenantid $TenantFilter - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + try { + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/Intents?`$expand=settings,categories" -tenantid $TenantFilter + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = $ErrorMessage + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntunePolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntunePolicy.ps1 index 5429292d5a6c..dbccf5a4004e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntunePolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntunePolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListIntunePolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -46,7 +48,7 @@ Function Invoke-ListIntunePolicy { default { $_.'assignments@odata.context' } } if ($_.displayname -eq $null) { $_ | Add-Member -NotePropertyName displayName -NotePropertyValue $_.name } - $_ | Add-Member -NotePropertyName PolicyTypeName -NotePropertyValue $policyTypeName + $_ | Add-Member -NotePropertyName PolicyTypeName -NotePropertyValue $policyTypeName $_ | Add-Member -NotePropertyName URLName -NotePropertyValue $URLName $_ } | Where-Object { $_.DisplayName -ne $null } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 index d9c02d090fb2..c94431612970 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListIntuneTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -36,7 +38,7 @@ Function Invoke-ListIntuneTemplates { $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force $data } | Sort-Object -Property displayName - } + } if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property guid -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 index 061146ae725f..09f488be2304 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListKnownIPDb { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLicenses.ps1 index ead6a0d2cd9d..1fc0f4ca57e9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLicenses.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLicenses.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListLicenses { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 index a3963bd0bc94..0a3877cfc4c9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 @@ -3,14 +3,18 @@ using namespace System.Net Function Invoke-ListLogs { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) + $AllowedTenants = Test-CIPPAccess -Request $Request -TenantList $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $TenantList = Get-Tenants -IncludeErrors if ($request.Query.Filter -eq 'True') { $LogLevel = if ($Request.query.Severity) { ($Request.query.Severity).split(',') } else { 'Info', 'Warn', 'Error', 'Critical', 'Alert' } $PartitionKey = $Request.query.DateFilter @@ -34,6 +38,15 @@ Function Invoke-ListLogs { $Filter = "PartitionKey eq '{0}'" -f $PartitionKey $Rows = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object { $_.Severity -In $LogLevel -and $_.user -like $username } foreach ($Row in $Rows) { + + if ($AllowedTenants -notcontains 'AllTenants') { + if ($Row.Tenant -ne 'None') { + $Tenant = $TenantList | Where-Object -Property defaultDomainName -EQ $Row.Tenant + if ($Tenant.customerId -notin $AllowedTenants) { + continue + } + } + } $LogData = if ($Row.LogData -and (Test-Json -Json $Row.LogData)) { $Row.LogData | ConvertFrom-Json } else { $Row.LogData } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMFAUsers.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMFAUsers.ps1 index 118ca8d4b050..e73aa9205517 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMFAUsers.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMFAUsers.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMFAUsers { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxCAS.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxCAS.ps1 index ef93210d4c25..4386157564d4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxCAS.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxCAS.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailboxCAS { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices copy.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices copy.ps1 deleted file mode 100644 index 8199d4204326..000000000000 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices copy.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -using namespace System.Net - -Function Invoke-ListMailboxMobileDevices { - <# - .FUNCTIONALITY - Entrypoint - #> - [CmdletBinding()] - param($Request, $TriggerMetadata) - - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - $Mailbox = $Request.Query.Mailbox - - Write-Host $TenantFilter - Write-Host $Mailbox - - $Bytes = [System.Text.Encoding]::UTF8.GetBytes($Mailbox) - $base64IdentityParam = [Convert]::ToBase64String($Bytes) - - try { - $GraphRequest = New-GraphGetRequest -uri "https://outlook.office365.com:443/adminapi/beta/$($TenantFilter)/mailbox('$($base64IdentityParam)')/MobileDevice/Exchange.GetMobileDeviceStatistics()/?IsEncoded=True" -Tenantid $tenantfilter -scope ExchangeOnline | Select-Object @{ Name = 'clientType'; Expression = { $_.ClientType } }, - @{ Name = 'clientVersion'; Expression = { $_.ClientVersion } }, - @{ Name = 'deviceAccessState'; Expression = { $_.DeviceAccessState } }, - @{ Name = 'deviceFriendlyName'; Expression = { if ([string]::IsNullOrEmpty($_.DeviceFriendlyName)) { 'Unknown' }else { $_.DeviceFriendlyName } } }, - @{ Name = 'deviceModel'; Expression = { $_.DeviceModel } }, - @{ Name = 'deviceOS'; Expression = { $_.DeviceOS } }, - @{ Name = 'deviceType'; Expression = { $_.DeviceType } }, - @{ Name = 'firstSync'; Expression = { $_.FirstSyncTime.toString() } }, - @{ Name = 'lastSyncAttempt'; Expression = { $_.LastSyncAttemptTime.toString() } }, - @{ Name = 'lastSuccessSync'; Expression = { $_.LastSuccessSync.toString() } }, - @{ Name = 'status'; Expression = { $_.Status } }, - @{ Name = 'deviceID'; Expression = { $_.deviceID } }, - @{ Name = 'Guid'; Expression = { $_.Guid } } - - $StatusCode = [HttpStatusCode]::OK - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage - } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) - -} diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices.ps1 index 8199d4204326..d1bab545e7a8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxMobileDevices.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailboxMobileDevices { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRestores.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRestores.ps1 index f47458585c09..35d44175e0a5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRestores.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRestores.ps1 @@ -1,4 +1,10 @@ function Invoke-ListMailboxRestores { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Exchange.Mailbox.Read + #> param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1 index 696369dc8c38..e5bd0a1530c9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailboxRules { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxStatistics.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxStatistics.ps1 index d1f1af749fb7..795812096c50 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxStatistics.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxStatistics.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailboxStatistics { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 index c924a85ea1dd..7a125550426a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListMailboxes { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 index 0acac97628d5..c1fb2e5c731a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListNamedLocations { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -18,7 +20,7 @@ Function Invoke-ListNamedLocations { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter try { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -Tenantid $tenantfilter | Select-Object *, + $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -Tenantid $tenantfilter | Select-Object *, @{ name = 'rangeOrLocation' expression = { if ($_.ipRanges) { $_.ipranges.cidrAddress -join ', ' } else { $_.countriesAndRegions -join ', ' } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 index 68545565ee6b..a375c65deb04 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListNotificationConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.AppSettings.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOAuthApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOAuthApps.ps1 index 13fafdf39a2c..2183317e991d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOAuthApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOAuthApps.ps1 @@ -1,54 +1,56 @@ using namespace System.Net Function Invoke-ListOAuthApps { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Application.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) - - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - if ($TenantFilter -eq 'AllTenants') { $Tenants = (Get-Tenants).defaultDomainName } else { $tenants = $TenantFilter } - - try { - $GraphRequest = foreach ($Tenant in $Tenants) { - try { - $ServicePrincipals = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$select=id,displayName,appid" -tenantid $Tenant - New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/oauth2PermissionGrants' -tenantid $Tenant | ForEach-Object { - $CurrentServicePrincipal = ($ServicePrincipals | Where-Object -Property id -EQ $_.clientId) - [PSCustomObject]@{ - Tenant = $Tenant - Name = $CurrentServicePrincipal.displayName - ApplicationID = $CurrentServicePrincipal.appid - ObjectID = $_.clientId - Scope = ($_.scope -join ',') - StartTime = $_.startTime - } - } - $StatusCode = [HttpStatusCode]::OK - } catch { - continue - } + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + + + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + if ($TenantFilter -eq 'AllTenants') { $Tenants = (Get-Tenants).defaultDomainName } else { $tenants = $TenantFilter } + + try { + $GraphRequest = foreach ($Tenant in $Tenants) { + try { + $ServicePrincipals = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$select=id,displayName,appid" -tenantid $Tenant + New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/oauth2PermissionGrants' -tenantid $Tenant | ForEach-Object { + $CurrentServicePrincipal = ($ServicePrincipals | Where-Object -Property id -EQ $_.clientId) + [PSCustomObject]@{ + Tenant = $Tenant + Name = $CurrentServicePrincipal.displayName + ApplicationID = $CurrentServicePrincipal.appid + ObjectID = $_.clientId + Scope = ($_.scope -join ',') + StartTime = $_.startTime + } } - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $StatusCode = [HttpStatusCode]::Forbidden - $GraphRequest = $ErrorMessage + $StatusCode = [HttpStatusCode]::OK + } catch { + continue + } } - - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = @($GraphRequest) - }) + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + $StatusCode = [HttpStatusCode]::Forbidden + $GraphRequest = $ErrorMessage + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($GraphRequest) + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 index 20842ce9dafb..feb6de0d2f74 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 @@ -1,32 +1,34 @@ using namespace System.Net Function Invoke-ListOrg { - <# + <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Core.Read #> - [CmdletBinding()] - param($Request, $TriggerMetadata) + [CmdletBinding()] + param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - if ($TenantFilter -eq 'AllTenants') { - - } else { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/organization' -tenantid $TenantFilter - } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.TenantFilter + if ($TenantFilter -eq 'AllTenants') { - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $GraphRequest - }) + } else { + $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/organization' -tenantid $TenantFilter + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $GraphRequest + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 index 591b6b23d3bf..6ca16cfe8fd9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListPartnerRelationships { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Relationship.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 index 24c7020f0e31..96c4a6eeb13a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListPendingWebhooks { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 index 86062e4e80fa..0dfbeaa01642 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListPotentialApps { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 index 6eca5db05c5b..9f17fde986f1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListRoles { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Directory.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -21,7 +23,7 @@ Function Invoke-ListRoles { [System.Collections.Generic.List[PSCustomObject]]$Roles = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/directoryRoles?`$expand=members" -tenantid $TenantFilter $GraphRequest = foreach ($Role in $Roles) { - + #[System.Collections.Generic.List[PSCustomObject]]$Members = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles/$($Role.id)/members?`$select=$($selectlist -join ',')" -tenantid $TenantFilter | Select-Object $SelectList $Members = if ($Role.members) { $role.members | ForEach-Object { " $($_.displayName) ($($_.userPrincipalName))" } } else { 'none' } [PSCustomObject]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoomLists.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoomLists.ps1 index 74148522dec5..6f586800d8d0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoomLists.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoomLists.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListRoomLists { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Room.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -20,9 +22,9 @@ Function Invoke-ListRoomLists { try { $params = @{ - uri = 'https://graph.microsoft.com/beta/places/microsoft.graph.roomlist' + uri = 'https://graph.microsoft.com/beta/places/microsoft.graph.roomlist' tenantid = $TenantFilter - AsApp = $true + AsApp = $true } $GraphRequest = New-GraphGetRequest @params diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRooms.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRooms.ps1 index 4e2f57124129..34074ce76c3c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRooms.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRooms.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListRooms { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Room.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListServiceHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListServiceHealth.ps1 index 1c497fb40f9e..d9242a3e29a3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListServiceHealth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListServiceHealth.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListServiceHealth { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Administration.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxAccountEnabled.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxAccountEnabled.ps1 index 683f05eed5a1..4467289996ab 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxAccountEnabled.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxAccountEnabled.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSharedMailboxAccountEnabled { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -27,18 +29,18 @@ Function Invoke-ListSharedMailboxAccountEnabled { if ($User.accountEnabled) { $User | Select-Object ` @{Name = 'UserPrincipalName'; Expression = { $User.UserPrincipalName } }, ` - @{Name = 'displayName'; Expression = { $User.displayName } }, - @{Name = 'givenName'; Expression = { $User.givenName } }, - @{Name = 'surname'; Expression = { $User.surname } }, + @{Name = 'displayName'; Expression = { $User.displayName } }, + @{Name = 'givenName'; Expression = { $User.givenName } }, + @{Name = 'surname'; Expression = { $User.surname } }, @{Name = 'accountEnabled'; Expression = { $User.accountEnabled } }, @{Name = 'id'; Expression = { $User.id } }, @{Name = 'onPremisesSyncEnabled'; Expression = { $User.onPremisesSyncEnabled } } - + } } } catch { - Write-LogMessage -API 'Tenant' -tenant $tenantfilter -message "Shared Mailbox Enabled Accounts on $($tenantfilter). Error: $($_.exception.message)" -sev 'Error' + Write-LogMessage -API 'Tenant' -tenant $tenantfilter -message "Shared Mailbox Enabled Accounts on $($tenantfilter). Error: $($_.exception.message)" -sev 'Error' } $GraphRequest = $EnabledUsersWithSharedMailbox diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxStatistics.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxStatistics.ps1 index 387d82b3f6dd..4b16ac630c80 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxStatistics.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharedMailboxStatistics.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSharedMailboxStatistics { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharepointQuota.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharepointQuota.ps1 index b1a7dc2236ab..b8d7d8a50995 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharepointQuota.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSharepointQuota.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListSharepointQuota { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Sharepoint.Admin.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSignIns.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSignIns.ps1 index debfb0931ac0..b58f472a7494 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSignIns.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSignIns.ps1 @@ -3,12 +3,14 @@ using namespace System.Net Function Invoke-ListSignIns { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.AuditLog.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) - + # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' @@ -18,8 +20,8 @@ Function Invoke-ListSignIns { if ($Request.query.failedlogonOnly) { $FailedLogons = ' and (status/errorCode eq 50126)' } - - $filters = if ($Request.query.Filter) { + + $filters = if ($Request.query.Filter) { $request.query.filter } else { $currentTime = Get-Date -Format 'yyyy-MM-dd' @@ -30,12 +32,12 @@ Function Invoke-ListSignIns { Write-Host $Filters $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/auditLogs/signIns?api-version=beta&`$filter=$($filters)" -tenantid $TenantFilter -erroraction stop - $response = $GraphRequest | Select-Object *, + $response = $GraphRequest | Select-Object *, @{l = 'additionalDetails'; e = { $_.status.additionalDetails } } , @{l = 'errorCode'; e = { $_.status.errorCode } }, - @{l = 'locationcipp'; e = { "$($_.location.city) - $($_.location.countryOrRegion)" } } + @{l = 'locationcipp'; e = { "$($_.location.city) - $($_.location.countryOrRegion)" } } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Retrieved sign in report' -Sev 'Debug' -tenant $TenantFilter - + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListStandards.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListStandards.ps1 index ef3e205c8467..dd39cb4ac683 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListStandards.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListStandards.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListStandards { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 index ed51de874171..d67651c0bc3f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListTenantAllowBlockList { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -16,7 +18,7 @@ Function Invoke-ListTenantAllowBlockList { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter - $ListTypes = 'Sender','Url','FileHash' + $ListTypes = 'Sender', 'Url', 'FileHash' try { $cmdletArray = $ListTypes | ForEach-Object { @{ @@ -26,7 +28,7 @@ Function Invoke-ListTenantAllowBlockList { } } } - $BatchResults = New-ExoBulkRequest -tenantid $TenantFilter -cmdletArray $cmdletArray + $BatchResults = New-ExoBulkRequest -tenantid $TenantFilter -cmdletArray @($cmdletArray) $StatusCode = [HttpStatusCode]::OK } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListmailboxPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListmailboxPermissions.ps1 index d855df71778b..41f16aba1e48 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListmailboxPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListmailboxPermissions.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-ListmailboxPermissions { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Mailbox.Read #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -21,9 +23,9 @@ Function Invoke-ListmailboxPermissions { Write-Host "Tenant Filter: $TenantFilter" try { $Bytes = [System.Text.Encoding]::UTF8.GetBytes($Request.Query.UserID) - $base64IdentityParam = [Convert]::ToBase64String($Bytes) - $PermsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Mailbox('$($Request.Query.UserID)')/MailboxPermission" -Tenantid $tenantfilter -scope ExchangeOnline - $PermsRequest2 = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Recipient('$base64IdentityParam')?`$expand=RecipientPermission&isEncoded=true" -Tenantid $tenantfilter -scope ExchangeOnline + $base64IdentityParam = [Convert]::ToBase64String($Bytes) + $PermsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Mailbox('$($Request.Query.UserID)')/MailboxPermission" -Tenantid $tenantfilter -scope ExchangeOnline + $PermsRequest2 = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/Recipient('$base64IdentityParam')?`$expand=RecipientPermission&isEncoded=true" -Tenantid $tenantfilter -scope ExchangeOnline $PermRequest3 = New-ExoRequest -Anchor $Request.Query.UserID -tenantid $Tenantfilter -cmdlet 'Get-Mailbox' -cmdParams @{Identity = $($Request.Query.UserID); } $GraphRequest = foreach ($Perm in $PermsRequest, $PermsRequest2.RecipientPermission, $PermRequest3) { @@ -34,20 +36,20 @@ Function Invoke-ListmailboxPermissions { Permissions = $_.accessRights } } - + } if ($perm.PermissionList) { $perm | Where-Object User | ForEach-Object { [PSCustomObject]@{ User = $_.User Permissions = $_.PermissionList.accessRights -join ', ' - } + } } } if ($perm.GrantSendonBehalfTo -ne $null) { $perm.GrantSendonBehalfTo | ForEach-Object { [PSCustomObject]@{ User = $_ Permissions = 'SendOnBehalf' - } + } } } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-PublicPhishingCheck.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-PublicPhishingCheck.ps1 index 37136c230bdd..105bdf0df0d8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-PublicPhishingCheck.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-PublicPhishingCheck.ps1 @@ -3,12 +3,12 @@ using namespace System.Net Function Invoke-PublicPhishingCheck { <# .FUNCTIONALITY - Entrypoint + Entrypoint #> [CmdletBinding()] param($Request, $TriggerMetadata) Write-Host ($request | ConvertTo-Json) - + # List valid referers $validList = @( 'https://login.microsoftonline.com', @@ -25,20 +25,20 @@ Function Invoke-PublicPhishingCheck { Write-Host 'Not being Phished, no issue' } else { $bytes = [Convert]::FromBase64String('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') - + $AlertMessage = If ($Request.headers.referer) { - "Potential Phishing page detected. Detected Information: Hosted at $($Request.headers.referer). Access by IP $($request.headers.'x-forwarded-for')" + "Potential Phishing page detected. Detected Information: Hosted at $($Request.headers.referer). Access by IP $($request.headers.'x-forwarded-for')" } else { - "Potential Phishing page detected. Detected Information: Access by IP $($request.headers.'x-forwarded-for')" + "Potential Phishing page detected. Detected Information: Access by IP $($request.headers.'x-forwarded-for')" } - Write-AlertMessage -message $AlertMessage -sev 'Alert' -tenant $Request.query.TenantId + Write-AlertMessage -message $AlertMessage -sev 'Alert' -tenant $Request.query.TenantId } - + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK ContentType = 'image/png' - Body = $bytes + Body = $bytes }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 index d9f99772b4d8..52807bdcc27f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveTenantAllowBlockList { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.SpamFilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 index 77a9e22e107b..fdcb3d3eb95b 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 @@ -103,7 +103,7 @@ function Get-Tenants { } } - $obj = [PSCustomObject]@{ + $Obj = [PSCustomObject]@{ PartitionKey = 'Tenants' RowKey = $_.Name customerId = $_.Name @@ -111,6 +111,7 @@ function Get-Tenants { relationshipEnd = $LatestRelationship.relationshipEnd relationshipCount = $_.Count defaultDomainName = $defaultDomainName + initialDomainName = $initialDomainName hasAutoExtend = $AutoExtend delegatedPrivilegeStatus = 'granularDelegatedAdminPrivileges' domains = '' @@ -125,7 +126,8 @@ function Get-Tenants { if ($Obj.defaultDomainName -eq 'Invalid' -or !$Obj.defaultDomainName) { continue } - Add-CIPPAzDataTableEntity @TenantsTable -Entity $obj -Force | Out-Null + Add-CIPPAzDataTableEntity @TenantsTable -Entity $Obj -Force | Out-Null + $Obj } } $IncludedTenantsCache = [system.collections.generic.list[object]]::new() @@ -136,7 +138,7 @@ function Get-Tenants { RowKey = $env:TenantID PartitionKey = 'Tenants' customerId = $env:TenantID - defaultDomainName = ($Domains | Where-Object { $_.isInitial -eq $true }).id + defaultDomainName = ($Domains | Where-Object { $_.isDefault -eq $true }).id initialDomainName = ($Domains | Where-Object { $_.isInitial -eq $true }).id displayName = '*Partner Tenant' domains = 'PartnerTenant' @@ -148,7 +150,7 @@ function Get-Tenants { RequiresRefresh = [bool]$RequiresRefresh LastRefresh = (Get-Date).ToUniversalTime() }) | Out-Null - + } foreach ($Tenant in $TenantList) { if ($Tenant.defaultDomainName -eq 'Invalid' -or !$Tenant.defaultDomainName) { diff --git a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 index dfbb5445c5e8..753a47922b66 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 @@ -1,5 +1,5 @@ -function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $NoAuthCheck, $skipTokenCache, $AddedHeaders, $contentType, $IgnoreErrors = $false) { +function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $NoAuthCheck, $skipTokenCache, $AddedHeaders, $contentType, $IgnoreErrors = $false, $returnHeaders = $false) { <# .FUNCTIONALITY Internal @@ -20,7 +20,7 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N $contentType = 'application/json; charset=utf-8' } try { - $ReturnedData = (Invoke-RestMethod -Uri $($uri) -Method $TYPE -Body $body -Headers $headers -ContentType $contentType -SkipHttpErrorCheck:$IgnoreErrors) + $ReturnedData = (Invoke-RestMethod -Uri $($uri) -Method $TYPE -Body $body -Headers $headers -ContentType $contentType -SkipHttpErrorCheck:$IgnoreErrors -ResponseHeadersVariable responseHeaders) } catch { $Message = if ($_.ErrorDetails.Message) { Get-NormalizedError -Message $_.ErrorDetails.Message @@ -29,7 +29,11 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N } throw $Message } - return $ReturnedData + if ($returnHeaders) { + return $responseHeaders + } else { + return $ReturnedData + } } else { Write-Error 'Not allowed. You cannot manage your own tenant or tenants not under your scope' } diff --git a/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1 index 0d45ac6311df..533d0954679a 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1 @@ -13,6 +13,7 @@ function Invoke-CIPPOffboardingJob { $Options = $Options | ConvertFrom-Json } $userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($username)" -tenantid $Tenantfilter).id + Write-Host "Running offboarding job for $username with options: $($Options | ConvertTo-Json -Depth 10)" $Return = switch ($Options) { { $_.'ConvertToShared' -eq 'true' } { Set-CIPPMailboxType -ExecutingUser $ExecutingUser -tenantFilter $tenantFilter -userid $username -username $username -MailboxType 'Shared' -APIName $APIName @@ -59,14 +60,15 @@ function Invoke-CIPPOffboardingJob { Remove-CIPPUser -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName } - { $_.'RemoveRules' -eq 'true' } { + { $_.'removeRules' -eq 'true' } { + Write-Host "Removing rules for $username" Remove-CIPPRules -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName } - { $_.'RemoveMobile' -eq 'true' } { + { $_.'removeMobile' -eq 'true' } { Remove-CIPPMobileDevice -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName } - { $_.'RemovePermissions' } { + { $_.'removePermissions' } { if ($RunScheduled) { Remove-CIPPMailboxPermissions -PermissionsLevel @('FullAccess', 'SendAs', 'SendOnBehalf') -userid 'AllUsers' -AccessUser $UserName -TenantFilter $TenantFilter -APIName $APINAME -ExecutingUser $ExecutingUser diff --git a/Modules/CIPPCore/Public/Invoke-RemoveAPDevice.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveAPDevice.ps1 index 8639d495321d..1c474b20a44f 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveAPDevice.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveAPDevice.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveAPDevice { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveApp.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveApp.ps1 index f0ca41db08a0..b154d77568eb 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveApp.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveCAPolicy.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveCAPolicy.ps1 index 8cef68c26155..da878e3dbba2 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveCAPolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveCAPolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 index 318184576061..7ff2f2bf5df8 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveCATemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.ConditionalAccess.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveContact.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveContact.ps1 index c4a47e9b182a..fc34c0073005 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveContact.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveContact.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveContact { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Contact.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveExConnector.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveExConnector.ps1 index f16befc4906b..79b201c068b4 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveExConnector.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveExConnector.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveExConnector { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -11,9 +13,9 @@ Function Invoke-RemoveExConnector { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $Tenantfilter = $request.Query.tenantfilter - + try { - + $Params = @{ Identity = $request.query.GUID } $GraphRequest = New-ExoRequest -tenantid $Tenantfilter -cmdlet "Remove-$($Request.query.Type)Connector" -cmdParams $params -useSystemMailbox $true $Result = "Deleted $($Request.query.guid)" diff --git a/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 index 3e78057683d9..b12df6a3d0aa 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveExConnectorTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Connector.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 index 2efd9d639307..85e4346a2b81 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveGroupTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.Group.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 index 4575cf0fe57a..f1b2c51ca2bf 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveIntuneTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemovePolicy.ps1 b/Modules/CIPPCore/Public/Invoke-RemovePolicy.ps1 index 58cc90823d16..c7805fb46a48 100644 --- a/Modules/CIPPCore/Public/Invoke-RemovePolicy.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemovePolicy.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemovePolicy { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 index add290577208..1e1d3fd4de14 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveQueuedApp { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Endpoint.Application.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilter.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilter.ps1 index e962aab4a7a4..a1b05e12c312 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilter.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilter.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveSpamfilter { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Spamfilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 index 8008d3b11a18..eaa19ff08df6 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveSpamfilterTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.Spamfilter.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 index d3898d337a73..88d7f21e3212 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveStandard { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 index e95f74ecd11e..b7c11bd2d584 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveStandardTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Tenant.Standards.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveTransportRule.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveTransportRule.ps1 index b340f331903f..3a86c418314d 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveTransportRule.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveTransportRule.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveTransportRule { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 index 952796e819d8..3510d02b34a2 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveTransportRuleTemplate { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Exchange.TransportRule.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveUser.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveUser.ps1 index 386ab3e4be6b..040278ba9d80 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveUser.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveUser.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveUser { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + Identity.User.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) diff --git a/Modules/CIPPCore/Public/Invoke-RemoveWebhookAlert.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveWebhookAlert.ps1 index 0e9a92ac7868..e2a0b4d3bce2 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveWebhookAlert.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveWebhookAlert.ps1 @@ -3,7 +3,9 @@ using namespace System.Net Function Invoke-RemoveWebhookAlert { <# .FUNCTIONALITY - Entrypoint + Entrypoint + .ROLE + CIPP.Alert.ReadWrite #> [CmdletBinding()] param($Request, $TriggerMetadata) @@ -13,7 +15,7 @@ Function Invoke-RemoveWebhookAlert { $Table = get-cipptable -TableName 'SchedulerConfig' try { - $WebhookTable = Get-CIPPTable -TableName SchedulerConfig + $WebhookTable = Get-CIPPTable -TableName SchedulerConfig $WebhookRow = Get-CIPPAzDataTableEntity @WebhookTable -Filter "PartitionKey eq 'WebhookAlert'" | Where-Object -Property Tenant -EQ $Request.query.TenantFilter Write-Host "The webhook count is $($WebhookRow.count)" if ($WebhookRow.count -gt 1) { @@ -37,7 +39,7 @@ Function Invoke-RemoveWebhookAlert { } else { $Tenants = $Request.query.TenantFilter } - + $Results = foreach ($Tenant in $Tenants) { Remove-CIPPGraphSubscription -TenantFilter $Tenant -Type 'AuditLog' $Entity = $WebhookRow | Where-Object -Property RowKey -EQ $Request.query.ID diff --git a/Modules/CIPPCore/Public/Set-CIPPAssignedPolicy.ps1 b/Modules/CIPPCore/Public/Set-CIPPAssignedPolicy.ps1 index 1aabf9920b17..25cc772e5802 100644 --- a/Modules/CIPPCore/Public/Set-CIPPAssignedPolicy.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPAssignedPolicy.ps1 @@ -72,9 +72,9 @@ function Set-CIPPAssignedPolicy { $null = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$Type('$($PolicyId)')/assign" -tenantid $tenantFilter -type POST -body ($assignmentsObject | ConvertTo-Json -Depth 10) Write-LogMessage -user $ExecutingUser -API $APIName -message "Assigned Policy to $($GroupName)" -Sev 'Info' -tenant $TenantFilter } - return "Assigned policy to $($GroupName)" + return "Assigned policy to $($GroupName) Policy ID is $($PolicyId)." } catch { - Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to assign Policy to $GroupName" -Sev 'Error' -tenant $TenantFilter -LogData (Get-CippException -Exception $_) - return "Could not assign policy to $GroupName. Error: $($_.Exception.Message)" + Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to assign Policy to $GroupName. Policy ID is $($PolicyId)." -Sev 'Error' -tenant $TenantFilter -LogData (Get-CippException -Exception $_) + return "Could not assign policy to $GroupName. Policy ID is $($PolicyId). Error: $($_.Exception.Message)" } } diff --git a/Modules/CIPPCore/Public/Set-CIPPDefaultAPEnrollment.ps1 b/Modules/CIPPCore/Public/Set-CIPPDefaultAPEnrollment.ps1 index 5d75e787f233..798dfdb71553 100644 --- a/Modules/CIPPCore/Public/Set-CIPPDefaultAPEnrollment.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPDefaultAPEnrollment.ps1 @@ -20,7 +20,7 @@ function Set-CIPPDefaultAPEnrollment { 'displayName' = 'All users and all devices' 'description' = 'This is the default enrollment status screen configuration applied with the lowest priority to all users and all devices regardless of group membership.' 'showInstallationProgress' = [bool]$ShowProgress - 'blockDeviceSetupRetryByUser' = [bool]$blockDevice + 'blockDeviceSetupRetryByUser' = ![bool]$blockDevice 'allowDeviceResetOnInstallFailure' = [bool]$AllowReset 'allowLogCollectionOnInstallFailure' = [bool]$EnableLog 'customErrorMessage' = "$ErrorMessage" diff --git a/Modules/CIPPCore/Public/Set-CIPPSchemaExtension.ps1 b/Modules/CIPPCore/Public/Set-CIPPSchemaExtension.ps1 new file mode 100644 index 000000000000..111e02daa7d1 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPSchemaExtension.ps1 @@ -0,0 +1,52 @@ +function Set-CIPPSchemaExtension { + [CmdletBinding()] + Param() + + $Schema = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/schemaExtensions?`$filter=owner eq '$($env:applicationid)'" -NoAuthCheck $true -AsApp $true + + $Properties = [PSCustomObject]@( + @{ + name = 'jitAdminEnabled' + type = 'Boolean' + } + @{ + name = 'jitAdminExpiration' + type = 'DateTime' + } + ) + $TargetTypes = @('User') + + if (!$Schema.id) { + $Body = [PSCustomObject]@{ + id = 'cippSchema' + description = 'CIPP Schema Extension' + targetTypes = $TargetTypes + properties = $Properties + } + + $Json = ConvertTo-Json -Depth 5 -InputObject $Body + Write-Host $Json + $Schema = New-GraphPOSTRequest -type POST -Uri 'https://graph.microsoft.com/v1.0/schemaExtensions' -Body $Json -AsApp $true -NoAuthCheck $true + $Schema.status = 'Available' + New-GraphPOSTRequest -type PATCH -Uri "https://graph.microsoft.com/v1.0/schemaExtensions/$($Schema.id)" -Body $Json -AsApp $true -NoAuthCheck $true + } else { + $Schema = $Schema | Where-Object { $_.id -match 'cippSchema' } + $Patch = @{} + if (Compare-Object -ReferenceObject ($Properties | Select-Object name, type) -DifferenceObject $Schema.properties) { + $Patch.properties = $Properties + } + if ($Schema.status -ne 'Available') { + $Patch.status = 'Available' + } + if ($Schema.targetTypes -ne $TargetTypes) { + $Patch.targetTypes = $TargetTypes + } + + if ($Patch.Keys.Count -gt 0) { + $Json = ConvertTo-Json -Depth 5 -InputObject $Patch + New-GraphPOSTRequest -type PATCH -Uri "https://graph.microsoft.com/v1.0/schemaExtensions/$($Schema.id)" -Body $Json -AsApp $true -NoAuthCheck $true + } else { + $Schema + } + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Set-CIPPUserJITAdmin.ps1 b/Modules/CIPPCore/Public/Set-CIPPUserJITAdmin.ps1 new file mode 100644 index 000000000000..143d12ae02b5 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPUserJITAdmin.ps1 @@ -0,0 +1,20 @@ +function Set-CIPPUserJITAdmin { + [CmdletBinding()] + Param( + [string]$TenantFilter, + [string]$UserId, + [switch]$Enabled, + $Expiration + ) + $Schema = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/schemaExtensions?`$filter=owner eq '$($env:applicationid)'" -NoAuthCheck $true -AsApp $true | Where-Object { $_.owner -eq $env:applicationid } + + $Body = [PSCustomObject]@{ + "$($Schema.id)" = @{ + jitAdminEnabled = $Enabled.IsPresent + jitAdminExpiration = $Expiration + } + } + $Json = ConvertTo-Json -Depth 5 -InputObject $Body + Write-Host $Json + New-GraphPOSTRequest -type PATCH -Uri "https://graph.microsoft.com/beta/users/$UserId" -Body $Json -tenantid $TenantFilter +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 b/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 index 60751d34303d..6e941c7608cd 100644 --- a/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 +++ b/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 @@ -43,7 +43,7 @@ function Get-CIPPStandards { if ($StandardsTenant.Standards.OverrideAllTenants.remediate -ne $true) { #Write-Host 'AllTenant Standards apply to this tenant.' foreach ($StandardName in $StandardsAllTenants.Standards.PSObject.Properties.Name) { - $CurrentStandard = $StandardsAllTenants.Standards.$StandardName + $CurrentStandard = $StandardsAllTenants.Standards.$StandardName.PSObject.Copy() #Write-Host ($CurrentStandard | ConvertTo-Json -Depth 10) if ($CurrentStandard.remediate -eq $true -or $CurrentStandard.alert -eq $true -or $CurrentStandard.report -eq $true) { #Write-Host "AllTenant Standard $StandardName" @@ -54,16 +54,16 @@ function Get-CIPPStandards { foreach ($StandardName in $StandardsTenant.Standards.PSObject.Properties.Name) { if ($StandardName -eq 'OverrideAllTenants') { continue } - $CurrentStandard = $StandardsTenant.Standards.$StandardName + $CurrentStandard = $StandardsTenant.Standards.$StandardName.PSObject.Copy() if ($CurrentStandard.remediate -eq $true -or $CurrentStandard.alert -eq $true -or $CurrentStandard.report -eq $true) { - #Write-Host "`r`nTenant: $StandardName" + # Write-Host "`r`nTenant: $StandardName" if (!$ComputedStandards[$StandardName] ) { #Write-Host "Applying tenant level $StandardName" $ComputedStandards[$StandardName] = $CurrentStandard } else { foreach ($Setting in $CurrentStandard.PSObject.Properties.Name) { - #Write-Host "$Setting - Current: $($CurrentStandard.$Setting) | Computed: $($ComputedStandards[$StandardName].$($Setting))" + # Write-Host "$Setting - Current: $($CurrentStandard.$Setting) | Computed: $($ComputedStandards[$StandardName].$($Setting))" if ($CurrentStandard.$Setting -ne $false -and $CurrentStandard.$Setting -ne $ComputedStandards[$StandardName].$($Setting) -and ![string]::IsNullOrEmpty($CurrentStandard.$Setting)) { #Write-Host "Overriding $Setting for $StandardName at tenant level" if ($ComputedStandards[$StandardName].PSObject.Properties.Name -contains $Setting) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 index 90d632232fe6..29d1862ecb01 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 @@ -4,41 +4,61 @@ function Invoke-CIPPStandardActivityBasedTimeout { Internal #> param($Tenant, $Settings) - $State = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -tenantid $tenant).id + + if ($Settings.timeout -eq 'Select a value') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'No value selected for Activity Based Timeout' -sev Error + Exit + } + + # Backwards compatibility for v5.7.0 and older + if ($null -eq $Settings.timeout ) { $Settings.timeout = '01:00:00' } + + $State = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -tenantid $tenant + $StateIsCorrect = $State.definition -like "*$($Settings.timeout)*" If ($Settings.remediate -eq $true) { try { - if (!$State) { - $body = @' -{ - "displayName": "DefaultTimeoutPolicy", - "isOrganizationDefault": true, - "definition":["{\"ActivityBasedTimeoutPolicy\":{\"Version\":1,\"ApplicationPolicies\":[{\"ApplicationId\":\"default\",\"WebSessionIdleTimeout\":\"01:00:00\"}]}}"] -} -'@ + if (!$StateIsCorrect) { + $PolicyTemplate = @{ + displayName = 'DefaultTimeoutPolicy' + isOrganizationDefault = $true + definition = @( + "{`"ActivityBasedTimeoutPolicy`":{`"Version`":1,`"ApplicationPolicies`":[{`"ApplicationId`":`"default`",`"WebSessionIdleTimeout`":`"$($Settings.timeout)`"}]}}" + ) + } + $body = ConvertTo-Json -InputObject $PolicyTemplate -Depth 10 -Compress - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -Type POST -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled Activity Based Timeout of one hour' -sev Info + # Switch between parameter sets if the policy already exists + if ($null -eq $State.id) { + $RequestType = 'POST' + $URI = 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' + } else { + $RequestType = 'PATCH' + $URI = "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies/$($State.id)" + } + New-GraphPostRequest -tenantid $tenant -Uri $URI -Type $RequestType -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled Activity Based Timeout with a value of $($Settings.timeout)" -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Activity Based Timeout is already enabled' -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is already enabled and set to $($Settings.timeout)" -sev Info } } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Activity Based Timeout $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Activity Based Timeout a value of $($Settings.timeout). Error: $ErrorMessage" -sev Error } } if ($Settings.alert -eq $true) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Activity Based Timeout is enabled' -sev Info + if ($StateIsCorrect) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is enabled and set to $($Settings.timeout)" -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Activity Based Timeout is not enabled' -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is not set to $($Settings.timeout)" -sev Alert } } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'ActivityBasedTimeout' -FieldValue $state -StoreAs bool -Tenant $tenant + + Add-CIPPBPAField -FieldName 'ActivityBasedTimeout' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 index b4673244d148..d4b8bd35166c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 @@ -5,7 +5,7 @@ function Invoke-CIPPStandardAddDKIM { #> param($Tenant, $Settings) - $AllDomains = (New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/domains?$top=999' -tenantid $Tenant | Where-Object { $_.supportedServices -contains 'Email' }).id + $AllDomains = (New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/domains?$top=999' -tenantid $Tenant | Where-Object { $_.supportedServices -contains 'Email' -or $_.id -like '*mail.onmicrosoft.com' }).id $DKIM = (New-ExoRequest -tenantid $tenant -cmdlet 'Get-DkimSigningConfig') | Select-Object Domain, Enabled, Status # List of domains for each way to enable DKIM @@ -18,6 +18,8 @@ function Invoke-CIPPStandardAddDKIM { Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is already enabled for all available domains.' -sev Info } else { $ErrorCounter = 0 + Write-LogMessage -API 'Standards' -tenant $tenant -message "Trying to enable DKIM for:$($NewDomains -join ', ' ) $($SetDomains.Domain -join ', ')" -sev Info + # New-domains $Request = $NewDomains | ForEach-Object { @{ @@ -27,8 +29,7 @@ function Invoke-CIPPStandardAddDKIM { } } } - - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) -useSystemMailbox $true + if ($null -ne $Request) { $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) -useSystemMailbox $true } $BatchResults | ForEach-Object { if ($_.error) { $ErrorCounter ++ @@ -36,29 +37,31 @@ function Invoke-CIPPStandardAddDKIM { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $ErrorMessage" -sev Error } } + # Set-domains $Request = $SetDomains | ForEach-Object { @{ CmdletInput = @{ CmdletName = 'Set-DkimSigningConfig' - Parameters = @{ Identity = $Domain.Domain; Enabled = $true } + Parameters = @{ Identity = $_.Domain; Enabled = $true } } } } - - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) -useSystemMailbox $true + if ($null -ne $Request) { $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) -useSystemMailbox $true } $BatchResults | ForEach-Object { if ($_.error) { + $ErrorCounter ++ $ErrorMessage = Get-NormalizedError -Message $_.error Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set DKIM. Error: $ErrorMessage" -sev Error - $ErrorCounter ++ } + } - if ($ErrorCounter -eq 0) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DKIM for all domains in tenant' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Failed to enable DKIM for all domains in tenant' -sev Error - } + if ($ErrorCounter -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DKIM for all domains in tenant' -sev Info + } elseif ($ErrorCounter -gt 0 -and $ErrorCounter -lt ($NewDomains.Count + $SetDomains.Count)) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Failed to enable DKIM for some domains in tenant' -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Failed to enable DKIM for all domains in tenant' -sev Error } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 index b96e9f47ec89..d561c3cc51d3 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 @@ -26,6 +26,17 @@ function Invoke-CIPPStandardAntiPhishPolicy { ($CurrentState.MailboxIntelligenceProtectionAction -eq $Settings.MailboxIntelligenceProtectionAction) -and ($CurrentState.MailboxIntelligenceQuarantineTag -eq $Settings.MailboxIntelligenceQuarantineTag) + $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' + + $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AntiPhishRule' | + Where-Object -Property Name -EQ "CIPP $PolicyName" | + Select-Object Name, AntiPhishPolicy, Priority, RecipientDomainIs + + $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + ($RuleState.AntiPhishPolicy -eq $PolicyName) -and + ($RuleState.Priority -eq 0) -and + (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) + if ($Settings.remediate -eq $true) { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing Policy already correctly configured' -sev Info @@ -61,8 +72,30 @@ function Invoke-CIPPStandardAntiPhishPolicy { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing Policy. Error: $ErrorMessage" -sev Error } } - } + if ($RuleStateIsCorrect -eq $false) { + $cmdparams = @{ + AntiPhishPolicy = $PolicyName + Priority = 0 + RecipientDomainIs = $AcceptedDomains.Name + } + + try { + if ($RuleState.Name -eq "CIPP $PolicyName") { + $cmdparams.Add('Identity', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AntiPhishRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated AntiPhish Rule' -sev Info + } else { + $cmdparams.Add('Name', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'New-AntiPhishRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created AntiPhish Rule' -sev Info + } + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create AntiPhish Rule. Error: $ErrorMessage" -sev Error + } + } + } if ($Settings.alert -eq $true) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardBookings.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardBookings.ps1 new file mode 100644 index 000000000000..24d4a7c0ee3b --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardBookings.ps1 @@ -0,0 +1,48 @@ +function Invoke-CIPPStandardBookings { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + # Input validation + if ([string]::isNullOrEmpty($Settings.state) -or $Settings.state -eq 'Select a value') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'BookingsEnabled: Invalid state parameter set' -sev Error + Exit + } + + $CurrentState = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').BookingsEnabled + $WantedState = if ($Settings.state -eq 'true') { $true } else { $false } + $StateIsCorrect = if ($CurrentState -eq $WantedState) { $true } else { $false } + + if ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' + if ($StateIsCorrect -eq $false) { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ BookingsEnabled = $WantedState } -useSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully set the tenant Bookings state to $($Settings.state)" -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set the tenant Bookings state to $($Settings.state). Error: $ErrorMessage" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Bookings state is already set correctly to $($Settings.state)" -sev Info + } + + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Bookings is set correctly to $($Settings.state)" -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Bookings is not set correctly to $($Settings.state)" -sev Alert + } + } + + if ($Settings.report -eq $true) { + # Default is not set, not set means it's enabled + if ($null -eq $CurrentState ) { $CurrentState = $true } + Add-CIPPBPAField -FieldName 'BookingsState' -FieldValue $CurrentState -StoreAs bool -Tenant $tenant + } + +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardCloudMessageRecall.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardCloudMessageRecall.ps1 new file mode 100644 index 000000000000..4994b6cf91c1 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardCloudMessageRecall.ps1 @@ -0,0 +1,48 @@ +function Invoke-CIPPStandardCloudMessageRecall { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + # Input validation + if ([string]::isNullOrEmpty($Settings.state) -or $Settings.state -eq 'Select a value') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'MessageRecallEnabled: Invalid state parameter set' -sev Error + Exit + } + + $CurrentState = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').MessageRecallEnabled + $WantedState = if ($Settings.state -eq 'true') { $true } else { $false } + $StateIsCorrect = if ($CurrentState -eq $WantedState) { $true } else { $false } + + if ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' + if ($StateIsCorrect -eq $false) { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ MessageRecallEnabled = $WantedState } -useSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully set the tenant Message Recall state to $($Settings.state)" -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set the tenant Message Recall state to $($Settings.state). Error: $ErrorMessage" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Message Recall state is already set correctly to $($Settings.state)" -sev Info + } + + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Message Recall is set correctly to $($Settings.state)" -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant Message Recall is not set correctly to $($Settings.state)" -sev Alert + } + } + + if ($Settings.report -eq $true) { + # Default is not set, not set means it's enabled + if ($null -eq $CurrentState ) { $CurrentState = $true } + Add-CIPPBPAField -FieldName 'MessageRecall' -FieldValue $CurrentState -StoreAs bool -Tenant $tenant + } + +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 index 0407d9b3555e..b8ee94aafe9b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 @@ -6,12 +6,13 @@ function Invoke-CIPPStandardDelegateSentItems { param($Tenant, $Settings) $Mailboxes = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdParams @{ RecipientTypeDetails = @('UserMailbox', 'SharedMailbox') } | Where-Object { $_.MessageCopyForSendOnBehalfEnabled -eq $false -or $_.MessageCopyForSentAsEnabled -eq $false } - + Write-Host "Mailboxes: $($Mailboxes.count)" If ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' if ($Mailboxes) { try { - $Request = $mailboxes | ForEach-Object { + $Request = $Mailboxes | ForEach-Object { @{ CmdletInput = @{ CmdletName = 'Set-Mailbox' @@ -19,7 +20,7 @@ function Invoke-CIPPStandardDelegateSentItems { } } } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray $Request + $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error @@ -27,6 +28,7 @@ function Invoke-CIPPStandardDelegateSentItems { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Delegate Sent Items Style to $($_.error.target) Error: $ErrorMessage" -sev Error } } + Write-LogMessage -API 'Standards' -tenant $tenant -message "Delegate Sent Items Style applied for $($Mailboxes.count - $BatchResults.Error.Count) mailboxes" -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Delegate Sent Items Style. Error: $ErrorMessage" -sev Error @@ -38,7 +40,7 @@ function Invoke-CIPPStandardDelegateSentItems { } if ($Settings.alert -eq $true) { if ($Mailboxes) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Delegate Sent Items Style is not enabled for $($mailboxes.count) mailboxes" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Delegate Sent Items Style is not enabled for $($Mailboxes.count) mailboxes" -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Delegate Sent Items Style is enabled' -sev Info } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableCustomerLockbox.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableCustomerLockbox.ps1 index a7d8bd090172..b5741d27ac4d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableCustomerLockbox.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableCustomerLockbox.ps1 @@ -7,6 +7,7 @@ function Invoke-CIPPStandardEnableCustomerLockbox { $CustomerLockboxStatus = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').CustomerLockboxEnabled if ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' try { if ($CustomerLockboxStatus) { @@ -17,7 +18,11 @@ function Invoke-CIPPStandardEnableCustomerLockbox { } } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Customer Lockbox. Error: $ErrorMessage" -sev Error + if ($ErrorMessage -match 'Ex5E8EA4') { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Customer Lockbox. E5 license required. Error: $ErrorMessage" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Customer Lockbox. Error: $ErrorMessage" -sev Error + } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 index 460569529242..9181ae888e66 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 @@ -32,7 +32,7 @@ function Invoke-CIPPStandardEnableMailboxAuditing { } } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray $Request + $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error @@ -53,7 +53,7 @@ function Invoke-CIPPStandardEnableMailboxAuditing { } } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray $Request + $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 index 92e387dc07ef..3c3dbd004c45 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 @@ -26,7 +26,7 @@ function Invoke-CIPPStandardEnableOnlineArchiving { } } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray $Request + $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index 5a78adfa373a..39af5a0f9402 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -60,7 +60,7 @@ function Invoke-CIPPStandardIntuneTemplate { $DeleteJson.added = @() $DeleteJson = ConvertTo-Json -Depth 10 -InputObject $DeleteJson $DeleteRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL('$($existingId.id)')/updateDefinitionValues" -tenantid $tenant -type POST -body $DeleteJson - $UpdateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL('$($existingId.id)')/updateDefinitionValues" -tenantid $tenant -type POST -body $RawJSON + $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL('$($existingId.id)')/updateDefinitionValues" -tenantid $tenant -type POST -body $RawJSON Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Updated policy $($Displayname) to template defaults" -Sev 'info' } else { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 index 473a75ab15c7..e3c7d190e072 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 @@ -8,7 +8,7 @@ function Invoke-CIPPStandardNudgeMFA { $State = if ($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate -eq $true) { - + $StateName = $Settings.state.Substring(0, 1).ToUpper() + $Settings.state.Substring(1) if ($Settings.state -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -or $Settings.snoozeDurationInDays -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays) { try { $Body = $CurrentInfo @@ -17,12 +17,12 @@ function Invoke-CIPPStandardNudgeMFA { $body = ConvertTo-Json -Depth 10 -InputObject ($body | Select-Object registrationEnforcement) New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message "$($Settings.state) Authenticator App Nudge with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message "$StateName Authenticator App Nudge with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $Settings.state $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays = $Settings.snoozeDurationInDays } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to $($Settings.state) Authenticator App Nudge: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Authenticator App Nudge to $($Settings.state): $ErrorMessage" -sev Error } } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is already set to $($Settings.state) with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 index 24d6c424d036..1973cb4efc10 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 @@ -17,6 +17,17 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { ($CurrentState.Redirect -eq $Settings.Redirect) -and (($null -eq $Settings.RedirectAddress) -or ($CurrentState.RedirectAddress -eq $Settings.RedirectAddress)) + $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' + + $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeAttachmentRule' | + Where-Object -Property Name -EQ "CIPP $PolicyName" | + Select-Object Name, SafeAttachmentPolicy, Priority, RecipientDomainIs + + $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + ($RuleState.SafeAttachmentPolicy -eq $PolicyName) -and + ($RuleState.Priority -eq 0) -and + (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) + if ($Settings.remediate -eq $true) { if ($StateIsCorrect -eq $true) { @@ -44,6 +55,29 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment Policy. Error: $ErrorMessage" -sev Error } } + + if ($RuleStateIsCorrect -eq $false) { + $cmdparams = @{ + SafeAttachmentPolicy = $PolicyName + Priority = 0 + RecipientDomainIs = $AcceptedDomains.Name + } + + try { + if ($RuleState.Name -eq "CIPP $PolicyName") { + $cmdparams.Add('Identity', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeAttachmentRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated SafeAttachment Rule' -sev Info + } else { + $cmdparams.Add('Name', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeAttachmentRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created SafeAttachment Rule' -sev Info + } + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeAttachment Rule. Error: $ErrorMessage" -sev Error + } + } } if ($Settings.alert -eq $true) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 index 65471148d7c8..bd353b32e485 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 @@ -23,6 +23,17 @@ function Invoke-CIPPStandardSafeLinksPolicy { ($CurrentState.DisableUrlRewrite -eq $Settings.DisableUrlRewrite) -and ($CurrentState.EnableOrganizationBranding -eq $Settings.EnableOrganizationBranding) + $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' + + $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeLinksRule' | + Where-Object -Property Name -EQ "CIPP $PolicyName" | + Select-Object Name, SafeLinksPolicy, Priority, RecipientDomainIs + + $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + ($RuleState.SafeLinksPolicy -eq $PolicyName) -and + ($RuleState.Priority -eq 0) -and + (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) + if ($Settings.remediate -eq $true) { if ($StateIsCorrect -eq $true) { @@ -56,6 +67,29 @@ function Invoke-CIPPStandardSafeLinksPolicy { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink Policy. Error: $ErrorMessage" -sev Error } } + + if ($RuleStateIsCorrect -eq $false) { + $cmdparams = @{ + SafeLinksPolicy = $PolicyName + Priority = 0 + RecipientDomainIs = $AcceptedDomains.Name + } + + try { + if ($RuleState.Name -eq "CIPP $PolicyName") { + $cmdparams.Add('Identity', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeLinksRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated SafeLink Rule' -sev Info + } else { + $cmdparams.Add('Name', "CIPP $PolicyName") + New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeLinksRule' -cmdparams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created SafeLink Rule' -sev Info + } + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink Rule. Error: $ErrorMessage" -sev Error + } + } } if ($Settings.alert -eq $true) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 index 4f01cbc8b55f..d70fe30cef99 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 @@ -20,7 +20,7 @@ function Invoke-CIPPStandardSafeSendersDisable { } } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray $Request + $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardShortenMeetings.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardShortenMeetings.ps1 new file mode 100644 index 000000000000..4946b64e8b4b --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardShortenMeetings.ps1 @@ -0,0 +1,57 @@ +function Invoke-CIPPStandardShortenMeetings { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + # Input validation + if ([Int32]$Settings.DefaultMinutesToReduceShortEventsBy -lt 0 -or [Int32]$Settings.DefaultMinutesToReduceShortEventsBy -gt 29) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Invalid shorten meetings settings specified. DefaultMinutesToReduceShortEventsBy must be an integer between 0 and 29' -sev Error + Exit + } + if ([Int32]$Settings.DefaultMinutesToReduceLongEventsBy -lt 0 -or [Int32]$Settings.DefaultMinutesToReduceLongEventsBy -gt 29) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Invalid shorten meetings settings specified. DefaultMinutesToReduceLongEventsBy must be an integer between 0 and 29' -sev Error + Exit + } + + $CurrentState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig' | + Select-Object -Property ShortenEventScopeDefault, DefaultMinutesToReduceShortEventsBy, DefaultMinutesToReduceLongEventsBy + $CorrectState = if ($CurrentState.ShortenEventScopeDefault -eq $Settings.ShortenEventScopeDefault -and + $CurrentState.DefaultMinutesToReduceShortEventsBy -eq $Settings.DefaultMinutesToReduceShortEventsBy -and + $CurrentState.DefaultMinutesToReduceLongEventsBy -eq $Settings.DefaultMinutesToReduceLongEventsBy) { $true } else { $false } + + if ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' + + if ($CorrectState -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Shorten meetings settings are already in the correct state. ' -sev Info + } else { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ShortenEventScopeDefault = $Settings.ShortenEventScopeDefault; DefaultMinutesToReduceShortEventsBy = $Settings.DefaultMinutesToReduceShortEventsBy; DefaultMinutesToReduceLongEventsBy = $Settings.DefaultMinutesToReduceLongEventsBy } + Write-LogMessage -API 'Standards' -tenant $tenant -message "Shorten meetings settings have been set to the following state. State: $($Settings.ShortenEventScopeDefault), Short:$($Settings.DefaultMinutesToReduceShortEventsBy), Long: $($Settings.DefaultMinutesToReduceLongEventsBy)" -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set shorten meetings settings. Error: $ErrorMessage" -sev Error + } + } + } + + if ($Settings.alert -eq $true) { + + if ($CorrectState -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Shorten meetings settings are already in the correct state. Current state: $($CurrentState.ShortenEventScopeDefault), Short:$($CurrentState.DefaultMinutesToReduceShortEventsBy), Long: $($CurrentState.DefaultMinutesToReduceLongEventsBy)" -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Shorten meetings settings are not in the correct state. Current state: $($CurrentState.ShortenEventScopeDefault), Short:$($CurrentState.DefaultMinutesToReduceShortEventsBy), Long: $($CurrentState.DefaultMinutesToReduceLongEventsBy)" -sev Alert + } + } + + if ($Settings.report -eq $true) { + + if ($CorrectState -eq $true) { + Add-CIPPBPAField -FieldName 'ShortenMeetings' -FieldValue $CorrectState -StoreAs bool -Tenant $tenant + } else { + Add-CIPPBPAField -FieldName 'ShortenMeetings' -FieldValue $CurrentState -StoreAs json -Tenant $tenant + } + } +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 new file mode 100644 index 000000000000..86509c52564b --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 @@ -0,0 +1,48 @@ +function Invoke-CIPPStandardTeamsMeetingsByDefault { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + # Input validation + if ([string]::isNullOrEmpty($Settings.state) -or $Settings.state -eq 'Select a value') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'TeamsMeetingsByDefault: Invalid state parameter set' -sev Error + Exit + } + + $CurrentState = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').OnlineMeetingsByDefaultEnabled + $WantedState = if ($Settings.state -eq 'true') { $true } else { $false } + $StateIsCorrect = if ($CurrentState -eq $WantedState) { $true } else { $false } + + if ($Settings.remediate -eq $true) { + Write-Host 'Time to remediate' + if ($StateIsCorrect -eq $false) { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ OnlineMeetingsByDefaultEnabled = $WantedState } -useSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully set the tenant TeamsMeetingsByDefault state to $($Settings.state)" -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set the tenant TeamsMeetingsByDefault state to $($Settings.state). Error: $ErrorMessage" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant TeamsMeetingsByDefault state is already set correctly to $($Settings.state)" -sev Info + } + + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant TeamsMeetingsByDefault is set correctly to $($Settings.state)" -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant TeamsMeetingsByDefault is not set correctly to $($Settings.state)" -sev Alert + } + } + + if ($Settings.report -eq $true) { + # Default is not set, not set means it's enabled + if ($null -eq $CurrentState ) { $CurrentState = $true } + Add-CIPPBPAField -FieldName 'TeamsMeetingsByDefault' -FieldValue $CurrentState -StoreAs bool -Tenant $tenant + } + +} \ No newline at end of file diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 800fd3618526..994dab0633bf 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -1,20 +1,44 @@ using namespace System.Net function Receive-CippHttpTrigger { - Param($Request, $TriggerMetadata) - #force path to CIPP-API - Set-Location (Get-Item $PSScriptRoot).Parent.Parent.FullName - Write-Information (Get-Item $PSScriptRoot).Parent.Parent.FullName - $APIName = $TriggerMetadata.FunctionName + <# + .FUNCTIONALITY + Entrypoint + #> + Param( + $Request, + $TriggerMetadata + ) - $FunctionName = 'Invoke-{0}' -f $APIName + Set-Location (Get-Item $PSScriptRoot).Parent.Parent.FullName + $FunctionName = 'Invoke-{0}' -f $Request.Params.CIPPEndpoint + Write-Host "Function: $($Request.Params.CIPPEndpoint)" $HttpTrigger = @{ Request = $Request TriggerMetadata = $TriggerMetadata } - & $FunctionName @HttpTrigger + if (Get-Command -Name $FunctionName -ErrorAction SilentlyContinue) { + try { + $Access = Test-CIPPAccess -Request $Request + Write-Information "Access: $Access" + if ($Access) { + & $FunctionName @HttpTrigger + } + } catch { + Write-Information $_.Exception.Message + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::Forbidden + Body = $_.Exception.Message + }) + } + } else { + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::NotFound + Body = 'Endpoint not found' + }) + } } function Receive-CippQueueTrigger { diff --git a/version_latest.txt b/version_latest.txt index 23900d674daa..dfa102a57492 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -5.7.3 \ No newline at end of file +5.7.4