From dc4de40ec9d21aa6545770f4e6fc78f18e97bb54 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Thu, 27 Jul 2023 10:28:56 +0100 Subject: [PATCH 001/119] Update Revoke-CIPPSessions.ps1 fixed error in writing to logbook --- Modules/CIPPCore/Public/Revoke-CIPPSessions.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Revoke-CIPPSessions.ps1 b/Modules/CIPPCore/Public/Revoke-CIPPSessions.ps1 index 6ee7b05d5686..bc1234fd05e6 100644 --- a/Modules/CIPPCore/Public/Revoke-CIPPSessions.ps1 +++ b/Modules/CIPPCore/Public/Revoke-CIPPSessions.ps1 @@ -10,12 +10,12 @@ function Revoke-CIPPSessions { try { $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userid)/invalidateAllRefreshTokens" -tenantid $TenantFilter -type POST -body '{}' -verbose - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APIName -message "Revoked sessions for $($username)" -Sev "Info" -tenant $TenantFilter + Write-LogMessage -user $ExecutingUser -API $APIName -message "Revoked sessions for $($username)" -Sev "Info" -tenant $TenantFilter return "Success. All sessions by $username have been revoked" } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APIName -message "Revoked sessions for $($username)" -Sev "Info" -tenant $TenantFilter + Write-LogMessage -user $ExecutingUser -API $APIName -message "Revoked sessions for $($username)" -Sev "Info" -tenant $TenantFilter return "Revoke Session Failed: $($_.Exception.Message)" } } From 32b479c1d3d35e1b5c2df5667a41650fd02e20e9 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:41:01 +0200 Subject: [PATCH 002/119] fix issue with disableM365 groupusers --- Standards_DisableM365GroupUsers/run.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Standards_DisableM365GroupUsers/run.ps1 b/Standards_DisableM365GroupUsers/run.ps1 index a6e1b1a94a03..a91b6c71e750 100644 --- a/Standards_DisableM365GroupUsers/run.ps1 +++ b/Standards_DisableM365GroupUsers/run.ps1 @@ -2,6 +2,12 @@ param($tenant) try { $CurrentState = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/settings" -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified' + if (!$CurrentState) { + #if no current configuration is found, we set it to the default template supplied by MS. + $CurrentState = '{"id":"","displayName":"Group.Unified","templateId":"62375ab9-6b52-47ed-826b-58e47e0e304b","values":[{"name":"NewUnifiedGroupWritebackDefault","value":"true"},{"name":"EnableMIPLabels","value":"false"},{"name":"CustomBlockedWordsList","value":""},{"name":"EnableMSStandardBlockedWords","value":"false"},{"name":"ClassificationDescriptions","value":""},{"name":"DefaultClassification","value":""},{"name":"PrefixSuffixNamingRequirement","value":""},{"name":"AllowGuestsToBeGroupOwner","value":"false"},{"name":"AllowGuestsToAccessGroups","value":"true"},{"name":"GuestUsageGuidelinesUrl","value":""},{"name":"GroupCreationAllowedGroupId","value":""},{"name":"AllowToAddGuests","value":"true"},{"name":"UsageGuidelinesUrl","value":""},{"name":"ClassificationList","value":""},{"name":"EnableGroupCreation","value":"true"}]}' + (New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type POST -Body $CurrentState -ContentType "application/json") + $CurrentState = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/settings" -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified' + } ($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value = "false" $body = "{values : $($CurrentState.values | ConvertTo-Json -Compress)}" (New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type patch -Body $body -ContentType "application/json") From bbb513401448bba9b3c478c8f9c2c476a2d542a0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 28 Jul 2023 01:29:35 +0200 Subject: [PATCH 003/119] Fix for CA policies with external tenants --- AddCAPolicy/run.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AddCAPolicy/run.ps1 b/AddCAPolicy/run.ps1 index ea7a52b2d9ab..c87a3cf54e52 100644 --- a/AddCAPolicy/run.ps1 +++ b/AddCAPolicy/run.ps1 @@ -38,7 +38,10 @@ $JSONObj = $request.body.RawJSON | ConvertFrom-Json | Select-Object * -ExcludePr Remove-EmptyArrays $JSONObj #Remove context as it does not belong in the payload. $JsonObj.grantControls.PSObject.Properties.Remove('authenticationStrength@odata.context') -$JsonObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.PSObject.Properties.Remove('@odata.type') +if ($JSONObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.Members) { + $JsonObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.PSObject.Properties.Remove('@odata.context') + $JsonObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.PSObject.Properties.Remove('@odata.type') +} $RawJSON = $JSONObj | ConvertTo-Json -Depth 10 $results = foreach ($Tenant in $tenants) { From f70b96addce6b55d36f9c175b847b786c87afbe5 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Fri, 28 Jul 2023 11:02:39 +0100 Subject: [PATCH 004/119] Added SendOnBehalf Permissions Added ability to add and remove send on behalf permissions from the edit mailbox screen --- ExecEditMailboxPermissions/run.ps1 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ExecEditMailboxPermissions/run.ps1 b/ExecEditMailboxPermissions/run.ps1 index 2e97e7005590..226f76245fa7 100644 --- a/ExecEditMailboxPermissions/run.ps1 +++ b/ExecEditMailboxPermissions/run.ps1 @@ -79,6 +79,34 @@ foreach ($UserSendAs in $RemoveSendAs) { } } +$AddSendOnBehalf = ($Request.body.AddSendOnBehalf).value + +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( "added $UserSendOnBehalf to $($username) with Send On Behalf Permissions") + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave send on behalf permissions to $($UserSendOnBehalf) on $($username)" -Sev "Info" -tenant $TenantFilter + } + catch { + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add send on behalf permissions for $($UserSendOnBehalf) on $($username)" -Sev "Error" -tenant $TenantFilter + $results.add("Could not add send on behalf permissions for $($username). Error: $($_.Exception.Message)") + } +} + +$RemoveSendOnBehalf = ($Request.body.RemoveSendOnBehalf).value + +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 Send On Behalf Permissions $UserSendOnBehalf on $($username)") + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Removed Send On Behalf Permissions to $($UserSendOnBehalf) on $($username)" -Sev "Info" -tenant $TenantFilter + } + catch { + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not Remove send on behalf permissions for $($UserSendOnBehalf) on $($username)" -Sev "Error" -tenant $TenantFilter + $results.add("Could not remove send on behalf permissions for $($username). Error: $($_.Exception.Message)") + } +} + $body = [pscustomobject]@{"Results" = @($results) } # Associate values to output bindings by calling 'Push-OutputBinding'. From c7c8535499539d33590ca7689c189099c43e1419 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Fri, 28 Jul 2023 13:19:39 +0100 Subject: [PATCH 005/119] Updated Permissions to show SendOnBehalf Updated Mailbox Permissions to show SendOnBehalf --- ListmailboxPermissions/run.ps1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ListmailboxPermissions/run.ps1 b/ListmailboxPermissions/run.ps1 index 847da14a535f..571485b8f123 100644 --- a/ListmailboxPermissions/run.ps1 +++ b/ListmailboxPermissions/run.ps1 @@ -19,8 +19,9 @@ try { $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) { + $GraphRequest = foreach ($Perm in $PermsRequest, $PermsRequest2.RecipientPermission, $PermRequest3) { if ($perm.Trustee) { $perm | Where-Object Trustee | ForEach-Object { [PSCustomObject]@{ @@ -37,6 +38,13 @@ try { } } } + if ($perm.GrantSendonBehalfTo -ne $null) { + $perm.GrantSendonBehalfTo | ForEach-Object { [PSCustomObject]@{ + User = $_ + Permissions = "SendOnBehalf" + } + } + } } $StatusCode = [HttpStatusCode]::OK } From c1e8f3d29a0ec90b4757e2b47a6bdf422550b88e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 29 Jul 2023 00:31:38 +0200 Subject: [PATCH 006/119] improved exchange errors --- GraphHelper.psm1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GraphHelper.psm1 b/GraphHelper.psm1 index 0c8aeb9a37bb..2da403251d02 100644 --- a/GraphHelper.psm1 +++ b/GraphHelper.psm1 @@ -562,7 +562,11 @@ function New-ExoRequest ($tenantid, $cmdlet, $cmdParams, $useSystemMailbox, $Anc catch { $ErrorMess = $($_.Exception.Message) $ReportedError = ($_.ErrorDetails | ConvertFrom-Json -ErrorAction SilentlyContinue) - $Message = if ($ReportedError.error.details.message) { $ReportedError.error.details.message } else { $ReportedError.error.innererror.internalException.message } + $Message = if ($ReportedError.error.details.message) { + $ReportedError.error.details.message + } + elseif ($ReportedError.error.message) { $ReportedError.error.message } + else { $ReportedError.error.innererror.internalException.message } if ($null -eq $Message) { $Message = $ErrorMess } throw $Message } From 9ce9ff2bac620d4eeed4b1e2f60988a954f45a5b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 30 Jul 2023 01:30:26 +0200 Subject: [PATCH 007/119] added parameter based routing header --- GraphHelper.psm1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/GraphHelper.psm1 b/GraphHelper.psm1 index 2da403251d02..bfc252464051 100644 --- a/GraphHelper.psm1 +++ b/GraphHelper.psm1 @@ -551,9 +551,10 @@ function New-ExoRequest ($tenantid, $cmdlet, $cmdParams, $useSystemMailbox, $Anc } Write-Host "Using $Anchor" $Headers = @{ - Authorization = "Bearer $($token.access_token)" - Prefer = 'odata.maxpagesize = 1000' - 'X-AnchorMailbox' = $anchor + Authorization = "Bearer $($token.access_token)" + Prefer = 'odata.maxpagesize = 1000' + 'parameter-based-routing' = $true + 'X-AnchorMailbox' = $anchor } try { From 38ac3c843f6f2eb51c2299a92f82b8f06c7725d1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 30 Jul 2023 02:56:22 +0200 Subject: [PATCH 008/119] API starttime/endtime edits --- Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 index ef44404354eb..738d24ab048b 100644 --- a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 @@ -22,7 +22,7 @@ function New-CIPPAPIConfig { Write-Host "Creating app" $APIApp = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications" -NoAuthCheck $true -type POST -body $CreateBody Write-Host "Creating password" - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"2023-07-20T12:47:59.217Z`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`"}}" Write-Host "Adding App URL" $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" Write-Host "Adding serviceprincipal" From 85d6ec068f6e12814f5f3350717fd68726fe6328 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 29 Jul 2023 21:11:52 -0400 Subject: [PATCH 009/119] Fix CIPP-API Integration --- ExecBackendURLs/run.ps1 | 12 ++-- Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 | 64 ++++++++++--------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/ExecBackendURLs/run.ps1 b/ExecBackendURLs/run.ps1 index 167353c244df..0c557c1625ea 100644 --- a/ExecBackendURLs/run.ps1 +++ b/ExecBackendURLs/run.ps1 @@ -4,12 +4,12 @@ using namespace System.Net param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 -$SWAName = $ENV:Website_SITE_NAME -replace "cipp", "CIPP-SWA-" +$SWAName = $ENV:Website_SITE_NAME -replace 'cipp', 'CIPP-SWA-' # Write to the Azure Functions log stream. -Write-Host "PowerShell HTTP trigger function processed a request." +Write-Host 'PowerShell HTTP trigger function processed a request.' $results = [PSCustomObject]@{ ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/overview" @@ -19,10 +19,14 @@ $results = [PSCustomObject]@{ FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/vstscd" SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/customDomains" SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/Roles" + Subscription = $Subscription + RGName = $ENV:Website_Resource_Group + FunctionName = $ENV:WEBSITE_SITE_NAME + SWAName = $SWAName } -$body = @{Results = $Results } +$body = @{Results = $Results } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 index ef44404354eb..a3e75a21df79 100644 --- a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 @@ -3,41 +3,42 @@ function New-CIPPAPIConfig { [CmdletBinding()] param ( - $APIName = "CIPP API Config", + $APIName = 'CIPP API Config', $ExecutingUser, $resetpassword ) - $null = Connect-AzAccount -Identity - $currentapp = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name "CIPPAPIAPP" -AsPlainText) + if (!$env:DEV_SKIP_KEYVAULT) { + $null = Connect-AzAccount -Identity + $currentapp = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -AsPlainText) + } $subscription = $($ENV:WEBSITE_OWNER_NAME).Split('+')[0] + $startDate = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ') + $endDate = (Get-Date).AddYears(10).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ') try { if ($currentapp) { - $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true - } - else { + $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true + } else { $CreateBody = @" {"api":{"oauth2PermissionScopes":[{"adminConsentDescription":"Allow the application to access CIPP-API on behalf of the signed-in user.","adminConsentDisplayName":"Access CIPP-API","id":"ba7ffeff-96ea-4ac4-9822-1bcfee9adaa4","isEnabled":true,"type":"User","userConsentDescription":"Allow the application to access CIPP-API on your behalf.","userConsentDisplayName":"Access CIPP-API","value":"user_impersonation"}]},"displayName":"CIPP-API","requiredResourceAccess":[{"resourceAccess":[{"id":"e1fe6dd8-ba31-4d61-89e7-88639da4683d","type":"Scope"}],"resourceAppId":"00000003-0000-0000-c000-000000000000"}],"signInAudience":"AzureADMyOrg","web":{"homePageUrl":"https://cipp.app","implicitGrantSettings":{"enableAccessTokenIssuance":false,"enableIdTokenIssuance":true},"redirectUris":["https://$($ENV:Website_hostname)/.auth/login/aad/callback"]}} "@ - Write-Host "Creating app" - $APIApp = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications" -NoAuthCheck $true -type POST -body $CreateBody - Write-Host "Creating password" - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"2023-07-20T12:47:59.217Z`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" - Write-Host "Adding App URL" - $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" - Write-Host "Adding serviceprincipal" - $ServicePrincipal = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/serviceprincipals" -NoAuthCheck $true -type POST -body "{`"accountEnabled`":true,`"appId`":`"$($APIApp.appId)`",`"displayName`":`"CIPP-API`",`"tags`":[`"WindowsAzureActiveDirectoryIntegratedApp`",`"AppServiceIntegratedApp`"]}" + Write-Host 'Creating app' + $APIApp = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/applications' -NoAuthCheck $true -type POST -body $CreateBody + Write-Host 'Creating password' + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$startDate`",`"endDateTime`":`"$endDate`"}}" + Write-Host 'Adding App URL' + $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" + Write-Host 'Adding serviceprincipal' + $ServicePrincipal = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/serviceprincipals' -NoAuthCheck $true -type POST -body "{`"accountEnabled`":true,`"appId`":`"$($APIApp.appId)`",`"displayName`":`"CIPP-API`",`"tags`":[`"WindowsAzureActiveDirectoryIntegratedApp`",`"AppServiceIntegratedApp`"]}" } if ($resetpassword) { - Write-Host "Removing all old passwords" + Write-Host 'Removing all old passwords' $RemovePasswords = New-GraphPOSTRequest -type Patch -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/" -body '{"passwordCredentials":[]}' -NoAuthCheck $true - $passwordDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$passwordDate`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message "Reset CIPP API Password." -Sev "info" - } - else { - $CurrentSettings = New-GraphGetRequest -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2/list?api-version=2018-11-01" -NoAuthCheck $true -scope "https://management.azure.com/.default" - Write-Host "setting settings" + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$startDate`",`"endDateTime`":`"$endDate`"}}" + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message 'Reset CIPP API Password.' -Sev 'info' + } else { + $CurrentSettings = New-GraphGetRequest -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2/list?api-version=2018-11-01" -NoAuthCheck $true -scope 'https://management.azure.com/.default' + Write-Host 'setting settings' $currentSettings.properties.identityProviders.azureActiveDirectory = @{ registration = @{ clientId = $APIApp.appId @@ -48,23 +49,24 @@ function New-CIPPAPIConfig { } } $currentBody = ConvertTo-Json -Depth 15 -InputObject ($currentSettings | Select-Object Properties) - Write-Host "writing to Azure" - $SetAPIAuth = New-GraphPOSTRequest -type "PUT" -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2?api-version=2018-11-01" -scope "https://management.azure.com/.default" -NoAuthCheck $true -body $currentBody - $null = Set-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -SecretValue (ConvertTo-SecureString -String $APIApp.AppID -AsPlainText -Force) - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message "Succesfully setup CIPP-API Access." -Sev "info" + Write-Host 'writing to Azure' + $SetAPIAuth = New-GraphPOSTRequest -type 'PUT' -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2?api-version=2018-11-01" -scope 'https://management.azure.com/.default' -NoAuthCheck $true -body $currentBody + if (!$env:DEV_SKIP_KEYVAULT) { + $null = Set-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -SecretValue (ConvertTo-SecureString -String $APIApp.AppID -AsPlainText -Force) + } + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message 'Succesfully setup CIPP-API Access.' -Sev 'info' } return @{ ApplicationID = $APIApp.AppId ApplicationSecret = $APIPassword.secretText Results = "API Enabled. Your API URL is https://$($ENV:Website_hostname). Your Application ID is $($APIApp.AppId) and your Application Secret is $($APIPassword.secretText) - Copy these keys, they are only shown once." } - - } - catch { - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($_.Exception.Message) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev "Error" + + } catch { + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($_.Exception.Message) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev 'Error' return @{ Results = " but could not set API configuration: $($_.Exception.Message)" } - + } } \ No newline at end of file From e37fe12717e97466d2bc3b14d4559a8e27a445f8 Mon Sep 17 00:00:00 2001 From: DChorn-ANS <94991453+DChorn-ANS@users.noreply.github.com> Date: Sun, 30 Jul 2023 14:21:20 -0600 Subject: [PATCH 010/119] Adding view query param Corrects display issues in the list templates page --- ListIntuneTemplates/run.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ListIntuneTemplates/run.ps1 b/ListIntuneTemplates/run.ps1 index fbc97d2909d9..63b32dc5af22 100644 --- a/ListIntuneTemplates/run.ps1 +++ b/ListIntuneTemplates/run.ps1 @@ -23,6 +23,16 @@ $Templates = Get-ChildItem "Config\*.IntuneTemplate.json" | ForEach-Object { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'IntuneTemplate'" $Templates = (Get-AzDataTableEntity @Table -Filter $Filter).JSON | ConvertFrom-Json +if ($Request.query.View) { + $Templates = $Templates | ForEach-Object { + $data = $_.RAWJson | ConvertFrom-Json + $data | Add-Member -NotePropertyName "displayName" -NotePropertyValue $_.Displayname + $data | Add-Member -NotePropertyName "description" -NotePropertyValue $_.Description + $data | Add-Member -NotePropertyName "Type" -NotePropertyValue $_.Type + $data | Add-Member -NotePropertyName "GUID" -NotePropertyValue $_.GUID + $data + } +} if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property guid -EQ $Request.query.id } From e494767c76e1ee476eced4240271e1e3a790cc2a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 30 Jul 2023 23:46:35 +0200 Subject: [PATCH 011/119] added webhook subscription management --- .../Public/New-CIPPGraphSubscription.ps1 | 46 +++++++++++++++++++ .../Public/Remove-CIPPGraphSubcription.ps1 | 22 +++++++++ .../Public/Set-CIPPGraphSubscription.ps1 | 34 ++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 create mode 100644 Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 create mode 100644 Modules/CIPPCore/Public/Set-CIPPGraphSubscription.ps1 diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 new file mode 100644 index 000000000000..b0af91a486fc --- /dev/null +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -0,0 +1,46 @@ +function New-CIPPGraphSubscription { + [CmdletBinding()] + param ( + $TenantFilter, + $TypeofSubscription, + $Resource, + $EventType, + $APIName = "Create Webhook", + $ExecutingUser + ) + $CIPPID = (New-Guid).GUID + $expiredate = (Get-Date).AddDays(1).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") + $params = @{ + changeType = $TypeofSubscription + notificationUrl = "https://webhook.site/9650bc4a-0120-41de-8ffd-6616e71244e1?EventType=$EventType&CIPPID=$CIPPID" + resource = $Resource + expirationDateTime = $expiredate + } | ConvertTo-Json + + try { + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter -type POST -body $params -verbose + #If creation is succesfull, we store the GUID in the storage table webhookTable to make sure we can check against this later on. + #We store the GUID as rowkey, the event type, the resource, and the expiration date as properties, we also add the Tenant name so we can easily find this later on. + #We don't store the return, because Ms decided that a renewal or re-authenticate does not change the url, but does change the id... + $WebhookTable = Get-CIPPTable -TableName webhookTable + $WebhookRow = @{ + PartitionKey = [string]$TenantFilter + RowKey = [string]$CIPPID + EventType = [string]$EventType + Resource = [string]$Resource + Expiration = [string]$expiredate + WebhookNotificationUrl = [string]$GraphRequest.notificationUrl + } + $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow + #todo: add remove webhook function, add check webhook function, add list webhooks function + #add refresh webhook function based on table. + Write-LogMessage -user $ExecutingUser -API $APIName -message "Created Webhook subscription for $($TenantFilter)" -Sev "Info" -tenant $TenantFilter + return "Created Webhook subscription for $($TenantFilter)" + } + catch { + Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to create Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter + Return "Failed to create Webhook Subscription: $($_.Exception.Message)" + } + +} + diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 new file mode 100644 index 000000000000..161ac2fe3b44 --- /dev/null +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 @@ -0,0 +1,22 @@ +function Remove-CIPPGraphSubscription { + [CmdletBinding()] + param ( + $TenantFilter, + $CIPPID, + $APIName = "Remove Graph Webhook", + $ExecutingUser + ) + try { + $WebhookTable = Get-CIPPTable -TableName webhookTable + $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } + $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose + $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow + return "Remove webhook subscription to $($GraphRequest.value.notificationUrl)" + + } + catch { + Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to renew Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter + return "Failed to remove Webhook Subscription $($GraphRequest.value.notificationUrl): $($_.Exception.Message)" + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Set-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/Set-CIPPGraphSubscription.ps1 new file mode 100644 index 000000000000..67207ddf1807 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPGraphSubscription.ps1 @@ -0,0 +1,34 @@ +function Set-CIPPGraphSubscription { + [CmdletBinding()] + param ( + $TenantFilter, + $RenewSubscriptions, + $Resource, + $EventType, + $APIName = "Set Graph Webhook", + $ExecutingUser + ) + + if ($RenewSubscriptions) { + $RenewalDate = (Get-Date).AddDays(1).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") + $body = @{ + "expirationDateTime" = "$RenewalDate" + } | ConvertTo-Json + $ExistingSub = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | ForEach-Object { + try { + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($_.id)" -tenantid $TenantFilter -type PATCH -body $body -Verbose + $WebhookTable = Get-CIPPTable -TableName webhookTable + #get the row from the table, grab it by the webhook notification url, and update the expiration date. + $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.WebhookNotificationUrl -eq $GraphRequest.notificationUrl } + $WebhookRow.Expiration = $RenewalDate + $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow -Force + return "Renewed $($GraphRequest.notificationUrl)" + + } + catch { + Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to renew Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter + return "Failed to renew Webhook Subscription $($WebhookRow.RowKey): $($_.Exception.Message)" + } + } + } +} \ No newline at end of file From 6c296d90ca4612c42a5027d44cbb88ed162f61fb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:52:07 +0200 Subject: [PATCH 012/119] add classic auditlog api. --- .../Public/New-CIPPGraphSubscription.ps1 | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 index b0af91a486fc..93d26412e3b1 100644 --- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -2,6 +2,7 @@ function New-CIPPGraphSubscription { [CmdletBinding()] param ( $TenantFilter, + [bool]$auditLogAPI = $false, $TypeofSubscription, $Resource, $EventType, @@ -16,24 +17,43 @@ function New-CIPPGraphSubscription { resource = $Resource expirationDateTime = $expiredate } | ConvertTo-Json + $WebhookTable = Get-CIPPTable -TableName webhookTable try { - $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter -type POST -body $params -verbose - #If creation is succesfull, we store the GUID in the storage table webhookTable to make sure we can check against this later on. - #We store the GUID as rowkey, the event type, the resource, and the expiration date as properties, we also add the Tenant name so we can easily find this later on. - #We don't store the return, because Ms decided that a renewal or re-authenticate does not change the url, but does change the id... - $WebhookTable = Get-CIPPTable -TableName webhookTable - $WebhookRow = @{ - PartitionKey = [string]$TenantFilter - RowKey = [string]$CIPPID - EventType = [string]$EventType - Resource = [string]$Resource - Expiration = [string]$expiredate - WebhookNotificationUrl = [string]$GraphRequest.notificationUrl + if ($auditLogAPI) { + $AuditLogParams = @{ + webhook = @{ + "address" = "https://webhook.site/9650bc4a-0120-41de-8ffd-6616e71244e1/" + } + } | ConvertTo-Json + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type POST -body $AuditLogparams -verbose + $WebhookRow = @{ + PartitionKey = [string]$TenantFilter + RowKey = [string]$CIPPID + EventType = [string]$EventType + Resource = "M365AuditLogs" + Expiration = "None" + WebhookNotificationUrl = [string]$Auditlog.webhook.address + } + $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow + } + else { + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter -type POST -body $params -verbose + #If creation is succesfull, we store the GUID in the storage table webhookTable to make sure we can check against this later on. + #We store the GUID as rowkey, the event type, the resource, and the expiration date as properties, we also add the Tenant name so we can easily find this later on. + #We don't store the return, because Ms decided that a renewal or re-authenticate does not change the url, but does change the id... + $WebhookRow = @{ + PartitionKey = [string]$TenantFilter + RowKey = [string]$CIPPID + EventType = [string]$EventType + Resource = [string]$Resource + Expiration = [string]$expiredate + WebhookNotificationUrl = [string]$GraphRequest.notificationUrl + } + $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow + #todo: add remove webhook function, add check webhook function, add list webhooks function + #add refresh webhook function based on table. } - $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow - #todo: add remove webhook function, add check webhook function, add list webhooks function - #add refresh webhook function based on table. Write-LogMessage -user $ExecutingUser -API $APIName -message "Created Webhook subscription for $($TenantFilter)" -Sev "Info" -tenant $TenantFilter return "Created Webhook subscription for $($TenantFilter)" } From c04b65dec4e66c60dfbee596a28b7514da9a9760 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:57:28 +0200 Subject: [PATCH 013/119] Added removal of auditlog subscription --- .../CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 index 161ac2fe3b44..1750eadb8441 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 @@ -9,9 +9,15 @@ function Remove-CIPPGraphSubscription { try { $WebhookTable = Get-CIPPTable -TableName webhookTable $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } - $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } - $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose - $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow + if ($WebhookRow.Resource -eq "M365AuditLogs") { + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -tenantid $TenantFilter -type POST -body "{}" -verbose + + } + else { + $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose + $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow + } return "Remove webhook subscription to $($GraphRequest.value.notificationUrl)" } From 756ce701ef3ee3cf0d069b320698a2c966069444 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Jul 2023 01:12:23 +0200 Subject: [PATCH 014/119] forgot scope --- Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 | 2 +- Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 index 93d26412e3b1..413af8653ebd 100644 --- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -26,7 +26,7 @@ function New-CIPPGraphSubscription { "address" = "https://webhook.site/9650bc4a-0120-41de-8ffd-6616e71244e1/" } } | ConvertTo-Json - $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type POST -body $AuditLogparams -verbose + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type -scope "https://manage.office.com/.default" POST -body $AuditLogparams -verbose $WebhookRow = @{ PartitionKey = [string]$TenantFilter RowKey = [string]$CIPPID diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 index 1750eadb8441..6f04e1796c28 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 @@ -10,7 +10,7 @@ function Remove-CIPPGraphSubscription { $WebhookTable = Get-CIPPTable -TableName webhookTable $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } if ($WebhookRow.Resource -eq "M365AuditLogs") { - $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -tenantid $TenantFilter -type POST -body "{}" -verbose + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -scope "https://manage.office.com/.default" -tenantid $TenantFilter -type POST -body "{}" -verbose } else { From 8e4cf225a088d7f58461963de217feb26b95bb23 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Jul 2023 07:20:57 -0400 Subject: [PATCH 015/119] Revert "Fix CIPP-API Integration" This reverts commit 85d6ec068f6e12814f5f3350717fd68726fe6328. --- ExecBackendURLs/run.ps1 | 12 ++-- Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 | 64 +++++++++---------- 2 files changed, 35 insertions(+), 41 deletions(-) diff --git a/ExecBackendURLs/run.ps1 b/ExecBackendURLs/run.ps1 index 0c557c1625ea..167353c244df 100644 --- a/ExecBackendURLs/run.ps1 +++ b/ExecBackendURLs/run.ps1 @@ -4,12 +4,12 @@ using namespace System.Net param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 -$SWAName = $ENV:Website_SITE_NAME -replace 'cipp', 'CIPP-SWA-' +$SWAName = $ENV:Website_SITE_NAME -replace "cipp", "CIPP-SWA-" # Write to the Azure Functions log stream. -Write-Host 'PowerShell HTTP trigger function processed a request.' +Write-Host "PowerShell HTTP trigger function processed a request." $results = [PSCustomObject]@{ ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/overview" @@ -19,14 +19,10 @@ $results = [PSCustomObject]@{ FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/vstscd" SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/customDomains" SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/Roles" - Subscription = $Subscription - RGName = $ENV:Website_Resource_Group - FunctionName = $ENV:WEBSITE_SITE_NAME - SWAName = $SWAName } -$body = @{Results = $Results } +$body = @{Results = $Results } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 index a3e75a21df79..ef44404354eb 100644 --- a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 @@ -3,42 +3,41 @@ function New-CIPPAPIConfig { [CmdletBinding()] param ( - $APIName = 'CIPP API Config', + $APIName = "CIPP API Config", $ExecutingUser, $resetpassword ) - if (!$env:DEV_SKIP_KEYVAULT) { - $null = Connect-AzAccount -Identity - $currentapp = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -AsPlainText) - } + $null = Connect-AzAccount -Identity + $currentapp = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name "CIPPAPIAPP" -AsPlainText) $subscription = $($ENV:WEBSITE_OWNER_NAME).Split('+')[0] - $startDate = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ') - $endDate = (Get-Date).AddYears(10).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ') try { if ($currentapp) { - $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true - } else { + $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true + } + else { $CreateBody = @" {"api":{"oauth2PermissionScopes":[{"adminConsentDescription":"Allow the application to access CIPP-API on behalf of the signed-in user.","adminConsentDisplayName":"Access CIPP-API","id":"ba7ffeff-96ea-4ac4-9822-1bcfee9adaa4","isEnabled":true,"type":"User","userConsentDescription":"Allow the application to access CIPP-API on your behalf.","userConsentDisplayName":"Access CIPP-API","value":"user_impersonation"}]},"displayName":"CIPP-API","requiredResourceAccess":[{"resourceAccess":[{"id":"e1fe6dd8-ba31-4d61-89e7-88639da4683d","type":"Scope"}],"resourceAppId":"00000003-0000-0000-c000-000000000000"}],"signInAudience":"AzureADMyOrg","web":{"homePageUrl":"https://cipp.app","implicitGrantSettings":{"enableAccessTokenIssuance":false,"enableIdTokenIssuance":true},"redirectUris":["https://$($ENV:Website_hostname)/.auth/login/aad/callback"]}} "@ - Write-Host 'Creating app' - $APIApp = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/applications' -NoAuthCheck $true -type POST -body $CreateBody - Write-Host 'Creating password' - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$startDate`",`"endDateTime`":`"$endDate`"}}" - Write-Host 'Adding App URL' - $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" - Write-Host 'Adding serviceprincipal' - $ServicePrincipal = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/serviceprincipals' -NoAuthCheck $true -type POST -body "{`"accountEnabled`":true,`"appId`":`"$($APIApp.appId)`",`"displayName`":`"CIPP-API`",`"tags`":[`"WindowsAzureActiveDirectoryIntegratedApp`",`"AppServiceIntegratedApp`"]}" + Write-Host "Creating app" + $APIApp = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications" -NoAuthCheck $true -type POST -body $CreateBody + Write-Host "Creating password" + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"2023-07-20T12:47:59.217Z`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" + Write-Host "Adding App URL" + $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" + Write-Host "Adding serviceprincipal" + $ServicePrincipal = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/serviceprincipals" -NoAuthCheck $true -type POST -body "{`"accountEnabled`":true,`"appId`":`"$($APIApp.appId)`",`"displayName`":`"CIPP-API`",`"tags`":[`"WindowsAzureActiveDirectoryIntegratedApp`",`"AppServiceIntegratedApp`"]}" } if ($resetpassword) { - Write-Host 'Removing all old passwords' + Write-Host "Removing all old passwords" $RemovePasswords = New-GraphPOSTRequest -type Patch -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/" -body '{"passwordCredentials":[]}' -NoAuthCheck $true - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$startDate`",`"endDateTime`":`"$endDate`"}}" - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message 'Reset CIPP API Password.' -Sev 'info' - } else { - $CurrentSettings = New-GraphGetRequest -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2/list?api-version=2018-11-01" -NoAuthCheck $true -scope 'https://management.azure.com/.default' - Write-Host 'setting settings' + $passwordDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$passwordDate`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message "Reset CIPP API Password." -Sev "info" + } + else { + $CurrentSettings = New-GraphGetRequest -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2/list?api-version=2018-11-01" -NoAuthCheck $true -scope "https://management.azure.com/.default" + Write-Host "setting settings" $currentSettings.properties.identityProviders.azureActiveDirectory = @{ registration = @{ clientId = $APIApp.appId @@ -49,24 +48,23 @@ function New-CIPPAPIConfig { } } $currentBody = ConvertTo-Json -Depth 15 -InputObject ($currentSettings | Select-Object Properties) - Write-Host 'writing to Azure' - $SetAPIAuth = New-GraphPOSTRequest -type 'PUT' -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2?api-version=2018-11-01" -scope 'https://management.azure.com/.default' -NoAuthCheck $true -body $currentBody - if (!$env:DEV_SKIP_KEYVAULT) { - $null = Set-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -SecretValue (ConvertTo-SecureString -String $APIApp.AppID -AsPlainText -Force) - } - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message 'Succesfully setup CIPP-API Access.' -Sev 'info' + Write-Host "writing to Azure" + $SetAPIAuth = New-GraphPOSTRequest -type "PUT" -uri "https://management.azure.com/subscriptions/$($subscription)/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$ENV:WEBSITE_SITE_NAME/Config/authsettingsV2?api-version=2018-11-01" -scope "https://management.azure.com/.default" -NoAuthCheck $true -body $currentBody + $null = Set-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'CIPPAPIAPP' -SecretValue (ConvertTo-SecureString -String $APIApp.AppID -AsPlainText -Force) + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message "Succesfully setup CIPP-API Access." -Sev "info" } return @{ ApplicationID = $APIApp.AppId ApplicationSecret = $APIPassword.secretText Results = "API Enabled. Your API URL is https://$($ENV:Website_hostname). Your Application ID is $($APIApp.AppId) and your Application Secret is $($APIPassword.secretText) - Copy these keys, they are only shown once." } - - } catch { - Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($_.Exception.Message) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev 'Error' + + } + catch { + Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($_.Exception.Message) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev "Error" return @{ Results = " but could not set API configuration: $($_.Exception.Message)" } - + } } \ No newline at end of file From a39876127938e3ef5452d5749b27e64ed4fd2acb Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Jul 2023 07:22:23 -0400 Subject: [PATCH 016/119] Add more properties to backend urls --- ExecBackendURLs/run.ps1 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ExecBackendURLs/run.ps1 b/ExecBackendURLs/run.ps1 index 167353c244df..0c557c1625ea 100644 --- a/ExecBackendURLs/run.ps1 +++ b/ExecBackendURLs/run.ps1 @@ -4,12 +4,12 @@ using namespace System.Net param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 -$SWAName = $ENV:Website_SITE_NAME -replace "cipp", "CIPP-SWA-" +$SWAName = $ENV:Website_SITE_NAME -replace 'cipp', 'CIPP-SWA-' # Write to the Azure Functions log stream. -Write-Host "PowerShell HTTP trigger function processed a request." +Write-Host 'PowerShell HTTP trigger function processed a request.' $results = [PSCustomObject]@{ ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/overview" @@ -19,10 +19,14 @@ $results = [PSCustomObject]@{ FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/vstscd" SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/customDomains" SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:Website_Resource_Group/providers/Microsoft.Web/staticSites/$SWAName/Roles" + Subscription = $Subscription + RGName = $ENV:Website_Resource_Group + FunctionName = $ENV:WEBSITE_SITE_NAME + SWAName = $SWAName } -$body = @{Results = $Results } +$body = @{Results = $Results } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ From 3c08aaa84d98b1f6cb348d14ba77237c6024f776 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Jul 2023 07:35:55 -0400 Subject: [PATCH 017/119] Update New-CIPPAPIConfig.ps1 --- Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 index ef44404354eb..58231273000e 100644 --- a/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAPIConfig.ps1 @@ -13,7 +13,7 @@ function New-CIPPAPIConfig { try { if ($currentapp) { - $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true + $APIApp = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/applications(appid='$($currentapp)')" -NoAuthCheck $true } else { $CreateBody = @" @@ -22,7 +22,7 @@ function New-CIPPAPIConfig { Write-Host "Creating app" $APIApp = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications" -NoAuthCheck $true -type POST -body $CreateBody Write-Host "Creating password" - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"2023-07-20T12:47:59.217Z`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`"}}" Write-Host "Adding App URL" $APIIdUrl = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)" -NoAuthCheck $true -type PATCH -body "{`"identifierUris`":[`"api://$($APIApp.appId)`"]}" Write-Host "Adding serviceprincipal" @@ -32,7 +32,7 @@ function New-CIPPAPIConfig { Write-Host "Removing all old passwords" $RemovePasswords = New-GraphPOSTRequest -type Patch -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/" -body '{"passwordCredentials":[]}' -NoAuthCheck $true $passwordDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") - $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`",`"startDateTime`":`"$passwordDate`",`"endDateTime`":`"2033-07-20T12:47:59.217Z`"}}" + $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`"}}" Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None '-message "Reset CIPP API Password." -Sev "info" } else { @@ -58,13 +58,13 @@ function New-CIPPAPIConfig { ApplicationSecret = $APIPassword.secretText Results = "API Enabled. Your API URL is https://$($ENV:Website_hostname). Your Application ID is $($APIApp.AppId) and your Application Secret is $($APIPassword.secretText) - Copy these keys, they are only shown once." } - + } catch { Write-LogMessage -user $ExecutingUser -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($_.Exception.Message) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev "Error" return @{ Results = " but could not set API configuration: $($_.Exception.Message)" } - + } } \ No newline at end of file From 70b68f2b3cfd464eec2053fad6fd2a44a6b0697c Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Tue, 1 Aug 2023 10:49:50 +0100 Subject: [PATCH 018/119] Fixed Issue with output on Mailbox Perms Fixed issue with output on Mailbox Perms described here: https://github.com/KelvinTegelaar/CIPP/issues/1662 --- ExecEditMailboxPermissions/run.ps1 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ExecEditMailboxPermissions/run.ps1 b/ExecEditMailboxPermissions/run.ps1 index 226f76245fa7..601a7f0c0070 100644 --- a/ExecEditMailboxPermissions/run.ps1 +++ b/ExecEditMailboxPermissions/run.ps1 @@ -16,7 +16,7 @@ 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 $($_) 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 @@ -29,11 +29,11 @@ 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( "added $($UserAutomap) to $($username) Mailbox with automapping") - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave full permissions to $($request.body.AccessAutomap) on $($username)" -Sev "Info" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave full permissions to $($UserAutomap) on $($username)" -Sev "Info" -tenant $TenantFilter } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($request.body.AccessAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($UserAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter $results.add( "Could not add shared mailbox permissions for $($username). Error: $($_.Exception.Message)") } } @@ -43,10 +43,10 @@ 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( "added $UserNoAutomap to $($username) Mailbox without automapping") - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave full permissions to $($request.body.AccessAutomap) on $($username)" -Sev "Info" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave full permissions to $($UserNoAutomap) on $($username)" -Sev "Info" -tenant $TenantFilter } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($request.body.AccessAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($UserNoAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter $results.add("Could not add shared mailbox permissions for $($username). Error: $($_.Exception.Message)") } } @@ -56,11 +56,11 @@ $AddSendAS = ($Request.body.AddSendAs).value foreach ($UserSendAs in $AddSendAS) { try { $MailboxPerms = New-ExoRequest -Anchor $username -tenantid $Tenantfilter -cmdlet "Add-RecipientPermission" -cmdParams @{Identity = $userid; Trustee = $UserSendAs; accessRights = @("SendAs") } - $results.add( "added $AddSendAS to $($username) with Send As permissions") - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave sendas permissions to $($request.body.AddSendAs) on $($username)" -Sev "Info" -tenant $TenantFilter + $results.add( "added $UserSendAs to $($username) with Send As permissions") + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Gave sendas permissions to $($UserSendAs) on $($username)" -Sev "Info" -tenant $TenantFilter } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($request.body.AccessAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not add mailbox permissions for $($UserSendAs) on $($username)" -Sev "Error" -tenant $TenantFilter $results.add("Could not add send-as permissions for $($username). Error: $($_.Exception.Message)") } } @@ -70,11 +70,11 @@ $RemoveSendAs = ($Request.body.RemoveSendAs).value 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 $RemoveSendAs from $($username) with Send As permissions") - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Remove sendas permissions to $($request.body.AddSendAs) on $($username)" -Sev "Info" -tenant $TenantFilter + $results.add( "Removed $UserSendAs from $($username) with Send As permissions") + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Remove sendas permissions to $($UserSendAs) on $($username)" -Sev "Info" -tenant $TenantFilter } catch { - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not remove mailbox permissions for $($request.body.AccessAutomap) on $($username)" -Sev "Error" -tenant $TenantFilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME-message "Could not remove mailbox permissions for $($UserSendAs) on $($username)" -Sev "Error" -tenant $TenantFilter $results.add("Could not remove send-as permissions for $($username). Error: $($_.Exception.Message)") } } From 84c5696f5d34fb75ad2a6d6cc3dbdb4fd297b825 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Tue, 1 Aug 2023 16:32:01 +0100 Subject: [PATCH 019/119] Fixed Missing API Name from LogBook Fixed Missing API Name from LogBook --- ExecEmailForward/run.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/ExecEmailForward/run.ps1 b/ExecEmailForward/run.ps1 index cb8286234bd5..868f0a0dbacf 100644 --- a/ExecEmailForward/run.ps1 +++ b/ExecEmailForward/run.ps1 @@ -7,6 +7,7 @@ $Tenantfilter = $request.body.tenantfilter $ForwardingAddress = $request.body.ForwardInternal.value $ForwardingSMTPAddress = $request.body.ForwardExternal $DisableForwarding = $request.body.disableForwarding +$APIName = $TriggerMetadata.FunctionName if ($ForwardingAddress) { try { From 14adc5fd0e89d166c701cfaa37eaebc67bcc8413 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Wed, 2 Aug 2023 11:11:50 +0100 Subject: [PATCH 020/119] Added Functionality to CIPP Notifications so you can filter by severity Added Functionality to CIPP Notifications so you can filter by severity --- ExecNotificationConfig/run.ps1 | 3 +++ ListNotificationConfig/run.ps1 | 7 ++++++- openapi.json | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ExecNotificationConfig/run.ps1 b/ExecNotificationConfig/run.ps1 index 99a36382e2b6..f86a8fe32023 100644 --- a/ExecNotificationConfig/run.ps1 +++ b/ExecNotificationConfig/run.ps1 @@ -26,6 +26,9 @@ $results = try { foreach ($logvalue in [pscustomobject]$Request.body.logsToInclude) { $SchedulerConfig[([pscustomobject]$logvalue.value)] = $true } + foreach ($severityvalue in [pscustomobject]$Request.body.Severity) { + $SchedulerConfig[([pscustomobject]$severityvalue.value)] = $true + } Add-AzDataTableEntity @Table -Entity $SchedulerConfig -Force | Out-Null diff --git a/ListNotificationConfig/run.ps1 b/ListNotificationConfig/run.ps1 index a5a75b7c3a31..7102dd077664 100644 --- a/ListNotificationConfig/run.ps1 +++ b/ListNotificationConfig/run.ps1 @@ -10,10 +10,15 @@ $Table = Get-CIPPTable -TableName SchedulerConfig $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" $Config = Get-AzDataTableEntity @Table -Filter $Filter | ConvertTo-Json -Depth 10 | ConvertFrom-Json -Depth 10 $config | Add-Member -NotePropertyValue @() -NotePropertyName 'logsToInclude' -Force -$config.logsToInclude = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, timestamp, webhook).psobject.properties.name) +$config | Add-Member -NotePropertyValue @() -NotePropertyName 'Severity' -Force +$config.logsToInclude = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, Severity, Alert, Info, Error, timestamp, webhook).psobject.properties.name) if (!$config.logsToInclude) { $config.logsToInclude = @('None') } +$config.Severity = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, Severity, Updates, Standards, TokensUpdater, ExecExcludeLicenses, ExecExcludeTenant, ExecDnsConfig, EditUser, ChocoApp, AddAPDevice, EditTenant, AddMSPApp, AddUser, timestamp, AddGroup, ExecOffboardUser, webhook).psobject.properties.name) +if (!$config.Severity) { + $config.Severity = @('None') +} $body = $Config # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/openapi.json b/openapi.json index 9d9cdea02554..20a5281ec68b 100644 --- a/openapi.json +++ b/openapi.json @@ -5729,6 +5729,14 @@ "name": "logsToInclude", "in": "body" }, + { + "required": true, + "schema": { + "type": "string" + }, + "name": "Severity", + "in": "body" + }, { "required": true, "schema": { From 4eaa2cd3d45c8e89fed25b9f2709f59fa874d784 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 3 Aug 2023 00:49:51 +0200 Subject: [PATCH 021/119] Add reverse tenant lookup logic --- ListExternalTenantInfo/run.ps1 | 76 ++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/ListExternalTenantInfo/run.ps1 b/ListExternalTenantInfo/run.ps1 index e9020bfa92ba..6d34411ec825 100644 --- a/ListExternalTenantInfo/run.ps1 +++ b/ListExternalTenantInfo/run.ps1 @@ -6,53 +6,65 @@ 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. $Tenant = $request.query.tenant -$GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByDomainName(domainName='$Tenant')" -noauthcheck $true -tenantid $TenantFilter -$StatusCode = [HttpStatusCode]::OK +# Normalize to tenantid and determine if tenant exists +$TenantId = (Invoke-RestMethod -Method GET "https://login.windows.net/$tenant/.well-known/openid-configuration").token_endpoint.Split('/')[3] + +if ($TenantId) { + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$TenantId')" -noauthcheck $true -tenantid $TenantFilter + $StatusCode = [HttpStatusCode]::OK +} + +if ($GraphRequest) { + + $TenantDefaultDomain = $GraphRequest.defaultDomainName -$body = @" + $body = @" - - http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation - https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc - - http://www.w3.org/2005/08/addressing/anonymous - - - - - - $Tenant - - - + + http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation + https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc + + http://www.w3.org/2005/08/addressing/anonymous + + + + + + $TenantDefaultDomain + + + "@ -# Create the headers -$headers = @{ - "Content-Type" = "text/xml; charset=utf-8" - "SOAPAction" = '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"' - "User-Agent" = "AutodiscoverClient" -} -# Invoke -$response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc" -Body $body -Headers $headers -# Return -$TenantDomains = $response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain | Sort-Object + # Create the headers + $headers = @{ + "Content-Type" = "text/xml; charset=utf-8" + "SOAPAction" = '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"' + "User-Agent" = "AutodiscoverClient" + } + + # Invoke + $response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc" -Body $body -Headers $headers + + # Return + $TenantDomains = $response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain | Sort-Object +} $results = [PSCustomObject]@{ - GraphRequest = $GraphRequest - Domains = $TenantDomains + GraphRequest = $GraphRequest + Domains = $TenantDomains } + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = $StatusCode - Body = $results + StatusCode = $StatusCode + Body = $results }) From db52bdc15f5b626fe42a2de36a27e85d445ae1c1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 3 Aug 2023 14:30:00 +0200 Subject: [PATCH 022/119] changes --- .../CIPPCore/Public/Invoke-CIPPWebhook.ps1 | 158 +++++ Modules/CIPPCore/Public/TemplateEmail.html | 641 ++++++++++++++++++ 2 files changed, 799 insertions(+) create mode 100644 Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 create mode 100644 Modules/CIPPCore/Public/TemplateEmail.html diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 new file mode 100644 index 000000000000..63845e1fecf0 --- /dev/null +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 @@ -0,0 +1,158 @@ +function Invoke-CippWebhook { + [CmdletBinding()] + param ( + $TenantFilter, + $Data, + $Resource, + $EventType, + $APIName = "Process webhook", + $ExecutingUser + ) + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String + $GeoTable = Get-CIPPTable -TableName geoipdb + $Data.ActorIpAddress.Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { + [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null + $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte + } + $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -First 1 + #0: TenantName + Alert title. E.g. "CyberDrainDev.onmicrosoft.com - New-InboxRule" + #1: Intro text + #2: button url + #3: button text + #4: after button text + switch ($data.Operation) { + "New-InboxRule" { + $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" + $TableObj = [PSCustomObject]::new() + $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('', '
') + $ParameterName + $IntroText = "

A new rule has been created for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" + $ButtonUrl = "BECURLHERE" + $ButtonText = "Start BEC Investigation" + $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Set-inboxrule" { + $Title = "$($TenantFilter) - Rule Edit Detected for $($data.UserId)" + $TableObj = [PSCustomObject]::new() + $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') + $ParameterName + $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" + $ButtonUrl = "BECURLHERE" + $ButtonText = "Start BEC Investigation" + $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Add member to role." { + $Title = "$($TenantFilter) - Role change detected for $($data.ObjectId)" + $Table = ($data.ModifiedProperties | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') + $IntroText = "

$($data.UserId) has added $($data.ObjectId) to the $(($data.ModifiedProperties | Where-Object -Property Name -EQ "Role.DisplayName").NewValue) role. The information about the role can be found in the table below.

$Table" + $ButtonUrl = "BECURLHERE" + $ButtonText = "Role Management" + $AfterButtonText = "

If this role is incorrect, or you need more information, use the button to jump to the Role Management page.

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + + } + "Disable account." { + $Title = "$($TenantFilter) - $($data.ObjectId) has been disabled" + $IntroText = "$($data.ObjectId) has been disabled by $($data.UserId)." + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Enable account." { + $Title = "$($TenantFilter) - $($data.ObjectId) has been enabled" + $IntroText = "$($data.ObjectId) has been enabled by $($data.UserId)." + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Update StsRefreshTokenValidFrom Timestamp." { + $Title = "$($TenantFilter) - $($data.ObjectId) has had all sessions revoked" + $IntroText = "$($data.ObjectId) has had their sessions revoked by $($data.UserId)." + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Disable Strong Authentication." { + $Title = "$($TenantFilter) - $($data.ObjectId) has been MFA disabled" + $IntroText = "$($data.ObjectId) MFA has been disabled by $($data.UserId)." + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to reenable MFA

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + "Remove Member from a role." { + $Title = "$($TenantFilter) - Role change detected for $($data.ObjectId)" + $Table = ($data.ModifiedProperties | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') + $IntroText = "

$($data.UserId) has removed $($data.ObjectId) to the $(($data.ModifiedProperties | Where-Object -Property Name -EQ "Role.DisplayName").NewValue) role. The information about the role can be found in the table below.

$Table" + $ButtonUrl = "BECURLHERE" + $ButtonText = "Role Management" + $AfterButtonText = "

If this role change is incorrect, or you need more information, use the button to jump to the Role Management page.

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + + } + "UserLoggedIn" { + $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId + if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } + + $TableObj = [PSCustomObject]::new() + $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') + $Country = $Location.CountryOrRegion + $City = $Location.city + if ($data.UserType -eq 2) { + $Title = "$($TenantFilter) - an admin account has logged on" + $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + + if ($data.UserType -eq 0) { + $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" + $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + } + + } + "Reset user password." { + $Title = "$($TenantFilter) - $($data.ObjectId) has had their password reset" + $IntroText = "$($data.UserId) has had their password reset." + $ButtonUrl = "BECURLHERE" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + + } + "UpdateInboxRules" { + $Title = "$($TenantFilter) - Rule Edit Detected for $($data.UserId)" + $TableObj = [PSCustomObject]::new() + $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') + $ParameterName + $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" + $ButtonUrl = "BECURLHERE" + $ButtonText = "Start BEC Investigation" + $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + + } + + } + return $HTML + +} +#check if e-mail notification or PSA is configured. If yes, use generated HTML to send e-mail or create PSA ticket + +#Check if webhook notification is configured. If yes, send webhook notification with raw data. diff --git a/Modules/CIPPCore/Public/TemplateEmail.html b/Modules/CIPPCore/Public/TemplateEmail.html new file mode 100644 index 000000000000..63e587b904d3 --- /dev/null +++ b/Modules/CIPPCore/Public/TemplateEmail.html @@ -0,0 +1,641 @@ + + + + {0} + + + + + + + + + + + + + + + + + + +
+{0}
+
+ +
+
+ + + + + +
+ +
+ + + + + + +
+ +
 
+ +
+
+ +
+ + +
+
+ + + + + + +
+ +
+ + + + + + + + + +
+ +
 
+ +
+
+ +
+
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+
+

+ {0} +

+
+
+
+

Webhook received.

+

{1}

+
+
+ + + + + + +
+ + {3} + +
+
+
+

{4}

+
+
+
+

+
+
+
+ +
+
+ +
+ + + +
+ + + + + + + From c629a2799245bbbc3b46469a4f16e1dc97eaf221 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 5 Aug 2023 15:39:36 +0200 Subject: [PATCH 023/119] fix standards number matching --- Standards_PWdisplayAppInformationRequiredState/run.ps1 | 2 +- Standards_PWnumberMatchingRequiredState/run.ps1 | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Standards_PWdisplayAppInformationRequiredState/run.ps1 b/Standards_PWdisplayAppInformationRequiredState/run.ps1 index e8dc974cf7d1..f56e9777bac2 100644 --- a/Standards_PWdisplayAppInformationRequiredState/run.ps1 +++ b/Standards_PWdisplayAppInformationRequiredState/run.ps1 @@ -2,7 +2,7 @@ param($tenant) try { $body = @" -{"@odata.type":"#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration","id":"MicrosoftAuthenticator","includeTargets":[{"id":"all_users","isRegistrationRequired":false,"targetType":"group","displayName":"All users","authenticationMode":"any"}],"excludeTargets":[],"state":"enabled","featureSettings":{"numberMatchingRequiredState":{"state":"enabled","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}},"displayLocationInformationRequiredState":{"state":"enabled","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}},"displayAppInformationRequiredState":{"state":"enabled","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}}}} +{"@odata.type":"#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration","id":"MicrosoftAuthenticator","includeTargets":[{"id":"all_users","isRegistrationRequired":false,"targetType":"group","authenticationMode":"any"}],"excludeTargets":[],"state":"enabled","isSoftwareOathEnabled":false,"featureSettings":{"displayLocationInformationRequiredState":{"state":"enabled","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}},"displayAppInformationRequiredState":{"state":"enabled","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}},"companionAppAllowedState":{"state":"default","includeTarget":{"id":"all_users","targetType":"group","displayName":"All users"}}}} "@ (New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator" -Type patch -Body $body -ContentType "application/json") diff --git a/Standards_PWnumberMatchingRequiredState/run.ps1 b/Standards_PWnumberMatchingRequiredState/run.ps1 index 18aa87eef461..65f5c3383852 100644 --- a/Standards_PWnumberMatchingRequiredState/run.ps1 +++ b/Standards_PWnumberMatchingRequiredState/run.ps1 @@ -1,12 +1,7 @@ param($tenant) try { - $body = @" -{"@odata.context":"https://graph.microsoft.com/beta/$metadata#authenticationMethodConfigurations/$entity","@odata.type":"#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration","id":"MicrosoftAuthenticator","state":"enabled","featureSettings":{"numberMatchingRequiredState":{"state":"enabled","includeTarget":{"targetType":"group","id":"all_users"},"excludeTarget":{"targetType":"group","id":"00000000-0000-0000-0000-000000000000"}}},"includeTargets@odata.context":"https://graph.microsoft.com/beta/$metadata#authenticationMethodsPolicy/authenticationMethodConfigurations('MicrosoftAuthenticator')/microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration/includeTargets","includeTargets":[{"targetType":"group","id":"all_users","isRegistrationRequired":false,"authenticationMode":"any",}]} -"@ - (New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator" -Type patch -Body $body -ContentType "application/json") - - Write-LogMessage -API "Standards" -tenant $tenant -message "Enabled passwordless with Number Matching." -sev Info + Write-LogMessage -API "Standards" -tenant $tenant -message "Passwordless with number matching is now enabled by default." -sev Info } catch { Write-LogMessage -API "Standards" -tenant $tenant -message "Failed to enable passwordless with Number Matching. Error: $($_.exception.message)" -sev "Error" From abada21df74b76fa073d4fad7a0120231c9b9138 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 6 Aug 2023 16:54:54 +0200 Subject: [PATCH 024/119] webhook stuff for auditlogs --- ListGenericTestFunction/run.ps1 | 4 +- ListWebhookAlert/function.json | 19 +++ ListWebhookAlert/run.ps1 | 16 ++ ...k.ps1 => Invoke-CIPPWebhookProcessing.ps1} | 146 +++++++++--------- .../Public/New-CIPPGraphSubscription.ps1 | 7 +- .../Public/Remove-CIPPGraphSubcription.ps1 | 2 +- Modules/CIPPCore/Public/Send-CIPPAlert.ps1 | 90 +++++++++++ PublicWebhooks/function.json | 16 ++ PublicWebhooks/run.ps1 | 44 ++++++ RemoveWebhookAlert/function.json | 19 +++ RemoveWebhookAlert/run.ps1 | 24 +++ Scheduler_CIPPNotifications/run.ps1 | 2 + 12 files changed, 311 insertions(+), 78 deletions(-) create mode 100644 ListWebhookAlert/function.json create mode 100644 ListWebhookAlert/run.ps1 rename Modules/CIPPCore/Public/{Invoke-CIPPWebhook.ps1 => Invoke-CIPPWebhookProcessing.ps1} (51%) create mode 100644 Modules/CIPPCore/Public/Send-CIPPAlert.ps1 create mode 100644 PublicWebhooks/function.json create mode 100644 PublicWebhooks/run.ps1 create mode 100644 RemoveWebhookAlert/function.json create mode 100644 RemoveWebhookAlert/run.ps1 diff --git a/ListGenericTestFunction/run.ps1 b/ListGenericTestFunction/run.ps1 index c764f4a7f8a2..67c30cc60e00 100644 --- a/ListGenericTestFunction/run.ps1 +++ b/ListGenericTestFunction/run.ps1 @@ -5,9 +5,7 @@ param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' -$body = '{"userPreferredMethodForSecondaryAuthentication": "push"}' -$graphRequest = New-GraphPOSTRequest -body $body -type PATCH -uri 'https://graph.microsoft.com/beta/users/b4156a0c-91c5-4195-bb1b-41b96d0806a7/authentication/signInPreferences' -tenantid $TenantFilter - +$graphRequest = $request.headers Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @($graphRequest) diff --git a/ListWebhookAlert/function.json b/ListWebhookAlert/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ListWebhookAlert/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ListWebhookAlert/run.ps1 b/ListWebhookAlert/run.ps1 new file mode 100644 index 000000000000..45723840f771 --- /dev/null +++ b/ListWebhookAlert/run.ps1 @@ -0,0 +1,16 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +param($Request, $TriggerMetadata) + +$APIName = $TriggerMetadata.FunctionName +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" +$WebhookTable = Get-CIPPTable -TableName webhookTable +$WebhookRow = Get-AzDataTableEntity @WebhookTable + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($WebhookRow) + }) + diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 similarity index 51% rename from Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 rename to Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 63845e1fecf0..e3a2f215ca5f 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhook.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -1,25 +1,32 @@ -function Invoke-CippWebhook { +function Invoke-CippWebhookProcessing { [CmdletBinding()] param ( $TenantFilter, $Data, $Resource, - $EventType, + $CIPPPURL, $APIName = "Process webhook", $ExecutingUser ) $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String + $LocationTable = Get-CIPPTable -TableName knownlocationdb + $GeoTable = Get-CIPPTable -TableName geoipdb - $Data.ActorIpAddress.Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { - [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null - $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte + if ($data.clientip) { + ($Data.clientIp).split(':')[0].Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { + [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null + $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte + } + $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -First 1 + $Country = if ($Location.CountryOrRegion) { $Location.CountryOrRegion } else { "Unknown" } + $City = if ($Location.City) { $Location.City } else { "Unknown" } + } - $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -First 1 - #0: TenantName + Alert title. E.g. "CyberDrainDev.onmicrosoft.com - New-InboxRule" - #1: Intro text - #2: button url - #3: button text - #4: after button text + #Custom cipp operations. + if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } + if ($data.operation -eq "UserLoggedIn" -and $Country -notin $AllowedLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } + if ($data.operation -eq "UserLoggedIn" -and $Country -notin $PreviousLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } + switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" @@ -28,10 +35,9 @@ function Invoke-CippWebhook { $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('', '
') $ParameterName $IntroText = "

A new rule has been created for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "Start BEC Investigation" $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Set-inboxrule" { $Title = "$($TenantFilter) - Rule Edit Detected for $($data.UserId)" @@ -40,119 +46,117 @@ function Invoke-CippWebhook { $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $ParameterName $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "Start BEC Investigation" $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Add member to role." { $Title = "$($TenantFilter) - Role change detected for $($data.ObjectId)" $Table = ($data.ModifiedProperties | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $IntroText = "

$($data.UserId) has added $($data.ObjectId) to the $(($data.ModifiedProperties | Where-Object -Property Name -EQ "Role.DisplayName").NewValue) role. The information about the role can be found in the table below.

$Table" - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/roles?customerId=$($data.OrganizationId)" $ButtonText = "Role Management" $AfterButtonText = "

If this role is incorrect, or you need more information, use the button to jump to the Role Management page.

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Disable account." { $Title = "$($TenantFilter) - $($data.ObjectId) has been disabled" $IntroText = "$($data.ObjectId) has been disabled by $($data.UserId)." - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Enable account." { $Title = "$($TenantFilter) - $($data.ObjectId) has been enabled" $IntroText = "$($data.ObjectId) has been enabled by $($data.UserId)." - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Update StsRefreshTokenValidFrom Timestamp." { $Title = "$($TenantFilter) - $($data.ObjectId) has had all sessions revoked" $IntroText = "$($data.ObjectId) has had their sessions revoked by $($data.UserId)." - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Disable Strong Authentication." { $Title = "$($TenantFilter) - $($data.ObjectId) has been MFA disabled" $IntroText = "$($data.ObjectId) MFA has been disabled by $($data.UserId)." - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to reenable MFA

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } "Remove Member from a role." { $Title = "$($TenantFilter) - Role change detected for $($data.ObjectId)" $Table = ($data.ModifiedProperties | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $IntroText = "

$($data.UserId) has removed $($data.ObjectId) to the $(($data.ModifiedProperties | Where-Object -Property Name -EQ "Role.DisplayName").NewValue) role. The information about the role can be found in the table below.

$Table" - $ButtonUrl = "BECURLHERE" + $ButtonUrl = "$CIPPPURL/identity/administration/roles?customerId=$($data.OrganizationId)" $ButtonText = "Role Management" $AfterButtonText = "

If this role change is incorrect, or you need more information, use the button to jump to the Role Management page.

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText } - "UserLoggedIn" { - $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId - if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } + "Reset user password." { + $Title = "$($TenantFilter) - $($data.UserId) has had their password reset" + $IntroText = "$($data.UserId) has had their password reset." + $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" + + } + "AdminLoggedIn" { $TableObj = [PSCustomObject]::new() $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') - $Country = $Location.CountryOrRegion - $City = $Location.city - if ($data.UserType -eq 2) { - $Title = "$($TenantFilter) - an admin account has logged on" - $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" - $ButtonUrl = "BECURLHERE" - $ButtonText = "User Management" - $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText - } - - if ($data.UserType -eq 0) { - $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" - $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" - $ButtonUrl = "BECURLHERE" - $ButtonText = "User Management" - $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText - } - - } - "Reset user password." { - $Title = "$($TenantFilter) - $($data.ObjectId) has had their password reset" - $IntroText = "$($data.UserId) has had their password reset." - $ButtonUrl = "BECURLHERE" + $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId + if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } + $Title = "$($TenantFilter) - an admin account has logged on" + $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "User Management" - $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } - "UpdateInboxRules" { - $Title = "$($TenantFilter) - Rule Edit Detected for $($data.UserId)" + "UserLoggedInFromUnknownLocation" { $TableObj = [PSCustomObject]::new() - $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } - $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') - $ParameterName - $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" - $ButtonUrl = "BECURLHERE" - $ButtonText = "Start BEC Investigation" - $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" - $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText + $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') + $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId + if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } + $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" + $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" + $ButtonText = "User Management" + $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } } - return $HTML + $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText -} -#check if e-mail notification or PSA is configured. If yes, use generated HTML to send e-mail or create PSA ticket + #Add IP and potential location to knownlocation db for this specific user + if ($data.ClientIP) { + $LocationInfo = @{ + RowKey = [string]$data.ClientIP.Split(':')[0] + PartitionKey = [string]$data.UserId + CountryOrRegion = "$Country" + City = "$City" + } + $null = Add-AzDataTableEntity @LocationTable -Entity $LocationInfo -Force + } + $JsonContent = @{ + Title = $Title + ActionUrl = $ButtonUrl + RawData = $Data + IP = $data.ClientIP + PotentialCountry = $Country + PotentialCity = $City + } | ConvertTo-Json -Depth 15 -Compress -#Check if webhook notification is configured. If yes, send webhook notification with raw data. + Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML + Send-CIPPAlert -Type 'webhook' -Title $title -JSONContent $JsonContent + Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML +} diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 index 413af8653ebd..8dc09e7a76d8 100644 --- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -4,6 +4,7 @@ function New-CIPPGraphSubscription { $TenantFilter, [bool]$auditLogAPI = $false, $TypeofSubscription, + $BaseURL, $Resource, $EventType, $APIName = "Create Webhook", @@ -13,7 +14,7 @@ function New-CIPPGraphSubscription { $expiredate = (Get-Date).AddDays(1).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") $params = @{ changeType = $TypeofSubscription - notificationUrl = "https://webhook.site/9650bc4a-0120-41de-8ffd-6616e71244e1?EventType=$EventType&CIPPID=$CIPPID" + notificationUrl = "$BaseURL?EventType=$EventType&CIPPID=$CIPPID" resource = $Resource expirationDateTime = $expiredate } | ConvertTo-Json @@ -23,10 +24,10 @@ function New-CIPPGraphSubscription { if ($auditLogAPI) { $AuditLogParams = @{ webhook = @{ - "address" = "https://webhook.site/9650bc4a-0120-41de-8ffd-6616e71244e1/" + "address" = "$BaseURL?EventType=$EventType&CIPPID=$CIPPID" } } | ConvertTo-Json - $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type -scope "https://manage.office.com/.default" POST -body $AuditLogparams -verbose + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type POST -scope "https://manage.office.com/.default" -body $AuditLogparams -verbose $WebhookRow = @{ PartitionKey = [string]$TenantFilter RowKey = [string]$CIPPID diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 index 6f04e1796c28..3f2e495def0c 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 @@ -18,7 +18,7 @@ function Remove-CIPPGraphSubscription { $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow } - return "Remove webhook subscription to $($GraphRequest.value.notificationUrl)" + return "Removed webhook subscription to $($GraphRequest.value.notificationUrl)" } catch { diff --git a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 new file mode 100644 index 000000000000..5f50df9eea9e --- /dev/null +++ b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 @@ -0,0 +1,90 @@ + +function Send-CIPPAlert { + [CmdletBinding()] + param ( + $Type, + $Title, + $HTMLContent, + $JSONContent, + $TenantFilter, + $APIName = "Send Alert", + $ExecutingUser + ) + + $Table = Get-CIPPTable -TableName SchedulerConfig + $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" + $Config = [pscustomobject](Get-AzDataTableEntity @Table -Filter $Filter) + if ($Type -eq 'email') { + try { + if ($Config.email -like '*@*') { + $Recipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { [pscustomobject]@{EmailAddress = @{Address = $_ } } } } + $PowerShellBody = [PSCustomObject]@{ + message = @{ + subject = $Title + body = @{ + contentType = "HTML" + content = $HTMLcontent + } + toRecipients = @($Recipients) + } + saveToSentItems = "true" + } + + $JSONBody = ConvertTo-Json -Compress -Depth 10 -InputObject $PowerShellBody + New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -NoAuthCheck $true -type POST -body ($JSONBody) + } + + } + catch { + Write-Host "Could not send alerts to email: $($_.Exception.message)" + Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + } + + } + if ($Type -eq 'webhook') { + try { + if ($Config.webhook -ne '') { + switch -wildcard ($config.webhook) { + + '*webhook.office.com*' { + $JSonBody = "{`"text`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log.

$JSONContent`"}" + Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody + } + + '*discord.com*' { + $JSonBody = "{`"content`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log. $JSONContent`"}" + Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody + } + default { + Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONContent + } + } + + } + + } + catch { + Write-Host "Could not send alerts to webhook: $($_.Exception.message)" + Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + } + } + if ($Type -eq 'psa') { + if ($config.sendtoIntegration) { + try { + + $Alert = @{ + TenantId = $Tenant + AlertText = "$HTMLContent" + AlertTitle = "$($Title)" + } + New-CippExtAlert -Alert $Alert + } + catch { + Write-Host "Could not send alerts to ticketing system: $($_.Exception.message)" + Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + } + } + } +} + + diff --git a/PublicWebhooks/function.json b/PublicWebhooks/function.json new file mode 100644 index 000000000000..4ee273331c44 --- /dev/null +++ b/PublicWebhooks/function.json @@ -0,0 +1,16 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": ["get", "post"] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 new file mode 100644 index 000000000000..cceb00b7c6bf --- /dev/null +++ b/PublicWebhooks/run.ps1 @@ -0,0 +1,44 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +param($Request, $TriggerMetadata) +$WebhookTable = Get-CIPPTable -TableName webhookTable +$Webhooks = Get-AzDataTableEntity @WebhookTable + +$WebhookAlertTable = Get-CIPPTable -TableName webhookAlertTable +$WebhookAlerts = Get-AzDataTableEntity $WebhookAlertTable +$url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 + +if ($Request.CIPPID -in $Webhooks.CIPPID) { + if ($Request.query.ValidationToken -or $Request.body.validationCode) { + $body = $request.query.ValidationToken + } + + if ($Request.body.ContentUri) { + if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { exit } + $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantID).defaultDomainName + $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" + } + else { + $TenantFilter = $Data.Tenant + $Data = $Request.body + } + + foreach ($Item in $Data) { + if ($item.Operation -in $WebhookAlerts.Operation) { + Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url + } + } + + $body = "OK" +} +else { + $body = "This webhook is not authorized." +} + + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) diff --git a/RemoveWebhookAlert/function.json b/RemoveWebhookAlert/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/RemoveWebhookAlert/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/RemoveWebhookAlert/run.ps1 b/RemoveWebhookAlert/run.ps1 new file mode 100644 index 000000000000..d425c18cd244 --- /dev/null +++ b/RemoveWebhookAlert/run.ps1 @@ -0,0 +1,24 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +param($Request, $TriggerMetadata) + +$APIName = $TriggerMetadata.FunctionName +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" +Import-Module CippCore +try { + $Results = Remove-CIPPGraphSubscription -TenantFilter $Request.query.TenantFilter -CIPPID $Request.query.CIPPID + $body = [pscustomobject]@{"Results" = $Results } +} +catch { + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to remove webhook alert. $($_.Exception.Message)" -Sev "Error" + $body = [pscustomobject]@{"Results" = "Failed to remove webhook alert: $($_.Exception.Message)" } +} + + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) + diff --git a/Scheduler_CIPPNotifications/run.ps1 b/Scheduler_CIPPNotifications/run.ps1 index 9826a29db506..f524a6ae2f14 100644 --- a/Scheduler_CIPPNotifications/run.ps1 +++ b/Scheduler_CIPPNotifications/run.ps1 @@ -78,6 +78,8 @@ catch { Write-Host "Could not send alerts to email: $($_.Exception.message)" Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info } + + try { Write-Host $($config | ConvertTo-Json) Write-Host $config.webhook From 3d16bce64fe5c74fccfaf99a8a483cf559d04320 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 6 Aug 2023 17:28:09 +0200 Subject: [PATCH 025/119] correct typo --- .../Public/Remove-CIPPGraphSubscription.ps1 | 28 +++++++++++++++++++ RemoveWebhookAlert/run.ps1 | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 new file mode 100644 index 000000000000..313c887072b6 --- /dev/null +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 @@ -0,0 +1,28 @@ +function Remove-CIPPGraphSubscription{ + [CmdletBinding()] + param ( + $TenantFilter, + $CIPPID, + $APIName = "Remove Graph Webhook", + $ExecutingUser + ) + try { + $WebhookTable = Get-CIPPTable -TableName webhookTable + $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } + if ($WebhookRow.Resource -eq "M365AuditLogs") { + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -scope "https://manage.office.com/.default" -tenantid $TenantFilter -type POST -body "{}" -verbose + + } + else { + $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } + $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose + $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow + } + return "Removed webhook subscription to $($GraphRequest.value.notificationUrl)" + + } + catch { + Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to renew Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter + return "Failed to remove Webhook Subscription $($GraphRequest.value.notificationUrl): $($_.Exception.Message)" + } +} \ No newline at end of file diff --git a/RemoveWebhookAlert/run.ps1 b/RemoveWebhookAlert/run.ps1 index d425c18cd244..dbda93213351 100644 --- a/RemoveWebhookAlert/run.ps1 +++ b/RemoveWebhookAlert/run.ps1 @@ -5,7 +5,7 @@ param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" -Import-Module CippCore + try { $Results = Remove-CIPPGraphSubscription -TenantFilter $Request.query.TenantFilter -CIPPID $Request.query.CIPPID $body = [pscustomobject]@{"Results" = $Results } From 16982a0e253d62364de09ee9c47508340ff3c7d6 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:53:35 +0200 Subject: [PATCH 026/119] webhook updates --- AddAlert/run.ps1 | 21 +++++++++----- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 3 +- .../Public/New-CIPPGraphSubscription.ps1 | 8 +++++- .../Public/Remove-CIPPGraphSubcription.ps1 | 28 ------------------- .../Public/Remove-CIPPGraphSubscription.ps1 | 4 +-- PublicWebhooks/run.ps1 | 7 ++--- 6 files changed, 28 insertions(+), 43 deletions(-) delete mode 100644 Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index 480236366cde..638fa7f7d42a 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -42,14 +42,21 @@ $Results = foreach ($Tenant in $tenants) { } $Table = get-cipptable -TableName 'SchedulerConfig' - <#$TableRow = @{ - table = () - property = $CompleteObject - UpdateExisting = $true - }#> - - #Add-AzTableRow @TableRow | Out-Null Add-AzDataTableEntity @Table -Entity $CompleteObject -Force + + $URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 + foreach ($eventype in $Request.body.EventTypes.value) { + $params = @{ + TenantFilter = $tenant + auditLogAPI = $true + operations = ($Request.body.Operations.value -join ',') + allowedLocations = ($Request.body.AllowedLocations.value -join ',') + BaseURL = $url + EventType = $Eventtype + ExecutingUser = $Request.headers.'x-ms-client-principal' + } + New-CIPPGraphSubscription @params + } "Successfully added Alert for $($Tenant) to queue." Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message "Successfully added Alert for $($Tenant) to queue." -Sev 'Info' } diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index e3a2f215ca5f..bd64e760e154 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -4,13 +4,14 @@ function Invoke-CippWebhookProcessing { $TenantFilter, $Data, $Resource, + $AllowedLocations, $CIPPPURL, $APIName = "Process webhook", $ExecutingUser ) $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String $LocationTable = Get-CIPPTable -TableName knownlocationdb - + $AllowedLocations = $AllowedLocations -split ',' $GeoTable = Get-CIPPTable -TableName geoipdb if ($data.clientip) { ($Data.clientIp).split(':')[0].Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 index 8dc09e7a76d8..5cb1ba62ad3e 100644 --- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -4,7 +4,9 @@ function New-CIPPGraphSubscription { $TenantFilter, [bool]$auditLogAPI = $false, $TypeofSubscription, + $AllowedLocations, $BaseURL, + $operations, $Resource, $EventType, $APIName = "Create Webhook", @@ -33,6 +35,8 @@ function New-CIPPGraphSubscription { RowKey = [string]$CIPPID EventType = [string]$EventType Resource = "M365AuditLogs" + Operations = [string]$operations + AllowedLocations = [string]$AllowedLocations Expiration = "None" WebhookNotificationUrl = [string]$Auditlog.webhook.address } @@ -49,6 +53,8 @@ function New-CIPPGraphSubscription { EventType = [string]$EventType Resource = [string]$Resource Expiration = [string]$expiredate + Operations = [string]$operations + AllowedLocations = [string]$AllowedLocations WebhookNotificationUrl = [string]$GraphRequest.notificationUrl } $null = Add-AzDataTableEntity @WebhookTable -Entity $WebhookRow @@ -60,7 +66,7 @@ function New-CIPPGraphSubscription { } catch { Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to create Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter - Return "Failed to create Webhook Subscription: $($_.Exception.Message)" + Return "Failed to create Webhook Subscription for $($TenantFilter): $($_.Exception.Message)" } } diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 deleted file mode 100644 index 3f2e495def0c..000000000000 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubcription.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -function Remove-CIPPGraphSubscription { - [CmdletBinding()] - param ( - $TenantFilter, - $CIPPID, - $APIName = "Remove Graph Webhook", - $ExecutingUser - ) - try { - $WebhookTable = Get-CIPPTable -TableName webhookTable - $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } - if ($WebhookRow.Resource -eq "M365AuditLogs") { - $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -scope "https://manage.office.com/.default" -tenantid $TenantFilter -type POST -body "{}" -verbose - - } - else { - $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } - $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose - $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow - } - return "Removed webhook subscription to $($GraphRequest.value.notificationUrl)" - - } - catch { - Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to renew Webhook Subscription: $($_.Exception.Message)" -Sev "Error" -tenant $TenantFilter - return "Failed to remove Webhook Subscription $($GraphRequest.value.notificationUrl): $($_.Exception.Message)" - } -} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 index 313c887072b6..37f501f69a35 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 @@ -1,4 +1,4 @@ -function Remove-CIPPGraphSubscription{ +function Remove-CIPPGraphSubscription { [CmdletBinding()] param ( $TenantFilter, @@ -18,7 +18,7 @@ function Remove-CIPPGraphSubscription{ $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/subscriptions/$($oldId.ID)" -tenantid $TenantFilter -type DELETE -body {} -Verbose $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow } - return "Removed webhook subscription to $($GraphRequest.value.notificationUrl)" + return "Removed webhook subscription to $($WebhookRow.resource) for $($TenantFilter)" } catch { diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index cceb00b7c6bf..57f1bb12695c 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -5,11 +5,10 @@ param($Request, $TriggerMetadata) $WebhookTable = Get-CIPPTable -TableName webhookTable $Webhooks = Get-AzDataTableEntity @WebhookTable -$WebhookAlertTable = Get-CIPPTable -TableName webhookAlertTable -$WebhookAlerts = Get-AzDataTableEntity $WebhookAlertTable $url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 if ($Request.CIPPID -in $Webhooks.CIPPID) { + $Webhookinfo = $Webhooks | Where-Object -Property CIPPID -EQ $Request.CIPPID if ($Request.query.ValidationToken -or $Request.body.validationCode) { $body = $request.query.ValidationToken } @@ -25,8 +24,8 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { } foreach ($Item in $Data) { - if ($item.Operation -in $WebhookAlerts.Operation) { - Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url + if ($item.Operation -in ($Webhooks.Operation -split ',')) { + Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } } From 2583b8d0ee69efc5bbcdb9dae748e5bd381aa39b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 11:42:59 +0200 Subject: [PATCH 027/119] changes to add alert and webhooks --- AddAlert/run.ps1 | 3 ++- ListGenericTestFunction/run.ps1 | 3 ++- Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index 638fa7f7d42a..fd3451dbab14 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -45,13 +45,14 @@ $Results = foreach ($Tenant in $tenants) { Add-AzDataTableEntity @Table -Entity $CompleteObject -Force $URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 + Write-Host $URL foreach ($eventype in $Request.body.EventTypes.value) { $params = @{ TenantFilter = $tenant auditLogAPI = $true operations = ($Request.body.Operations.value -join ',') allowedLocations = ($Request.body.AllowedLocations.value -join ',') - BaseURL = $url + BaseURL = $URL EventType = $Eventtype ExecutingUser = $Request.headers.'x-ms-client-principal' } diff --git a/ListGenericTestFunction/run.ps1 b/ListGenericTestFunction/run.ps1 index 67c30cc60e00..64b7583f9f3c 100644 --- a/ListGenericTestFunction/run.ps1 +++ b/ListGenericTestFunction/run.ps1 @@ -5,7 +5,8 @@ param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' -$graphRequest = $request.headers +$graphRequest = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @($graphRequest) diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 index 5cb1ba62ad3e..ae42c1828b65 100644 --- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 @@ -16,7 +16,7 @@ function New-CIPPGraphSubscription { $expiredate = (Get-Date).AddDays(1).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ") $params = @{ changeType = $TypeofSubscription - notificationUrl = "$BaseURL?EventType=$EventType&CIPPID=$CIPPID" + notificationUrl = "$BaseURL/API/PublicWebhooks?EventType=$EventType&CIPPID=$CIPPID" resource = $Resource expirationDateTime = $expiredate } | ConvertTo-Json @@ -26,9 +26,10 @@ function New-CIPPGraphSubscription { if ($auditLogAPI) { $AuditLogParams = @{ webhook = @{ - "address" = "$BaseURL?EventType=$EventType&CIPPID=$CIPPID" + "address" = "$BaseURL/API/Publicwebhooks?EventType=$EventType&CIPPID=$CIPPID" } } | ConvertTo-Json + Write-Host ($AuditLogParams) $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type POST -scope "https://manage.office.com/.default" -body $AuditLogparams -verbose $WebhookRow = @{ PartitionKey = [string]$TenantFilter From 2910b5d966bf4485c81b8888ca64f8f8c7af2d9e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 11:48:39 +0200 Subject: [PATCH 028/119] typo --- AddAlert/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index fd3451dbab14..7325bb1d17e4 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -53,7 +53,7 @@ $Results = foreach ($Tenant in $tenants) { operations = ($Request.body.Operations.value -join ',') allowedLocations = ($Request.body.AllowedLocations.value -join ',') BaseURL = $URL - EventType = $Eventtype + EventType = $eventype ExecutingUser = $Request.headers.'x-ms-client-principal' } New-CIPPGraphSubscription @params From 2d619a28e298f7a533f02a84a51b19eea762bbbd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:09:49 +0200 Subject: [PATCH 029/119] added logging --- PublicWebhooks/run.ps1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 57f1bb12695c..ee4d4879f64c 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -4,16 +4,21 @@ using namespace System.Net param($Request, $TriggerMetadata) $WebhookTable = Get-CIPPTable -TableName webhookTable $Webhooks = Get-AzDataTableEntity @WebhookTable - +Write-Host "Received request" +Write-Host "CIPPID: $($request.CIPPID)" $url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 if ($Request.CIPPID -in $Webhooks.CIPPID) { + Write-Host "Found matching CIPPID" + $Webhookinfo = $Webhooks | Where-Object -Property CIPPID -EQ $Request.CIPPID if ($Request.query.ValidationToken -or $Request.body.validationCode) { + Write-Host "Validation token received" $body = $request.query.ValidationToken } if ($Request.body.ContentUri) { + Write-Host "ContentUri received" if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { exit } $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantID).defaultDomainName $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" @@ -24,7 +29,10 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { } foreach ($Item in $Data) { + Write-Host "Data to process found." + if ($item.Operation -in ($Webhooks.Operation -split ',')) { + Write-Host "Working on $($item.operation)." Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } } From 59995bef191e989e317f78496dc6194ac81cbbb0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:25:07 +0200 Subject: [PATCH 030/119] typo --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index ee4d4879f64c..564f6fcbbf53 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -5,7 +5,7 @@ param($Request, $TriggerMetadata) $WebhookTable = Get-CIPPTable -TableName webhookTable $Webhooks = Get-AzDataTableEntity @WebhookTable Write-Host "Received request" -Write-Host "CIPPID: $($request.CIPPID)" +Write-Host "CIPPID: $($request.Query.CIPPID)" $url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 if ($Request.CIPPID -in $Webhooks.CIPPID) { From a3874fcedf392a81eddcd5204f5691ef5d505b55 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:26:01 +0200 Subject: [PATCH 031/119] typo --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 564f6fcbbf53..c57cd85510c4 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -31,7 +31,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { foreach ($Item in $Data) { Write-Host "Data to process found." - if ($item.Operation -in ($Webhooks.Operation -split ',')) { + if ($item.Operation -in ($Webhookinfo.Operations -split ',')) { Write-Host "Working on $($item.operation)." Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } From 2f6a1899e2c4d4dcf9f0dd60152eecbdc67a561f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:50:14 +0200 Subject: [PATCH 032/119] added permissions endpoint --- Cache_SAMSetup/PermissionsTranslator.json | 9 +++++++++ Cache_SAMSetup/SAMManifest.json | 6 ++++++ ExecCPVPermissions/run.ps1 | 2 ++ UpdatePermissionsQueue/run.ps1 | 1 + 4 files changed, 18 insertions(+) diff --git a/Cache_SAMSetup/PermissionsTranslator.json b/Cache_SAMSetup/PermissionsTranslator.json index f7ce2cf3235a..fdb6b61d88a0 100644 --- a/Cache_SAMSetup/PermissionsTranslator.json +++ b/Cache_SAMSetup/PermissionsTranslator.json @@ -2982,6 +2982,15 @@ "userConsentDisplayName": "Read all terms of use acceptance statuses", "value": "AgreementAcceptance.Read.All" }, + { + "description": "Read activity data for your organization", + "displayName": "Allows the application to read activity data for your organization.", + "id": "594c1fb6-4f81-4475-ae41-0c394909246c", + "Origin": "Delegated", + "userConsentDescription": "Read activity data for your organization", + "userConsentDisplayName": "Allows the application to read activity data for your organization.", + "value": "ActivityFeed.Read" + }, { "description": "Allows the app to read and query your audit log activities, on behalf of the signed-in user.", "displayName": "Read audit log data", diff --git a/Cache_SAMSetup/SAMManifest.json b/Cache_SAMSetup/SAMManifest.json index 3f458048fda0..0520249e1663 100644 --- a/Cache_SAMSetup/SAMManifest.json +++ b/Cache_SAMSetup/SAMManifest.json @@ -191,6 +191,12 @@ "resourceAccess": [ { "id": "e60370c1-e451-437e-aa6e-d76df38e5f15", "type": "Scope" } ] + }, + { + "resourceAppId": "c5393580-f805-4401-95e8-94b7a6ef2fc2", + "resourceAccess": [ + { "id": "594c1fb6-4f81-4475-ae41-0c394909246c", "type": "Scope" } + ] } ] } diff --git a/ExecCPVPermissions/run.ps1 b/ExecCPVPermissions/run.ps1 index 7494a1b54f99..cf7e6501a3c4 100644 --- a/ExecCPVPermissions/run.ps1 +++ b/ExecCPVPermissions/run.ps1 @@ -33,6 +33,8 @@ $GraphRequest = $ExpectedPermissions.requiredResourceAccess | ForEach-Object { 'fc780465-2017-40d4-a0c5-307022471b92' { 'WindowsDefenderATP' } '00000003-0000-0ff1-ce00-000000000000' { 'Sharepoint' } '48ac35b8-9aa8-4d74-927d-1f4a14a0b239' { 'Skype and Teams Tenant Admin API' } + 'c5393580-f805-4401-95e8-94b7a6ef2fc2' { 'Office 365 Management API' } + } $Scope = ($Translator | Where-Object { $_.id -in $Resource.ResourceAccess.id } | Where-Object { $_.value -notin 'profile', 'openid', 'offline_access' }).value -join ', ' if ($Scope) { diff --git a/UpdatePermissionsQueue/run.ps1 b/UpdatePermissionsQueue/run.ps1 index 17e9c30df1c5..f0505b18f59f 100644 --- a/UpdatePermissionsQueue/run.ps1 +++ b/UpdatePermissionsQueue/run.ps1 @@ -25,6 +25,7 @@ $GraphRequest = $ExpectedPermissions.requiredResourceAccess | ForEach-Object { 'fc780465-2017-40d4-a0c5-307022471b92' { 'WindowsDefenderATP' } '00000003-0000-0ff1-ce00-000000000000' { 'Sharepoint' } '48ac35b8-9aa8-4d74-927d-1f4a14a0b239' { 'Skype and Teams Tenant Admin API' } + 'c5393580-f805-4401-95e8-94b7a6ef2fc2' { 'Office 365 Management API' } } From 4a10bf84a478d0550be6ce1cf8dfb2e7affae084 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:56:26 +0200 Subject: [PATCH 033/119] added some more logging --- PublicWebhooks/run.ps1 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index c57cd85510c4..282bbdd4f72b 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -12,6 +12,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Found matching CIPPID" $Webhookinfo = $Webhooks | Where-Object -Property CIPPID -EQ $Request.CIPPID + Write-Host "Webhookinfo: $($Webhookinfo | ConvertTo-Json -Depth 10)" if ($Request.query.ValidationToken -or $Request.body.validationCode) { Write-Host "Validation token received" $body = $request.query.ValidationToken @@ -27,11 +28,12 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $TenantFilter = $Data.Tenant $Data = $Request.body } - + Write-Host "Data to process found: $(($data.operation).count) items" + $operations = $Webhookinfo.Operations -split ',' + Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" foreach ($Item in $Data) { - Write-Host "Data to process found." - - if ($item.Operation -in ($Webhookinfo.Operations -split ',')) { + Write-Host "Processing $($item.operation)" + if ($item.Operation -in $operations) { Write-Host "Working on $($item.operation)." Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } From fabfc907f6d11cf1db6f2baba28c520a8ea0707f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:23:08 +0200 Subject: [PATCH 034/119] correction in webhook code --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 282bbdd4f72b..22b8b14b5e1e 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -11,7 +11,7 @@ $url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -Fir if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Found matching CIPPID" - $Webhookinfo = $Webhooks | Where-Object -Property CIPPID -EQ $Request.CIPPID + $Webhookinfo = $Webhooks | Where-Object -Property RowKey -EQ $Request.query.CIPPID Write-Host "Webhookinfo: $($Webhookinfo | ConvertTo-Json -Depth 10)" if ($Request.query.ValidationToken -or $Request.body.validationCode) { Write-Host "Validation token received" From 459e07b37b62c898735d6f0763c7e2a2b8768d3d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:25:45 +0200 Subject: [PATCH 035/119] moved ok into body --- PublicWebhooks/run.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 22b8b14b5e1e..e24df8b42b77 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -37,9 +37,10 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Working on $($item.operation)." Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } + $body = "OK" } - $body = "OK" + } else { $body = "This webhook is not authorized." From ee39ee85a4ca2994f6f53256acced476a04c3f6b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:27:52 +0200 Subject: [PATCH 036/119] public webhook fixes --- PublicWebhooks/run.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index e24df8b42b77..4b974ec54839 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -21,13 +21,15 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { if ($Request.body.ContentUri) { Write-Host "ContentUri received" if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { exit } - $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantID).defaultDomainName + $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantId).defaultDomainName + Write-Host "TenantFilter: $TenantFilter" $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" } else { $TenantFilter = $Data.Tenant $Data = $Request.body } + Write-Host "Data to process found: $(($data.operation).count) items" $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" From da02df95f4a4ef9c282c2485431749f838619c9d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:28:55 +0200 Subject: [PATCH 037/119] added logging --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 4b974ec54839..e91a56f4938a 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -17,7 +17,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Validation token received" $body = $request.query.ValidationToken } - + Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" if ($Request.body.ContentUri) { Write-Host "ContentUri received" if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { exit } From 551741962d90938462ca31800f2ed7821718d9fe Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:49:10 +0200 Subject: [PATCH 038/119] webhook writehosts --- PublicWebhooks/run.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index e91a56f4938a..57b428680648 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -18,9 +18,12 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $body = $request.query.ValidationToken } Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" - if ($Request.body.ContentUri) { + if ($Request.body.contentUri -ne $null) { Write-Host "ContentUri received" - if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { exit } + if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { + Write-Host "Potential url forgery detected. Quitting to not send headers." + exit + } $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantId).defaultDomainName Write-Host "TenantFilter: $TenantFilter" $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" From 3ff607edc6c625566e39ef02e5ee967244c76ce7 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:46:33 +0200 Subject: [PATCH 039/119] removed future code --- PublicWebhooks/run.ps1 | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 57b428680648..397a4eee1742 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -18,21 +18,15 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $body = $request.query.ValidationToken } Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" - if ($Request.body.contentUri -ne $null) { - Write-Host "ContentUri received" - if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { - Write-Host "Potential url forgery detected. Quitting to not send headers." - exit - } - $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantId).defaultDomainName - Write-Host "TenantFilter: $TenantFilter" - $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" - } - else { - $TenantFilter = $Data.Tenant - $Data = $Request.body - } + Write-Host "ContentUri received" + if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { + Write-Host "Potential url forgery detected. Quitting to not send headers." + exit + } + $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantId).defaultDomainName + Write-Host "TenantFilter: $TenantFilter" + $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" Write-Host "Data to process found: $(($data.operation).count) items" $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" From cec1a62e578633801ccb3529847870f8a0c15384 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:24:51 +0200 Subject: [PATCH 040/119] loop through received arr --- PublicWebhooks/run.ps1 | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 397a4eee1742..2df0c3471fe3 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -18,28 +18,28 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $body = $request.query.ValidationToken } Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" - - Write-Host "ContentUri received" - if ($Request.body.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { - Write-Host "Potential url forgery detected. Quitting to not send headers." - exit - } - $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $Request.body.TenantId).defaultDomainName - Write-Host "TenantFilter: $TenantFilter" - $Data = New-GraphPostRequest -type GET -uri "$($request.body.contenturi)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" - Write-Host "Data to process found: $(($data.operation).count) items" - $operations = $Webhookinfo.Operations -split ',' - Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" - foreach ($Item in $Data) { - Write-Host "Processing $($item.operation)" - if ($item.Operation -in $operations) { - Write-Host "Working on $($item.operation)." - Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations + foreach ($ReceivedItem in $Request.body) { + Write-Host "ContentUri received" + if ($ReceivedItem.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { + Write-Host "Potential url forgery detected. Quitting to not send headers." + exit + } + $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $ReceivedItem.TenantId).defaultDomainName + Write-Host "TenantFilter: $TenantFilter" + $Data = New-GraphPostRequest -type GET -uri $($ReceivedItem.contenturi) -tenantid $TenantFilter -scope "https://manage.office.com/.default" + Write-Host "Data to process found: $(($ReceivedItem.operation).count) items" + $operations = $Webhookinfo.Operations -split ',' + Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" + foreach ($Item in $Data) { + Write-Host "Processing $($item.operation)" + if ($item.Operation -in $operations) { + Write-Host "Working on $($item.operation)." + Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations + } + $body = "OK" } - $body = "OK" } - } else { $body = "This webhook is not authorized." From 77d46a307909bc315623ebda90a36d807f52cd46 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:44:13 +0200 Subject: [PATCH 041/119] checking uri --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 2df0c3471fe3..55ebed5f26fe 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -19,7 +19,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { } Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" foreach ($ReceivedItem in $Request.body) { - Write-Host "ContentUri received" + Write-Host "ContentUri received: $($ReceivedItem.ContentUri)" if ($ReceivedItem.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { Write-Host "Potential url forgery detected. Quitting to not send headers." exit From 613427ddd3be62073b7f1c6c677d033e6320d792 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:12:49 +0200 Subject: [PATCH 042/119] sending item, not all of data --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 55ebed5f26fe..d19ca836883f 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -34,7 +34,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Processing $($item.operation)" if ($item.Operation -in $operations) { Write-Host "Working on $($item.operation)." - Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Data -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations + Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Item -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations } $body = "OK" } From af8ab3efab70f4f8976d0e3d714a933bd03103e2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:18:01 +0200 Subject: [PATCH 043/119] force typecasting? --- PublicWebhooks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index d19ca836883f..c9834d51af1f 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -18,7 +18,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $body = $request.query.ValidationToken } Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" - foreach ($ReceivedItem in $Request.body) { + foreach ($ReceivedItem in ([pscustomobject]$Request.body)) { Write-Host "ContentUri received: $($ReceivedItem.ContentUri)" if ($ReceivedItem.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { Write-Host "Potential url forgery detected. Quitting to not send headers." From 06ffc05114227ae5883524fce504b31b83ec1976 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:36:17 +0200 Subject: [PATCH 044/119] something funky with conversion --- PublicWebhooks/run.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index c9834d51af1f..95ad3b58b90b 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -17,8 +17,9 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Validation token received" $body = $request.query.ValidationToken } - Write-Host "Request body: $($request.body | ConvertTo-Json -Depth 10)" - foreach ($ReceivedItem in ([pscustomobject]$Request.body)) { + Write-Host "Request body: $($request.body.gettype())" + foreach ($ReceivedItem In ($Request.body)) { + $ReceivedItem = [pscustomobject]$ReceivedItem Write-Host "ContentUri received: $($ReceivedItem.ContentUri)" if ($ReceivedItem.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { Write-Host "Potential url forgery detected. Quitting to not send headers." From 6c9620489caf9eb2d4b0136727a7126084cd22c2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:43:06 +0200 Subject: [PATCH 045/119] why use a external url if we can just craft it ourselves? saftey! --- PublicWebhooks/run.ps1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 95ad3b58b90b..e0e496721d6a 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -21,13 +21,9 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { foreach ($ReceivedItem In ($Request.body)) { $ReceivedItem = [pscustomobject]$ReceivedItem Write-Host "ContentUri received: $($ReceivedItem.ContentUri)" - if ($ReceivedItem.ContentUri -notlike "https://manage.office.com/api/v1.0/*") { - Write-Host "Potential url forgery detected. Quitting to not send headers." - exit - } $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $ReceivedItem.TenantId).defaultDomainName Write-Host "TenantFilter: $TenantFilter" - $Data = New-GraphPostRequest -type GET -uri $($ReceivedItem.contenturi) -tenantid $TenantFilter -scope "https://manage.office.com/.default" + $Data = New-GraphPostRequest -type GET -uri "https://manage.office.com/api/v1.0/$($ReceivedItem.tenantId)/activity/feed/audit/$($ReceivedItem.contentid)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" Write-Host "Data to process found: $(($ReceivedItem.operation).count) items" $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" From f02f385e2b05a980e0dd0d5a39b8e9ebec811a58 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:53:55 +0200 Subject: [PATCH 046/119] updated manually built url --- PublicWebhooks/run.ps1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index e0e496721d6a..7eed955cfa4a 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -17,10 +17,8 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Validation token received" $body = $request.query.ValidationToken } - Write-Host "Request body: $($request.body.gettype())" foreach ($ReceivedItem In ($Request.body)) { $ReceivedItem = [pscustomobject]$ReceivedItem - Write-Host "ContentUri received: $($ReceivedItem.ContentUri)" $TenantFilter = (Get-Tenants | Where-Object -Property customerId -EQ $ReceivedItem.TenantId).defaultDomainName Write-Host "TenantFilter: $TenantFilter" $Data = New-GraphPostRequest -type GET -uri "https://manage.office.com/api/v1.0/$($ReceivedItem.tenantId)/activity/feed/audit/$($ReceivedItem.contentid)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" From aa5192ada4418598e8218b60b352afceff047d6c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:54:41 +0200 Subject: [PATCH 047/119] added text --- PublicWebhooks/run.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 7eed955cfa4a..1692b5cf0dae 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -26,6 +26,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" foreach ($Item in $Data) { + Write-Host "Item: $($item | ConvertTo-Json -Depth 10)" Write-Host "Processing $($item.operation)" if ($item.Operation -in $operations) { Write-Host "Working on $($item.operation)." From c8cf8a46ba6da42ebd4d844b36c4d1dbdb8d51af Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:53:02 +0200 Subject: [PATCH 048/119] added root set --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index bd64e760e154..9601a4dece8c 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -9,6 +9,8 @@ function Invoke-CippWebhookProcessing { $APIName = "Process webhook", $ExecutingUser ) + Set-Location (Get-Item $PSScriptRoot).FullName + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String $LocationTable = Get-CIPPTable -TableName knownlocationdb $AllowedLocations = $AllowedLocations -split ',' From 0467f85e5f8fcfc064894ab63468f333915f373d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:06:32 +0200 Subject: [PATCH 049/119] added write hosts for troubleshooting --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 7 +++++-- Modules/CIPPCore/Public/Send-CIPPAlert.ps1 | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 9601a4dece8c..93f824cc70d3 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -29,7 +29,7 @@ function Invoke-CippWebhookProcessing { if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } if ($data.operation -eq "UserLoggedIn" -and $Country -notin $AllowedLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } if ($data.operation -eq "UserLoggedIn" -and $Country -notin $PreviousLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } - + Write-Host "Selecting the Operation: $($data.operation)" switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" @@ -140,7 +140,7 @@ function Invoke-CippWebhookProcessing { } $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText - #Add IP and potential location to knownlocation db for this specific user + Write-Host "Add IP and potential location to knownlocation db for this specific user" if ($data.ClientIP) { $LocationInfo = @{ RowKey = [string]$data.ClientIP.Split(':')[0] @@ -159,7 +159,10 @@ function Invoke-CippWebhookProcessing { PotentialCity = $City } | ConvertTo-Json -Depth 15 -Compress + Write-Host "Sending alert to email" Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML + Write-Host "Sending alert to webhook" Send-CIPPAlert -Type 'webhook' -Title $title -JSONContent $JsonContent + Write-Host "Sending alert to PSA" Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML } diff --git a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 index 5f50df9eea9e..6645b70e6a48 100644 --- a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 +++ b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 @@ -10,11 +10,12 @@ function Send-CIPPAlert { $APIName = "Send Alert", $ExecutingUser ) - + Write-Host "Shipping Alert" $Table = Get-CIPPTable -TableName SchedulerConfig $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" $Config = [pscustomobject](Get-AzDataTableEntity @Table -Filter $Filter) if ($Type -eq 'email') { + Write-Host "Trying to send email" try { if ($Config.email -like '*@*') { $Recipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { [pscustomobject]@{EmailAddress = @{Address = $_ } } } } @@ -41,7 +42,10 @@ function Send-CIPPAlert { } } + if ($Type -eq 'webhook') { + Write-Host "Trying to send webhook" + try { if ($Config.webhook -ne '') { switch -wildcard ($config.webhook) { @@ -68,6 +72,8 @@ function Send-CIPPAlert { Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info } } + Write-Host "Trying to send to PSA" + if ($Type -eq 'psa') { if ($config.sendtoIntegration) { try { From f5c7173ddc5f0dea26a84da1cea278878934e9b6 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:48:17 +0200 Subject: [PATCH 050/119] added succesful logging --- Modules/CIPPCore/Public/Send-CIPPAlert.ps1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 index 6645b70e6a48..83331941a471 100644 --- a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 +++ b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 @@ -34,11 +34,12 @@ function Send-CIPPAlert { $JSONBody = ConvertTo-Json -Compress -Depth 10 -InputObject $PowerShellBody New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -NoAuthCheck $true -type POST -body ($JSONBody) } - + Write-LogMessage -API 'Alerts' -message "Sent a webhook alert to email: $Title" -sev info + } catch { - Write-Host "Could not send alerts to email: $($_.Exception.message)" - Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + Write-Host "Could not send webhook alert to email: $($_.Exception.message)" + Write-LogMessage -API 'Alerts' -message "Could not send webhook alerts to email. $($_.Exception.message)" -sev info } } @@ -65,6 +66,7 @@ function Send-CIPPAlert { } } + Write-LogMessage -API 'Alerts' -message "Sent Webhook alert $title to External webhook" -sev info } catch { @@ -84,6 +86,8 @@ function Send-CIPPAlert { AlertTitle = "$($Title)" } New-CippExtAlert -Alert $Alert + Write-LogMessage -API 'Alerts' -message "Sent PSA alert $title" -sev info + } catch { Write-Host "Could not send alerts to ticketing system: $($_.Exception.message)" From 028243b29f385553f6131fcf4f07d426b8e893f4 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:18:42 +0200 Subject: [PATCH 051/119] added all tenants support --- AddAlert/run.ps1 | 19 +++++++++++++++++-- .../Public/Remove-CIPPGraphSubscription.ps1 | 9 +++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index 7325bb1d17e4..21e5e1e5ec5f 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -45,8 +45,23 @@ $Results = foreach ($Tenant in $tenants) { Add-AzDataTableEntity @Table -Entity $CompleteObject -Force $URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 - Write-Host $URL - foreach ($eventype in $Request.body.EventTypes.value) { + if ($Tenant -eq 'AllTenants') { + Get-Tenants | ForEach-Object { + foreach ($eventype in $Request.body.EventTypes.value) { + $params = @{ + TenantFilter = $_.defaultDomainName + auditLogAPI = $true + operations = ($Request.body.Operations.value -join ',') + allowedLocations = ($Request.body.AllowedLocations.value -join ',') + BaseURL = $URL + EventType = $eventype + ExecutingUser = $Request.headers.'x-ms-client-principal' + } + New-CIPPGraphSubscription @params + } + } + } + else { $params = @{ TenantFilter = $tenant auditLogAPI = $true diff --git a/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 index 37f501f69a35..31a877b092bc 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGraphSubscription.ps1 @@ -10,8 +10,13 @@ function Remove-CIPPGraphSubscription { $WebhookTable = Get-CIPPTable -TableName webhookTable $WebhookRow = Get-AzDataTableEntity @WebhookTable | Where-Object { $_.RowKey -eq $CIPPID } if ($WebhookRow.Resource -eq "M365AuditLogs") { - $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -scope "https://manage.office.com/.default" -tenantid $TenantFilter -type POST -body "{}" -verbose - + try { + $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($WebhookRow.EventType)" -scope "https://manage.office.com/.default" -tenantid $TenantFilter -type POST -body "{}" -verbose + } + catch { + #allowed to fail if the subscription is already removed + } + $null = Remove-AzDataTableEntity @WebhookTable -Entity $WebhookRow } else { $OldID = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/subscriptions" -tenantid $TenantFilter) | Where-Object { $_.notificationUrl -eq $WebhookRow.WebhookNotificationUrl } From e3f781d3992611199d805ad2e344cdf17d9dcecd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:46:02 +0200 Subject: [PATCH 052/119] changed how we handle operations --- .../CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 10 ++++++++-- PublicWebhooks/run.ps1 | 7 +------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 93f824cc70d3..b084164b9cfa 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -4,6 +4,7 @@ function Invoke-CippWebhookProcessing { $TenantFilter, $Data, $Resource, + $Operations, $AllowedLocations, $CIPPPURL, $APIName = "Process webhook", @@ -28,8 +29,13 @@ function Invoke-CippWebhookProcessing { #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } if ($data.operation -eq "UserLoggedIn" -and $Country -notin $AllowedLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } - if ($data.operation -eq "UserLoggedIn" -and $Country -notin $PreviousLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } - Write-Host "Selecting the Operation: $($data.operation)" + + #Check if the operation is allowed for this webhook. + if ($data.operation -notin $Operations) { + Write-Host "No need to process this operation." + return "" + } + switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 1692b5cf0dae..6116ec422673 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -12,7 +12,6 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Found matching CIPPID" $Webhookinfo = $Webhooks | Where-Object -Property RowKey -EQ $Request.query.CIPPID - Write-Host "Webhookinfo: $($Webhookinfo | ConvertTo-Json -Depth 10)" if ($Request.query.ValidationToken -or $Request.body.validationCode) { Write-Host "Validation token received" $body = $request.query.ValidationToken @@ -26,12 +25,8 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" foreach ($Item in $Data) { - Write-Host "Item: $($item | ConvertTo-Json -Depth 10)" Write-Host "Processing $($item.operation)" - if ($item.Operation -in $operations) { - Write-Host "Working on $($item.operation)." - Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Item -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations - } + Invoke-CippWebhookProcessing -TenantFilter $TenantFilter -Data $Item -CIPPPURL $url -allowedlocations $Webhookinfo.AllowedLocations -Operations $operations $body = "OK" } } From adafc624e392b59a3cffdd161b772f7a7d459e6b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:55:59 +0200 Subject: [PATCH 053/119] add remote geoipdb --- ExecGeoIPLookup/function.json | 19 ++++++++++++++++++ ExecGeoIPLookup/run.ps1 | 15 ++++++++++++++ ListKnownIPDb/function.json | 19 ++++++++++++++++++ ListKnownIPDb/run.ps1 | 20 +++++++++++++++++++ .../CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 | 19 ++++++++++++++++++ .../Public/Invoke-CIPPWebhookProcessing.ps1 | 13 +++--------- 6 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 ExecGeoIPLookup/function.json create mode 100644 ExecGeoIPLookup/run.ps1 create mode 100644 ListKnownIPDb/function.json create mode 100644 ListKnownIPDb/run.ps1 create mode 100644 Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 diff --git a/ExecGeoIPLookup/function.json b/ExecGeoIPLookup/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ExecGeoIPLookup/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ExecGeoIPLookup/run.ps1 b/ExecGeoIPLookup/run.ps1 new file mode 100644 index 000000000000..fb188418ac3d --- /dev/null +++ b/ExecGeoIPLookup/run.ps1 @@ -0,0 +1,15 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +param($Request, $TriggerMetadata) + +$APIName = $TriggerMetadata.FunctionName +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + +$location = Get-CIPPGeoIPLocation -IP $Request.Query.IP + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($location) + }) diff --git a/ListKnownIPDb/function.json b/ListKnownIPDb/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ListKnownIPDb/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ListKnownIPDb/run.ps1 b/ListKnownIPDb/run.ps1 new file mode 100644 index 000000000000..8eac7add747e --- /dev/null +++ b/ListKnownIPDb/run.ps1 @@ -0,0 +1,20 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +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.' +$Table = Get-CIPPTable -TableName 'knownlocationdb' +$Filter = "Tenant eq '$($Request.Query.TenantFilter)'" +$KnownIPDb = Get-AzDataTableEntity @Table -Filter $Filter + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($KnownIPDb) + }) diff --git a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 new file mode 100644 index 000000000000..d06254428ef8 --- /dev/null +++ b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 @@ -0,0 +1,19 @@ + + +function Get-CIPPGeoIPLocation { + [CmdletBinding()] + param ( + $IP + ) + if ($IP -like '*:*') { $IP = $IP.split(':')[0] } + $CTX = new-azdatatablecontext -TableName geoipdb -ConnectionString 'TableEndpoint=https://cyberdraingeoipdb.table.core.windows.net/;SharedAccessSignature=sv=2022-11-02&ss=t&srt=o&sp=rl&se=2025-08-08T21:05:23Z&st=2023-08-08T13:05:23Z&spr=https&sig=89Bmk2Un89xqNzZPLkryFnLRCjHs9rCWGUJjhvf5mso%3D' + $GeoTable = @{ Context = $CTX } + $IP.Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { + [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null + $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte + } + $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -Last 1 + + return $location + +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index b084164b9cfa..25430dc9bb89 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -11,20 +11,13 @@ function Invoke-CippWebhookProcessing { $ExecutingUser ) Set-Location (Get-Item $PSScriptRoot).FullName - + #Create a RO connection or our central geoipdb $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String - $LocationTable = Get-CIPPTable -TableName knownlocationdb $AllowedLocations = $AllowedLocations -split ',' - $GeoTable = Get-CIPPTable -TableName geoipdb if ($data.clientip) { - ($Data.clientIp).split(':')[0].Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { - [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null - $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte - } - $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -First 1 + Get-CIPPGeoIPLocation -IP $Request.Query.IP $Country = if ($Location.CountryOrRegion) { $Location.CountryOrRegion } else { "Unknown" } $City = if ($Location.City) { $Location.City } else { "Unknown" } - } #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } @@ -140,7 +133,6 @@ function Invoke-CippWebhookProcessing { $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" - } } @@ -151,6 +143,7 @@ function Invoke-CippWebhookProcessing { $LocationInfo = @{ RowKey = [string]$data.ClientIP.Split(':')[0] PartitionKey = [string]$data.UserId + Tenant = [string]$TenantFilter CountryOrRegion = "$Country" City = "$City" } From dc3325b23fb41560afe5214505ec5e7b860a37f6 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 8 Aug 2023 18:04:07 -0400 Subject: [PATCH 054/119] Add ExecDeleteGDAPRoleMapping --- ExecDeleteGDAPRoleMapping/function.json | 19 ++++++++++++++++++ ExecDeleteGDAPRoleMapping/run.ps1 | 26 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 ExecDeleteGDAPRoleMapping/function.json create mode 100644 ExecDeleteGDAPRoleMapping/run.ps1 diff --git a/ExecDeleteGDAPRoleMapping/function.json b/ExecDeleteGDAPRoleMapping/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ExecDeleteGDAPRoleMapping/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ExecDeleteGDAPRoleMapping/run.ps1 b/ExecDeleteGDAPRoleMapping/run.ps1 new file mode 100644 index 000000000000..949087e6257a --- /dev/null +++ b/ExecDeleteGDAPRoleMapping/run.ps1 @@ -0,0 +1,26 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +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' + +Write-Host $Table +try { + $Filter = "PartitionKey eq 'Roles' and RowKey eq '{0}'" -f $Request.Query.GroupId + $Entity = Get-AzDataTableEntity @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)" } +} + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) From 5b296b958ca0f7289e1894bd5929d5c0e824c2ee Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 00:21:48 +0200 Subject: [PATCH 055/119] added severity handling to alerts --- ExecNotificationConfig/run.ps1 | 6 ++---- ListNotificationConfig/run.ps1 | 7 ++++--- Scheduler_CIPPNotifications/run.ps1 | 17 +++++++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ExecNotificationConfig/run.ps1 b/ExecNotificationConfig/run.ps1 index f86a8fe32023..959818c8b535 100644 --- a/ExecNotificationConfig/run.ps1 +++ b/ExecNotificationConfig/run.ps1 @@ -9,6 +9,7 @@ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -m # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' +$sev = ([pscustomobject]$Request.body.Severity).value -join (',') $results = try { $Table = Get-CIPPTable -TableName SchedulerConfig $SchedulerConfig = @{ @@ -16,6 +17,7 @@ $results = try { 'tenantid' = 'TenantId' 'type' = 'CIPPNotifications' 'schedule' = 'Every 15 minutes' + 'Severity' = [string]$sev 'email' = "$($Request.Body.Email)" 'webhook' = "$($Request.Body.Webhook)" 'onePerTenant' = [boolean]$Request.Body.onePerTenant @@ -26,10 +28,6 @@ $results = try { foreach ($logvalue in [pscustomobject]$Request.body.logsToInclude) { $SchedulerConfig[([pscustomobject]$logvalue.value)] = $true } - foreach ($severityvalue in [pscustomobject]$Request.body.Severity) { - $SchedulerConfig[([pscustomobject]$severityvalue.value)] = $true - } - Add-AzDataTableEntity @Table -Entity $SchedulerConfig -Force | Out-Null 'Successfully set the configuration' diff --git a/ListNotificationConfig/run.ps1 b/ListNotificationConfig/run.ps1 index 7102dd077664..9b89d666c283 100644 --- a/ListNotificationConfig/run.ps1 +++ b/ListNotificationConfig/run.ps1 @@ -10,14 +10,15 @@ $Table = Get-CIPPTable -TableName SchedulerConfig $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" $Config = Get-AzDataTableEntity @Table -Filter $Filter | ConvertTo-Json -Depth 10 | ConvertFrom-Json -Depth 10 $config | Add-Member -NotePropertyValue @() -NotePropertyName 'logsToInclude' -Force -$config | Add-Member -NotePropertyValue @() -NotePropertyName 'Severity' -Force $config.logsToInclude = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, Severity, Alert, Info, Error, timestamp, webhook).psobject.properties.name) if (!$config.logsToInclude) { $config.logsToInclude = @('None') } -$config.Severity = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, Severity, Updates, Standards, TokensUpdater, ExecExcludeLicenses, ExecExcludeTenant, ExecDnsConfig, EditUser, ChocoApp, AddAPDevice, EditTenant, AddMSPApp, AddUser, timestamp, AddGroup, ExecOffboardUser, webhook).psobject.properties.name) if (!$config.Severity) { - $config.Severity = @('None') + $config.Severity = @('Alert') +} +else { + $config.Severity = $config.Severity -split ',' } $body = $Config diff --git a/Scheduler_CIPPNotifications/run.ps1 b/Scheduler_CIPPNotifications/run.ps1 index f524a6ae2f14..f1b409137812 100644 --- a/Scheduler_CIPPNotifications/run.ps1 +++ b/Scheduler_CIPPNotifications/run.ps1 @@ -7,17 +7,22 @@ $Config = [pscustomobject](Get-AzDataTableEntity @Table -Filter $Filter) $Settings = [System.Collections.ArrayList]@('Alerts') $Config.psobject.properties.name | ForEach-Object { $settings.add($_) } - +$severity = $Config.Severity -split ',' +if (!$severity) { + $severity = [System.Collections.ArrayList]@('Info', 'Error', 'Warning', 'Critical', 'Alert') +} $Table = Get-CIPPTable -$PartitionKey = Get-Date -UFormat '%Y%m%d' -$Filter = "PartitionKey eq '{0}'" -f $PartitionKey -$Currentlog = Get-AzDataTableEntity @Table -Filter $Filter | Where-Object { $_.API -In $Settings -and $_.SentAsAlert -ne $true } +$PartitionKey = Get-Date -UFormat '% Y%m%d' +$Filter = "PartitionKey eq '{ 0 }'" -f $PartitionKey +$Currentlog = Get-AzDataTableEntity @Table -Filter $Filter | Where-Object { + $_.API -In $Settings -and $_.SentAsAlert -ne $true -and $_.Severity -In $severity +} #email try try { if ($config.onePerTenant) { if ($Config.email -like '*@*' -and $null -ne $CurrentLog) { - $JSONRecipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { '{"EmailAddress": {"Address": "' + $_ + '"}},' } } + $JSONRecipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } } $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1) foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) { $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) -replace '
', '
' | Out-String @@ -47,7 +52,7 @@ try { } else { if ($Config.email -like '*@*' -and $null -ne $CurrentLog) { - $JSONRecipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { '{"EmailAddress": {"Address": "' + $_ + '"}},' } } + $JSONRecipients = $Config.email.split(",").trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } } $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1) $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | ConvertTo-Html -frag) -replace '
', '
' | Out-String $JSONBody = @" From 97ffd1c40c8b2ec40264437c4a02e5a0556fc3cb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:41:40 +0200 Subject: [PATCH 056/119] bugfix --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 25430dc9bb89..06817a9b0c31 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -15,9 +15,9 @@ function Invoke-CippWebhookProcessing { $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String $AllowedLocations = $AllowedLocations -split ',' if ($data.clientip) { - Get-CIPPGeoIPLocation -IP $Request.Query.IP - $Country = if ($Location.CountryOrRegion) { $Location.CountryOrRegion } else { "Unknown" } - $City = if ($Location.City) { $Location.City } else { "Unknown" } + $Location = Get-CIPPGeoIPLocation -IP $data.clientip + $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } + $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } } #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } From 405d460bec3830810259b9a7bb61a774f1fd4e7e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:44:10 +0200 Subject: [PATCH 057/119] typo in db --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 06817a9b0c31..38abcf1144a1 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -17,7 +17,7 @@ function Invoke-CippWebhookProcessing { if ($data.clientip) { $Location = Get-CIPPGeoIPLocation -IP $data.clientip $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } - $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } + $City = if ($Location.cityyName) { $Location.cityyName } else { "Unknown" } } #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } From 41715e2329169f8995fa8cf3d0050ce4cb90a46f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:05:53 +0200 Subject: [PATCH 058/119] returned foreach --- AddAlert/run.ps1 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index 21e5e1e5ec5f..1618be054143 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -47,14 +47,14 @@ $Results = foreach ($Tenant in $tenants) { $URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 if ($Tenant -eq 'AllTenants') { Get-Tenants | ForEach-Object { - foreach ($eventype in $Request.body.EventTypes.value) { + foreach ($eventType in $Request.body.EventTypes.value) { $params = @{ TenantFilter = $_.defaultDomainName auditLogAPI = $true operations = ($Request.body.Operations.value -join ',') allowedLocations = ($Request.body.AllowedLocations.value -join ',') BaseURL = $URL - EventType = $eventype + EventType = $eventType ExecutingUser = $Request.headers.'x-ms-client-principal' } New-CIPPGraphSubscription @params @@ -62,16 +62,18 @@ $Results = foreach ($Tenant in $tenants) { } } else { - $params = @{ - TenantFilter = $tenant - auditLogAPI = $true - operations = ($Request.body.Operations.value -join ',') - allowedLocations = ($Request.body.AllowedLocations.value -join ',') - BaseURL = $URL - EventType = $eventype - ExecutingUser = $Request.headers.'x-ms-client-principal' + foreach ($eventType in $Request.body.EventTypes.value) { + $params = @{ + TenantFilter = $tenant + auditLogAPI = $true + operations = ($Request.body.Operations.value -join ',') + allowedLocations = ($Request.body.AllowedLocations.value -join ',') + BaseURL = $URL + EventType = $eventType + ExecutingUser = $Request.headers.'x-ms-client-principal' + } + New-CIPPGraphSubscription @params } - New-CIPPGraphSubscription @params } "Successfully added Alert for $($Tenant) to queue." Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message "Successfully added Alert for $($Tenant) to queue." -Sev 'Info' From d51087507cb0835e110ab2384577f92722c3bd60 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:32:44 +0200 Subject: [PATCH 059/119] only process if a title has been set. --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 38abcf1144a1..7353ea7ae62d 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -157,11 +157,12 @@ function Invoke-CippWebhookProcessing { PotentialCountry = $Country PotentialCity = $City } | ConvertTo-Json -Depth 15 -Compress - - Write-Host "Sending alert to email" - Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML - Write-Host "Sending alert to webhook" - Send-CIPPAlert -Type 'webhook' -Title $title -JSONContent $JsonContent - Write-Host "Sending alert to PSA" - Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML + if ($Title) { + Write-Host "Sending alert to email" + Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML + Write-Host "Sending alert to webhook" + Send-CIPPAlert -Type 'webhook' -Title $title -JSONContent $JsonContent + Write-Host "Sending alert to PSA" + Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML + } } From 1500df8479d0be6de6fc076ee15c1b655da1bbe8 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:49:08 +0200 Subject: [PATCH 060/119] correction --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 7353ea7ae62d..fea095480fbd 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -17,7 +17,7 @@ function Invoke-CippWebhookProcessing { if ($data.clientip) { $Location = Get-CIPPGeoIPLocation -IP $data.clientip $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } - $City = if ($Location.cityyName) { $Location.cityyName } else { "Unknown" } + $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } } #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } @@ -139,9 +139,10 @@ function Invoke-CippWebhookProcessing { $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText Write-Host "Add IP and potential location to knownlocation db for this specific user" + $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 if ($data.ClientIP) { $LocationInfo = @{ - RowKey = [string]$data.ClientIP.Split(':')[0] + RowKey = [string]$ip PartitionKey = [string]$data.UserId Tenant = [string]$TenantFilter CountryOrRegion = "$Country" From 06580bb1e3ada0dfe219c36d70c273b94c810746 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:49:30 +0200 Subject: [PATCH 061/119] inside of if --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index fea095480fbd..6d602f11aae2 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -139,8 +139,9 @@ function Invoke-CippWebhookProcessing { $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText Write-Host "Add IP and potential location to knownlocation db for this specific user" - $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 + if ($data.ClientIP) { + $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 $LocationInfo = @{ RowKey = [string]$ip PartitionKey = [string]$data.UserId From ec7a6415a45d66f77dacd9222f861f1632e22846 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:50:56 +0200 Subject: [PATCH 062/119] correction to location of if statement --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 6d602f11aae2..22db6ebeb075 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -141,6 +141,7 @@ function Invoke-CippWebhookProcessing { Write-Host "Add IP and potential location to knownlocation db for this specific user" if ($data.ClientIP) { + $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 $LocationInfo = @{ RowKey = [string]$ip From ccf426aef010cbe849e07a556ae1b4522548dd39 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:51:41 +0200 Subject: [PATCH 063/119] moved db to top --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 22db6ebeb075..04e451fa77aa 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -19,6 +19,9 @@ function Invoke-CippWebhookProcessing { $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } } + #Database for knownlocations + $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' + #Custom cipp operations. if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } if ($data.operation -eq "UserLoggedIn" -and $Country -notin $AllowedLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } @@ -141,7 +144,6 @@ function Invoke-CippWebhookProcessing { Write-Host "Add IP and potential location to knownlocation db for this specific user" if ($data.ClientIP) { - $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 $LocationInfo = @{ RowKey = [string]$ip From 7fa37d6c0b333ceabe3dd6ae894fbad0b779f9d8 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:53:01 +0200 Subject: [PATCH 064/119] improved geoip lookup --- ExecGeoIPLookup/run.ps1 | 15 ++++++++++++--- Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 | 13 +++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ExecGeoIPLookup/run.ps1 b/ExecGeoIPLookup/run.ps1 index fb188418ac3d..27ec9a354887 100644 --- a/ExecGeoIPLookup/run.ps1 +++ b/ExecGeoIPLookup/run.ps1 @@ -5,11 +5,20 @@ param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - -$location = Get-CIPPGeoIPLocation -IP $Request.Query.IP +Write-Host $Request.Query.IP +$location = Get-CIPPGeoIPLocation -IP $Request.query.IP +$ARINInfo = Invoke-RestMethod -Uri "https://whois.arin.net/rest/ip/$($Request.Query.IP)" -Method Get -ContentType "application/json" -Headers @{Accept = "application/json" } +$LocationInfo = [pscustomobject]@{ + location = $location + arin = $ARINInfo + startaddress = $arininfo.net.startaddress.'$' + endAddress = $arininfo.net.endAddress.'$' + OrgRef = $arininfo.net.orgRef.'@NAME' + SubnetName = $arininfo.net.name.'$' +} # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK - Body = @($location) + Body = $LocationInfo }) diff --git a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 index d06254428ef8..88a94127a8ef 100644 --- a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 @@ -1,5 +1,3 @@ - - function Get-CIPPGeoIPLocation { [CmdletBinding()] param ( @@ -8,12 +6,15 @@ function Get-CIPPGeoIPLocation { if ($IP -like '*:*') { $IP = $IP.split(':')[0] } $CTX = new-azdatatablecontext -TableName geoipdb -ConnectionString 'TableEndpoint=https://cyberdraingeoipdb.table.core.windows.net/;SharedAccessSignature=sv=2022-11-02&ss=t&srt=o&sp=rl&se=2025-08-08T21:05:23Z&st=2023-08-08T13:05:23Z&spr=https&sig=89Bmk2Un89xqNzZPLkryFnLRCjHs9rCWGUJjhvf5mso%3D' $GeoTable = @{ Context = $CTX } - $IP.Split(".") | ForEach-Object { $IPAsint = 0; $IPAddressByte = 0 } { + + $IPAsint = 0 + $IP.Split(".") | ForEach-Object { + $IPAddressByte = 0 [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null - $IPAsint = $IPAsint -shl 8 -bor $IPAddressByte + $IPAsint = ([long]($IPAsint -shl 8)) -bor [byte]$_ } + $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -Last 1 return $location - -} \ No newline at end of file +} From 9829a33badc1f3b1e0ebd5bc2f4d817311c233d1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:52:30 +0200 Subject: [PATCH 065/119] changes to geoip location for ipv6 --- .../CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 index 88a94127a8ef..a291f2399c1d 100644 --- a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 @@ -1,20 +1,34 @@ function Get-CIPPGeoIPLocation { [CmdletBinding()] param ( - $IP + [string]$IP ) - if ($IP -like '*:*') { $IP = $IP.split(':')[0] } - $CTX = new-azdatatablecontext -TableName geoipdb -ConnectionString 'TableEndpoint=https://cyberdraingeoipdb.table.core.windows.net/;SharedAccessSignature=sv=2022-11-02&ss=t&srt=o&sp=rl&se=2025-08-08T21:05:23Z&st=2023-08-08T13:05:23Z&spr=https&sig=89Bmk2Un89xqNzZPLkryFnLRCjHs9rCWGUJjhvf5mso%3D' - $GeoTable = @{ Context = $CTX } - $IPAsint = 0 - $IP.Split(".") | ForEach-Object { - $IPAddressByte = 0 - [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null - $IPAsint = ([long]($IPAsint -shl 8)) -bor [byte]$_ + if ($IP -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { + $IP = $IP -replace ':\d+$', '' # Remove the port number if present } - $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq 'GeoIP' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -Last 1 + $partitionKey = "GeoIP" + $IPAsint = [System.Numerics.BigInteger]::Zero + $ipAddress = [System.Net.IPAddress]::Parse($IP) + if ($ipAddress.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6) { + $partitionKey = "GeoIPv6" + $bytes = $ipAddress.GetAddressBytes() + for ($i = 0; $i -lt $bytes.Length; $i++) { + $IPAsint = $IPAsint -shl 8 -bor $bytes[$i] + } + } + else { + $IP.Split(".") | ForEach-Object { + $IPAddressByte = 0 + [int]::TryParse($_, [ref] $IPAddressByte) | Out-Null + $IPAsint = ([long]($IPAsint -shl 8)) -bor [byte]$_ + } + } + + $CTX = New-AzDataTableContext -TableName geoipdb -ConnectionString 'TableEndpoint=https://cyberdraingeoipdb.table.core.windows.net/;SharedAccessSignature=sv=2022-11-02&ss=t&srt=o&sp=rl&se=2025-08-08T21:05:23Z&st=2023-08-08T13:05:23Z&spr=https&sig=89Bmk2Un89xqNzZPLkryFnLRCjHs9rCWGUJjhvf5mso%3D' + $GeoTable = @{ Context = $CTX } + $location = (Get-AzDataTableEntity @GeoTable -Filter "PartitionKey eq '$partitionKey' and RowKey le '$IPAsint' and ipTo ge '$IPAsint'") | Select-Object -Last 1 return $location } From 59d017482ced4c10744248265067660dfa94c0d1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:14:02 +0200 Subject: [PATCH 066/119] Improvements to login processing --- .../CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 04e451fa77aa..b703ff192b6a 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -23,9 +23,10 @@ function Invoke-CippWebhookProcessing { $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' #Custom cipp operations. - if ($data.operation -eq "UserloggedIn" -and $data.UserType -eq 2) { $data.operation = "AdminLoggedIn" } - if ($data.operation -eq "UserLoggedIn" -and $Country -notin $AllowedLocations) { $data.operation = "UserLoggedInFromUnknownLocation" } - + switch ($data.operation) { + { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -and $Country -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } + } #Check if the operation is allowed for this webhook. if ($data.operation -notin $Operations) { Write-Host "No need to process this operation." @@ -110,7 +111,7 @@ function Invoke-CippWebhookProcessing { $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" } - "AdminLoggedIn" { + { "AdminLoggedIn" -and $data.ResultStatus -eq "Success" } { $TableObj = [PSCustomObject]::new() $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } @@ -124,7 +125,7 @@ function Invoke-CippWebhookProcessing { $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } - "UserLoggedInFromUnknownLocation" { + { "UserLoggedInFromUnknownLocation" -and $data.ResultStatus -eq "Success" } { $TableObj = [PSCustomObject]::new() $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } From 0d577b1c3660588cb32f3e3e5588f92d7226030e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:23:35 +0200 Subject: [PATCH 067/119] convert url to frontend --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index b703ff192b6a..a5cc2561ff3c 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -32,7 +32,8 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } - + #Make URL frontend URL: + $CIPPPURL = $CIPPURL -split '/API' | select-object -first 1 switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" From 332478c7191ceb7d12867e6cd367bf7e37c8e27e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:46:31 +0200 Subject: [PATCH 068/119] added default break --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index a5cc2561ff3c..9a8425426a9f 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -25,7 +25,8 @@ function Invoke-CippWebhookProcessing { #Custom cipp operations. switch ($data.operation) { { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } - { "UserLoggedIn" -and $Country -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } + { "UserLoggedIn" -and @($Country) -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } + default { break } } #Check if the operation is allowed for this webhook. if ($data.operation -notin $Operations) { @@ -33,7 +34,7 @@ function Invoke-CippWebhookProcessing { return "" } #Make URL frontend URL: - $CIPPPURL = $CIPPURL -split '/API' | select-object -first 1 + $CIPPPURL = $CIPPURL -split '/API' | Select-Object -First 1 switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" From 0ef5851d824c881b483a087efbb1cc06fc5fb318 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:46:57 +0200 Subject: [PATCH 069/119] does not ahve to be arr --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 9a8425426a9f..309da9cd4eba 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -25,7 +25,7 @@ function Invoke-CippWebhookProcessing { #Custom cipp operations. switch ($data.operation) { { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } - { "UserLoggedIn" -and @($Country) -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } + { "UserLoggedIn" -and $Country -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } default { break } } #Check if the operation is allowed for this webhook. From e0f7b95ab4556cbbb5e0df6eb1adeecc6e4dc8e0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:00:54 +0200 Subject: [PATCH 070/119] added debug --- .../CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 309da9cd4eba..787b5cce4d65 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -21,13 +21,21 @@ function Invoke-CippWebhookProcessing { } #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - + Write-Host "Processing $($data.operation)" + Write-Host "Country: $Country" + Write-Host "City: $City" + Write-Host "AllowedLocations: $AllowedLocations" + Write-Host "Operations: $Operations" + Write-Host "Allowed: $($Country -in $AllowedLocations)" #Custom cipp operations. + Write-Host "Processing $($data.operation)" switch ($data.operation) { - { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } { "UserLoggedIn" -and $Country -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } + { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } default { break } } + + Write-Host "Processing $($data.operation)" #Check if the operation is allowed for this webhook. if ($data.operation -notin $Operations) { Write-Host "No need to process this operation." From 6f901e328025f6e134c6db72431832c0b2f735a0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:12:02 +0200 Subject: [PATCH 071/119] added userkey --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 787b5cce4d65..d70bfe5619e2 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -129,7 +129,7 @@ function Invoke-CippWebhookProcessing { $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - an admin account has logged on" - $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" + $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" @@ -143,7 +143,7 @@ function Invoke-CippWebhookProcessing { $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" - $IntroText = "$($data.UserId) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" + $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" From ca15d5d94d94a1e9158e6f13b241f83fb7e7866d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:22:54 +0200 Subject: [PATCH 072/119] added a default break --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index d70bfe5619e2..d3cc0febbef6 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -148,6 +148,9 @@ function Invoke-CippWebhookProcessing { $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } + default { + break + } } $HTML = "$HTML" -f $Title, $IntroText, $ButtonUrl, $ButtonText, $AfterButtonText From ecb132951bd1cda2ca9cdf9b7326ac0829578cc0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:41:19 +0200 Subject: [PATCH 073/119] improvements --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index d3cc0febbef6..2632695acc56 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -30,8 +30,8 @@ function Invoke-CippWebhookProcessing { #Custom cipp operations. Write-Host "Processing $($data.operation)" switch ($data.operation) { - { "UserLoggedIn" -and $Country -notin $AllowedLocations } { $data.operation = "UserLoggedInFromUnknownLocation" ; break } - { "UserloggedIn" -and $data.UserType -eq 2 } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } @@ -121,7 +121,7 @@ function Invoke-CippWebhookProcessing { $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" } - { "AdminLoggedIn" -and $data.ResultStatus -eq "Success" } { + "AdminLoggedIn" { $TableObj = [PSCustomObject]::new() $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } @@ -135,7 +135,7 @@ function Invoke-CippWebhookProcessing { $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } - { "UserLoggedInFromUnknownLocation" -and $data.ResultStatus -eq "Success" } { + "UserLoggedInFromUnknownLocation" { $TableObj = [PSCustomObject]::new() $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } From 2c3e689c37fb1ad9fa97e7cd341cbe73d1c7641a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:57:51 +0200 Subject: [PATCH 074/119] remove redirects --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 2632695acc56..0ac1b4beba11 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -30,8 +30,8 @@ function Invoke-CippWebhookProcessing { #Custom cipp operations. Write-Host "Processing $($data.operation)" switch ($data.operation) { - { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } - { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } From 60b6df8dd32bddb61b2326b09d57c93b0f3246ac Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:59:05 +0200 Subject: [PATCH 075/119] result status --- .../CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 0ac1b4beba11..e73308e7bae9 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -21,21 +21,14 @@ function Invoke-CippWebhookProcessing { } #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - Write-Host "Processing $($data.operation)" - Write-Host "Country: $Country" - Write-Host "City: $City" - Write-Host "AllowedLocations: $AllowedLocations" - Write-Host "Operations: $Operations" - Write-Host "Allowed: $($Country -in $AllowedLocations)" - #Custom cipp operations. - Write-Host "Processing $($data.operation)" + + Write-Host "Result status $($data.ResultStatus))" switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } - Write-Host "Processing $($data.operation)" #Check if the operation is allowed for this webhook. if ($data.operation -notin $Operations) { Write-Host "No need to process this operation." From 77db727f164bf1daf25e4bb400adb87110debea5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:11:04 +0200 Subject: [PATCH 076/119] d --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index e73308e7bae9..8a065114e873 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -22,7 +22,8 @@ function Invoke-CippWebhookProcessing { #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - Write-Host "Result status $($data.ResultStatus))" + Write-Host "Result status $($data.ResultStatus)" + Write-Host "Result status detail $($data.ExtendedProperties.resultstatusdetail)" switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } From bd5ac6e249f097c27e33e565929b8fdaa47be472 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:21:59 +0200 Subject: [PATCH 077/119] add country logging --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 8a065114e873..9a145e5eb08f 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -24,6 +24,7 @@ function Invoke-CippWebhookProcessing { Write-Host "Result status $($data.ResultStatus)" Write-Host "Result status detail $($data.ExtendedProperties.resultstatusdetail)" + Write-Host "country: $Country" switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } From 3af8a33402c361521055a7a3935fbfe798843585 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:52:26 +0200 Subject: [PATCH 078/119] typo? --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 9a145e5eb08f..1983849b0c18 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -23,11 +23,11 @@ function Invoke-CippWebhookProcessing { $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' Write-Host "Result status $($data.ResultStatus)" - Write-Host "Result status detail $($data.ExtendedProperties.resultstatusdetail)" + Write-Host "Result status detail $($data.ExtendedProperties.ResultStatusDetai)" Write-Host "country: $Country" switch ($data.operation) { - { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } - { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.resultstatusdetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } From e5126cf6ca09986228062c659da421a251d85a37 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:57:54 +0200 Subject: [PATCH 079/119] still a typo --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 1983849b0c18..5211c1aa4c2a 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -23,7 +23,7 @@ function Invoke-CippWebhookProcessing { $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' Write-Host "Result status $($data.ResultStatus)" - Write-Host "Result status detail $($data.ExtendedProperties.ResultStatusDetai)" + Write-Host "Result status detail $($data.ExtendedProperties.ResultStatusDetail)" Write-Host "country: $Country" switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } From 78253fbe8684664aac906601e159535c847c982c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:20:40 +0200 Subject: [PATCH 080/119] print all extended properties as test --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 5211c1aa4c2a..29d8810e5102 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -23,8 +23,10 @@ function Invoke-CippWebhookProcessing { $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' Write-Host "Result status $($data.ResultStatus)" - Write-Host "Result status detail $($data.ExtendedProperties.ResultStatusDetail)" + Write-Host "Result status detail $($data.ExtendedProperties['ResultStatusDetail'])" + Write-Host "Extended properties as json: $($data.ExtendedProperties | ConvertTo-Json -Depth 10)" Write-Host "country: $Country" + switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } @@ -36,8 +38,7 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } - #Make URL frontend URL: - $CIPPPURL = $CIPPURL -split '/API' | Select-Object -First 1 + switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" From 7a2b48d82b718a28c8bb5c645432e227e0495976 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 14:53:50 +0200 Subject: [PATCH 081/119] performance improvements --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 29d8810e5102..c37e5c62e670 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -22,14 +22,13 @@ function Invoke-CippWebhookProcessing { #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - Write-Host "Result status $($data.ResultStatus)" - Write-Host "Result status detail $($data.ExtendedProperties['ResultStatusDetail'])" - Write-Host "Extended properties as json: $($data.ExtendedProperties | ConvertTo-Json -Depth 10)" - Write-Host "country: $Country" - + $TableObj = [PSCustomObject]::new() + $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } switch ($data.operation) { - { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } - { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $data.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } @@ -38,12 +37,11 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } - + $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId + switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" - $TableObj = [PSCustomObject]::new() - $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $ParameterName $IntroText = "

A new rule has been created for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" @@ -53,8 +51,6 @@ function Invoke-CippWebhookProcessing { } "Set-inboxrule" { $Title = "$($TenantFilter) - Rule Edit Detected for $($data.UserId)" - $TableObj = [PSCustomObject]::new() - $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $ParameterName $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" @@ -118,11 +114,7 @@ function Invoke-CippWebhookProcessing { } "AdminLoggedIn" { - $TableObj = [PSCustomObject]::new() - $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } - $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') - $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - an admin account has logged on" $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" @@ -132,11 +124,7 @@ function Invoke-CippWebhookProcessing { } "UserLoggedInFromUnknownLocation" { - $TableObj = [PSCustomObject]::new() - $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } - $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') - $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" From 01b641cf9dce58af4b82f9d02e47f91fb5604c9f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:10:59 +0200 Subject: [PATCH 082/119] clean error logs --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index c37e5c62e670..cf10dde666d6 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -23,8 +23,8 @@ function Invoke-CippWebhookProcessing { $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' $TableObj = [PSCustomObject]::new() - $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } - $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + if ( $Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } + if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } From eca8e2a5ad3c7926b0e1ac6c1845068a5da04f64 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:12:02 +0200 Subject: [PATCH 083/119] missed one --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index cf10dde666d6..ab0beca0051f 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -25,7 +25,7 @@ function Invoke-CippWebhookProcessing { $TableObj = [PSCustomObject]::new() if ( $Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } - $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } + if ($Data.parameters) { $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } From 8b39c396757b792b037e352549cabfad2a9f4abf Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:12:54 +0200 Subject: [PATCH 084/119] typos --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index ab0beca0051f..356dd05dc0e9 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -27,8 +27,8 @@ function Invoke-CippWebhookProcessing { if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.parameters) { $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } switch ($data.operation) { - { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } - { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ExtendedProperties.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } default { break } } From 2d0fe7ccc0ab2e58939f3da59356dfdcc9a78925 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:44:44 +0200 Subject: [PATCH 085/119] geo ip location --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 356dd05dc0e9..a1c471598d52 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -11,7 +11,7 @@ function Invoke-CippWebhookProcessing { $ExecutingUser ) Set-Location (Get-Item $PSScriptRoot).FullName - #Create a RO connection or our central geoipdb + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String $AllowedLocations = $AllowedLocations -split ',' if ($data.clientip) { @@ -26,6 +26,7 @@ function Invoke-CippWebhookProcessing { if ( $Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.parameters) { $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } + Write-Host ($TableObj | ConvertTo-Json -Depth 10) switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } From cd00d68299887d529fa174f2f78ebf4b8a3bc9b3 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:45:09 +0200 Subject: [PATCH 086/119] country --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index a1c471598d52..7bf25a33dcdf 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -21,7 +21,7 @@ function Invoke-CippWebhookProcessing { } #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - + Write-Host $Country $TableObj = [PSCustomObject]::new() if ( $Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } From 5e65c5207cf1357b570089a0a76d6fa49bb9751a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:48:50 +0200 Subject: [PATCH 087/119] passwords --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 7bf25a33dcdf..6bbea9462931 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -107,8 +107,8 @@ function Invoke-CippWebhookProcessing { } "Reset user password." { - $Title = "$($TenantFilter) - $($data.UserId) has had their password reset" - $IntroText = "$($data.UserId) has had their password reset." + $Title = "$($TenantFilter) - $($data.ObjectId) has had their password reset" + $IntroText = "$($data.ObjectId) has had their password reset by $($data.userId)." $ButtonUrl = "$CIPPPURL/identity/administration/users?customerId=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to unblock the users sign-in

" From 5fb3e248dfceb23a472b4a00d94074acbab2233e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 16:54:02 +0200 Subject: [PATCH 088/119] speed improvements --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 30 ++++++++++--------- PublicWebhooks/run.ps1 | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 6bbea9462931..398574f68c97 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -10,26 +10,15 @@ function Invoke-CippWebhookProcessing { $APIName = "Process webhook", $ExecutingUser ) - Set-Location (Get-Item $PSScriptRoot).FullName - $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String - $AllowedLocations = $AllowedLocations -split ',' - if ($data.clientip) { - $Location = Get-CIPPGeoIPLocation -IP $data.clientip - $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } - $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } - } - #Database for knownlocations - $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - Write-Host $Country $TableObj = [PSCustomObject]::new() - if ( $Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } + if ($Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.parameters) { $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } Write-Host ($TableObj | ConvertTo-Json -Depth 10) switch ($data.operation) { - { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation"; break } - { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn"; break } + { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation" } + { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn" } default { break } } @@ -38,6 +27,19 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } + Set-Location (Get-Item $PSScriptRoot).FullName + + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String + $AllowedLocations = $AllowedLocations -split ',' + if ($data.clientip) { + $Location = Get-CIPPGeoIPLocation -IP $data.clientip + $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } + $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } + } + #Database for knownlocations + $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' + + $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId switch ($data.Operation) { diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 6116ec422673..1cac4f9191c5 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -12,6 +12,7 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Found matching CIPPID" $Webhookinfo = $Webhooks | Where-Object -Property RowKey -EQ $Request.query.CIPPID + $operations = $Webhookinfo.Operations -split ',' if ($Request.query.ValidationToken -or $Request.body.validationCode) { Write-Host "Validation token received" $body = $request.query.ValidationToken @@ -22,7 +23,6 @@ if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "TenantFilter: $TenantFilter" $Data = New-GraphPostRequest -type GET -uri "https://manage.office.com/api/v1.0/$($ReceivedItem.tenantId)/activity/feed/audit/$($ReceivedItem.contentid)" -tenantid $TenantFilter -scope "https://manage.office.com/.default" Write-Host "Data to process found: $(($ReceivedItem.operation).count) items" - $operations = $Webhookinfo.Operations -split ',' Write-Host "Operations to process for this client: $($Webhookinfo.Operations)" foreach ($Item in $Data) { Write-Host "Processing $($item.operation)" From 425c6ef7da91600dcd70c56d188383eae28255e2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 18:39:01 +0200 Subject: [PATCH 089/119] reorder --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 398574f68c97..1442d1ec7019 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -10,7 +10,15 @@ function Invoke-CippWebhookProcessing { $APIName = "Process webhook", $ExecutingUser ) + Set-Location (Get-Item $PSScriptRoot).FullName + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String + $AllowedLocations = $AllowedLocations -split ',' + if ($data.clientip) { + $Location = Get-CIPPGeoIPLocation -IP $data.clientip + $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } + $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } + } $TableObj = [PSCustomObject]::new() if ($Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } @@ -27,15 +35,7 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } - Set-Location (Get-Item $PSScriptRoot).FullName - - $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String - $AllowedLocations = $AllowedLocations -split ',' - if ($data.clientip) { - $Location = Get-CIPPGeoIPLocation -IP $data.clientip - $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } - $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } - } + #Database for knownlocations $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' From 7d7eb0ba2dd58bc0d74983880066adbe1dd31e23 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 21:23:50 +0200 Subject: [PATCH 090/119] added writing of url --- PublicWebhooks/run.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 1cac4f9191c5..587fe02fe862 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -6,8 +6,8 @@ $WebhookTable = Get-CIPPTable -TableName webhookTable $Webhooks = Get-AzDataTableEntity @WebhookTable Write-Host "Received request" Write-Host "CIPPID: $($request.Query.CIPPID)" -$url = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 - +$url = ($request.headers.'x-ms-original-url').split('/API') | Select-Object -First 1 +write-host $url if ($Request.CIPPID -in $Webhooks.CIPPID) { Write-Host "Found matching CIPPID" From 0dc8bcb8058101187d6495b06e70563b4e839de5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 23:31:32 +0200 Subject: [PATCH 091/119] alert mods --- AddAlert/run.ps1 | 57 +++++++++++++++-------------- Scheduler_CIPPNotifications/run.ps1 | 8 ++-- profile.ps1 | 6 +-- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/AddAlert/run.ps1 b/AddAlert/run.ps1 index 1618be054143..7499c4ec7a51 100644 --- a/AddAlert/run.ps1 +++ b/AddAlert/run.ps1 @@ -15,35 +15,36 @@ $Results = foreach ($Tenant in $tenants) { else { 'AllTenants' } - $CompleteObject = @{ - tenant = $tenant - tenantid = $TenantID - AdminPassword = [bool]$Request.body.AdminPassword - DefenderMalware = [bool]$Request.body.DefenderMalware - DefenderStatus = [bool]$Request.body.DefenderStatus - MFAAdmins = [bool]$Request.body.MFAAdmins - MFAAlertUsers = [bool]$Request.body.MFAAlertUsers - NewGA = [bool]$Request.body.NewGA - NewRole = [bool]$Request.body.NewRole - QuotaUsed = [bool]$Request.body.QuotaUsed - UnusedLicenses = [bool]$Request.body.UnusedLicenses - OverusedLicenses = [bool]$Request.body.OverusedLicenses - AppSecretExpiry = [bool]$Request.body.AppSecretExpiry - ApnCertExpiry = [bool]$Request.body.ApnCertExpiry - VppTokenExpiry = [bool]$Request.body.VppTokenExpiry - DepTokenExpiry = [bool]$Request.body.DepTokenExpiry - NoCAConfig = [bool]$Request.body.NoCAConfig - SecDefaultsUpsell = [bool]$Request.body.SecDefaultsUpsell - SharePointQuota = [bool]$Request.body.SharePointQuota - ExpiringLicenses = [bool]$Request.body.ExpiringLicenses - type = 'Alert' - RowKey = $TenantID - PartitionKey = 'Alert' - } - - $Table = get-cipptable -TableName 'SchedulerConfig' - Add-AzDataTableEntity @Table -Entity $CompleteObject -Force + if ($Request.body.SetAlerts) { + $CompleteObject = @{ + tenant = $tenant + tenantid = $TenantID + AdminPassword = [bool]$Request.body.AdminPassword + DefenderMalware = [bool]$Request.body.DefenderMalware + DefenderStatus = [bool]$Request.body.DefenderStatus + MFAAdmins = [bool]$Request.body.MFAAdmins + MFAAlertUsers = [bool]$Request.body.MFAAlertUsers + NewGA = [bool]$Request.body.NewGA + NewRole = [bool]$Request.body.NewRole + QuotaUsed = [bool]$Request.body.QuotaUsed + UnusedLicenses = [bool]$Request.body.UnusedLicenses + OverusedLicenses = [bool]$Request.body.OverusedLicenses + AppSecretExpiry = [bool]$Request.body.AppSecretExpiry + ApnCertExpiry = [bool]$Request.body.ApnCertExpiry + VppTokenExpiry = [bool]$Request.body.VppTokenExpiry + DepTokenExpiry = [bool]$Request.body.DepTokenExpiry + NoCAConfig = [bool]$Request.body.NoCAConfig + SecDefaultsUpsell = [bool]$Request.body.SecDefaultsUpsell + SharePointQuota = [bool]$Request.body.SharePointQuota + ExpiringLicenses = [bool]$Request.body.ExpiringLicenses + type = 'Alert' + RowKey = $TenantID + PartitionKey = 'Alert' + } + $Table = get-cipptable -TableName 'SchedulerConfig' + Add-AzDataTableEntity @Table -Entity $CompleteObject -Force + } $URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1 if ($Tenant -eq 'AllTenants') { Get-Tenants | ForEach-Object { diff --git a/Scheduler_CIPPNotifications/run.ps1 b/Scheduler_CIPPNotifications/run.ps1 index f1b409137812..19d4f19b8e2d 100644 --- a/Scheduler_CIPPNotifications/run.ps1 +++ b/Scheduler_CIPPNotifications/run.ps1 @@ -8,16 +8,18 @@ $Config = [pscustomobject](Get-AzDataTableEntity @Table -Filter $Filter) $Settings = [System.Collections.ArrayList]@('Alerts') $Config.psobject.properties.name | ForEach-Object { $settings.add($_) } $severity = $Config.Severity -split ',' +Write-Host "Our Severity table is: $severity" if (!$severity) { $severity = [System.Collections.ArrayList]@('Info', 'Error', 'Warning', 'Critical', 'Alert') } +Write-Host "Our Severity table is: $severity" $Table = Get-CIPPTable -$PartitionKey = Get-Date -UFormat '% Y%m%d' -$Filter = "PartitionKey eq '{ 0 }'" -f $PartitionKey +$PartitionKey = Get-Date -UFormat '%Y%m%d' +$Filter = "PartitionKey eq '{0}'" -f $PartitionKey $Currentlog = Get-AzDataTableEntity @Table -Filter $Filter | Where-Object { $_.API -In $Settings -and $_.SentAsAlert -ne $true -and $_.Severity -In $severity } - +Write-Host ($Currentlog).count #email try try { if ($config.onePerTenant) { diff --git a/profile.ps1 b/profile.ps1 index 7e80bf71358f..3970e8e3b97d 100644 --- a/profile.ps1 +++ b/profile.ps1 @@ -12,11 +12,11 @@ # Authenticate with Azure PowerShell using MSI. # Remove this if you are not planning on using MSI or Azure PowerShell. Import-Module .\GraphHelper.psm1 -Import-Module Az.KeyVault -Import-Module Az.Accounts +#Import-Module Az.KeyVault +#Import-Module Az.Accounts Import-Module GraphRequests Import-Module CippExtensions -Import-module CippCore +Import-Module CippCore try { Disable-AzContextAutosave -Scope Process | Out-Null From b6362019deb2c7eb024bcc07dfdbc3199d0cd7be Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Aug 2023 23:50:29 +0200 Subject: [PATCH 092/119] fixes issuers with returned results --- ExecCPVPermissions/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExecCPVPermissions/run.ps1 b/ExecCPVPermissions/run.ps1 index cf7e6501a3c4..7b05d3559f5f 100644 --- a/ExecCPVPermissions/run.ps1 +++ b/ExecCPVPermissions/run.ps1 @@ -91,5 +91,5 @@ $StatusCode = [HttpStatusCode]::OK # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode - Body = @($GraphRequest) + Body = @(@{Results = $GraphRequest }) }) From 1138265af2d0b586a3ec56432e800af57c82d445 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 00:23:35 +0200 Subject: [PATCH 093/119] improved cpv permissions settings for app perms --- ExecCPVPermissions/run.ps1 | 4 ++++ UpdatePermissionsQueue/run.ps1 | 1 + 2 files changed, 5 insertions(+) diff --git a/ExecCPVPermissions/run.ps1 b/ExecCPVPermissions/run.ps1 index 7b05d3559f5f..c70a37e2217f 100644 --- a/ExecCPVPermissions/run.ps1 +++ b/ExecCPVPermissions/run.ps1 @@ -63,6 +63,9 @@ $ourSVCPrincipal = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/se # if the app svc principal exists, consent app permissions $apps = $ExpectedPermissions +#get current roles +$CurrentRoles = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals/$($ourSVCPrincipal.id)/appRoleAssignments" -tenantid $tenantfilter +#If $Grants = foreach ($App in $apps.requiredResourceAccess) { try { $svcPrincipalId = New-GraphGETRequest -uri "https://graph.microsoft.com/v1.0/servicePrincipals(appId='$($app.resourceAppId)')" -tenantid $tenantfilter @@ -71,6 +74,7 @@ $Grants = foreach ($App in $apps.requiredResourceAccess) { continue } foreach ($SingleResource in $app.ResourceAccess | Where-Object -Property Type -EQ "Role") { + if ($singleresource.id -In $currentroles.appRoleId) { continue } [pscustomobject]@{ principalId = $($ourSVCPrincipal.id) resourceId = $($svcPrincipalId.id) diff --git a/UpdatePermissionsQueue/run.ps1 b/UpdatePermissionsQueue/run.ps1 index f0505b18f59f..a8f01f5572aa 100644 --- a/UpdatePermissionsQueue/run.ps1 +++ b/UpdatePermissionsQueue/run.ps1 @@ -65,6 +65,7 @@ $Grants = foreach ($App in $apps.requiredResourceAccess) { continue } foreach ($SingleResource in $app.ResourceAccess | Where-Object -Property Type -EQ "Role") { + if ($singleresource.id -In $currentroles.appRoleId) { continue } [pscustomobject]@{ principalId = $($ourSVCPrincipal.id) resourceId = $($svcPrincipalId.id) From ede38dea1b789ec65953e714e2bb8b500fcd0d38 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 20:26:37 +0200 Subject: [PATCH 094/119] speed increase by using localdb first if address has already been seen. --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 1442d1ec7019..77f9c261bb20 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -11,13 +11,25 @@ function Invoke-CippWebhookProcessing { $ExecutingUser ) Set-Location (Get-Item $PSScriptRoot).FullName + $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String $AllowedLocations = $AllowedLocations -split ',' + if ($data.userId -eq "Not Available") { $data.userId = $data.userKey } + if ($data.Userkey -eq "Not Available") { $data.Userkey = $data.userId } if ($data.clientip) { - $Location = Get-CIPPGeoIPLocation -IP $data.clientip - $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } - $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } + #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. + $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)' and PartitionKey eq 'knownlocationdb'" + #If we have a location, we use that. If not, we perform a lookup in the GeoIP database. + if ($Location) { + $Country = $Location.CountryOrRegion + $City = $Location.City + } + else { + $Location = Get-CIPPGeoIPLocation -IP $data.clientip + $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } + $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } + } } $TableObj = [PSCustomObject]::new() if ($Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } @@ -35,9 +47,6 @@ function Invoke-CippWebhookProcessing { Write-Host "No need to process this operation." return "" } - - #Database for knownlocations - $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId From f619949cd2336a2c054573c2e625b81a6658981a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 20:27:00 +0200 Subject: [PATCH 095/119] Improvements to password expire via domains endpoint --- Standards_PasswordExpireDisabled/run.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Standards_PasswordExpireDisabled/run.ps1 b/Standards_PasswordExpireDisabled/run.ps1 index 296f0f9e6cb9..58f5cdb972b7 100644 --- a/Standards_PasswordExpireDisabled/run.ps1 +++ b/Standards_PasswordExpireDisabled/run.ps1 @@ -1,8 +1,7 @@ param($tenant) try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/?`$top=999&`$select=id,userPrincipalName,passwordPolicies" -tenantid $Tenant | Where-Object -Property passwordPolicies -EQ $null | ForEach-Object { - $userid = $_.id - New-GraphPostRequest -type Patch -tenantid $Tenant -uri "https://graph.microsoft.com/beta/users/$($userid)" -body '{"passwordPolicies": "DisablePasswordExpiration"}' + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/domains" -tenantid $Tenant | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' | ForEach-Object { + New-GraphPostRequest -type Patch -tenantid $Tenant -uri "https://graph.microsoft.com/beta/domains/$($_.id)" -body '{"passwordValidityPeriodInDays": 2147483647 }' } Write-LogMessage -API "Standards" -tenant $tenant -message "Disabled Password Expiration" -sev Info } From 2827d9a936d474353f3073d09ee79d2a2006a379 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 20:27:16 +0200 Subject: [PATCH 096/119] Fixes alerts to have correct api --- Modules/CIPPCore/Public/Send-CIPPAlert.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 index 83331941a471..23a640eb4027 100644 --- a/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 +++ b/Modules/CIPPCore/Public/Send-CIPPAlert.ps1 @@ -34,12 +34,12 @@ function Send-CIPPAlert { $JSONBody = ConvertTo-Json -Compress -Depth 10 -InputObject $PowerShellBody New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -NoAuthCheck $true -type POST -body ($JSONBody) } - Write-LogMessage -API 'Alerts' -message "Sent a webhook alert to email: $Title" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Sent a webhook alert to email: $Title" -sev info } catch { Write-Host "Could not send webhook alert to email: $($_.Exception.message)" - Write-LogMessage -API 'Alerts' -message "Could not send webhook alerts to email. $($_.Exception.message)" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Could not send webhook alerts to email. $($_.Exception.message)" -sev info } } @@ -66,12 +66,12 @@ function Send-CIPPAlert { } } - Write-LogMessage -API 'Alerts' -message "Sent Webhook alert $title to External webhook" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Sent Webhook alert $title to External webhook" -sev info } catch { Write-Host "Could not send alerts to webhook: $($_.Exception.message)" - Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info } } Write-Host "Trying to send to PSA" @@ -86,12 +86,12 @@ function Send-CIPPAlert { AlertTitle = "$($Title)" } New-CippExtAlert -Alert $Alert - Write-LogMessage -API 'Alerts' -message "Sent PSA alert $title" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Sent PSA alert $title" -sev info } catch { Write-Host "Could not send alerts to ticketing system: $($_.Exception.message)" - Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info + Write-LogMessage -API 'Webhook Alerts' -message "Could not send alerts to : $($_.Exception.message)" -sev info } } } From 3c3e63fa865884651514b88ce8662847f628b4b4 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 22:30:31 +0200 Subject: [PATCH 097/119] ipv6 improvements --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 77f9c261bb20..d8a7cc092edd 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -19,7 +19,7 @@ function Invoke-CippWebhookProcessing { if ($data.Userkey -eq "Not Available") { $data.Userkey = $data.userId } if ($data.clientip) { #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. - $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)' and PartitionKey eq 'knownlocationdb'" + $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)'" | Select-Object -Last 1 #If we have a location, we use that. If not, we perform a lookup in the GeoIP database. if ($Location) { $Country = $Location.CountryOrRegion @@ -154,7 +154,10 @@ function Invoke-CippWebhookProcessing { Write-Host "Add IP and potential location to knownlocation db for this specific user" if ($data.ClientIP) { - $IP = $data.ClientIP.Split(':') | Select-Object -Last 1 + $IP = $data.ClientIP + if ($IP -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { + $IP = $IP -replace ':\d+$', '' # Remove the port number if present + } $LocationInfo = @{ RowKey = [string]$ip PartitionKey = [string]$data.UserId From 77e9adb6a51e552996e2f58e07d5f365ff422c97 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Fri, 11 Aug 2023 23:22:41 +0200 Subject: [PATCH 098/119] add ip even if action is not required so we get a corre3ct db. --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index d8a7cc092edd..08dd1839040b 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -44,7 +44,23 @@ function Invoke-CippWebhookProcessing { #Check if the operation is allowed for this webhook. if ($data.operation -notin $Operations) { - Write-Host "No need to process this operation." + Write-Host "No need to process this operation, but we're saving the IP for future" + Write-Host "Add IP and potential location to knownlocation db for this specific user" + + if ($data.ClientIP) { + $IP = $data.ClientIP + if ($IP -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { + $IP = $IP -replace ':\d+$', '' # Remove the port number if present + } + $LocationInfo = @{ + RowKey = [string]$ip + PartitionKey = [string]$data.UserId + Tenant = [string]$TenantFilter + CountryOrRegion = "$Country" + City = "$City" + } + $null = Add-AzDataTableEntity @LocationTable -Entity $LocationInfo -Force + } return "" } From 76cb1ce9b38019840d0174501c3ea7db8ab5cc93 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 14 Aug 2023 17:13:42 +0200 Subject: [PATCH 099/119] new bpa --- BestPracticeAnalyser_All/run.ps1 | 315 +++++++-------------- BestPracticeAnalyser_Orchestration/run.ps1 | 15 - GraphHelper.psm1 | 2 +- ListBPA/function.json | 19 ++ ListBPA/run.ps1 | 57 ++++ ListBPATemplates/function.json | 19 ++ ListBPATemplates/run.ps1 | 26 ++ 7 files changed, 229 insertions(+), 224 deletions(-) create mode 100644 ListBPA/function.json create mode 100644 ListBPA/run.ps1 create mode 100644 ListBPATemplates/function.json create mode 100644 ListBPATemplates/run.ps1 diff --git a/BestPracticeAnalyser_All/run.ps1 b/BestPracticeAnalyser_All/run.ps1 index 741da28b8eaa..5d9ee8a8bfed 100644 --- a/BestPracticeAnalyser_All/run.ps1 +++ b/BestPracticeAnalyser_All/run.ps1 @@ -1,219 +1,118 @@ param($tenant) -# Prepare tokens, connections and variables that will be used multiple times later - -try { - $token = Get-ClassicAPIToken -resource 'https://outlook.office365.com' -tenantid $tenant - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Token retrieved for Best Practice Analyser on $($tenant)" -sev 'Debug' -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Unable to Retrieve token for Best Practice Analyser $($tenant) Error: $($_.exception.message)" -sev 'Error' -} $TenantName = Get-Tenants | Where-Object -Property defaultDomainName -EQ $tenant -# Build up the result object that will be passed back to the durable function -$Result = @{ - Tenant = "$($TenantName.displayName)" - GUID = "$($TenantName.customerId)" - RowKey = "$($TenantName.customerId)" - PartitionKey = 'bpa' - LastRefresh = $(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z') - SecureDefaultState = '' - PrivacyEnabled = '' - UnifiedAuditLog = '' - MessageCopyForSend = '' - MessageCopyForSendAsCount = '' - MessageCopyForSendOnBehalfCount = '' - MessageCopyForSendList = '' - AdminConsentForApplications = '' - DoNotExpirePasswords = '' - SelfServicePasswordReset = '' - DisabledSharedMailboxLogins = '' - DisabledSharedMailboxLoginsCount = '' - UnusedLicensesCount = '' - UnusedLicensesTotal = '' - UnusedLicensesResult = '' - UnusedLicenseList = '' - SecureScoreCurrent = '' - SecureScoreMax = '' - SecureScorePercentage = '' - SentFromAlias = '' - MFANudge = '' - TAPEnabled = '' -} - -# Starting the Best Practice Analyser -# Get the TAP state -try { - $TAPEnabled = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass' -tenantid $tenant) - $Result.TAPEnabled = $TAPEnabled.State -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Retrieving TAP state failed: $($tenant) Error: $($_.exception.message)" -sev 'Error' -} -# Get the nudge State -try { - $NudgeState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -tenantid $tenant) - $Result.MFANudge = $NudgeState.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Security Defaults State on $($tenant) Error: $($_.exception.message)" -sev 'Error' -} - -# Get the Secure Default State -try { - $SecureDefaultsState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy' -tenantid $tenant) - $Result.SecureDefaultState = $SecureDefaultsState.IsEnabled -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Security Defaults State on $($tenant) Error: $($_.exception.message)" -sev 'Error' -} - - -# Get the Privacy Enabled State -try { - $Result.PrivacyEnabled = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -tenantid $tenant).displayConcealedNames -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Privacy Enabled State on $($tenant) Error: $($_.exception.message)" -sev 'Error' -} - -# Get Send and Send Behalf Of -try { - # Send and Send Behalf Of - $MailboxBPA = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' | Where-Object { $_.RecipientTypeDetails -In @('UserMailbox', 'SharedMailbox') -and $_.userPrincipalName -notlike 'DiscoverySearchMailbox' } - $TotalMailboxes = $MailboxBPA | Measure-Object | Select-Object -ExpandProperty Count - $TotalMessageCopyForSentAsEnabled = $MailboxBPA | Where-Object { $_.MessageCopyForSentAsEnabled -eq $true } | Measure-Object | Select-Object -ExpandProperty Count - $TotalMessageCopyForSendOnBehalfEnabled = $MailboxBPA | Where-Object { $_.MessageCopyForSendOnBehalfEnabled -eq $true } | Measure-Object | Select-Object -ExpandProperty Count - If (($TotalMailboxes -eq $TotalMessageCopyForSentAsEnabled) -and ($TotalMailboxes -eq $TotalMessageCopyForSendOnBehalfEnabled)) { - $Result.MessageCopyForSend = 'PASS' - $Result.MessageCopyForSendAsCount = $TotalMessageCopyForSentAsEnabled - $Result.MessageCopyForSendOnBehalfCount = $TotalMessageCopyForSendOnBehalfEnabled - } - else { - $Result.MessageCopyForSend = 'FAIL' - $Result.MessageCopyForSendAsCount = $MailboxBPA | Where-Object { $_.MessageCopyForSentAsEnabled -eq $false } | Measure-Object | Select-Object -ExpandProperty Count - $Result.MessageCopyForSendOnBehalfCount = $MailboxBPA | Where-Object { $_.MessageCopyForSendOnBehalfEnabled -eq $false } | Measure-Object | Select-Object -ExpandProperty Count - $Result.MessageCopyForSendList = ($MailboxBPA | Where-Object { ($_.MessageCopyForSendOnBehalfEnabled -eq $false) -or ( $_.MessageCopyForSendOnBehalfEnabled -eq $false) } | Select-Object -ExpandProperty userPrincipalName) -join '
' +Set-Location (Get-Item $PSScriptRoot).Parent.FullName +$TemplatesLoc = Get-ChildItem "Config\*.BPATemplate.json" +$Templates = $TemplatesLoc | ForEach-Object { + $Template = $(Get-Content $_) | ConvertFrom-Json + [PSCustomObject]@{ + Data = $Template + Name = $Template.Name + Style = $Template.Style } } -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Send and Send Behalf Of on $($tenant) Error: $($_.exception.message)" -sev 'Error' -} - - -# Get Unified Audit Log -try { - $EXOAdminAuditLogConfig = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AdminAuditLogConfig' - $Result.UnifiedAuditLog = $EXOAdminAuditLogConfig | Select-Object -ExpandProperty UnifiedAuditLogIngestionEnabled - -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Unified Audit Log on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - -# Get Basic Auth States -try { - #No longer used - Basic authentication is deprecated. -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Basic Auth States on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - - -# Get OAuth Admin Consenst -try { - $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant - $Result.AdminConsentForApplications = if ($GraphRequest.permissionGrantPolicyIdsAssignedToDefaultUserRole -eq 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy') { $true } else { $false } -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "OAuth Admin Consent on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - -# Get Self Service Password Reset State -try { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/authenticationMethods/usersRegisteredByFeature(includedUserTypes='all',includedUserRoles='all')" -tenantid $Tenant - $RegState = ($GraphRequest.userRegistrationFeatureCounts | Where-Object -Property Feature -EQ "ssprRegistered").usercount - $CapableState = ($GraphRequest.userRegistrationFeatureCounts | Where-Object -Property Feature -EQ "ssprCapable").usercount - $Result.SelfServicePasswordReset = if ($RegState -ge $CapableState -and $CapableState -ne 0) { $true } else { $false } - - -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Self Service Password Reset on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - -# Get Passwords set to Never Expire -try { - $ExpirePasswordReq = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/?`$top=999&`$select=userPrincipalName,passwordPolicies" -tenantid $Tenant | Where-Object -Property passwordPolicies -EQ $null).userPrincipalName - $Result.DoNotExpirePasswords = if ($ExpirePasswordReq) { $false } else { $true } -} - -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Passwords never expire setting on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - - -# Get Shared Mailbox Stuff -try { - $SharedMailboxList = (New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenant)/Mailbox?`$filter=RecipientTypeDetails eq 'SharedMailbox'" -Tenantid $tenant -scope ExchangeOnline) - $AllUsersAccountState = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/users?select=userPrincipalName,accountEnabled' -tenantid $Tenant - $EnabledUsersWithSharedMailbox = foreach ($SharedMailbox in $SharedMailboxList) { - # Match the User - $User = $AllUsersAccountState | Where-Object { $_.userPrincipalName -eq $SharedMailbox.userPrincipalName } | Select-Object -First 1 - if ($User.accountEnabled) { - $User.userPrincipalName +$Table = Get-CippTable -tablename 'cachebpav2' +$AddRow = foreach ($Template in $templates) { + # Build up the result object that will be passed back to the durable function + $Result = @{ + Tenant = "$($TenantName.displayName)" + GUID = "$($TenantName.customerId)" + RowKey = "$($Template.Name)" + PartitionKey = "$($TenantName.customerId)" + LastRefresh = [string]$(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z') + } + foreach ($field in $Template.Data.Fields) { + + if ($Field.Where) { $filterscript = [scriptblock]::Create($Field.Where) } else { $filterscript = { $true } } + try { + switch ($field.API) { + "Graph" { + $paramsField = @{ + uri = $field.URL + tenantid = $TenantName.defaultDomainName + } + if ($Field.parameters) { + $field.Parameters | ForEach-Object { + Write-Host "Doing: $($_.psobject.properties.name) with value $($_.psobject.properties.value)" + $paramsField.Add($_.psobject.properties.name, $_.psobject.properties.value) + } + } + $FieldInfo = New-GraphGetRequest @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields + } + "Exchange" { + if ($field.Command -notlike "get-*") { + Write-LogMessage -API "BPA" -tenant $tenant -message "The BPA only supports get- exchange commands. A set or update command was used." -sev Error + break + } + else { + $paramsField = @{ + tenantid = $TenantName.defaultDomainName + cmdlet = $field.Command + } + if ($Field.Parameters) { $paramsfield.add('cmdparams', $field.parameters) } + $FieldInfo = New-ExoRequest @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields + } + } + "CIPPFunction" { + if ($field.Command -notlike "get-CIPP*") { + Write-LogMessage -API "BPA" -tenant $tenant -message "The BPA only supports get-CIPP commands. A set or update command was used, or a command that is not allowed." -sev Error + break + } + $paramsField = @{ + TenantFilter = $TenantName.defaultDomainName + } + if ($field.parameters) { + $field.Parameters | ForEach-Object { + $paramsField.Add($_.psobject.properties.name, $_.psobject.properties.value) + } + } + $FieldInfo = Invoke-Expression -Command $field.Command @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields + } + } + } + catch { + Write-Host "Error getting $($field.Name) in $($field.api) for $($TenantName.displayName) with GUID $($TenantName.customerId). Error: $($_.Exception.Message)" + Write-LogMessage -API "BPA" -tenant $tenant -message "Error getting $($field.Name) for $($TenantName.displayName) with GUID $($TenantName.customerId). Error: $($_.Exception.Message)" -sev Error + $fieldinfo = $null + } + switch ($field.StoreAs) { + "bool" { + if ($field.ExtractFields.Count -gt 1) { + Write-LogMessage -API "BPA" -tenant $tenant -message "The BPA only supports 1 field for a bool. $($field.ExtractFields.Count) fields were specified." -sev Error + break + } + if ($FieldInfo.$($field.ExtractFields) -eq $null) { $FieldInfo.$($field.ExtractFields) = $false } + if ($field.Condition) { + $operator = $field.condition.operator + $value = $($field.condition.value) + Write-Host "$FieldInfo.$($field.ExtractFields) -$operator $value" + if (Invoke-Expression "$FieldInfo.$($field.ExtractFields) -$operator $value") { + $fieldInfo = $true + } + else { + $fieldInfo = $false + } + } + $Result.Add($field.Name, [bool]$FieldInfo.$($field.ExtractFields)) + } + "JSON" { + if ($FieldInfo -eq $null) { $JsonString = '{}' } else { $JsonString = (ConvertTo-Json -Depth 15 -InputObject $FieldInfo) } + $Result.Add($field.Name, $JSONString) + } + "string" { + $Result.Add($field.Name, [string]$FieldInfo) + } } + } - - if (($EnabledUsersWithSharedMailbox | Measure-Object | Select-Object -ExpandProperty Count) -gt 0) { $Result.DisabledSharedMailboxLogins = ($EnabledUsersWithSharedMailbox) -join '
' } else { $Result.DisabledSharedMailboxLogins = 'PASS' } - $Result.DisabledSharedMailboxLoginsCount = $EnabledUsersWithSharedMailbox | Measure-Object | Select-Object -ExpandProperty Count -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Shared Mailbox Enabled Accounts on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} + + if ($Result) { + try { + Add-AzDataTableEntity @Table -Entity $Result + } + catch { + Write-LogMessage -API "BPA" -tenant $tenant -message "Error getting saving data for $($template.Name) - $($TenantName.customerId). Error: $($_.Exception.Message)" -sev Error -# Get unused Licenses -try { - $LicenseUsage = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/subscribedSkus' -tenantid $Tenant - # Import the licenses conversion table - Set-Location (Get-Item $PSScriptRoot).Parent.FullName - $ConvertTable = Import-Csv Conversiontable.csv | Sort-Object -Property 'guid' -Unique - $Table = Get-CIPPTable -TableName ExcludedLicenses - $ExcludeList = Get-AzDataTableEntity @Table - $UnusedLicenses = $LicenseUsage | Where-Object { ($_.prepaidUnits.enabled -ne $_.consumedUnits) -and ($_.SkuID -notin $ExcludeList.GUID) } - $UnusedLicensesCount = $UnusedLicenses | Measure-Object | Select-Object -ExpandProperty Count - $UnusedLicensesResult = if ($UnusedLicensesCount -gt 0) { 'FAIL' } else { 'PASS' } - $Result.UnusedLicenseList = foreach ($License in $UnusedLicenses) { - $PrettyName = ($ConvertTable | Where-Object { $_.guid -eq $License.skuid }).'Product_Display_Name' | Select-Object -Last 1 - if (!$PrettyName) { $PrettyName = $License.skuPartNumber } - [PSCustomObject]@{ - License = $($PrettyName) - Purchased = $($License.prepaidUnits.enabled) - Consumed = $($License.consumedUnits) } } - - $TempCount = 0 - foreach ($License in $UnusedLicenses) { - $TempCount = $TempCount + ($($License.prepaidUnits.enabled) - $($License.ConsumedUnits)) - } - $Result.UnusedLicenseList = ConvertTo-Json -InputObject @($Result.UnusedLicenseList) -Compress - $Result.UnusedLicensesTotal = $TempCount - $Result.UnusedLicensesCount = $UnusedLicensesCount - $Result.UnusedLicensesResult = $UnusedLicensesResult -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Unused Licenses on $($tenant). Error: $($_.exception.message)" -sev 'Error' -} - -# Get Secure Score -try { - $SecureScore = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/security/secureScores?`$top=1" -tenantid $tenant -noPagination $true - $Result.SecureScoreCurrent = [int]$SecureScore.currentScore - $Result.SecureScoreMax = [int]$SecureScore.maxScore - $Result.SecureScorePercentage = [int](($SecureScore.currentScore / $SecureScore.maxScore) * 100) -} -catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Secure Score Retrieval on $($tenant). Error: $($_.exception.message)" -sev 'Error' } -$Result diff --git a/BestPracticeAnalyser_Orchestration/run.ps1 b/BestPracticeAnalyser_Orchestration/run.ps1 index a76d8bab3316..1ff8cf4659cb 100644 --- a/BestPracticeAnalyser_Orchestration/run.ps1 +++ b/BestPracticeAnalyser_Orchestration/run.ps1 @@ -14,19 +14,4 @@ $ParallelTasks = foreach ($Item in $Batch) { Invoke-DurableActivity -FunctionName 'BestPracticeAnalyser_All' -Input $item -NoWait -RetryOptions $RetryOptions } -$TableParams = Get-CippTable -tablename 'cachebpa' -$TableParams.Entity = Wait-ActivityFunction -Task $ParallelTasks -$TableParams.Force = $true -$TableParams = $TableParams | Where-Object -Property RowKey -NE "" | ConvertTo-Json -Compress -if ($TableParams) { - try { - Invoke-ActivityFunction -FunctionName 'Activity_AddOrUpdateTableRows' -Input $TableParams - } - catch { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Best Practice Analyser could not write to table: $($_.Exception.Message)" -sev error - } -} -else { - Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message "Tried writing empty values to BestPracticeAnalyser" -sev Info -} Write-LogMessage -API 'BestPracticeAnalyser' -tenant $tenant -message 'Best Practice Analyser has Finished' -sev Info \ No newline at end of file diff --git a/GraphHelper.psm1 b/GraphHelper.psm1 index bfc252464051..283912865ef0 100644 --- a/GraphHelper.psm1 +++ b/GraphHelper.psm1 @@ -233,7 +233,7 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N #setting ErrorMess because the error from a failed json conversion overwrites the exception. $ErrorMess = $($_.Exception.Message) try { - $Message = ($_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue).error.message + $Message = ($_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction Stop).error.message } catch { $Message = $ErrorMess diff --git a/ListBPA/function.json b/ListBPA/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ListBPA/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ListBPA/run.ps1 b/ListBPA/run.ps1 new file mode 100644 index 000000000000..faf92b9dbf71 --- /dev/null +++ b/ListBPA/run.ps1 @@ -0,0 +1,57 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +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 'cachebpav2' +$name = $Request.query.Report +if ($name -eq $null) { $name = "CIPP Best Practices v1.0 - Table view" } + +# Get all possible JSON files for reports, find the correct one, select the Columns +$JSONFields = @() +(Get-ChildItem -Path "Config\*.BPATemplate.json" -Recurse | Select-Object -ExpandProperty FullName | ForEach-Object { + $Template = $(Get-Content $_) | ConvertFrom-Json + if ($Template.Name -eq $NAME) { + $JSONFields = $Template.Fields | Where-Object { $_.StoreAs -eq 'JSON' } | ForEach-Object { $_.name } + } +}) + +$Data = (Get-AzDataTableEntity @Table -Filter "RowKey eq '$NAME'") | ForEach-Object { + $row = $_ + $JSONFields | ForEach-Object { + $jsonContent = $row.$_ + if ($jsonContent -ne $null) { + $row.$_ = $jsonContent | ConvertFrom-Json -Depth 15 + } + } + $row +} + +$Columns = $null +(Get-ChildItem -Path "Config\*.BPATemplate.json" -Recurse | Select-Object -ExpandProperty FullName | ForEach-Object { + $Template = $(Get-Content $_) | ConvertFrom-Json + if ($Template.Name -eq $NAME) { + $Columns = $Template.fields.FrontendFields | Where-Object -Property name -NE $null + } +}) + +$Results = [PSCustomObject]@{ + Data = $Data + Columns = $Columns +} + +if (!$Results) { + $Results = @{ + Columns = @( value = "Results"; name = "Results") + Data = @(@{ Results = "The BPA has not yet run." }) + } +} + +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = ($Results | ConvertTo-Json -Depth 15) + }) diff --git a/ListBPATemplates/function.json b/ListBPATemplates/function.json new file mode 100644 index 000000000000..306b0c51e560 --- /dev/null +++ b/ListBPATemplates/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "Request", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ] +} \ No newline at end of file diff --git a/ListBPATemplates/run.ps1 b/ListBPATemplates/run.ps1 new file mode 100644 index 000000000000..b00d60b7854e --- /dev/null +++ b/ListBPATemplates/run.ps1 @@ -0,0 +1,26 @@ +using namespace System.Net + +# Input bindings are passed in via param block. +param($Request, $TriggerMetadata) + +$APIName = $TriggerMetadata.FunctionName +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" + +Write-Host "PowerShell HTTP trigger function processed a request." +Write-Host $Request.query.id + +Set-Location (Get-Item $PSScriptRoot).Parent.FullName +$Templates = Get-ChildItem "Config\*.BPATemplate.json" +$Templates = $Templates | ForEach-Object { + $Template = $(Get-Content $_) | ConvertFrom-Json + @{ + Data = $Template.fields + Name = $Template.Name + Style = $Template.Style + } +} +# Associate values to output bindings by calling 'Push-OutputBinding'. +Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($Templates) + }) From 21c701623f47de119c1362e3bd77e03b76f08a2f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:54:46 +0200 Subject: [PATCH 100/119] improvements bpa and access check --- BestPracticeAnalyser_All/run.ps1 | 51 +++++++++++++++----------------- ExecAccessChecks/run.ps1 | 29 ++++++++++++++++-- ListBPA/run.ps1 | 2 +- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/BestPracticeAnalyser_All/run.ps1 b/BestPracticeAnalyser_All/run.ps1 index 5d9ee8a8bfed..053b424d41de 100644 --- a/BestPracticeAnalyser_All/run.ps1 +++ b/BestPracticeAnalyser_All/run.ps1 @@ -73,42 +73,39 @@ $AddRow = foreach ($Template in $templates) { catch { Write-Host "Error getting $($field.Name) in $($field.api) for $($TenantName.displayName) with GUID $($TenantName.customerId). Error: $($_.Exception.Message)" Write-LogMessage -API "BPA" -tenant $tenant -message "Error getting $($field.Name) for $($TenantName.displayName) with GUID $($TenantName.customerId). Error: $($_.Exception.Message)" -sev Error - $fieldinfo = $null - } - switch ($field.StoreAs) { - "bool" { - if ($field.ExtractFields.Count -gt 1) { - Write-LogMessage -API "BPA" -tenant $tenant -message "The BPA only supports 1 field for a bool. $($field.ExtractFields.Count) fields were specified." -sev Error - break - } - if ($FieldInfo.$($field.ExtractFields) -eq $null) { $FieldInfo.$($field.ExtractFields) = $false } - if ($field.Condition) { - $operator = $field.condition.operator - $value = $($field.condition.value) - Write-Host "$FieldInfo.$($field.ExtractFields) -$operator $value" - if (Invoke-Expression "$FieldInfo.$($field.ExtractFields) -$operator $value") { - $fieldInfo = $true - } - else { - $fieldInfo = $false + $fieldinfo = "FAILED" + $field.StoreAs = "string" + } + try { + switch -Wildcard ($field.StoreAs) { + "*bool" { + if ($field.ExtractFields.Count -gt 1) { + Write-LogMessage -API "BPA" -tenant $tenant -message "The BPA only supports 1 field for a bool. $($field.ExtractFields.Count) fields were specified." -sev Error + break } + if ($null -eq $FieldInfo.$($field.ExtractFields)) { $FieldInfo = $false } + + $Result.Add($field.Name, [bool]$FieldInfo.$($field.ExtractFields)) + } + "JSON" { + if ($FieldInfo -eq $null) { $JsonString = '{}' } else { $JsonString = (ConvertTo-Json -Depth 15 -InputObject $FieldInfo) } + $Result.Add($field.Name, $JSONString) + } + "string" { + $Result.Add($field.Name, [string]$FieldInfo) } - $Result.Add($field.Name, [bool]$FieldInfo.$($field.ExtractFields)) - } - "JSON" { - if ($FieldInfo -eq $null) { $JsonString = '{}' } else { $JsonString = (ConvertTo-Json -Depth 15 -InputObject $FieldInfo) } - $Result.Add($field.Name, $JSONString) - } - "string" { - $Result.Add($field.Name, [string]$FieldInfo) } } + catch { + Write-LogMessage -API "BPA" -tenant $tenant -message "Error storing $($field.Name) for $($TenantName.displayName) with GUID $($TenantName.customerId). Error: $($_.Exception.Message)" -sev Error + $Result.Add($field.Name, "FAILED") + } } if ($Result) { try { - Add-AzDataTableEntity @Table -Entity $Result + Add-AzDataTableEntity @Table -Entity $Result -Force } catch { Write-LogMessage -API "BPA" -tenant $tenant -message "Error getting saving data for $($template.Name) - $($TenantName.customerId). Error: $($_.Exception.Message)" -sev Error diff --git a/ExecAccessChecks/run.ps1 b/ExecAccessChecks/run.ps1 index a07a4f7cfb5b..c97199a1e0b3 100644 --- a/ExecAccessChecks/run.ps1 +++ b/ExecAccessChecks/run.ps1 @@ -126,10 +126,32 @@ if ($Request.query.Tenants -eq 'true') { if (!$Tenants) { $results = 'Could not load the tenants list from cache. Please run permissions check first, or visit the tenants page.' } $results = foreach ($tenant in $Tenants) { try { - $token = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/Organization' -tenantid $tenant + $ExpectedRoles = @( + @{ Name = "Application Administrator"; Id = "9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3" }, + @{ Name = "User Administrator"; Id = "fe930be7-5e62-47db-91af-98c3a49a38b1" }, + @{ Name = "Intune Administrator"; Id = "3a2c62db-5318-420d-8d74-23affee5d9d5" }, + @{ Name = "Exchange Administrator"; Id = "29232cdf-9323-42fd-ade2-1d097af3e4de" }, + @{ Name = "Security Administrator"; Id = "194ae4cb-b126-40b2-bd5b-6091b380977d" }, + @{ Name = "Cloud App Security Administrator"; Id = "158c047a-c907-4556-b7ef-446551a6b5f7" }, + @{ Name = "Cloud Device Administrator"; Id = "7698a772-787b-4ac8-901f-60d6b08affd2" }, + @{ Name = "Teams Administrator"; Id = "69091246-20e8-4a56-aa4d-066075b2a7a8" }, + @{ Name = "Sharepoint Administrator"; Id = "f28a1f50-f6e7-4571-818b-6a12f2af6b6c" }, + @{ Name = "Authentication Policy Administrator"; Id = "0526716b-113d-4c15-b2c8-68e3c22b9f80" }, + @{ Name = "Privileged Role Administrator"; Id = "e8611ab8-c189-46e8-94e1-60213ab1f814" }, + @{ Name = "Privileged Authentication Administrator"; Id = "7be44c8a-adaf-4e2a-84d6-ab2649e08a13" } + ) + $GDAPRoles = foreach ($RoleId in $ExpectedRoles) { + $Role = (New-graphGetRequest -uri "https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$($RoleId.id)'&`$expand=principal" -tenantid $tenant).principal | Where-Object -Property organizationId -EQ $ENV:tenantid + if (!$role) { + "$($RoleId.Name) " + $AddedText = "but potentially missing GDAP roles" + } + } + @{ TenantName = "$($Tenant)" - Status = 'Successfully connected' + Status = "Successfully connected $($AddedText)" + GDAP = $GDAPRoles } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message 'Tenant access check executed successfully' -Sev 'Info' @@ -137,7 +159,8 @@ if ($Request.query.Tenants -eq 'true') { catch { @{ TenantName = "$($tenant)" - Status = "Failed to connect to: $(Get-NormalizedError -message $_.Exception.Message)" + Status = "Failed to connect: $(Get-NormalizedError -message $_.Exception.Message)" + GDAP = '' } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message "Tenant access check failed: $(Get-NormalizedError -message $_) " -Sev 'Error' diff --git a/ListBPA/run.ps1 b/ListBPA/run.ps1 index faf92b9dbf71..af91cc3b4dbc 100644 --- a/ListBPA/run.ps1 +++ b/ListBPA/run.ps1 @@ -23,7 +23,7 @@ $Data = (Get-AzDataTableEntity @Table -Filter "RowKey eq '$NAME'") | ForEach-Obj $row = $_ $JSONFields | ForEach-Object { $jsonContent = $row.$_ - if ($jsonContent -ne $null) { + if ($jsonContent -ne $null -and $jsonContent -ne "FAILED") { $row.$_ = $jsonContent | ConvertFrom-Json -Depth 15 } } From 48a93f4d6b5a9afe1b3c5c7e031207be5630babd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:58:58 +0200 Subject: [PATCH 101/119] added comma for pretification --- ExecAccessChecks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExecAccessChecks/run.ps1 b/ExecAccessChecks/run.ps1 index c97199a1e0b3..2898edb9aa06 100644 --- a/ExecAccessChecks/run.ps1 +++ b/ExecAccessChecks/run.ps1 @@ -143,7 +143,7 @@ if ($Request.query.Tenants -eq 'true') { $GDAPRoles = foreach ($RoleId in $ExpectedRoles) { $Role = (New-graphGetRequest -uri "https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$($RoleId.id)'&`$expand=principal" -tenantid $tenant).principal | Where-Object -Property organizationId -EQ $ENV:tenantid if (!$role) { - "$($RoleId.Name) " + "$($RoleId.Name), " $AddedText = "but potentially missing GDAP roles" } } From 6eb9852b2a9da98835f3ea61c8da83ee944f041f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 14:36:04 +0200 Subject: [PATCH 102/119] fixed guid in access check for tests --- ExecAccessChecks/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExecAccessChecks/run.ps1 b/ExecAccessChecks/run.ps1 index 2898edb9aa06..528bd55758a4 100644 --- a/ExecAccessChecks/run.ps1 +++ b/ExecAccessChecks/run.ps1 @@ -132,7 +132,7 @@ if ($Request.query.Tenants -eq 'true') { @{ Name = "Intune Administrator"; Id = "3a2c62db-5318-420d-8d74-23affee5d9d5" }, @{ Name = "Exchange Administrator"; Id = "29232cdf-9323-42fd-ade2-1d097af3e4de" }, @{ Name = "Security Administrator"; Id = "194ae4cb-b126-40b2-bd5b-6091b380977d" }, - @{ Name = "Cloud App Security Administrator"; Id = "158c047a-c907-4556-b7ef-446551a6b5f7" }, + @{ Name = "Cloud App Security Administrator"; Id = "892c5842-a9a6-463a-8041-72aa08ca3cf6" }, @{ Name = "Cloud Device Administrator"; Id = "7698a772-787b-4ac8-901f-60d6b08affd2" }, @{ Name = "Teams Administrator"; Id = "69091246-20e8-4a56-aa4d-066075b2a7a8" }, @{ Name = "Sharepoint Administrator"; Id = "f28a1f50-f6e7-4571-818b-6a12f2af6b6c" }, From c30c58b59bf7266b2f816a07fd68dd6e7246c468 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 15:48:51 +0200 Subject: [PATCH 103/119] finalizing bpa execution --- BestPracticeAnalyser_All/run.ps1 | 2 +- profile.ps1 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BestPracticeAnalyser_All/run.ps1 b/BestPracticeAnalyser_All/run.ps1 index 053b424d41de..b6071547d46e 100644 --- a/BestPracticeAnalyser_All/run.ps1 +++ b/BestPracticeAnalyser_All/run.ps1 @@ -66,7 +66,7 @@ $AddRow = foreach ($Template in $templates) { $paramsField.Add($_.psobject.properties.name, $_.psobject.properties.value) } } - $FieldInfo = Invoke-Expression -Command $field.Command @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields + $FieldInfo = & $field.Command @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields } } } diff --git a/profile.ps1 b/profile.ps1 index 3970e8e3b97d..f5947f1314cc 100644 --- a/profile.ps1 +++ b/profile.ps1 @@ -12,8 +12,8 @@ # Authenticate with Azure PowerShell using MSI. # Remove this if you are not planning on using MSI or Azure PowerShell. Import-Module .\GraphHelper.psm1 -#Import-Module Az.KeyVault -#Import-Module Az.Accounts +Import-Module Az.KeyVault +Import-Module Az.Accounts Import-Module GraphRequests Import-Module CippExtensions Import-Module CippCore From 042d367395f76a11c514592c7c0918f358578435 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 15:53:54 +0200 Subject: [PATCH 104/119] bug fix --- Standards_ActivityBasedTimeout/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standards_ActivityBasedTimeout/run.ps1 b/Standards_ActivityBasedTimeout/run.ps1 index 849f9c6e7ab7..158fa444936d 100644 --- a/Standards_ActivityBasedTimeout/run.ps1 +++ b/Standards_ActivityBasedTimeout/run.ps1 @@ -1,6 +1,6 @@ param($tenant) try { - $State = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies" -tenantid $tenant) + $State = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies" -tenantid $tenant).id if (!$State) { $body = @" { From 49700fe512a3c49ac0d892133c8e5b91087ce082 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 15 Aug 2023 17:06:51 +0200 Subject: [PATCH 105/119] removed extra space --- BestPracticeAnalyser_All/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BestPracticeAnalyser_All/run.ps1 b/BestPracticeAnalyser_All/run.ps1 index b6071547d46e..986c3511fbdc 100644 --- a/BestPracticeAnalyser_All/run.ps1 +++ b/BestPracticeAnalyser_All/run.ps1 @@ -37,7 +37,7 @@ $AddRow = foreach ($Template in $templates) { $paramsField.Add($_.psobject.properties.name, $_.psobject.properties.value) } } - $FieldInfo = New-GraphGetRequest @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields + $FieldInfo = New-GraphGetRequest @paramsField | Where-Object $filterscript | Select-Object $field.ExtractFields } "Exchange" { if ($field.Command -notlike "get-*") { From 76db9ac65bfd3a86ef4ed29254c999844785705f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 01:23:57 +0200 Subject: [PATCH 106/119] prep for release --- BestPracticeAnalyser_All/run.ps1 | 2 +- ListBPA/run.ps1 | 47 ++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/BestPracticeAnalyser_All/run.ps1 b/BestPracticeAnalyser_All/run.ps1 index 986c3511fbdc..9185c07e02d6 100644 --- a/BestPracticeAnalyser_All/run.ps1 +++ b/BestPracticeAnalyser_All/run.ps1 @@ -22,7 +22,7 @@ $AddRow = foreach ($Template in $templates) { LastRefresh = [string]$(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z') } foreach ($field in $Template.Data.Fields) { - + if ($field.UseExistingInfo) { continue } if ($Field.Where) { $filterscript = [scriptblock]::Create($Field.Where) } else { $filterscript = { $true } } try { switch ($field.API) { diff --git a/ListBPA/run.ps1 b/ListBPA/run.ps1 index af91cc3b4dbc..cd6b5b450bb0 100644 --- a/ListBPA/run.ps1 +++ b/ListBPA/run.ps1 @@ -12,35 +12,54 @@ if ($name -eq $null) { $name = "CIPP Best Practices v1.0 - Table view" } # Get all possible JSON files for reports, find the correct one, select the Columns $JSONFields = @() +$Columns = $null (Get-ChildItem -Path "Config\*.BPATemplate.json" -Recurse | Select-Object -ExpandProperty FullName | ForEach-Object { $Template = $(Get-Content $_) | ConvertFrom-Json if ($Template.Name -eq $NAME) { $JSONFields = $Template.Fields | Where-Object { $_.StoreAs -eq 'JSON' } | ForEach-Object { $_.name } + $Columns = $Template.fields.FrontendFields | Where-Object -Property name -NE $null + $Style = $Template.Style } }) -$Data = (Get-AzDataTableEntity @Table -Filter "RowKey eq '$NAME'") | ForEach-Object { - $row = $_ - $JSONFields | ForEach-Object { - $jsonContent = $row.$_ - if ($jsonContent -ne $null -and $jsonContent -ne "FAILED") { - $row.$_ = $jsonContent | ConvertFrom-Json -Depth 15 + +if ($Request.query.tenantFilter -ne "AllTenants" -and $Style -eq "Tenant") { + $mergedObject = New-Object pscustomobject + + $Data = (Get-AzDataTableEntity @Table -Filter "PartitionKey eq '$($Request.query.tenantFilter)'") | ForEach-Object { + $row = $_ + $JSONFields | ForEach-Object { + $jsonContent = $row.$_ + if ($jsonContent -ne $null -and $jsonContent -ne "FAILED") { + $row.$_ = $jsonContent | ConvertFrom-Json -Depth 15 + } + } + $row.PSObject.Properties | ForEach-Object { + $mergedObject | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force } } - $row -} -$Columns = $null -(Get-ChildItem -Path "Config\*.BPATemplate.json" -Recurse | Select-Object -ExpandProperty FullName | ForEach-Object { - $Template = $(Get-Content $_) | ConvertFrom-Json - if ($Template.Name -eq $NAME) { - $Columns = $Template.fields.FrontendFields | Where-Object -Property name -NE $null + $Data = $mergedObject +} +else { + $Data = (Get-AzDataTableEntity @Table -Filter "RowKey eq '$NAME'") | ForEach-Object { + $row = $_ + $JSONFields | ForEach-Object { + $jsonContent = $row.$_ + if ($jsonContent -ne $null -and $jsonContent -ne "FAILED") { + $row.$_ = $jsonContent | ConvertFrom-Json -Depth 15 + } + } + $row } -}) + + +} $Results = [PSCustomObject]@{ Data = $Data Columns = $Columns + Style = $Style } if (!$Results) { From b76f2a4273cf18f321f1f64d865e3f1a883f76f3 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 01:52:18 +0200 Subject: [PATCH 107/119] BPA Templates --- Config/CIPPDefaultTable.BPATemplate.json | 192 ++++++++++++++++++ Config/CIPPDefaultTenantPage.BPATemplate.json | 155 ++++++++++++++ Config/SharePoint.BPATemplate.json | 70 +++++++ 3 files changed, 417 insertions(+) create mode 100644 Config/CIPPDefaultTable.BPATemplate.json create mode 100644 Config/CIPPDefaultTenantPage.BPATemplate.json create mode 100644 Config/SharePoint.BPATemplate.json diff --git a/Config/CIPPDefaultTable.BPATemplate.json b/Config/CIPPDefaultTable.BPATemplate.json new file mode 100644 index 000000000000..bb2d6667b15d --- /dev/null +++ b/Config/CIPPDefaultTable.BPATemplate.json @@ -0,0 +1,192 @@ +{ + "name": "CIPP Best Practices v1.0 - Table view", + "style": "Table", + "Fields": [ + { + "name": "PasswordNeverExpires", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/domains", + "ExtractFields": "passwordValidityPeriodInDays", + "where": "$_.passwordValidityPeriodInDays -eq 2147483647", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Password Never Expires", + "value": "PasswordNeverExpires", + "formatter": "bool" + } + ] + }, + { + "name": "OAuthAppConsent", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy", + "ExtractFields": "permissionGrantPolicyIdsAssignedToDefaultUserRole", + "where": "'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' -notin $_.permissionGrantPolicyIdsAssignedToDefaultUserRole", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "OAuth App Consent", + "value": "OAuthAppConsent", + "formatter": "bool" + } + ] + }, + { + "name": "UnifiedAuditLog", + "API": "Exchange", + "Command": "Get-AdminAuditLogConfig", + "ExtractFields": "UnifiedAuditLogIngestionEnabled", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Unified Audit Log", + "value": "UnifiedAuditLog", + "formatter": "bool" + } + ] + }, + { + "name": "MFANudgeState", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy", + "ExtractFields": ["registrationEnforcement"], + "StoreAs": "bool", + "where": "$_.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'Enabled'", + "FrontendFields": [ + { + "name": "MFA Registration Campaign Enabled", + "value": "MFANudgeState", + "formatter": "bool" + } + ] + }, + { + "name": "TAPEnabled", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass", + "ExtractFields": "State", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Temporary Access Pass Enabled", + "value": "TAPEnabled", + "formatter": "bool" + } + ] + }, + { + "name": "SecureDefaultState", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy", + "ExtractFields": "IsEnabled", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Secure Defaults State Enabled", + "value": "SecureDefaultState", + "formatter": "warnBool" + } + ] + }, + { + "name": "AnonymousPrivacyReports", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/admin/reportSettings", + "ExtractFields": "displayConcealedNames", + "StoreAs": "bool", + "where": "$_.displayConcealedNames -eq $false", + "FrontendFields": [ + { + "name": "Anonymous Privacy Reports", + "value": "AnonymousPrivacyReports", + "formatter": "reverseBool" + } + ] + }, + { + "name": "MessageCopyforSentAsDisabled", + "API": "Exchange", + "Command": "Get-Mailbox", + "Parameters": { + "RecipientTypeDetails": "SharedMailbox" + }, + "where": "$_.MessageCopyForSentAsEnabled -eq $false", + "ExtractFields": ["userprincipalname", "messageCopyForSentAsEnabled"], + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Message Copy for Sent-As Disabled", + "formatter": "table", + "value": "MessageCopyforSentAsDisabled" + } + ] + }, + { + "name": "SharedMailboxeswithenabledusers", + "API": "Exchange", + "Command": "Get-Mailbox", + "Parameters": { + "RecipientTypeDetails": "SharedMailbox" + }, + "where": "$_.accountDisabled -eq $false", + "ExtractFields": ["userprincipalname", "accountDisabled"], + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Shared Mailboxes with enabled users", + "formatter": "table", + "value": "SharedMailboxeswithenabledusers" + } + ] + }, + { + "name": "Unusedlicenses", + "API": "CIPPFunction", + "Command": "Get-CIPPLicenseOverview", + "ExtractFields": [ + "License", + "TotalLicenses", + "availableUnits", + "CountUsed" + ], + "StoreAs": "JSON", + "where": "$_.availableUnits -gt 0", + "FrontendFields": [ + { + "name": "Unused licenses", + "formatter": "table", + "value": "Unusedlicenses" + } + ] + }, + { + "name": "CurrentSecureScore", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/security/secureScores?$top=1", + "Parameters": { + "Nopagination": true + }, + "ExtractFields": ["currentScore", "maxScore", "averageComparativeScores"], + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Current Secure Score", + "value": "CurrentSecureScore.currentScore" + }, + { + "name": "Max Secure Score", + "value": "CurrentSecureScore.maxScore" + }, + { + "name": "Average Comparative Score (All Tenants)", + "value": "CurrentSecureScore.averageComparativeScores[0].averageScore" + }, + { + "name": "Average Comparative Score (Similiar Size Tenants)", + "value": "CurrentSecureScore.averageComparativeScores[1].averageScore" + } + ] + } + ] +} diff --git a/Config/CIPPDefaultTenantPage.BPATemplate.json b/Config/CIPPDefaultTenantPage.BPATemplate.json new file mode 100644 index 000000000000..aa4b828e4ff8 --- /dev/null +++ b/Config/CIPPDefaultTenantPage.BPATemplate.json @@ -0,0 +1,155 @@ +{ + "name": "CIPP Best Practices v1.0 - Tenant view", + "style": "Tenant", + "Fields": [ + { + "name": "PasswordNeverExpires", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Password Never Expires", + "value": "PasswordNeverExpires", + "formatter": "bool", + "desc": "This setting shows if your environment has enabled the password never expires setting. This setting is expected to be set to 'No'" + } + ] + }, + { + "name": "OAuthAppConsent", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "OAuth App Consent", + "value": "OAuthAppConsent", + "formatter": "bool", + "desc": "This setting shows if your environment has enabled OAuth App Consent. This setting is expected to be set to 'Yes'" + } + ] + }, + { + "name": "UnifiedAuditLog", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Unified Audit Log", + "value": "UnifiedAuditLog", + "formatter": "bool", + "desc": "This setting shows if your environment has enabled the unified audit log. This setting is expected to be set to 'Yes'" + } + ] + }, + { + "name": "MFANudgeState", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "MFA Registration Campaign Enabled", + "value": "MFANudgeState", + "formatter": "bool", + "desc": "This setting shows if your environment has enabled the MFA registration campaign, also known as the MFA Nudge. This setting is recommended to be set to 'Yes'" + } + ] + }, + { + "name": "TAPEnabled", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Temporary Access Pass Enabled", + "value": "TAPEnabled", + "formatter": "bool", + "desc": "This setting shows if your environment has enabled the temporary access pass feature." + } + ] + }, + { + "name": "SecureDefaultState", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Secure Defaults State Enabled", + "value": "SecureDefaultState", + "formatter": "warnBool", + "desc": "This setting shows if your environment has enabled the secure defaults state. If you are using Conditional Access this setting may be set to `No`" + } + ] + }, + { + "name": "AnonymousPrivacyReports", + "UseExistingInfo": "true", + "StoreAs": "bool", + "FrontendFields": [ + { + "name": "Anonymous Privacy Reports", + "value": "AnonymousPrivacyReports", + "formatter": "reverseBool", + "desc": "This setting shows if your environment has enabled the anonymous privacy reports, these will need to be disabled to be able to view mailboxes and onedrive reports" + } + ] + }, + { + "name": "MessageCopyforSentAsDisabled", + "UseExistingInfo": "true", + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Message Copy for Sent-As Disabled", + "formatter": "table", + "value": "MessageCopyforSentAsDisabled", + "desc": "These are the mailboxes that have the MessageCopyForSentAsDisabled setting enabled." + } + ] + }, + { + "name": "SharedMailboxeswithenabledusers", + "UseExistingInfo": "true", + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Shared Mailboxes with enabled users", + "formatter": "table", + "value": "SharedMailboxeswithenabledusers", + "desc": "These are the shared mailboxes that have enabled users." + } + ] + }, + { + "name": "Unusedlicenses", + "UseExistingInfo": "true", + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Unused licenses", + "formatter": "table", + "value": "Unusedlicenses", + "desc": "These are the licenses that are not assigned to an user, but have been purchased." + } + ] + }, + { + "name": "CurrentSecureScore", + "UseExistingInfo": "true", + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Current Secure Score", + "value": "CurrentSecureScore.currentScore", + "desc": "The current Secure Score for this tenant. This is the sum of all the individual controls that have been implemented.", + "formatter": "number" + }, + { + "name": "Max Secure Score", + "value": "CurrentSecureScore.maxScore", + "desc": "The maximum Secure Score for this tenant. This is the sum of all the individual controls that can be implemented.", + "formatter": "number" + } + ] + } + ] +} diff --git a/Config/SharePoint.BPATemplate.json b/Config/SharePoint.BPATemplate.json new file mode 100644 index 000000000000..99ba97e5caa7 --- /dev/null +++ b/Config/SharePoint.BPATemplate.json @@ -0,0 +1,70 @@ +{ + "name": "CIPP SharePoint Report v1.0 - Table view", + "style": "Table", + "Fields": [ + { + "name": "SharepointSettings", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/admin/sharepoint/settings", + "Parameters": { + "asApp": "True" + }, + "ExtractFields": [ + "sharingCapability", + "isMacSyncAppEnabled", + "isResharingByExternalUsersEnabled", + "isUnmanagedSyncAppForTenantRestricted", + "isSiteCreationEnabled", + "deletedUserPersonalSiteRetentionPeriodInDays" + ], + "StoreAs": "JSON", + "FrontendFields": [ + { + "name": "Sharing capability", + "value": "SharepointSettings.sharingCapability", + "formatter": "string" + }, + { + "name": "Mac Sync Enabled", + "value": "SharepointSettings.isMacSyncAppEnabled", + "formatter": "warnBool" + }, + { + "name": "Resharing by external users", + "value": "isResharingByExternalUsersEnabled", + "formatter": "reverseBool" + }, + { + "name": "Allow users to sync from unmanaged devices", + "value": "SharepointSettings.isUnmanagedSyncAppForTenantRestricted", + "formatter": "bool" + }, + { + "name": "Site creation by standards users enabled", + "value": "SharepointSettings.isSiteCreationEnabled", + "formatter": "reverseBool" + }, + { + "name": "Deleted user data rention(days)", + "value": "SharepointSettings.deletedUserPersonalSiteRetentionPeriodInDays", + "formatter": "string" + } + ] + }, + { + "name": "WebtimeOut", + "API": "Graph", + "URL": "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies", + "ExtractFields": ["definition"], + "StoreAs": "bool", + "where": "$_.definition -like '*WebSessionIdleTimeout*'", + "FrontendFields": [ + { + "name": "Web Time-Out enabled", + "value": "WebtimeOut", + "formatter": "bool" + } + ] + } + ] +} From 5b571219dfcf7bd576ddfd27630d3f6fb3e21c12 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 01:53:14 +0200 Subject: [PATCH 108/119] upped versions --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index 00e897bdaeb8..0c89fc927e32 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -3.8.2 \ No newline at end of file +4.0.0 \ No newline at end of file From d65a9828a87e051a8aa9cd6312232a4d69c696e4 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 10:32:38 +0200 Subject: [PATCH 109/119] #1688 --- AddCAPolicy/run.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AddCAPolicy/run.ps1 b/AddCAPolicy/run.ps1 index c87a3cf54e52..0e9785487833 100644 --- a/AddCAPolicy/run.ps1 +++ b/AddCAPolicy/run.ps1 @@ -42,6 +42,9 @@ if ($JSONObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.Membe $JsonObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.PSObject.Properties.Remove('@odata.context') $JsonObj.conditions.users.excludeGuestsOrExternalUsers.externalTenants.PSObject.Properties.Remove('@odata.type') } +if ($Request.body.newstate -and $Request.body.newstate -ne 'donotchange') { + $Jsonobj.state = $Request.body.newstate +} $RawJSON = $JSONObj | ConvertTo-Json -Depth 10 $results = foreach ($Tenant in $tenants) { From 86210c60c6e7c413eb1348b78036b31f91e45e17 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 10:40:51 +0200 Subject: [PATCH 110/119] add low risk default --- Standards_OauthConsentLowSec/function.json | 9 +++++++++ Standards_OauthConsentLowSec/run.ps1 | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 Standards_OauthConsentLowSec/function.json create mode 100644 Standards_OauthConsentLowSec/run.ps1 diff --git a/Standards_OauthConsentLowSec/function.json b/Standards_OauthConsentLowSec/function.json new file mode 100644 index 000000000000..ce713ef7d4f6 --- /dev/null +++ b/Standards_OauthConsentLowSec/function.json @@ -0,0 +1,9 @@ +{ + "bindings": [ + { + "name": "tenant", + "type": "activityTrigger", + "direction": "in" + } + ] +} \ No newline at end of file diff --git a/Standards_OauthConsentLowSec/run.ps1 b/Standards_OauthConsentLowSec/run.ps1 new file mode 100644 index 000000000000..9e4278f153fd --- /dev/null +++ b/Standards_OauthConsentLowSec/run.ps1 @@ -0,0 +1,13 @@ +param($tenant) + +try { + $State = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy" -tenantid $tenant) + if ($State.permissionGrantPolicyIdsAssignedToDefaultUserRole -notin @("managePermissionGrantsForSelf.microsoft-user-default-low")) { + Write-Host "Going to set" + New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy" -Type PATCH -Body '{"permissionGrantPolicyIdsAssignedToDefaultUserRole":["managePermissionGrantsForSelf.microsoft-user-default-low"]}' -ContentType "application/json" + } + Write-LogMessage -API "Standards" -tenant $tenant -message "Application Consent Mode(microsoft-user-default-low) has been enabled." -sev Info +} +catch { + Write-LogMessage -API "Standards" -tenant $tenant -message "Failed to apply Application Consent Mode (microsoft-user-default-low) Error: $($_.exception.message)" -sev Error +} \ No newline at end of file From bf1a44356c1f7abefabe62887da6992c036536dd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 11:03:21 +0200 Subject: [PATCH 111/119] exclude some logon processing --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 08dd1839040b..a7245c6a7536 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -21,7 +21,7 @@ function Invoke-CippWebhookProcessing { #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)'" | Select-Object -Last 1 #If we have a location, we use that. If not, we perform a lookup in the GeoIP database. - if ($Location) { + if ($Location -and $location.CountryOrRegion -ne "Unknown") { $Country = $Location.CountryOrRegion $City = $Location.City } @@ -35,7 +35,16 @@ function Invoke-CippWebhookProcessing { if ($Data.ExtendedProperties) { $Data.ExtendedProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.DeviceProperties) { $Data.DeviceProperties | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } if ($Data.parameters) { $Data.parameters | ForEach-Object { $TableObj | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value } } - Write-Host ($TableObj | ConvertTo-Json -Depth 10) + + $ExtendedPropertiesIgnoreList = @( + "OAuth2:Authorize" + "SAS:EndAuth" + "SAS:ProcessAuth" + ) + if ($TableObj.RequestType -in $ExtendedPropertiesIgnoreList) { + Write-Host "No need to process this operation." + return "" + } switch ($data.operation) { { "UserLoggedIn" -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "UserLoggedInFromUnknownLocation" } { "UserloggedIn" -eq $data.operation -and $data.UserType -eq 2 -and $data.ResultStatus -eq "Success" -and $TableObj.ResultStatusDetail -eq "Success" } { $data.operation = "AdminLoggedIn" } From c5733db53aa2017d37a312ba920f7be992eb918f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 11:19:58 +0200 Subject: [PATCH 112/119] Added bulk requests. --- ExecAccessChecks/run.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ExecAccessChecks/run.ps1 b/ExecAccessChecks/run.ps1 index 528bd55758a4..216027ff5a56 100644 --- a/ExecAccessChecks/run.ps1 +++ b/ExecAccessChecks/run.ps1 @@ -140,8 +140,18 @@ if ($Request.query.Tenants -eq 'true') { @{ Name = "Privileged Role Administrator"; Id = "e8611ab8-c189-46e8-94e1-60213ab1f814" }, @{ Name = "Privileged Authentication Administrator"; Id = "7be44c8a-adaf-4e2a-84d6-ab2649e08a13" } ) + $BulkRequests = $ExpectedRoles | ForEach-Object { @( + @{ + id = "roleManagement_$($_.id)" + method = 'GET' + url = "roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$($_.id)'&`$expand=principal" + } + ) + } + $GDAPRolesGraph = New-GraphBulkRequest -tenantid $tenant -Requests $BulkRequests $GDAPRoles = foreach ($RoleId in $ExpectedRoles) { - $Role = (New-graphGetRequest -uri "https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$($RoleId.id)'&`$expand=principal" -tenantid $tenant).principal | Where-Object -Property organizationId -EQ $ENV:tenantid + $GraphRole = $GDAPRolesGraph.body.value | Where-Object -Property roleDefinitionId -EQ $RoleId.Id + $Role = $GraphRole.principal | Where-Object -Property organizationId -EQ $ENV:tenantid if (!$role) { "$($RoleId.Name), " $AddedText = "but potentially missing GDAP roles" From c379636e65112c97e23efb2ee3f08a0720c927ed Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:59:46 +0200 Subject: [PATCH 113/119] fixed some links --- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index a7245c6a7536..aa24b5c4ae8f 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -82,7 +82,7 @@ function Invoke-CippWebhookProcessing { $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $ParameterName $IntroText = "

