From 6950f3ab3353c615aa0aadd466274288d21426c2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 14:58:35 +0100 Subject: [PATCH 01/39] upped line --- PublicWebhooksProcess/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index 69e153f60e01..132349f58dbe 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -68,7 +68,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { } } } catch { - Write-Host "Webhook Failed: $($_.Exception.Message)" + Write-Host "Webhook Failed: $($_.Exception.Message). Line number $($_.InvocationInfo.ScriptLineNumber)" } } From 229a8cab1458fbe4991e505f2e4ab2fc57536b46 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:06:22 +0100 Subject: [PATCH 02/39] minor update --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 1eaeeda79a70..0ae95bc08540 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -3,7 +3,6 @@ function New-CIPPAlertTemplate { [Parameter(Mandatory = $true)] $Data, [Parameter(Mandatory = $true)] - [ValidateSet('html', 'json')] $Format, $LocationInfo, $ActionResults From dbe6d8866d56324745f17fc72b53daed3947ac49 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:10:53 +0100 Subject: [PATCH 03/39] processing update --- 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 9e05e5f92bb5..acd4fe90c7ef 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -192,9 +192,11 @@ function Invoke-CippWebhookProcessing { } } } + Write-Host 'Going to create the content' foreach ($action in $dos) { switch ($action.execute) { 'generatemail' { + Write-Host 'Going to create the email' $GenerateEmail = New-CIPPAlertTemplate -format 'html' -data $Data -LocationInfo $Location -ActionResults $ActionResults Send-CIPPAlert -Type 'email' -Title $GenerateEmail.title -HTMLContent $GenerateEmail.htmlcontent -TenantFilter $TenantFilter } From 17b9e7ab8da368903dcddf493a56a2de66c8af3f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:15:20 +0100 Subject: [PATCH 04/39] fixes email open bug --- 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 acd4fe90c7ef..b4c1fe4fec39 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -198,7 +198,10 @@ function Invoke-CippWebhookProcessing { 'generatemail' { Write-Host 'Going to create the email' $GenerateEmail = New-CIPPAlertTemplate -format 'html' -data $Data -LocationInfo $Location -ActionResults $ActionResults + Write-Host 'Going to send the mail' Send-CIPPAlert -Type 'email' -Title $GenerateEmail.title -HTMLContent $GenerateEmail.htmlcontent -TenantFilter $TenantFilter + Write-Host 'email should be sent' + } 'generatePSA' { $GenerateEmail = New-CIPPAlertTemplate -format 'html'-data $Data -LocationInfo $Location -ActionResults $ActionResults From d8cbc4576fd2e3d393beb23a15bd34f61efb5a0c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:16:04 +0100 Subject: [PATCH 05/39] set location --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 0ae95bc08540..912eb25a271a 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -7,7 +7,7 @@ function New-CIPPAlertTemplate { $LocationInfo, $ActionResults ) - + 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 $HTMLTemplate = Get-Content 'TemplateEmail.HTML' -Raw | Out-String $Title = '' From c3e983da6c94bae3501e5cbc1718c08139265a74 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:22:16 +0100 Subject: [PATCH 06/39] pathing issues --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 1 - PublicWebhooks/run.ps1 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 912eb25a271a..9d0d9f70c1cb 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -7,7 +7,6 @@ function New-CIPPAlertTemplate { $LocationInfo, $ActionResults ) - 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 $HTMLTemplate = Get-Content 'TemplateEmail.HTML' -Raw | Out-String $Title = '' diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index 124f05bd761a..2a44861c59c9 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -3,7 +3,7 @@ using namespace System.Net # Input bindings are passed in via param block. param($Request, $TriggerMetadata) - +Set-Location (Get-Item $PSScriptRoot).Parent.FullName $WebhookTable = Get-CIPPTable -TableName webhookTable $Webhooks = Get-CIPPAzDataTableEntity @WebhookTable Write-Host 'Received request' From d6ba6618ee94c82ecd8feb3667e45250ffdf9eef Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 12 Jan 2024 15:26:49 +0100 Subject: [PATCH 07/39] corrected typo or email generation --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 9d0d9f70c1cb..e44402d121a4 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -16,7 +16,7 @@ function New-CIPPAlertTemplate { $AfterButtonText = '' $RuleTable = '' $Table = '' - $LocationInfo = $LocationInfo | Select-Object *, -excludeproperty Etag, PartitionKey, RowKey, TimeStamp + $LocationInfo = $LocationInfo | Select-Object * -ExcludeProperty Etag, PartitionKey, RowKey, TimeStamp switch ($Data.Operation) { 'New-InboxRule' { $Title = "$($TenantFilter) - New Rule Detected for $($data.UserId)" From dca8f3d6105182b260fb44cd7d891af453c4adbf Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 12 Jan 2024 10:25:42 -0500 Subject: [PATCH 08/39] fix group check --- .../Push-ExecOnboardTenantQueue.ps1 | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-ExecOnboardTenantQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-ExecOnboardTenantQueue.ps1 index 1ed88b340cc4..6c12ad723332 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-ExecOnboardTenantQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-ExecOnboardTenantQueue.ps1 @@ -224,35 +224,32 @@ Function Push-ExecOnboardTenantQueue { if ($AccessAssignments.status -notcontains 'pending') { $OnboardingSteps.Step3.Message = 'Group check: Access assignments are mapped and active' $OnboardingSteps.Step3.Status = 'succeeded' + if ($QueueItem.AddMissingGroups -eq $true) { + $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = 'Checking for missing groups for SAM user' }) + $SamUserId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me?`$select=id").id + $CurrentMemberships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me/transitiveMemberOf?`$select=id,displayName" + foreach ($Role in $QueueItem.Roles) { + if ($CurrentMemberships.id -notcontains $Role.GroupId) { + $PostBody = @{ + '@odata.id' = 'https://graph.microsoft.com/v1.0/directoryObjects/{0}' -f $SamUserId + } | ConvertTo-Json -Compress + try { + New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($Role.GroupId)/members/`$ref" -body $PostBody -AsApp $true -NoAuthCheck $true + $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = "Added SAM user to $($Role.GroupName)" }) + } catch { + $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = "Failed to add SAM user to $($Role.GroupName) - $($_.Exception.Message)" }) + } + } + } + $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = 'SAM user group check completed' }) + } } else { $OnboardingSteps.Step3.Message = 'Group check: Access assignments are still pending, try again later' $OnboardingSteps.Step3.Status = 'failed' $TenantOnboarding.Status = 'failed' - $TenantOnboarding.OnboardingSteps = [string](ConvertTo-Json -InputObject $OnboardingSteps -Compress) - $TenantOnboarding.Logs = [string](ConvertTo-Json -InputObject @($Logs) -Compress) - Add-CIPPAzDataTableEntity @OnboardTable -Entity $TenantOnboarding -Force -ErrorAction Stop - return - } - } - if ($QueueItem.AddMissingGroups -eq $true) { - $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = 'Checking for missing groups for SAM user' }) - $SamUserId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me?`$select=id").id - $CurrentMemberships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me/transitiveMemberOf?`$select=id,displayName" - foreach ($Role in $QueueItem.Roles) { - if ($CurrentMemberships.id -notcontains $Role.GroupId) { - $PostBody = @{ - '@odata.id' = 'https://graph.microsoft.com/v1.0/directoryObjects/{0}' -f $SamUserId - } | ConvertTo-Json -Compress - try { - New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($Role.GroupId)/members/`$ref" -body $PostBody -AsApp $true -NoAuthCheck $true - $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = "Added SAM user to $($Role.GroupName)" }) - } catch { - $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = "Failed to add SAM user to $($Role.GroupName) - $($_.Exception.Message)" }) - } - } } - $Logs.Add([PSCustomObject]@{ Date = Get-Date -UFormat $DateFormat; Log = 'SAM user group check completed' }) } + $TenantOnboarding.OnboardingSteps = [string](ConvertTo-Json -InputObject $OnboardingSteps -Compress) $TenantOnboarding.Logs = [string](ConvertTo-Json -InputObject @($Logs) -Compress) Add-CIPPAzDataTableEntity @OnboardTable -Entity $TenantOnboarding -Force -ErrorAction Stop From 2a0f2e479cce4bdbae93246641e41707a7ff7b6c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 13:58:21 +0100 Subject: [PATCH 09/39] add error code when fails instaed ofcrash --- Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1 index 695fb64ffa29..6d2d1d1106ef 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1 @@ -142,6 +142,7 @@ Function Invoke-ListDomainHealth { } catch { Write-LogMessage -API $APINAME -tenant $($name) -user $request.headers.'x-ms-client-principal' -message "DNS Helper API failed. $($_.Exception.Message)" -Sev 'Error' $body = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + $StatusCode = [HttpStatusCode]::InternalServerError } # Associate values to output bindings by calling 'Push-OutputBinding'. From e973e07f96e0fa3bc7e5bdae44901f9dffddecca Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 14:49:07 +0100 Subject: [PATCH 10/39] update geo location lookup --- .../Entrypoints/Invoke-ExecGeoIPLookup.ps1 | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGeoIPLookup.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGeoIPLookup.ps1 index ebd5cab52f88..3410320f99a8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGeoIPLookup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGeoIPLookup.ps1 @@ -1,6 +1,6 @@ - using namespace System.Net +using namespace System.Net - Function Invoke-ExecGeoIPLookup { +Function Invoke-ExecGeoIPLookup { <# .FUNCTIONALITY Entrypoint @@ -8,24 +8,16 @@ [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' -Write-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.'$' -} + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + Write-Host $Request.Query.IP + $locationInfo = 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 = $LocationInfo - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $LocationInfo + }) - } +} From df971419a7a527b69f4019416d8cc10f382aa89b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 17:18:46 +0100 Subject: [PATCH 11/39] add function to exclude/include users in CA policy --- .../CIPPCore/Public/Set-CIPPCAExclusion.ps1 | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 diff --git a/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 b/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 new file mode 100644 index 000000000000..e784b5f17918 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 @@ -0,0 +1,39 @@ +function Set-CIPPCAExclusion { + [CmdletBinding()] + param( + $TenantFilter, + $ExclusionType, + $UserID, + $PolicyId, + $executingUser + ) + try { + $CheckExististing = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($PolicyId)" -tenantid $TenantFilter + if ($ExclusionType -eq 'add') { + $NewExclusions = [pscustomobject]@{ + conditions = [pscustomobject]@{ users = [pscustomobject]@{ + excludeUsers = @($CheckExististing.conditions.users.excludeUsers + $UserID) + } + } + } + $RawJson = ConvertTo-Json -Depth 10 -InputObject $NewExclusions + New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($CheckExististing.id)" -tenantid $tenantfilter -type PATCH -body $RawJSON + + } + + if ($ExclusionType -eq 'remove') { + $NewExclusions = [pscustomobject]@{ + conditions = [pscustomobject]@{ users = [pscustomobject]@{ + excludeUsers = @($CheckExististing.conditions.users.excludeUsers | Where-Object { $_ -ne $UserID }) + } + } + } + $RawJson = ConvertTo-Json -Depth 10 -InputObject $NewExclusions + New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($CheckExististing.id)" -tenantid $tenantfilter -type PATCH -body $RawJSON + } + + Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Successfully performed $($ExclusionType) user from policy $($PolicyId)" -Sev 'Info' -tenant $TenantFilter + } catch { + Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Failed to $($ExclusionType) user from policy $($PolicyId): $_" -Sev 'Error' -tenant $TenantFilter + } +} \ No newline at end of file From 1f2f02f77c0f76e0d5cf477c0bc7ab47ea00de14 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 19:51:23 +0100 Subject: [PATCH 12/39] add vacation mode CA policies --- .../Entrypoints/Invoke-ExecCAExclusion.ps1 | 51 ++++++++++++++++ Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 | 58 ++++++++----------- .../CIPPCore/Public/Set-CIPPCAExclusion.ps1 | 8 ++- 3 files changed, 80 insertions(+), 37 deletions(-) create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 new file mode 100644 index 000000000000..5195ef9dbe41 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 @@ -0,0 +1,51 @@ +using namespace System.Net + +Function Invoke-ExecCAExclusion { + <# + .FUNCTIONALITY + Entrypoint + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + #If UserId is a guid, get the user's UPN + if ($Request.body.UserId -match '^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$') { + $Username = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($Request.body.UserId)" -tenantid $Request.body.TenantFilter).userPrincipalName + } + if ($Request.body.vacation -eq 'true') { + $StartDate = $Request.body.StartDate + $TaskBody = @{ + TenantFilter = $Request.body.TenantFilter + Name = "Add CA Exclusion Vacation Mode: $Username - $($Request.body.TenantFilter)" + Command = @{ + value = 'Set-CIPPCAExclusion' + label = 'Set-CIPPCAExclusion' + } + Parameters = @{ + ExclusionType = 'Add' + UserID = $Request.body.UserID + PolicyId = $Request.body.PolicyId + UserName = $Username + } + ScheduledTime = $StartDate + } + Add-CIPPScheduledTask -Task $TaskBody -hidden $false + #Removal of the exclusion + $TaskBody.Parameters.ExclusionType = 'Remove' + $TaskBody.Name = "Remove CA Exclusion Vacation Mode: $($Request.body.UserId) - $($Request.body.TenantFilter)" + $TaskBody.ScheduledTime = $Request.body.EndDate + Add-CIPPScheduledTask -Task $TaskBody -hidden $false + $body = @{ Results = "Successfully added vacation mode schedule for $Username." } + } else { + Set-CIPPCAExclusion -TenantFilter $Request.body.TenantFilter -ExclusionType $Request.body.ExclusionType -UserID $Request.body.UserID -PolicyId $Request.body.PolicyId -executingUser $request.headers.'x-ms-client-principal' -UserName $Username + } + + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Body + }) + +} diff --git a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 index 345d5fa7af97..ee1a1002cc0b 100644 --- a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 @@ -6,30 +6,25 @@ function New-CIPPCAPolicy { $TenantFilter, $State, $Overwrite, - $APIName = "Create CA Policy", + $APIName = 'Create CA Policy', $ExecutingUser ) function Remove-EmptyArrays ($Object) { if ($Object -is [Array]) { foreach ($Item in $Object) { Remove-EmptyArrays $Item } - } - elseif ($Object -is [HashTable]) { + } elseif ($Object -is [HashTable]) { foreach ($Key in @($Object.get_Keys())) { if ($Object[$Key] -is [Array] -and $Object[$Key].get_Count() -eq 0) { $Object.Remove($Key) - } - else { Remove-EmptyArrays $Object[$Key] } + } else { Remove-EmptyArrays $Object[$Key] } } - } - elseif ($Object -is [PSCustomObject]) { + } elseif ($Object -is [PSCustomObject]) { foreach ($Name in @($Object.psobject.properties.Name)) { if ($Object.$Name -is [Array] -and $Object.$Name.get_Count() -eq 0) { $Object.PSObject.Properties.Remove($Name) - } - elseif ($object.$name -eq $null) { + } elseif ($object.$name -eq $null) { $Object.PSObject.Properties.Remove($Name) - } - else { Remove-EmptyArrays $Object.$Name } + } else { Remove-EmptyArrays $Object.$Name } } } } @@ -46,8 +41,7 @@ function New-CIPPCAPolicy { if ($State -and $State -ne 'donotchange') { $Jsonobj.state = $State } - } - catch { + } catch { # no issues here. } @@ -55,19 +49,18 @@ function New-CIPPCAPolicy { $LocationLookupTable = foreach ($locations in $jsonobj.LocationInfo) { foreach ($location in $locations) { if (!$location.displayName) { continue } - $CheckExististing = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations" -tenantid $TenantFilter + $CheckExististing = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -tenantid $TenantFilter if ($Location.displayName -in $CheckExististing.displayName) { [pscustomobject]@{ id = ($CheckExististing | Where-Object -Property displayName -EQ $Location.displayName).id name = ($CheckExististing | Where-Object -Property displayName -EQ $Location.displayName).displayName } - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Matched a CA policy with the existing Named Location: $($location.displayName)" -Sev "Info" + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Matched a CA policy with the existing Named Location: $($location.displayName)" -Sev 'Info' - } - else { + } else { $Body = ConvertTo-Json -InputObject $Location - $GraphRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations" -body $body -Type POST -tenantid $tenantfilter - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created new Named Location: $($location.displayName)" -Sev "Info" + $GraphRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -body $body -Type POST -tenantid $tenantfilter + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created new Named Location: $($location.displayName)" -Sev 'Info' [pscustomobject]@{ id = $GraphRequest.id name = $GraphRequest.displayName @@ -75,7 +68,7 @@ function New-CIPPCAPolicy { } } } - Write-Host "here5" + Write-Host 'here5' foreach ($location in $JSONObj.conditions.locations.includeLocations) { Write-Host "Replacting $location" @@ -97,29 +90,26 @@ function New-CIPPCAPolicy { $RawJSON = $JSONObj | ConvertTo-Json -Depth 10 Write-Host $RawJSON try { - Write-Host "Checking" - $CheckExististing = New-GraphGETRequest -uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" -tenantid $TenantFilter + Write-Host 'Checking' + $CheckExististing = New-GraphGETRequest -uri 'https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies' -tenantid $TenantFilter if ($displayname -in $CheckExististing.displayName) { if ($Overwrite -ne $true) { Throw "Conditional Access Policy with Display Name $($Displayname) Already exists" return $false - } - else { - Write-Host "overwriting" + } else { + Write-Host 'overwriting' $PatchRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($CheckExististing.id)" -tenantid $tenantfilter -type PATCH -body $RawJSON - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Updated Conditional Access Policy $($JSONObj.Displayname) to the template standard." -Sev "Info" + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Updated Conditional Access Policy $($JSONObj.Displayname) to the template standard." -Sev 'Info' return "Updated policy $displayname for $tenantfilter" } - } - else { - Write-Host "Creating" - $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies" -tenantid $tenantfilter -type POST -body $RawJSON - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Added Conditional Access Policy $($JSONObj.Displayname)" -Sev "Info" + } else { + Write-Host 'Creating' + $CreateRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/policies' -tenantid $tenantfilter -type POST -body $RawJSON + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Added Conditional Access Policy $($JSONObj.Displayname)" -Sev 'Info' return "Created policy $displayname for $tenantfilter" } - } - catch { + } catch { throw "Failed to create or update conditional access rule $($JSONObj.displayName): $($_.exception.message)" - Write-LogMessage -API "Standards" -tenant $tenant -message "Failed to create or update conditional access rule $($JSONObj.displayName): $($_.exception.message) " -sev "Error" + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to create or update conditional access rule $($JSONObj.displayName): $($_.exception.message) " -sev 'Error' } } diff --git a/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 b/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 index e784b5f17918..888a90749cd8 100644 --- a/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPCAExclusion.ps1 @@ -5,6 +5,7 @@ function Set-CIPPCAExclusion { $ExclusionType, $UserID, $PolicyId, + $Username, $executingUser ) try { @@ -31,9 +32,10 @@ function Set-CIPPCAExclusion { $RawJson = ConvertTo-Json -Depth 10 -InputObject $NewExclusions New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($CheckExististing.id)" -tenantid $tenantfilter -type PATCH -body $RawJSON } - - Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Successfully performed $($ExclusionType) user from policy $($PolicyId)" -Sev 'Info' -tenant $TenantFilter + "Successfully performed $($ExclusionType) exclusion for $username from policy $($PolicyId)" + Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Successfully performed $($ExclusionType) exclusion for $username from policy $($PolicyId)" -Sev 'Info' -tenant $TenantFilter } catch { - Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Failed to $($ExclusionType) user from policy $($PolicyId): $_" -Sev 'Error' -tenant $TenantFilter + "Failed to $($ExclusionType) user exclusion for $username from policy $($PolicyId): $_" + Write-LogMessage -user $executingUser -API 'Set-CIPPConditionalAccessExclusion' -message "Failed to $($ExclusionType) user exclusion for $username from policy $($PolicyId): $_" -Sev 'Error' -tenant $TenantFilter } } \ No newline at end of file From 24b42664f707ff8772022d99f0b58616dccb35c7 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 20:06:30 +0100 Subject: [PATCH 13/39] display bug fix --- Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 index 5195ef9dbe41..4dafed5af25a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCAExclusion.ps1 @@ -34,7 +34,7 @@ Function Invoke-ExecCAExclusion { Add-CIPPScheduledTask -Task $TaskBody -hidden $false #Removal of the exclusion $TaskBody.Parameters.ExclusionType = 'Remove' - $TaskBody.Name = "Remove CA Exclusion Vacation Mode: $($Request.body.UserId) - $($Request.body.TenantFilter)" + $TaskBody.Name = "Remove CA Exclusion Vacation Mode: $username - $($Request.body.TenantFilter)" $TaskBody.ScheduledTime = $Request.body.EndDate Add-CIPPScheduledTask -Task $TaskBody -hidden $false $body = @{ Results = "Successfully added vacation mode schedule for $Username." } From 52ba33e928e9e6f9080c436059c72ee6a52a97d0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 21:47:53 +0100 Subject: [PATCH 14/39] add CE TEmplate --- Config/CyberEssentials.BPATemplate.json | 97 +++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Config/CyberEssentials.BPATemplate.json diff --git a/Config/CyberEssentials.BPATemplate.json b/Config/CyberEssentials.BPATemplate.json new file mode 100644 index 000000000000..400d39bb0841 --- /dev/null +++ b/Config/CyberEssentials.BPATemplate.json @@ -0,0 +1,97 @@ +{ + "name": "CIPP Cyber Essentials Helper - Tenant view", + "style": "Tenant", + "Fields": [ + { + "name": "deviceregister", + "UseExistingInfo": false, + "FrontendFields": [ + { + "name": "Device Register", + "value": "deviceregister", + "formatter": "table" + } + ], + "desc": "These are all devices found in M365 to add to your CE Device Register.", + "StoreAs": "JSON", + "API": "Graph", + "ExtractFields": [ + "deviceName", + "lastSyncDateTime", + "osVersion", + "userPrincipalName", + "complianceState" + ], + "URL": "https://graph.microsoft.com/beta/deviceManagement/managedDevices" + }, + { + "name": "adminsTable", + "UseExistingInfo": false, + "FrontendFields": [ + { + "name": "Admins Table", + "value": "adminsTable", + "formatter": "table" + } + ], + "desc": "The list of admin accounts in your M365 environment. These must all be named and attached to actual users.", + "StoreAs": "JSON", + "API": "Graph", + "ExtractFields": ["displayName", "userPrincipalName"], + "URL": "https://graph.microsoft.com/beta/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190-012177145e10/members" + }, + { + "name": "windowsProtectionState", + "UseExistingInfo": false, + "FrontendFields": [ + { + "name": "Defender List", + "value": "windowsProtectionState", + "formatter": "table" + } + ], + "desc": "List of Defender protected workstations. Add this to your Malware Protection Audit List", + "StoreAs": "JSON", + "API": "Graph", + "ExtractFields": ["windowsProtectionState"], + "parameters": {}, + "URL": "https://graph.microsoft.com/beta/deviceManagement/managedDevices?$expand=windowsProtectionState" + }, + { + "name": "detectedApps", + "UseExistingInfo": false, + "FrontendFields": [ + { + "name": "Detected Apps", + "value": "detectedApps", + "formatter": "table" + } + ], + "desc": "All Detected Software and their version. Add this to your software audit list", + "StoreAs": "JSON", + "API": "Graph", + "ExtractFields": ["displayName", "version", "platform", "publisher"], + "URL": "https://graph.microsoft.com/beta/deviceManagement/detectedApps" + }, + { + "name": "userRegistrationDetails", + "UseExistingInfo": false, + "FrontendFields": [ + { + "name": "User Regsitration Details", + "value": "userRegistrationDetails" + } + ], + "desc": "All MFA settings (Requires a P1 Subscription)", + "StoreAs": "JSON", + "API": "Graph", + "ExtractFields": [ + "userDisplayName", + "isAdmin", + "isMFARegistered", + "defaultMFAMethod" + ], + "URL": "https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails" + } + ] +} From c9d7bd3f60623f2e32fda799d665f0e8c56d1a8f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 13 Jan 2024 21:59:23 +0100 Subject: [PATCH 15/39] minor updates --- Config/CyberEssentials.BPATemplate.json | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Config/CyberEssentials.BPATemplate.json b/Config/CyberEssentials.BPATemplate.json index 400d39bb0841..31d25321dc88 100644 --- a/Config/CyberEssentials.BPATemplate.json +++ b/Config/CyberEssentials.BPATemplate.json @@ -9,10 +9,10 @@ { "name": "Device Register", "value": "deviceregister", + "desc": "These are all devices found in M365 to add to your CE Device Register.", "formatter": "table" } ], - "desc": "These are all devices found in M365 to add to your CE Device Register.", "StoreAs": "JSON", "API": "Graph", "ExtractFields": [ @@ -31,10 +31,10 @@ { "name": "Admins Table", "value": "adminsTable", + "desc": "The list of admin accounts in your M365 environment. These must all be named and attached to actual users.", "formatter": "table" } ], - "desc": "The list of admin accounts in your M365 environment. These must all be named and attached to actual users.", "StoreAs": "JSON", "API": "Graph", "ExtractFields": ["displayName", "userPrincipalName"], @@ -47,10 +47,10 @@ { "name": "Defender List", "value": "windowsProtectionState", - "formatter": "table" + "formatter": "table", + "desc": "List of Defender protected workstations. Add this to your Malware Protection Audit List" } ], - "desc": "List of Defender protected workstations. Add this to your Malware Protection Audit List", "StoreAs": "JSON", "API": "Graph", "ExtractFields": ["windowsProtectionState"], @@ -64,10 +64,10 @@ { "name": "Detected Apps", "value": "detectedApps", + "desc": "All Detected Software and their version. Add this to your software audit list", "formatter": "table" } ], - "desc": "All Detected Software and their version. Add this to your software audit list", "StoreAs": "JSON", "API": "Graph", "ExtractFields": ["displayName", "version", "platform", "publisher"], @@ -78,11 +78,12 @@ "UseExistingInfo": false, "FrontendFields": [ { - "name": "User Regsitration Details", - "value": "userRegistrationDetails" + "name": "User Registration Details", + "desc": "All MFA settings (Requires a P1 Subscription)", + "value": "userRegistrationDetails", + "formatter": "table" } ], - "desc": "All MFA settings (Requires a P1 Subscription)", "StoreAs": "JSON", "API": "Graph", "ExtractFields": [ From 3a812b69f8df88c115476c4f7c3c000d7a152ab0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 01:32:52 +0100 Subject: [PATCH 16/39] Add trusted IP --- .../Entrypoints/Invoke-ExecAddTrustedIP.ps1 | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 new file mode 100644 index 000000000000..a09f9e680b4b --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 @@ -0,0 +1,24 @@ +using namespace System.Net + +Function Invoke-ExecAddTrustedIP { + <# + .FUNCTIONALITY + Entrypoint + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $Table = Get-CippTable -tablename 'trustedIps' + Add-CIPPAzDataTableEntity @Table -Entity @{ + PartitionKey = 'trustedIps' + RowKey = 'trustedIps' + trustedIps = $request.query.ip + tenantfilter = $request.query.tenantfilter + state = $request.query.State + } -Force + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @{ results = "Added $($ip) to database with state $($Request.query.state)" } + }) +} \ No newline at end of file From b8ad7d41683c44701a1b165490701419ccdd6dcb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 01:54:46 +0100 Subject: [PATCH 17/39] trusted IP adding --- .../Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 | 2 +- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 index a09f9e680b4b..853932d96ed0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 @@ -11,7 +11,7 @@ Function Invoke-ExecAddTrustedIP { $Table = Get-CippTable -tablename 'trustedIps' Add-CIPPAzDataTableEntity @Table -Entity @{ PartitionKey = 'trustedIps' - RowKey = 'trustedIps' + RowKey = $Request.query.ip trustedIps = $request.query.ip tenantfilter = $request.query.tenantfilter state = $request.query.State diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index b4c1fe4fec39..4603f5c181c3 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -11,6 +11,7 @@ function Invoke-CippWebhookProcessing { ) $ConfigTable = get-cipptable -TableName 'SchedulerConfig' $LocationTable = Get-CIPPTable -TableName 'knownlocationdb' + $TrustedIPsTable = Get-CIPPTable -TableName 'trustedIps' $Alertconfig = Get-CIPPAzDataTableEntity @ConfigTable -Filter "Tenant eq '$tenantfilter'" if (!$Alertconfig) { $Alertconfig = Get-CIPPAzDataTableEntity @ConfigTable -Filter "Tenant eq 'AllTenants'" @@ -19,6 +20,8 @@ function Invoke-CippWebhookProcessing { if ($data.userId -eq 'Not Available') { $data.userId = $data.userKey } if ($data.Userkey -eq 'Not Available') { $data.Userkey = $data.userId } if ($data.clientip) { + $TrustedIps = Get-CIPPAzDataTableEntity @TrustedIPsTable -Filter "PartitionKey eq 'trustedIps' and RowKey eq '$($data.clientip)'" + Write-Host "TrustedIPs: $($TrustedIps | ConvertTo-Json -Depth 15 -Compress)" #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. $Location = Get-CIPPAzDataTableEntity @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. @@ -61,8 +64,8 @@ function Invoke-CippWebhookProcessing { Write-Host "These are the allowed locations: $($AllowedLocations)" Write-Host "Operation: $($data.operation)" switch ($data.operation) { - { 'UserLoggedIn' -eq $data.operation -and $proxy -eq $true } { $data.operation = 'BadRepIP' } - { 'UserLoggedIn' -eq $data.operation -and $hosting -eq $true } { $data.operation = 'HostedIP' } + { 'UserLoggedIn' -eq $data.operation -and $proxy -eq $true -and !$TrustedIps } { $data.operation = 'BadRepIP' } + { 'UserLoggedIn' -eq $data.operation -and $hosting -eq $true -and !$TrustedIps } { $data.operation = 'HostedIP' } { 'UserLoggedIn' -eq $data.operation -and $Country -notin $AllowedLocations -and $data.ResultStatus -eq 'Success' -and $TableObj.ResultStatusDetail -eq 'Success' } { Write-Host "$($country) is not in $($AllowedLocations)" $data.operation = 'UserLoggedInFromUnknownLocation' From 52dc02c09ae96f22b65450fd0e2a78992f6ec246 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 01:59:51 +0100 Subject: [PATCH 18/39] better ip handling --- .../CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 | 4 +--- Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 index 853932d96ed0..4a812864d6a8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 @@ -10,10 +10,8 @@ Function Invoke-ExecAddTrustedIP { $Table = Get-CippTable -tablename 'trustedIps' Add-CIPPAzDataTableEntity @Table -Entity @{ - PartitionKey = 'trustedIps' + PartitionKey = $request.query.tenantfilter RowKey = $Request.query.ip - trustedIps = $request.query.ip - tenantfilter = $request.query.tenantfilter state = $request.query.State } -Force diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index 4603f5c181c3..d7569186b9f9 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -20,7 +20,7 @@ function Invoke-CippWebhookProcessing { if ($data.userId -eq 'Not Available') { $data.userId = $data.userKey } if ($data.Userkey -eq 'Not Available') { $data.Userkey = $data.userId } if ($data.clientip) { - $TrustedIps = Get-CIPPAzDataTableEntity @TrustedIPsTable -Filter "PartitionKey eq 'trustedIps' and RowKey eq '$($data.clientip)'" + $TrustedIps = Get-CIPPAzDataTableEntity @TrustedIPsTable -Filter "PartitionKey eq '$($TenantFilter)' and RowKey eq '$($data.clientip)' and state eq 'Trusted'" Write-Host "TrustedIPs: $($TrustedIps | ConvertTo-Json -Depth 15 -Compress)" #First we perform a lookup in the knownlocationdb table to see if we have a location for this IP address. $Location = Get-CIPPAzDataTableEntity @LocationTable -Filter "RowKey eq '$($data.clientip)'" | Select-Object -Last 1 From f4923a1ee99afc3a521796196f7e290a676a8a83 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 02:12:45 +0100 Subject: [PATCH 19/39] update text --- Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 index 4a812864d6a8..da3934249de5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 @@ -17,6 +17,6 @@ Function Invoke-ExecAddTrustedIP { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK - Body = @{ results = "Added $($ip) to database with state $($Request.query.state)" } + Body = @{ results = "Added $($Request.query.ip) to database with state $($Request.query.state)" } }) } \ No newline at end of file From bf1ac402944778b069af27c51449c66a435d9d94 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 02:19:19 +0100 Subject: [PATCH 20/39] template changes --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index e44402d121a4..e57586f568b9 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -175,9 +175,9 @@ function New-CIPPAlertTemplate { $LocationTable = ($LocationInfo | ConvertTo-Html -Fragment -As List | Out-String).Replace('', '
') $IntroText = $IntroText + "

The location information for this IP is as follows:

$LocationTable" } - $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

' + $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true" + $ButtonText = 'Whitelist IP' + $AfterButtonText = '

If this is incorrect, you can whitelist the following IP.

' } 'HostedIP' { $Table = ($TableObj | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') @@ -189,9 +189,9 @@ function New-CIPPAlertTemplate { $LocationTable = ($LocationInfo | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') $IntroText = $IntroText + "

The location information for this IP is as follows:

$LocationTable" } - $ButtonUrl = "$CIPPPURL/identity/administration/ViewBec?userId=$($data.ObjectId)&tenantDomain=$($data.OrganizationId)" + $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true" $ButtonText = 'User Management' - $AfterButtonText = '

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

' + $AfterButtonText = '

If this is incorrect, you can whitelist the following IP.

' } 'Add service principal.' { if ($Appname) { $AppName = $AppName.'Application Name' } else { $appName = $data.ApplicationId } From 75ed26aa6f7ab25a173710205d7cf7ce97ee8ca0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 02:23:35 +0100 Subject: [PATCH 21/39] text change --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index e57586f568b9..9a2a83a4b07a 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -190,7 +190,7 @@ function New-CIPPAlertTemplate { $IntroText = $IntroText + "

The location information for this IP is as follows:

$LocationTable" } $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true" - $ButtonText = 'User Management' + $ButtonText = 'Whitelist IP' $AfterButtonText = '

If this is incorrect, you can whitelist the following IP.

' } 'Add service principal.' { From c07720c48b24679c1e5a1c0513d136b1e6a0e11b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 02:31:05 +0100 Subject: [PATCH 22/39] upped --- Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 index da3934249de5..db587ae67959 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecAddTrustedIP.ps1 @@ -17,6 +17,6 @@ Function Invoke-ExecAddTrustedIP { Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK - Body = @{ results = "Added $($Request.query.ip) to database with state $($Request.query.state)" } + Body = @{ results = "Added $($Request.query.ip) to database with state $($Request.query.state) for $($Request.query.tenantfilter)" } }) } \ No newline at end of file From d5d2593f8997cffcbd78a39bd9bff691bc423d69 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 14:45:05 +0100 Subject: [PATCH 23/39] add org id --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 9a2a83a4b07a..442d149133a9 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -175,7 +175,7 @@ function New-CIPPAlertTemplate { $LocationTable = ($LocationInfo | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') $IntroText = $IntroText + "

The location information for this IP is as follows:

$LocationTable" } - $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true" + $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true&customerId=$($data.OrganizationId)" $ButtonText = 'Whitelist IP' $AfterButtonText = '

If this is incorrect, you can whitelist the following IP.

' } @@ -189,7 +189,7 @@ function New-CIPPAlertTemplate { $LocationTable = ($LocationInfo | ConvertTo-Html -Fragment -As List | Out-String).Replace('
', '
') $IntroText = $IntroText + "

The location information for this IP is as follows:

$LocationTable" } - $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true" + $ButtonUrl = "$CIPPPURL/tenant/tools/geoiplookup?ip=$($data.ClientIP)&SearchNow=true&customerId=$($data.OrganizationId)" $ButtonText = 'Whitelist IP' $AfterButtonText = '

If this is incorrect, you can whitelist the following IP.

' } From 80b34e270c9d91bad52d5e5453bb40f494b23dd5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 14 Jan 2024 16:32:20 +0100 Subject: [PATCH 24/39] secure score % --- Config/CIPPDefaultTable.BPATemplate.json | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Config/CIPPDefaultTable.BPATemplate.json b/Config/CIPPDefaultTable.BPATemplate.json index 2f7f31ac326c..735012b4bd77 100644 --- a/Config/CIPPDefaultTable.BPATemplate.json +++ b/Config/CIPPDefaultTable.BPATemplate.json @@ -1,5 +1,5 @@ { - "name": "CIPP Best Practices v1.0 - Table view", + "name": "CIPP Best Practices v1.5 - Table view", "style": "Table", "Fields": [ { @@ -172,19 +172,21 @@ "FrontendFields": [ { "name": "Current Secure Score", - "value": "CurrentSecureScore.currentScore" - }, - { - "name": "Max Secure Score", - "value": "CurrentSecureScore.maxScore" + "value": "CurrentSecureScore.currentScore / CurrentSecureScore.maxScore * 100", + "formatter": "math", + "showAs": "percentage" }, { "name": "Average Comparative Score (All Tenants)", - "value": "CurrentSecureScore.averageComparativeScores[0].averageScore" + "value": "CurrentSecureScore.averageComparativeScores[0].averageScore / CurrentSecureScore.maxScore * 100", + "formatter": "math", + "showAs": "percentage" }, { "name": "Average Comparative Score (Similiar Size Tenants)", - "value": "CurrentSecureScore.averageComparativeScores[1].averageScore" + "value": "CurrentSecureScore.averageComparativeScores[1].averageScore / CurrentSecureScore.maxScore * 100", + "formatter": "math", + "showAs": "percentage" } ] } From 1b0c4929cb562898254aade61161735db4b039fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 14 Jan 2024 17:00:29 +0100 Subject: [PATCH 25/39] Add enable all MailTips standard --- .../Invoke-CIPPStandardEnableMailTips.ps1 | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 new file mode 100644 index 000000000000..51991bf57f9e --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 @@ -0,0 +1,42 @@ +function Invoke-CIPPStandardEnableMailTips { + <# + .FUNCTIONALITY + Internal + #> + + param($Tenant, $Settings) + + if ($Settings.remediate) { + + + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdparams @{ MailTipsAllTipsEnabled = $true; MailTipsExternalRecipientsTipsEnabled = $true; MailTipsGroupMetricsEnabled = $true; MailTipsLargeAudienceThreshold = $Settings.MailTipsLargeAudienceThreshold } + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Enabled all MailTips' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to enable all MailTips: $($_.exception.message)" -sev Error + } + } + + + if ($Settings.alert -or $Settings.report) { + $MailTipsState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig' | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold + + if ($Settings.alert) { + if ($MailTipsState.MailTipsAllTipsEnabled -and $MailTipsState.MailTipsExternalRecipientsTipsEnabled -and $MailTipsState.MailTipsGroupMetricsEnabled -and $MailTipsState.MailTipsLargeAudienceThreshold -eq $Settings.MailTipsLargeAudienceThreshold) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Not all MailTips are enabled' -sev Alert + } + } + + if ($Settings.report) { + + if ($MailTipsState.MailTipsAllTipsEnabled -and $MailTipsState.MailTipsExternalRecipientsTipsEnabled -and $MailTipsState.MailTipsGroupMetricsEnabled -and $MailTipsState.MailTipsLargeAudienceThreshold -eq $Settings.MailTipsLargeAudienceThreshold) { + $MailTipsState = $true + } else { + $MailTipsState = $false + } + Add-CIPPBPAField -FieldName 'MailTipsEnabled' -FieldValue [bool]$MailTipsState -StoreAs bool -Tenant $tenant + } + } +} \ No newline at end of file From f3fd1be8e96417e058ecb45797ef7886445ba9fd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Mon, 15 Jan 2024 13:59:53 +0100 Subject: [PATCH 26/39] cleanup old code --- BestPracticeAnalyser_List/function.json | 19 ------------------ BestPracticeAnalyser_List/run.ps1 | 26 ------------------------- 2 files changed, 45 deletions(-) delete mode 100644 BestPracticeAnalyser_List/function.json delete mode 100644 BestPracticeAnalyser_List/run.ps1 diff --git a/BestPracticeAnalyser_List/function.json b/BestPracticeAnalyser_List/function.json deleted file mode 100644 index 306b0c51e560..000000000000 --- a/BestPracticeAnalyser_List/function.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "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/BestPracticeAnalyser_List/run.ps1 b/BestPracticeAnalyser_List/run.ps1 deleted file mode 100644 index dd27bc04a93b..000000000000 --- a/BestPracticeAnalyser_List/run.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -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" - -$Tenants = Get-Tenants -$Table = get-cipptable 'cachebpa' -$Results = (Get-CIPPAzDataTableEntity @Table) | ForEach-Object { - $_.UnusedLicenseList = @(ConvertFrom-Json -ErrorAction silentlycontinue -InputObject $_.UnusedLicenseList) - $_ -} - -if (!$Results) { - $Results = @{ - Tenant = "The BPA has not yet run." - } -} -Write-Host ($Tenants | ConvertTo-Json) -# Associate values to output bindings by calling 'Push-OutputBinding'. -Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = @(($Results | Where-Object -Property RowKey -In $Tenants.customerId)) - }) \ No newline at end of file From 8340d2db6a5586467034ab0750549bcb873fd1c2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Mon, 15 Jan 2024 14:07:37 +0100 Subject: [PATCH 27/39] moved domain analyser list to normal api --- DomainAnalyser_List/function.json | 19 --------- DomainAnalyser_List/run.ps1 | 42 ------------------- .../Entrypoints/Invoke-ListDomainAnalyser.ps1 | 39 +++++++++++++++++ 3 files changed, 39 insertions(+), 61 deletions(-) delete mode 100644 DomainAnalyser_List/function.json delete mode 100644 DomainAnalyser_List/run.ps1 create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainAnalyser.ps1 diff --git a/DomainAnalyser_List/function.json b/DomainAnalyser_List/function.json deleted file mode 100644 index 306b0c51e560..000000000000 --- a/DomainAnalyser_List/function.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "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/DomainAnalyser_List/run.ps1 b/DomainAnalyser_List/run.ps1 deleted file mode 100644 index 65a72671901f..000000000000 --- a/DomainAnalyser_List/run.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -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.' - -$DomainTable = Get-CIPPTable -Table 'Domains' - -# Get all the things - -if ($Request.Query.tenantFilter -ne 'AllTenants') { - $DomainTable.Filter = "TenantId eq '{0}'" -f $Request.Query.tenantFilter -} - -try { - # Extract json from table results - $Results = foreach ($DomainAnalyserResult in (Get-CIPPAzDataTableEntity @DomainTable).DomainAnalyser) { - try { - if (![string]::IsNullOrEmpty($DomainAnalyserResult)) { - $Object = $DomainAnalyserResult | ConvertFrom-Json - - if (($Request.Query.tenantFilter -eq 'AllTenants' -and $Object.Tenant -notin $Skiplist.Name) -or $Request.Query.tenantFilter -ne 'AllTenants') { - $Object.GUID = $Object.GUID -replace '[^a-zA-Z-]', '' - $Object - } - } - } catch {} - } -} catch { - $Results = @() -} - - -# Associate values to output bindings by calling 'Push-OutputBinding'. -Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = @($Results) - }) \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainAnalyser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainAnalyser.ps1 new file mode 100644 index 000000000000..ef10d6a3505d --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainAnalyser.ps1 @@ -0,0 +1,39 @@ + +using namespace System.Net + +Function Invoke-ListDomainAnalyser { + <# + .FUNCTIONALITY + Entrypoint + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + $DomainTable = Get-CIPPTable -Table 'Domains' + + # Get all the things + + if ($Request.Query.tenantFilter -ne 'AllTenants') { + $DomainTable.Filter = "TenantId eq '{0}'" -f $Request.Query.tenantFilter + } + + try { + # Extract json from table results + $Results = foreach ($DomainAnalyserResult in (Get-CIPPAzDataTableEntity @DomainTable).DomainAnalyser) { + try { + if (![string]::IsNullOrEmpty($DomainAnalyserResult)) { + $Object = $DomainAnalyserResult | ConvertFrom-Json -ErrorAction SilentlyContinue + $Object + } + } catch {} + } + } catch { + $Results = @() + } + + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = @($Results) + }) +} \ No newline at end of file From 057de50656566c3436a64a4a0b230ed47c1a7bdc Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 11:10:51 +0100 Subject: [PATCH 28/39] any alert fix --- 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 d7569186b9f9..1f698dc9f475 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -60,7 +60,7 @@ function Invoke-CippWebhookProcessing { return '' } - $AllowedLocations = ($Alertconfig.if | ConvertFrom-Json).allowedcountries.value + $AllowedLocations = ($Alertconfig.if | ConvertFrom-Json -ErrorAction SilentlyContinue).allowedcountries.value Write-Host "These are the allowed locations: $($AllowedLocations)" Write-Host "Operation: $($data.operation)" switch ($data.operation) { @@ -78,7 +78,7 @@ function Invoke-CippWebhookProcessing { foreach ($AlertSetting in $Alertconfig) { $ifs = $AlertSetting.If | ConvertFrom-Json $Dos = $AlertSetting.execution | ConvertFrom-Json - if ($data.operation -notin $Ifs.selection -and $ifs.selection -ne 'AnyAlert' -and ($ifs.count -le 1 -and $ifs.selection -ne 'customField')) { + if ($data.operation -notin $Ifs.selection -and 'AnyAlert' -notin $ifs.selection -and ($ifs.count -le 1 -and $ifs.selection -ne 'customField')) { Write-Host 'Not an operation to do anything for. storing IP info' if ($data.ClientIP -and $data.operation -like '*LoggedIn*') { Write-Host 'Add IP and potential location to knownlocation db for this specific user.' From e3a00661845c86f16e1b5cb6e9508986f3b762af Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 11:24:37 +0100 Subject: [PATCH 29/39] add writehost --- PublicWebhooksProcess/run.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index 132349f58dbe..c4319bf483df 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -53,6 +53,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { #Compare $Operations to $MappingTable. If there is a match, we make a new variable called $LogsToDownload #Example: $Operations = 'UserLoggedIn', 'Set-InboxRule' makes : $LogsToDownload = @('Audit.AzureActiveDirectory',Audit.Exchange) $LogsToDownload = $Operations | Where-Object { $MappingTable.$_ } | ForEach-Object { $MappingTable.$_ } + Write-Host "Logs to download: $LogsToDownload" if ($ReceivedItem.ContentType -in $LogsToDownload -or $LogsToDownload -contains 'AnyLog') { $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' } else { From 4f87cc167ffb61cb0e7376fe547578203003b536 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 11:32:31 +0100 Subject: [PATCH 30/39] logging --- PublicWebhooksProcess/run.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index c4319bf483df..0e28b5763500 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -53,6 +53,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { #Compare $Operations to $MappingTable. If there is a match, we make a new variable called $LogsToDownload #Example: $Operations = 'UserLoggedIn', 'Set-InboxRule' makes : $LogsToDownload = @('Audit.AzureActiveDirectory',Audit.Exchange) $LogsToDownload = $Operations | Where-Object { $MappingTable.$_ } | ForEach-Object { $MappingTable.$_ } + Write-Host "Our operations: $Operations" Write-Host "Logs to download: $LogsToDownload" if ($ReceivedItem.ContentType -in $LogsToDownload -or $LogsToDownload -contains 'AnyLog') { $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 82fa6cec827aa5f57b6b8ea0a0415bd38e561215 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 12:24:38 +0100 Subject: [PATCH 31/39] changed to in instead of contains --- PublicWebhooksProcess/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index 0e28b5763500..c8b6c31ea243 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -55,7 +55,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { $LogsToDownload = $Operations | Where-Object { $MappingTable.$_ } | ForEach-Object { $MappingTable.$_ } Write-Host "Our operations: $Operations" Write-Host "Logs to download: $LogsToDownload" - if ($ReceivedItem.ContentType -in $LogsToDownload -or $LogsToDownload -contains 'AnyLog') { + if ($ReceivedItem.ContentType -in $LogsToDownload -or 'AnyLog' -in $LogsToDownload) { $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' } else { Write-Host "No data to download for $($ReceivedItem.ContentType)" From e83c09ecc7dbe7529773431a73db0d98d34d5bca Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 12:34:23 +0100 Subject: [PATCH 32/39] if anylog, process all --- PublicWebhooksProcess/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index c8b6c31ea243..0af2531d9b6f 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -62,7 +62,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { continue } Write-Host "Data found: $($data.count) items" - $DataToProcess = $Data | Where-Object -Property Operation -In $Operations + $DataToProcess = if ('anylog' -NotIn $LogsToDownload) { $Data | Where-Object -Property Operation -In $Operations } else { $Data } Write-Host "Data to process found: $($DataToProcess.count) items" foreach ($Item in $DataToProcess) { Write-Host "Processing $($item.operation)" From fee4bd785432b1b4f10c91761b8fca7518db983c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 12:44:28 +0100 Subject: [PATCH 33/39] API Name --- Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardUser.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardUser.ps1 index 6e6e9970f39a..2391bd643995 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardUser.ps1 @@ -8,6 +8,7 @@ Function Invoke-ExecOffboardUser { [CmdletBinding()] param($Request, $TriggerMetadata) try { + $APIName = 'ExecOffboardUser' Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $Username = $request.body.user $Tenantfilter = $request.body.tenantfilter From 2f659986529d619f2a40709e832da54fd10e0e16 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 15:57:33 +0100 Subject: [PATCH 34/39] added halomapping logic --- Modules/CippExtensions/Private/Get-HaloMapping.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/CippExtensions/Private/Get-HaloMapping.ps1 b/Modules/CippExtensions/Private/Get-HaloMapping.ps1 index d86753f29306..adfdd8e72102 100644 --- a/Modules/CippExtensions/Private/Get-HaloMapping.ps1 +++ b/Modules/CippExtensions/Private/Get-HaloMapping.ps1 @@ -24,8 +24,10 @@ function Get-HaloMapping { $i++ $pagecount = [Math]::Ceiling($Result.record_count / 999) } while ($i -le $pagecount) + } catch { + Write-LogMessage -Message "Could not get HaloPSA Clients, error: $($_.Exception.Message)" -Level Error -tenant 'CIPP' -API 'HaloMapping' + $RawHaloClients = @(@{name = "Could not get HaloPSA Clients, error: $($_.Exception.Message)" }) } - catch { $RawHaloClients = @() } $HaloClients = $RawHaloClients | ForEach-Object { [PSCustomObject]@{ name = $_.name From 4f9656448f172bd8480ac0af3be659c2e23dbe4e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 16:45:24 +0100 Subject: [PATCH 35/39] added logging --- .../CippExtensions/Private/New-HaloPSATicket.ps1 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Modules/CippExtensions/Private/New-HaloPSATicket.ps1 b/Modules/CippExtensions/Private/New-HaloPSATicket.ps1 index 2b1b18486d7b..3dd96ee6eb28 100644 --- a/Modules/CippExtensions/Private/New-HaloPSATicket.ps1 +++ b/Modules/CippExtensions/Private/New-HaloPSATicket.ps1 @@ -15,7 +15,7 @@ function New-HaloPSATicket { usertype = 1 userlookup = @{ id = -1 - lookupdisplay = "Enter Details Manually" + lookupdisplay = 'Enter Details Manually' } client_id = $client site_id = $null @@ -28,20 +28,19 @@ function New-HaloPSATicket { } if ($Configuration.TicketType) { - $object | Add-Member -MemberType NoteProperty -Name "tickettype_id" -Value $Configuration.TicketType + $object | Add-Member -MemberType NoteProperty -Name 'tickettype_id' -Value $Configuration.TicketType } #use the token to create a new ticket in HaloPSA $body = ConvertTo-Json -Compress -Depth 10 -InputObject @($Object) - Write-Host "Sending ticket to HaloPSA" + Write-Host 'Sending ticket to HaloPSA' Write-Host $body try { $Ticket = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Tickets" -ContentType 'application/json; charset=utf-8' -Method Post -Body $body -Headers @{Authorization = "Bearer $($token.access_token)" } - } - catch { - Write-Host "Failed to send ticket to HaloPSA" - Write-Host $_.Exception.Message + } catch { + Write-LogMessage -message "Failed to send ticket to HaloPSA: $($_.Exception.Message)" -API 'HaloPSATicket' -sev Error + Write-Host "Failed to send ticket to HaloPSA: $($_.Exception.Message)" } } \ No newline at end of file From b99fc6f2665ea17419c8b566f38dfcde19430f89 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 20:24:37 +0100 Subject: [PATCH 36/39] hotfix for webhook --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index 14d8a90bcd7a..0bd140765c01 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -4.9.6 \ No newline at end of file +4.9.7 \ No newline at end of file From 77c22d1da383fe5b8f4f4184544acd5262335538 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 21:39:39 +0100 Subject: [PATCH 37/39] Minor update --- PublicWebhooksProcess/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PublicWebhooksProcess/run.ps1 b/PublicWebhooksProcess/run.ps1 index 0af2531d9b6f..50bbde87cfb2 100644 --- a/PublicWebhooksProcess/run.ps1 +++ b/PublicWebhooksProcess/run.ps1 @@ -30,7 +30,7 @@ if ($Request.query.CIPPID -in $Webhooks.RowKey) { Write-Host "Webhook TenantFilter: $TenantFilter" $ConfigTable = get-cipptable -TableName 'SchedulerConfig' $Alertconfig = Get-CIPPAzDataTableEntity @ConfigTable | Where-Object { $_.Tenant -eq $TenantFilter -or $_.Tenant -eq 'AllTenants' } - $Operations = ($AlertConfig.if | ConvertFrom-Json -ErrorAction SilentlyContinue).selection, 'UserLoggedIn' + $Operations = ($AlertConfig.if | ConvertFrom-Json -ErrorAction SilentlyContinue).selection + 'UserLoggedIn' $Webhookinfo = $Webhooks | Where-Object -Property RowKey -EQ $Request.query.CIPPID #Increased download efficiency: only download the data we need for processing. Todo: Change this to load from table or dynamic source. $MappingTable = [pscustomobject]@{ From e889585af52e6137381952904423fc34cdbb5644 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Tue, 16 Jan 2024 21:39:55 +0100 Subject: [PATCH 38/39] hotfix --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index 0bd140765c01..ec4595317e77 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -4.9.7 \ No newline at end of file +4.9.8 \ No newline at end of file From 9a23dcbf8fa4ebe1920fb8d7fe32d8070cb4c0f2 Mon Sep 17 00:00:00 2001 From: Dirk Haex Date: Wed, 17 Jan 2024 12:47:07 +0100 Subject: [PATCH 39/39] Update 7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json Change configuration policy naming to align all Standards. --- Config/7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json b/Config/7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json index fde8371a4af5..46b4483e224a 100644 --- a/Config/7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json +++ b/Config/7547f73c-3cb0-460c-a4bd-391944908007.IntuneTemplate.json @@ -1,5 +1,5 @@ { - "Displayname": "CIPP Default: Skip Autopilot User Setup Page", + "Displayname": "CIPP: Skip Autopilot User Setup Page", "Description": "Skips the autopilot user setup page", "RAWJson": "{\"id\":\"00000000-0000-0000-0000-000000000000\",\"displayName\":\"Skip Autopilot User Setup Page\",\"roleScopeTagIds\":[\"0\"],\"@odata.type\":\"#microsoft.graph.windows10CustomConfiguration\",\"omaSettings\":[{\"displayName\":\"SkipUserSetupPage\",\"omaUri\":\"./Device/Vendor/MSFT/DMClient/Provider/MS DM Server/FirstSyncStatus/SkipUserStatusPage\",\"@odata.type\":\"#microsoft.graph.omaSettingBoolean\",\"value\":\"true\"}]}", "Type": "Device",