A new rule has been created for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" - $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationName)" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationId)" $ButtonText = "Start BEC Investigation" $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" } @@ -91,7 +91,7 @@ function Invoke-CippWebhookProcessing { $RuleTable = ($TableObj | ConvertTo-Html -Fragment | Out-String).Replace('
', '
') $ParameterName $IntroText = "

A rule has been edited for the user $($data.UserId). You should check if this rule is not malicious. The rule information can be found in the table below.

$RuleTable" - $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationName)" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserId)&tenantDomain=$($data.OrganizationId)" $ButtonText = "Start BEC Investigation" $AfterButtonText = "

If you believe this is a suspect rule, you can click the button above to start the investigation.

" } @@ -155,7 +155,7 @@ function Invoke-CippWebhookProcessing { if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - an admin account has logged on" $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). See the table below for more information. $Table" - $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.UserKey)&tenantDomain=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" @@ -165,7 +165,7 @@ function Invoke-CippWebhookProcessing { if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } $Title = "$($TenantFilter) - a user has logged on from a potentially unsafe location" $IntroText = "$($data.UserId) ($($data.Userkey)) has logged on from IP $($data.ClientIP) to the application $($Appname). According to our database this is located in $($Country) - $($City).

You have set up alerts to be notified when this happens. See the table below for more info.$Table" - $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationName)" + $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationId)" $ButtonText = "User Management" $AfterButtonText = "

If this is incorrect, use the user management screen to block the user and revoke the sessions

" } From eec6a77dd06698e93b1bb48e4691a1cb2cdffd9f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:21:55 +0200 Subject: [PATCH 114/119] added some debugging --- .../CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index aa24b5c4ae8f..3489143ae40d 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -10,10 +10,9 @@ function Invoke-CippWebhookProcessing { $APIName = "Process webhook", $ExecutingUser ) - Set-Location (Get-Item $PSScriptRoot).FullName $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' - $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String + $AllowedLocations = $AllowedLocations -split ',' if ($data.userId -eq "Not Available") { $data.userId = $data.userKey } if ($data.Userkey -eq "Not Available") { $data.Userkey = $data.userId } @@ -21,11 +20,13 @@ function Invoke-CippWebhookProcessing { #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)'" | Select-Object -Last 1 #If we have a location, we use that. If not, we perform a lookup in the GeoIP database. - if ($Location -and $location.CountryOrRegion -ne "Unknown") { + if ($Location) { + Write-Host "Using known location" $Country = $Location.CountryOrRegion $City = $Location.City } else { + Write-Host "We have to do a lookup" $Location = Get-CIPPGeoIPLocation -IP $data.clientip $Country = if ($Location.countryCode) { $Location.CountryCode } else { "Unknown" } $City = if ($Location.cityName) { $Location.cityName } else { "Unknown" } @@ -73,9 +74,9 @@ function Invoke-CippWebhookProcessing { return "" } - + Set-Location (Get-Item $PSScriptRoot).FullName $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId - + $HTML = Get-Content "TemplateEmail.HTML" -Raw | Out-String switch ($data.Operation) { "New-InboxRule" { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" From c3d6eba0f7da89b27b521e4f39fab6afae1116f4 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:26:11 +0200 Subject: [PATCH 115/119] removed logo as it made email in outlook ugly --- Modules/CIPPCore/Public/TemplateEmail.html | 94 ---------------------- 1 file changed, 94 deletions(-) diff --git a/Modules/CIPPCore/Public/TemplateEmail.html b/Modules/CIPPCore/Public/TemplateEmail.html index 63e587b904d3..f94a467298f0 100644 --- a/Modules/CIPPCore/Public/TemplateEmail.html +++ b/Modules/CIPPCore/Public/TemplateEmail.html @@ -240,100 +240,6 @@ style="margin: 0px auto; border-radius: 20px 20px 0 0; max-width: 800px" >
-
- - - - - -
- -
- - - - - - - - - -
- -
 
- -
-
- -