diff --git a/CIPPTimers.json b/CIPPTimers.json index e527285dd78f..c38acd967d56 100644 --- a/CIPPTimers.json +++ b/CIPPTimers.json @@ -1,4 +1,12 @@ [ + { + "Command": "Start-DurableCleanup", + "Description": "Timer function to cleanup durable functions", + "Cron": "0 */15 * * * *", + "Priority": 0, + "RunOnProcessor": true, + "IsSystem": true + }, { "Command": "Start-UserTasksOrchestrator", "Description": "Orchestrator to process user scheduled tasks", @@ -23,6 +31,15 @@ "PreferredProcessor": "auditlog", "IsSystem": true }, + { + "Command": "Start-AuditLogSearchCreation", + "Description": "Timer to create audit log searches", + "Cron": "0 */30 * * * *", + "Priority": 3, + "RunOnProcessor": true, + "PreferredProcessor": "auditlog", + "IsSystem": true + }, { "Command": "Start-ApplicationOrchestrator", "Description": "Orchestrator to process application uploads", diff --git a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.dll b/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.dll deleted file mode 100644 index 72910599b85e..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.pdb b/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.pdb deleted file mode 100644 index 38ccee09c6c2..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.PS.pdb and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/CHANGELOG.md b/Modules/AzBobbyTables/3.1.3/CHANGELOG.md deleted file mode 100644 index c7880a5f68cf..000000000000 --- a/Modules/AzBobbyTables/3.1.3/CHANGELOG.md +++ /dev/null @@ -1,28 +0,0 @@ -# Changelog for the module - -The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added - -- Added Sampler ([#48](https://github.com/PalmEmanuel/AzBobbyTables/issues/48)). -- Added support for user-assigned managed identities ([#54](https://github.com/PalmEmanuel/AzBobbyTables/issues/54)). - -## [3.1.2] - 2024-01-05 - -### Added - -- Help documentation for a DateTime problem caused by the SDK (#43). - -### Fixed - -### Changed - -### Removed - -## 3.1.1 - 2023-05-03 - -[Unreleased]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.1.2...HEAD - -[3.1.2]: https://github.com/PalmEmanuel/AzBobbyTables/compare/d854153aca6c5cce35a123deb86653a0d3289b07...v3.1.2 diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.dll b/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.dll deleted file mode 100644 index 1a9a170b6f32..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.pdb b/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.pdb deleted file mode 100644 index 252b9c04eaa6..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/AzBobbyTables.Core.pdb and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Core.dll b/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Core.dll deleted file mode 100644 index f7369932f113..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Core.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Data.Tables.dll b/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Data.Tables.dll deleted file mode 100644 index 33b1aaf7903e..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/Azure.Data.Tables.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.Bcl.AsyncInterfaces.dll b/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.Bcl.AsyncInterfaces.dll deleted file mode 100644 index cd1ca92a2beb..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.Bcl.AsyncInterfaces.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.VisualStudio.Threading.dll b/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.VisualStudio.Threading.dll deleted file mode 100644 index f3b23c328c0f..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.VisualStudio.Threading.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Encodings.Web.dll b/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Encodings.Web.dll deleted file mode 100644 index a4d360553c9d..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Encodings.Web.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Json.dll b/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Json.dll deleted file mode 100644 index fe2154a3bf3a..000000000000 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/System.Text.Json.dll and /dev/null differ diff --git a/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.dll b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.dll new file mode 100644 index 000000000000..7d9b64a3818b Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.pdb b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.pdb new file mode 100644 index 000000000000..cb1c42199263 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.PS.pdb differ diff --git a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.psd1 b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.psd1 similarity index 93% rename from Modules/AzBobbyTables/3.1.3/AzBobbyTables.psd1 rename to Modules/AzBobbyTables/3.3.1/AzBobbyTables.psd1 index 5bd7c13ba243..0b1f9cc6a082 100644 --- a/Modules/AzBobbyTables/3.1.3/AzBobbyTables.psd1 +++ b/Modules/AzBobbyTables/3.3.1/AzBobbyTables.psd1 @@ -4,7 +4,7 @@ RootModule = 'AzBobbyTables.PS.dll' # Version number of this module. -ModuleVersion = '3.1.3' +ModuleVersion = '3.3.1' # Supported PSEditions CompatiblePSEditions = @('Core') @@ -67,6 +67,7 @@ FunctionsToExport = @() CmdletsToExport = @( 'Add-AzDataTableEntity' 'Clear-AzDataTable' + 'Get-AzDataTable' 'Get-AzDataTableEntity' 'Remove-AzDataTableEntity' 'Update-AzDataTableEntity' @@ -108,12 +109,11 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = '## [3.1.3] - 2024-01-20 + ReleaseNotes = '## [3.3.1] - 2024-10-19 ### Added -- Added Sampler ([#48](https://github.com/PalmEmanuel/AzBobbyTables/issues/48)). -- Added support for user-assigned managed identities ([#54](https://github.com/PalmEmanuel/AzBobbyTables/issues/54)). +- Added `-OperationType` parameter to `Add-AzDataTableEntity` and `Update-AzDataTableEntity` to support merge or replace operations [#81](https://github.com/PalmEmanuel/AzBobbyTables/pull/81) ' diff --git a/Modules/AzBobbyTables/3.3.1/CHANGELOG.md b/Modules/AzBobbyTables/3.3.1/CHANGELOG.md new file mode 100644 index 000000000000..8b9681a286b1 --- /dev/null +++ b/Modules/AzBobbyTables/3.3.1/CHANGELOG.md @@ -0,0 +1,62 @@ +# Changelog for the module + +The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Added `-OperationType` parameter to `Add-AzDataTableEntity` and `Update-AzDataTableEntity` to support merge or replace operations [#81](https://github.com/PalmEmanuel/AzBobbyTables/pull/81) + +## [3.3.0] - 2024-10-18 + +### Added + +- Added command `Get-AzDataTable` to get the names of tables in a storage account [#77](https://github.com/PalmEmanuel/AzBobbyTables/issues/77) + +### Changed + +- Implemented TableServiceClient to support operations on tables in the storage account. + +## [3.2.1] - 2024-07-09 + +### Fixed + +- Fixed bug where empty lines were written to console. + +## [3.2.0] - 2024-03-21 + +### Added + +- ETag validation for Update- & Remove-AzDataTableEntity ([#58](https://github.com/PalmEmanuel/AzBobbyTables/issues/58)) + +### Fixed + +- Missing examples of Remove-AzDataTableEntity ([#62](https://github.com/PalmEmanuel/AzBobbyTables/issues/62)) + +## [3.1.3] - 2024-01-20 + +### Added + +- Added Sampler ([#48](https://github.com/PalmEmanuel/AzBobbyTables/issues/48)). +- Added support for user-assigned managed identities ([#54](https://github.com/PalmEmanuel/AzBobbyTables/issues/54)). + +## [3.1.2] - 2024-01-05 + +### Added + +- Help documentation for a DateTime problem caused by the SDK (#43). + +## 3.1.1 - 2023-05-03 + +[Unreleased]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.3.0...HEAD + +[3.3.0]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.2.1...v3.3.0 + +[3.2.1]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.2.0...v3.2.1 + +[3.2.0]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.1.3...v3.2.0 + +[3.1.3]: https://github.com/PalmEmanuel/AzBobbyTables/compare/v3.1.2...v3.1.3 + +[3.1.2]: https://github.com/PalmEmanuel/AzBobbyTables/compare/d854153aca6c5cce35a123deb86653a0d3289b07...v3.1.2 diff --git a/Modules/AzBobbyTables/3.1.3/LICENSE b/Modules/AzBobbyTables/3.3.1/LICENSE similarity index 100% rename from Modules/AzBobbyTables/3.1.3/LICENSE rename to Modules/AzBobbyTables/3.3.1/LICENSE diff --git a/Modules/AzBobbyTables/3.1.3/PSGetModuleInfo.xml b/Modules/AzBobbyTables/3.3.1/PSGetModuleInfo.xml similarity index 62% rename from Modules/AzBobbyTables/3.1.3/PSGetModuleInfo.xml rename to Modules/AzBobbyTables/3.3.1/PSGetModuleInfo.xml index 775321568df1..2559d56021b4 100644 --- a/Modules/AzBobbyTables/3.1.3/PSGetModuleInfo.xml +++ b/Modules/AzBobbyTables/3.3.1/PSGetModuleInfo.xml @@ -7,13 +7,13 @@ AzBobbyTables - 3.1.3 + 3.3.1 Module A module for handling Azure Table Storage operations by wrapping the Azure Data Tables SDK. Emanuel Palm PalmEmanuel (c) Emanuel Palm. All rights reserved. -
2024-01-20T16:49:22-05:00
+
2024-10-19T09:03:27-04:00
https://github.com/PalmEmanuel/AzBobbyTables/blob/main/LICENSE @@ -50,11 +50,11 @@ - Function + Workflow - DscResource + Function @@ -64,6 +64,7 @@ Add-AzDataTableEntity Clear-AzDataTable + Get-AzDataTable Get-AzDataTableEntity Remove-AzDataTableEntity Update-AzDataTableEntity @@ -73,6 +74,10 @@ + + DscResource + + Cmdlet @@ -80,6 +85,7 @@ Add-AzDataTableEntity Clear-AzDataTable + Get-AzDataTable Get-AzDataTableEntity Remove-AzDataTableEntity Update-AzDataTableEntity @@ -89,14 +95,10 @@ - - Workflow - - - ## [3.1.3] - 2024-01-20_x000A__x000A_### Added_x000A__x000A_- Added Sampler ([#48](https://github.com/PalmEmanuel/AzBobbyTables/issues/48))._x000A_- Added support for user-assigned managed identities ([#54](https://github.com/PalmEmanuel/AzBobbyTables/issues/54)). + ## [3.3.1] - 2024-10-19_x000A__x000A_### Added_x000A__x000A_- Added `-OperationType` parameter to `Add-AzDataTableEntity` and `Update-AzDataTableEntity` to support merge or replace operations [#81](https://github.com/PalmEmanuel/AzBobbyTables/pull/81) @@ -113,29 +115,29 @@ (c) Emanuel Palm. All rights reserved. A module for handling Azure Table Storage operations by wrapping the Azure Data Tables SDK. False - ## [3.1.3] - 2024-01-20_x000A__x000A_### Added_x000A__x000A_- Added Sampler ([#48](https://github.com/PalmEmanuel/AzBobbyTables/issues/48))._x000A_- Added support for user-assigned managed identities ([#54](https://github.com/PalmEmanuel/AzBobbyTables/issues/54)). + ## [3.3.1] - 2024-10-19_x000A__x000A_### Added_x000A__x000A_- Added `-OperationType` parameter to `Add-AzDataTableEntity` and `Update-AzDataTableEntity` to support merge or replace operations [#81](https://github.com/PalmEmanuel/AzBobbyTables/pull/81) True True - 3242 - 12058 - 1356423 - 1/20/2024 4:49:22 PM -05:00 - 1/20/2024 4:49:22 PM -05:00 - 3/18/2024 2:41:34 PM -04:00 - azure storage table cosmos cosmosdb data PSModule PSEdition_Core PSCmdlet_Add-AzDataTableEntity PSCommand_Add-AzDataTableEntity PSCmdlet_Clear-AzDataTable PSCommand_Clear-AzDataTable PSCmdlet_Get-AzDataTableEntity PSCommand_Get-AzDataTableEntity PSCmdlet_Remove-AzDataTableEntity PSCommand_Remove-AzDataTableEntity PSCmdlet_Update-AzDataTableEntity PSCommand_Update-AzDataTableEntity PSCmdlet_New-AzDataTableContext PSCommand_New-AzDataTableContext PSCmdlet_Remove-AzDataTable PSCommand_Remove-AzDataTable PSCmdlet_New-AzDataTable PSCommand_New-AzDataTable PSIncludes_Cmdlet + 16 + 20865 + 1478233 + 10/19/2024 9:03:27 AM -04:00 + 10/19/2024 9:03:27 AM -04:00 + 10/19/2024 4:20:00 PM -04:00 + azure storage table cosmos cosmosdb data PSModule PSEdition_Core PSCmdlet_Add-AzDataTableEntity PSCommand_Add-AzDataTableEntity PSCmdlet_Clear-AzDataTable PSCommand_Clear-AzDataTable PSCmdlet_Get-AzDataTable PSCommand_Get-AzDataTable PSCmdlet_Get-AzDataTableEntity PSCommand_Get-AzDataTableEntity PSCmdlet_Remove-AzDataTableEntity PSCommand_Remove-AzDataTableEntity PSCmdlet_Update-AzDataTableEntity PSCommand_Update-AzDataTableEntity PSCmdlet_New-AzDataTableContext PSCommand_New-AzDataTableContext PSCmdlet_Remove-AzDataTable PSCommand_Remove-AzDataTable PSCmdlet_New-AzDataTable PSCommand_New-AzDataTable PSIncludes_Cmdlet False - 2024-03-18T14:41:34Z - 3.1.3 + 2024-10-19T16:20:00Z + 3.3.1 Emanuel Palm false Module - AzBobbyTables.nuspec|CHANGELOG.md|dependencies\AzBobbyTables.Core.pdb|dependencies\Microsoft.VisualStudio.Validation.dll|dependencies\System.Memory.Data.dll|dependencies\System.Runtime.CompilerServices.Unsafe.dll|dependencies\System.Numerics.Vectors.dll|dependencies\System.Text.Json.dll|LICENSE|dependencies\AzBobbyTables.Core.dll|dependencies\System.Threading.Tasks.Extensions.dll|dependencies\Microsoft.VisualStudio.Threading.dll|AzBobbyTables.PS.pdb|dependencies\System.Security.AccessControl.dll|dependencies\Microsoft.Win32.Registry.dll|dependencies\System.Text.Encodings.Web.dll|AzBobbyTables.psd1|dependencies\System.Buffers.dll|dependencies\Azure.Data.Tables.dll|dependencies\System.Memory.dll|AzBobbyTables.PS.dll|dependencies\System.Diagnostics.DiagnosticSource.dll|dependencies\Microsoft.Bcl.AsyncInterfaces.dll|dependencies\System.Security.Principal.Windows.dll|en-US\AzBobbyTables.PS.dll-Help.xml|dependencies\System.Linq.Async.dll|dependencies\Azure.Core.dll + AzBobbyTables.nuspec|dependencies\Azure.Data.Tables.dll|dependencies\Microsoft.Bcl.AsyncInterfaces.dll|dependencies\System.Memory.Data.dll|AzBobbyTables.PS.dll|dependencies\System.Text.Encodings.Web.dll|dependencies\Azure.Core.dll|dependencies\AzBobbyTables.Core.dll|LICENSE|dependencies\System.Security.Principal.Windows.dll|dependencies\Microsoft.VisualStudio.Validation.dll|dependencies\System.Runtime.CompilerServices.Unsafe.dll|CHANGELOG.md|dependencies\AzBobbyTables.Core.pdb|dependencies\Microsoft.VisualStudio.Threading.dll|dependencies\System.Text.Json.dll|AzBobbyTables.PS.pdb|dependencies\System.ClientModel.dll|dependencies\System.Linq.Async.dll|dependencies\System.Threading.Tasks.Extensions.dll|AzBobbyTables.psd1|dependencies\Microsoft.Win32.Registry.dll|dependencies\System.Numerics.Vectors.dll|dependencies\System.Buffers.dll|en-US\AzBobbyTables.PS.dll-Help.xml|dependencies\System.Memory.dll|dependencies\System.Diagnostics.DiagnosticSource.dll|dependencies\System.Security.AccessControl.dll eead4f42-5080-4f83-8901-340c529a5a11 7.0 pipe.how
- C:\GitHub\CIPP Workspace\CIPP-API\Modules\AzBobbyTables\3.1.3 + C:\GitHub\CIPP Workspace\CIPP-API\Modules\AzBobbyTables\3.3.1 diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.dll b/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.dll new file mode 100644 index 000000000000..ed1ae67e4b44 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.pdb b/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.pdb new file mode 100644 index 000000000000..00c402d71f90 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/AzBobbyTables.Core.pdb differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Core.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Core.dll new file mode 100644 index 000000000000..fb5b1ba52966 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Core.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Data.Tables.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Data.Tables.dll new file mode 100644 index 000000000000..9527e455da9d Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/Azure.Data.Tables.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.Bcl.AsyncInterfaces.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.Bcl.AsyncInterfaces.dll new file mode 100644 index 000000000000..39fd1311f266 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.Bcl.AsyncInterfaces.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.VisualStudio.Threading.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.VisualStudio.Threading.dll new file mode 100644 index 000000000000..62814912b2cf Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.VisualStudio.Threading.dll differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.VisualStudio.Validation.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.VisualStudio.Validation.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.VisualStudio.Validation.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.VisualStudio.Validation.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.Win32.Registry.dll b/Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.Win32.Registry.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/Microsoft.Win32.Registry.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/Microsoft.Win32.Registry.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Buffers.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Buffers.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Buffers.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Buffers.dll diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/System.ClientModel.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.ClientModel.dll new file mode 100644 index 000000000000..1363faf66562 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/System.ClientModel.dll differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Diagnostics.DiagnosticSource.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Diagnostics.DiagnosticSource.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Diagnostics.DiagnosticSource.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Diagnostics.DiagnosticSource.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Linq.Async.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Linq.Async.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Linq.Async.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Linq.Async.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Memory.Data.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Memory.Data.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Memory.Data.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Memory.Data.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Memory.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Memory.dll similarity index 91% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Memory.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Memory.dll index 953a9d2e3926..1e6aef802063 100644 Binary files a/Modules/AzBobbyTables/3.1.3/dependencies/System.Memory.dll and b/Modules/AzBobbyTables/3.3.1/dependencies/System.Memory.dll differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Numerics.Vectors.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Numerics.Vectors.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Numerics.Vectors.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Numerics.Vectors.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Runtime.CompilerServices.Unsafe.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Runtime.CompilerServices.Unsafe.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Runtime.CompilerServices.Unsafe.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Runtime.CompilerServices.Unsafe.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Security.AccessControl.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Security.AccessControl.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Security.AccessControl.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Security.AccessControl.dll diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Security.Principal.Windows.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Security.Principal.Windows.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Security.Principal.Windows.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Security.Principal.Windows.dll diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Encodings.Web.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Encodings.Web.dll new file mode 100644 index 000000000000..29ef2aeda7ed Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Encodings.Web.dll differ diff --git a/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Json.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Json.dll new file mode 100644 index 000000000000..5417430f23c0 Binary files /dev/null and b/Modules/AzBobbyTables/3.3.1/dependencies/System.Text.Json.dll differ diff --git a/Modules/AzBobbyTables/3.1.3/dependencies/System.Threading.Tasks.Extensions.dll b/Modules/AzBobbyTables/3.3.1/dependencies/System.Threading.Tasks.Extensions.dll similarity index 100% rename from Modules/AzBobbyTables/3.1.3/dependencies/System.Threading.Tasks.Extensions.dll rename to Modules/AzBobbyTables/3.3.1/dependencies/System.Threading.Tasks.Extensions.dll diff --git a/Modules/AzBobbyTables/3.1.3/en-US/AzBobbyTables.PS.dll-Help.xml b/Modules/AzBobbyTables/3.3.1/en-US/AzBobbyTables.PS.dll-Help.xml similarity index 77% rename from Modules/AzBobbyTables/3.1.3/en-US/AzBobbyTables.PS.dll-Help.xml rename to Modules/AzBobbyTables/3.3.1/en-US/AzBobbyTables.PS.dll-Help.xml index ca1b9df08912..0261a5fa7941 100644 --- a/Modules/AzBobbyTables/3.1.3/en-US/AzBobbyTables.PS.dll-Help.xml +++ b/Modules/AzBobbyTables/3.3.1/en-US/AzBobbyTables.PS.dll-Help.xml @@ -50,7 +50,7 @@ None - + Force Overwrites provided entities if they exist. @@ -62,6 +62,62 @@ False + + Add-AzDataTableEntity + + Context + + A context object created by New-AzDataTableContext, with authentication information for the table to operate on. + + AzDataTableContext + + AzDataTableContext + + + None + + + CreateTableIfNotExists + + If the table should be created if it does not exist. + + + SwitchParameter + + + False + + + Entity + + The entities to add to the table. + + Object[] + + Object[] + + + None + + + OperationType + + The operation type to perform on the entities. See the Azure SDK documentation for more information: + https://learn.microsoft.com/en-us/dotnet/api/azure.data.tables.tabletransactionactiontype + + + Add + UpsertReplace + UpsertMerge + + String + + String + + + None + + @@ -100,7 +156,7 @@ None - + Force Overwrites provided entities if they exist. @@ -112,6 +168,19 @@ False + + OperationType + + The operation type to perform on the entities. See the Azure SDK documentation for more information: + https://learn.microsoft.com/en-us/dotnet/api/azure.data.tables.tabletransactionactiontype + + String + + String + + + None + @@ -161,6 +230,17 @@ PS C:\> Add-AzDataTableEntity -Entity $Users -Context $Context -ForceAdd multiple users to a table using a shared access signature URL, overwriting any existing rows. + + -------------------------- Example 3 -------------------------- + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $Users = @( +>> @{ FirstName = 'Bobby'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '1' }, +>> @{ FirstName = 'Bobby Junior'; LastName = 'Tables'; PartitionKey = 'Example'; RowKey = '2' } ) +PS C:\> Add-AzDataTableEntity -Entity $Users -Context $Context -OperationType 'UpsertMerge' + + Add multiple users to a table using a connection string, merging entities with any existing rows. + + @@ -252,6 +332,120 @@ PS C:\> Clear-AzDataTable $Context + + + Get-AzDataTable + Get + AzDataTable + + Get the names of all tables in the storage account. + + + + Get the names of all tables in the storage account. + The optional `-Filter` parameter can be used to filter the tables returned. For more information on the filter syntax, see the Azure Table service documentation: + https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities + + + + Get-AzDataTable + + Context + + A context object created by New-AzDataTableContext, with authentication information for the storage account to operate on. + + AzDataTableContext + + AzDataTableContext + + + None + + + Filter + + A string to filter the tables returned. For more information on the filter syntax, see the Azure Table service documentation: + https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities + + String + + String + + + None + + + + + + Context + + A context object created by New-AzDataTableContext, with authentication information for the storage account to operate on. + + AzDataTableContext + + AzDataTableContext + + + None + + + Filter + + A string to filter the tables returned. For more information on the filter syntax, see the Azure Table service documentation: + https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities + + String + + String + + + None + + + + + + None + + + + + + + + + + System.String + + + + + + + + + + + + + + -------------------------- Example 1 -------------------------- + PS C:\> Get-AzDataTable -Context $Context + + Gets all table names in the storage account. + + + + -------------------------- Example 2 -------------------------- + PS C:\> Get-AzDataTable -Context $Context -Filter "TableName eq '$MyTableName'" + + Gets the table named `$MyTableName` to see if it exists. + + + + + Get-AzDataTableEntity @@ -647,7 +841,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -674,7 +868,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -701,7 +895,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -740,7 +934,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -767,7 +961,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -866,7 +1060,7 @@ PS C:\> New-AzDataTable -Context $Context None - + TableName The name of the table. @@ -1074,6 +1268,17 @@ PS C:\> Remove-AzDataTable -Context $Context None + + Force + + Skips ETag validation and remove entity even if it has changed. + + + SwitchParameter + + + False + @@ -1101,6 +1306,18 @@ PS C:\> Remove-AzDataTable -Context $Context None + + Force + + Skips ETag validation and remove entity even if it has changed. + + SwitchParameter + + SwitchParameter + + + False + @@ -1130,26 +1347,42 @@ PS C:\> Remove-AzDataTable -Context $Context -------------------------- Example 1 -------------------------- - PS C:\> $Entity = @{ PartitionKey = 'Example'; RowKey = '1' } -PS C:\> Remove-AzDataTableEntity -Entity $Entity -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key +PS C:\> $Entity = @{ PartitionKey = 'Example'; RowKey = '1' } +PS C:\> Remove-AzDataTableEntity -Entity $Entity -Context $Context Remove the entity with PartitionKey "Example" and RowKey "1", using the storage account name and an access key. -------------------------- Example 2 -------------------------- - PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby' and LastName eq 'Tables'" -TableName $TableName -ConnectionString $ConnectionString -PS C:\> Remove-AzDataTableEntity -Entity $UserEntity -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby' and LastName eq 'Tables'" -Context $Context +PS C:\> Remove-AzDataTableEntity -Entity $UserEntity -Context $Context Get the user "Bobby Tables" from the table using a connection string, then remove the user using the storage account name and an access key. -------------------------- Example 3 -------------------------- - PS C:\> $Users = Get-AzDataTableEntity -Filter "LastName eq 'Tables'" -TableName $TableName -ConnectionString $ConnectionString -PS C:\> Remove-AzDataTableEntity -Entity $Users -TableName $TableName -StorageAccountName $Name -StorageAccountKey $Key + PS C:\> $Context = New-AzDataTableContext -StorageAccountName $StorageName -TableName $TableName -ManagedIdentity +PS C:\> $Users = Get-AzDataTableEntity -Filter "LastName eq 'Tables'" -Context $Context +PS C:\> Remove-AzDataTableEntity -Entity $Users -Context $Context + + Gets all users with the last name "Tables" from the table using a system-assigned managed identity, then removes the users. + + + + -------------------------- Example 4 -------------------------- + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $Users = Get-AzDataTableEntity -Filter "LastName eq 'Tables'" -Context $Context +PS C:\> # Imagine that the users are updated somewhere else +PS C:\> Remove-AzDataTableEntity -Entity $Users -Context $Context +PS C:\> # ERROR - The ETag of Users do not match +PS C:\> Remove-AzDataTableEntity -Entity $Users -Context $Context -Force +PS C:\> # OK - The -Force switch overrides ETag validation - Gets all users with the last name "Tables" from the table using a connection string, then removes the users using the storage account name and an access key. + Force remove all users with the last name Tables, overriding ETag validation. @@ -1196,6 +1429,34 @@ PS C:\> Remove-AzDataTableEntity -Entity $Users -TableName $TableName -Storag None + + Force + + Skips ETag validation and updates entity even if it has changed. + + + SwitchParameter + + + False + + + OperationType + + The operation type to perform on the entities. See the Azure SDK documentation for more information: + https://learn.microsoft.com/en-us/dotnet/api/azure.data.tables.tabletransactionactiontype + + + UpdateMerge + UpdateReplace + + String + + String + + + None + @@ -1223,6 +1484,31 @@ PS C:\> Remove-AzDataTableEntity -Entity $Users -TableName $TableName -Storag None + + Force + + Skips ETag validation and updates entity even if it has changed. + + SwitchParameter + + SwitchParameter + + + False + + + OperationType + + The operation type to perform on the entities. See the Azure SDK documentation for more information: + https://learn.microsoft.com/en-us/dotnet/api/azure.data.tables.tabletransactionactiontype + + String + + String + + + None + @@ -1252,13 +1538,28 @@ PS C:\> Remove-AzDataTableEntity -Entity $Users -TableName $TableName -Storag -------------------------- Example 1 -------------------------- - PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby'" -TableName $TableName -ConnectionString $ConnectionString + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby'" -Context $Context PS C:\> $UserEntity['LastName'] = 'Tables' -PS C:\> Update-AzDataTableEntity -Entity $UserEntity -TableName $TableName -ConnectionString $ConnectionString +PS C:\> Update-AzDataTableEntity -Entity $UserEntity -Context $Context Update the last name of the user "Bobby" to "Tables" using a connection string. + + -------------------------- Example 2 -------------------------- + PS C:\> $Context = New-AzDataTableContext -TableName $TableName -ConnectionString $ConnectionString +PS C:\> $UserEntity = Get-AzDataTableEntity -Filter "FirstName eq 'Bobby'" -Context $Context +PS C:\> $UserEntity['LastName'] = 'Tables' +PS C:\> # Imagine that the user is updated somewhere else +PS C:\> Update-AzDataTableEntity -Entity $UserEntity -Context $Context +PS C:\> # ERROR - The ETag of UserEntity does not match +PS C:\> Update-AzDataTableEntity -Entity $UserEntity -Context $Context -Force +PS C:\> # OK - The -Force switch overrides ETag validation + + Force update the last name of the user "Bobby" to "Tables" using a connection string, overriding ETag validation. + + diff --git a/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 b/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 index 86affa77ad29..5b811bbd405e 100644 --- a/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 +++ b/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 @@ -85,14 +85,19 @@ function Add-CIPPDelegatedPermission { $OldScope = ($CurrentDelegatedScopes | Where-Object -Property Resourceid -EQ $svcPrincipalId.id) if (!$OldScope) { - $Createbody = @{ - clientId = $ourSVCPrincipal.id - consentType = 'AllPrincipals' - resourceId = $svcPrincipalId.id - scope = $NewScope - } | ConvertTo-Json -Compress - $CreateRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/oauth2PermissionGrants' -tenantid $Tenantfilter -body $Createbody -type POST -NoAuthCheck $true - $Results.add("Successfully added permissions for $($svcPrincipalId.displayName)") + try { + $Createbody = @{ + clientId = $ourSVCPrincipal.id + consentType = 'AllPrincipals' + resourceId = $svcPrincipalId.id + scope = $NewScope + } | ConvertTo-Json -Compress + $CreateRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/oauth2PermissionGrants' -tenantid $Tenantfilter -body $Createbody -type POST -NoAuthCheck $true + $Results.add("Successfully added permissions for $($svcPrincipalId.displayName)") + } catch { + $Results.add("Failed to add permissions for $($svcPrincipalId.displayName): $(Get-NormalizedError -message $_.Exception.Message)") + continue + } } else { # Cleanup multiple scope entries and patch first id if (($OldScope.id | Measure-Object).Count -gt 1) { diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 index 8832bc51ec1f..ed3ed22e4b95 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertSharepointQuota.ps1 @@ -27,7 +27,7 @@ function Get-CIPPAlertSharepointQuota { } $UsedStoragePercentage = [int](($sharepointQuota.GeoUsedStorageMB / $sharepointQuota.TenantStorageMB) * 100) if ($UsedStoragePercentage -gt $Value) { - $AlertData = "SharePoint Storage is at $($UsedStoragePercentage)%. Your alert threshold is $($Value)%" + $AlertData = "SharePoint Storage is at $($UsedStoragePercentage)% [$([math]::Round($sharepointQuota.GeoUsedStorageMB / 1024, 2)) GB/$([math]::Round($sharepointQuota.TenantStorageMB / 1024, 2)) GB]. Your alert threshold is $($Value)%" Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData } } diff --git a/Modules/CIPPCore/Public/AuditLogs/Get-CippAuditLogSearches.ps1 b/Modules/CIPPCore/Public/AuditLogs/Get-CippAuditLogSearches.ps1 index ba21f2dedcb2..1aac0b36eeab 100644 --- a/Modules/CIPPCore/Public/AuditLogs/Get-CippAuditLogSearches.ps1 +++ b/Modules/CIPPCore/Public/AuditLogs/Get-CippAuditLogSearches.ps1 @@ -17,7 +17,8 @@ function Get-CippAuditLogSearches { if ($ReadyToProcess.IsPresent) { $AuditLogSearchesTable = Get-CippTable -TableName 'AuditLogSearches' $15MinutesAgo = (Get-Date).AddMinutes(-15).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') - $PendingQueries = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "Tenant eq '$TenantFilter' and (CippStatus eq 'Pending' or (CippStatus eq 'Processing' and Timestamp le datetime'$15MinutesAgo'))" | Sort-Object Timestamp + $1DayAgo = (Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') + $PendingQueries = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "Tenant eq '$TenantFilter' and (CippStatus eq 'Pending' or (CippStatus eq 'Processing' and Timestamp le datetime'$15MinutesAgo')) and Timestamp ge datetime'$1DayAgo'" | Sort-Object Timestamp $BulkRequests = foreach ($PendingQuery in $PendingQueries) { @{ diff --git a/Modules/CIPPCore/Public/AuditLogs/Remove-CippAuditLogSearch.ps1 b/Modules/CIPPCore/Public/AuditLogs/Remove-CippAuditLogSearch.ps1 new file mode 100644 index 000000000000..39457758e848 --- /dev/null +++ b/Modules/CIPPCore/Public/AuditLogs/Remove-CippAuditLogSearch.ps1 @@ -0,0 +1,23 @@ +function Remove-CippAuditLogSearch { + <# + .SYNOPSIS + Get the results of an audit log search + .DESCRIPTION + Get the results of an audit log search from the Graph API + .PARAMETER TenantFilter + The tenant to filter on. + .PARAMETER QueryId + The ID of the query to get the results for. + #> + param ( + [Parameter(Mandatory = $true)] + [string]$TenantFilter, + [Parameter(ValueFromPipelineByPropertyName = $true, Mandatory = $true)] + [Alias('id')] + [string]$QueryId + ) + + process { + New-GraphPostRequest -type DELETE -body '{}' -uri ('https://graph.microsoft.com/beta/security/auditLog/queries/{0}' -f $QueryId) -AsApp $true -tenantid $TenantFilter + } +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Applications/Push-UploadApplication.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Applications/Push-UploadApplication.ps1 index f718564301fc..f96467bd98eb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Applications/Push-UploadApplication.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Applications/Push-UploadApplication.ps1 @@ -40,7 +40,7 @@ function Push-UploadApplication { } $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter $RemoveCacheFile = if ($chocoapp.Tenant -ne 'AllTenants') { - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow } else { $Table.Force = $true Add-CIPPAzDataTableEntity @Table -Entity @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 index 3c682fb8854d..168342bd7701 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 @@ -6,7 +6,7 @@ function Push-DomainAnalyserDomain { param($Item) $DomainTable = Get-CippTable -tablename 'Domains' $Filter = "PartitionKey eq 'TenantDomains' and RowKey eq '{0}'" -f $Item.RowKey - $DomainObject = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter + $DomainObject = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter | Select-Object * -ExcludeProperty table try { $ConfigTable = Get-CippTable -tablename Config @@ -35,7 +35,7 @@ function Push-DomainAnalyserDomain { try { $Tenant = $DomainObject.TenantDetails | ConvertFrom-Json -ErrorAction Stop } catch { - $Tenant = @{Tenant = 'None' } + $Tenant = @{ Tenant = 'None' } } $Result = [PSCustomObject]@{ @@ -310,7 +310,13 @@ function Push-DomainAnalyserDomain { $Result.ScorePercentage = [int](($Result.Score / $Result.MaximumScore) * 100) $Result.ScoreExplanation = ($ScoreExplanation) -join ', ' - $DomainObject.DomainAnalyser = (ConvertTo-Json -InputObject $Result -Depth 5 -Compress).ToString() + $Json = (ConvertTo-Json -InputObject $Result -Depth 5 -Compress).ToString() + + if ($DomainObject.PSObject.Properties.Name -notcontains 'DomainAnalyser') { + $DomainObject | Add-Member -MemberType NoteProperty -Name DomainAnalyser -Value $Json + } else { + $DomainObject.DomainAnalyser = $Json + } try { $DomainTable.Entity = $DomainObject diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserTenant.ps1 index 203428ec580e..3b4e14f17ba2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserTenant.ps1 @@ -14,13 +14,30 @@ function Push-DomainAnalyserTenant { $CleanupCount = ($CleanupRows | Measure-Object).Count if ($CleanupCount -gt 0) { Write-LogMessage -API 'DomainAnalyser' -tenant $Tenant.defaultDomainName -message "Cleaning up $CleanupCount domain(s) for excluded tenant" -sev Info - Remove-AzDataTableEntity @DomainTable -Entity $CleanupRows + Remove-AzDataTableEntity -Force @DomainTable -Entity $CleanupRows } } elseif ($Tenant.GraphErrorCount -gt 50) { return } else { try { - $Domains = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $Tenant.customerId | Where-Object { ($_.id -notlike '*.microsoftonline.com' -and $_.id -NotLike '*.exclaimer.cloud' -and $_.id -Notlike '*.excl.cloud' -and $_.id -NotLike '*.codetwo.online' -and $_.id -NotLike '*.call2teams.com' -and $_.id -notlike '*signature365.net' -and $_.isVerified) } + # Remove domains that are not wanted, and used for cloud signature services + $ExclusionDomains = @( + '*.microsoftonline.com' + '*.exclaimer.cloud' + '*.excl.cloud' + '*.codetwo.online' + '*.call2teams.com' + '*signature365.net' + ) + $Domains = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $Tenant.customerId | Where-Object { $_.isVerified -eq $true } | ForEach-Object { + $Domain = $_ + foreach ($ExclusionDomain in $ExclusionDomains) { + if ($Domain.id -like $ExclusionDomain) { + $Domain = $null + } + } + $Domain + } | Where-Object { $_ -ne $null } $TenantDomains = foreach ($d in $Domains) { [PSCustomObject]@{ @@ -51,7 +68,7 @@ function Push-DomainAnalyserTenant { $OldDomain = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter if ($OldDomain) { - Remove-AzDataTableEntity @DomainTable -Entity $OldDomain | Out-Null + Remove-AzDataTableEntity -Force @DomainTable -Entity $OldDomain | Out-Null } $Filter = "PartitionKey eq 'TenantDomains' and RowKey eq '{0}'" -f $TenantDomain.Domain diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Graph Requests/Push-ListGraphRequestQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Graph Requests/Push-ListGraphRequestQueue.ps1 index c7b2de89ec5a..3c47e4eb5c51 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Graph Requests/Push-ListGraphRequestQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Graph Requests/Push-ListGraphRequestQueue.ps1 @@ -25,7 +25,7 @@ function Push-ListGraphRequestQueue { Write-Information "Filter: $Filter" $Existing = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey if ($Existing) { - $null = Remove-AzDataTableEntity @Table -Entity $Existing + $null = Remove-AzDataTableEntity -Force @Table -Entity $Existing } $GraphRequestParams = @{ TenantFilter = $Item.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandard.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandard.ps1 index 964cd1d9294e..276c90519a39 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandard.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Standards/Push-CIPPStandard.ps1 @@ -7,17 +7,17 @@ function Push-CIPPStandard { $Item ) - Write-Host "Received queue item for $($Item.Tenant) and standard $($Item.Standard)." + Write-Information "Received queue item for $($Item.Tenant) and standard $($Item.Standard)." $Tenant = $Item.Tenant $Standard = $Item.Standard $FunctionName = 'Invoke-CIPPStandard{0}' -f $Standard - Write-Host "We'll be running $FunctionName" - $Rerun = Test-CIPPRerun -Type Standard -Tenant $Tenant -Settings $Item.Settings -API $Standard + Write-Information "We'll be running $FunctionName" + $Rerun = Test-CIPPRerun -Type Standard -Tenant $Tenant -API $Standard if ($Rerun) { - Write-Host 'Detected rerun. Exiting cleanly' + Write-Information 'Detected rerun. Exiting cleanly' exit 0 } else { - Write-Host "Rerun is set to false. We'll be running $FunctionName" + Write-Information "Rerun is set to false. We'll be running $FunctionName" } try { & $FunctionName -Tenant $Item.Tenant -Settings $Item.Settings -ErrorAction Stop diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-AuditLogTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-AuditLogTenant.ps1 index ef5ea518bcb8..b5cb9286edc5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-AuditLogTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-AuditLogTenant.ps1 @@ -3,77 +3,97 @@ function Push-AuditLogTenant { $ConfigTable = Get-CippTable -TableName 'WebhookRules' $TenantFilter = $Item.TenantFilter - Write-Information "Audit Logs: Processing $($TenantFilter)" - - # Get CIPP Url, cleanup legacy tasks - $SchedulerConfig = Get-CippTable -TableName 'SchedulerConfig' - $LegacyWebhookTasks = Get-CIPPAzDataTableEntity @SchedulerConfig -Filter "PartitionKey eq 'webhookcreation'" - $LegacyUrl = $LegacyWebhookTasks | Select-Object -First 1 -ExpandProperty CIPPURL - $CippConfigTable = Get-CippTable -tablename Config - $CippConfig = Get-CIPPAzDataTableEntity @CippConfigTable -Filter "PartitionKey eq 'InstanceProperties' and RowKey eq 'CIPPURL'" - if ($LegacyUrl) { - if (!$CippConfig) { - $Entity = @{ - PartitionKey = 'InstanceProperties' - RowKey = 'CIPPURL' - Value = [string]([System.Uri]$LegacyUrl).Host + try { + Write-Information "Audit Logs: Processing $($TenantFilter)" + # Get CIPP Url, cleanup legacy tasks + $SchedulerConfig = Get-CippTable -TableName 'SchedulerConfig' + $LegacyWebhookTasks = Get-CIPPAzDataTableEntity @SchedulerConfig -Filter "PartitionKey eq 'webhookcreation'" + $LegacyUrl = $LegacyWebhookTasks | Select-Object -First 1 -ExpandProperty CIPPURL + $CippConfigTable = Get-CippTable -tablename Config + $CippConfig = Get-CIPPAzDataTableEntity @CippConfigTable -Filter "PartitionKey eq 'InstanceProperties' and RowKey eq 'CIPPURL'" + if ($LegacyUrl) { + if (!$CippConfig) { + $Entity = @{ + PartitionKey = 'InstanceProperties' + RowKey = 'CIPPURL' + Value = [string]([System.Uri]$LegacyUrl).Host + } + Add-CIPPAzDataTableEntity @CippConfigTable -Entity $Entity -Force } - Add-CIPPAzDataTableEntity @CippConfigTable -Entity $Entity -Force - } - # remove legacy webhooks - foreach ($Task in $LegacyWebhookTasks) { - Remove-AzDataTableEntity @SchedulerConfig -Entity $Task + # remove legacy webhooks + foreach ($Task in $LegacyWebhookTasks) { + Remove-AzDataTableEntity -Force @SchedulerConfig -Entity $Task + } + $CIPPURL = $LegacyUrl + } else { + $CIPPURL = 'https://{0}' -f $CippConfig.Value } - $CIPPURL = $LegacyUrl - } else { - $CIPPURL = 'https://{0}' -f $CippConfig.Value - } - # Get webhook rules - $ConfigEntries = Get-CIPPAzDataTableEntity @ConfigTable - $LogSearchesTable = Get-CippTable -TableName 'AuditLogSearches' + # Get webhook rules + $ConfigEntries = Get-CIPPAzDataTableEntity @ConfigTable + $LogSearchesTable = Get-CippTable -TableName 'AuditLogSearches' - $Configuration = $ConfigEntries | Where-Object { ($_.Tenants -match $TenantFilter -or $_.Tenants -match 'AllTenants') } - if ($Configuration) { - try { - $LogSearches = Get-CippAuditLogSearches -TenantFilter $TenantFilter -ReadyToProcess | Select-Object -First 20 - Write-Information ('Audit Logs: Found {0} searches, begin processing' -f $LogSearches.Count) - foreach ($Search in $LogSearches) { - $SearchEntity = Get-CIPPAzDataTableEntity @LogSearchesTable -Filter "Tenant eq '$($TenantFilter)' and RowKey eq '$($Search.id)'" - $SearchEntity.CippStatus = 'Processing' - Add-CIPPAzDataTableEntity @LogSearchesTable -Entity $SearchEntity -Force - try { - # Test the audit log rules against the search results - $AuditLogTest = Test-CIPPAuditLogRules -TenantFilter $TenantFilter -SearchId $Search.id + $Configuration = $ConfigEntries | Where-Object { ($_.Tenants -match $TenantFilter -or $_.Tenants -match 'AllTenants') } + if ($Configuration) { + try { + $LogSearches = Get-CippAuditLogSearches -TenantFilter $TenantFilter -ReadyToProcess | Select-Object -First 10 + Write-Information ('Audit Logs: Found {0} searches, begin processing' -f $LogSearches.Count) + foreach ($Search in $LogSearches) { + $SearchEntity = Get-CIPPAzDataTableEntity @LogSearchesTable -Filter "Tenant eq '$($TenantFilter)' and RowKey eq '$($Search.id)'" + $SearchEntity.CippStatus = 'Processing' + Add-CIPPAzDataTableEntity @LogSearchesTable -Entity $SearchEntity -Force + try { + # Test the audit log rules against the search results + $AuditLogTest = Test-CIPPAuditLogRules -TenantFilter $TenantFilter -SearchId $Search.id - $SearchEntity.CippStatus = 'Completed' - $MatchedRules = [string](ConvertTo-Json -Compress -InputObject $AuditLogTest.MatchedRules) - $SearchEntity | Add-Member -MemberType NoteProperty -Name MatchedRules -Value $MatchedRules -Force - $SearchEntity | Add-Member -MemberType NoteProperty -Name MatchedLogs -Value $AuditLogTest.MatchedLogs -Force - $SearchEntity | Add-Member -MemberType NoteProperty -Name TotalLogs -Value $AuditLogTest.TotalLogs -Force - } catch { - $SearchEntity.CippStatus = 'Failed' - Write-Information "Error processing audit log rules: $($_.Exception.Message)" - $Exception = [string](ConvertTo-Json -Compress -InputObject (Get-CippException -Exception $_)) - $SearchEntity | Add-Member -MemberType NoteProperty -Name Error -Value $Exception - } - Add-CIPPAzDataTableEntity @LogSearchesTable -Entity $SearchEntity -Force - $DataToProcess = ($AuditLogTest).DataToProcess - Write-Information "Audit Logs: Data to process found: $($DataToProcess.count) items" - if ($DataToProcess) { - foreach ($AuditLog in $DataToProcess) { - Write-Information "Processing $($AuditLog.operation)" - $Webhook = @{ - Data = $AuditLog - CIPPURL = [string]$CIPPURL - TenantFilter = $TenantFilter + $SearchEntity.CippStatus = 'Completed' + $MatchedRules = [string](ConvertTo-Json -Compress -InputObject $AuditLogTest.MatchedRules) + $SearchEntity | Add-Member -MemberType NoteProperty -Name MatchedRules -Value $MatchedRules -Force + $SearchEntity | Add-Member -MemberType NoteProperty -Name MatchedLogs -Value $AuditLogTest.MatchedLogs -Force + $SearchEntity | Add-Member -MemberType NoteProperty -Name TotalLogs -Value $AuditLogTest.TotalLogs -Force + } catch { + if ($_.Exception.Message -match 'Request rate is large. More Request Units may be needed, so no changes were made. Please retry this request later.') { + $SearchEntity.CippStatus = 'Pending' + Write-Information "Audit Log search: Rate limit hit for $($SearchEntity.RowKey)." + if ($SearchEntity.PSObject.Properties.Name -contains 'RetryCount') { + $SearchEntity.RetryCount++ + } else { + $SearchEntity | Add-Member -MemberType NoteProperty -Name RetryCount -Value 1 + } + } else { + $Exception = [string](ConvertTo-Json -Compress -InputObject (Get-CippException -Exception $_)) + $SearchEntity | Add-Member -MemberType NoteProperty -Name Error -Value $Exception + $SearchEntity.CippStatus = 'Failed' + Write-Information "Error processing audit log rules: $($_.Exception.Message)" + } + $AuditLogTest = [PSCustomObject]@{ + DataToProcess = @() + } + } + Add-CIPPAzDataTableEntity @LogSearchesTable -Entity $SearchEntity -Force + $DataToProcess = ($AuditLogTest).DataToProcess + Write-Information "Audit Logs: Data to process found: $($DataToProcess.count) items" + if ($DataToProcess) { + foreach ($AuditLog in $DataToProcess) { + Write-Information "Processing $($AuditLog.operation)" + $Webhook = @{ + Data = $AuditLog + CIPPURL = [string]$CIPPURL + TenantFilter = $TenantFilter + } + try { + Invoke-CippWebhookProcessing @Webhook + } catch { + Write-Information "Error processing webhook: $($_.Exception.Message)" + } } - Invoke-CippWebhookProcessing @Webhook } } + } catch { + Write-Information ( 'Audit Log search: Error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message) } - } catch { - Write-Information ( 'Audit Logs: Error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message) } + } catch { + Write-Information ( 'Push-AuditLogTenant: Error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message) } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-PublicWebhookProcess.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-PublicWebhookProcess.ps1 index 0669c01fabfa..0cdc860b7e48 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-PublicWebhookProcess.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-PublicWebhookProcess.ps1 @@ -19,6 +19,6 @@ function Push-PublicWebhookProcess { Write-Host "Webhook Exception: $($_.Exception.Message)" } finally { $Entity = $Webhook | Select-Object -Property RowKey, PartitionKey - Remove-AzDataTableEntity @Table -Entity $Entity + Remove-AzDataTableEntity -Force @Table -Entity $Entity } -} \ No newline at end of file +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-Schedulerwebhookcreation.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-Schedulerwebhookcreation.ps1 index 62da83dff4cd..de538961a47a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-Schedulerwebhookcreation.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Webhooks/Push-Schedulerwebhookcreation.ps1 @@ -20,13 +20,13 @@ function Push-Schedulerwebhookcreation { if ($Webhook) { Write-Information "Found existing webhook for $Tenant - $($Row.webhookType)" if ($Row.tenantid -ne 'AllTenants') { - Remove-AzDataTableEntity @Table -Entity $Row + Remove-AzDataTableEntity -Force @Table -Entity $Row } if (($Webhook | Measure-Object).Count -gt 1) { $Webhook = $Webhook | Select-Object -First 1 $WebhooksToRemove = $ExistingWebhooks | Where-Object { $_.RowKey -ne $Webhook.RowKey } foreach ($RemoveWebhook in $WebhooksToRemove) { - Remove-AzDataTableEntity @WebhookTable -Entity $RemoveWebhook + Remove-AzDataTableEntity -Force @WebhookTable -Entity $RemoveWebhook } } } else { @@ -34,7 +34,7 @@ function Push-Schedulerwebhookcreation { try { $NewSub = New-CIPPGraphSubscription -TenantFilter $Tenant -EventType $Row.webhookType -auditLogAPI $true if ($NewSub.Success -and $Row.tenantid -ne 'AllTenants') { - Remove-AzDataTableEntity @Table -Entity $Row + Remove-AzDataTableEntity -Force @Table -Entity $Row } else { Write-Information "Failed to create webhook for $Tenant - $($Row.webhookType) - $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 index f01062fe5720..e852991c7c9a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 @@ -142,11 +142,11 @@ function Invoke-ExecDurableFunctions { if ($Request.Query.PartitionKey) { $HistoryEntities = Get-CIPPAzDataTableEntity @HistoryTable -Filter "PartitionKey eq '$($Request.Query.PartitionKey)'" -Property RowKey, PartitionKey if ($HistoryEntities) { - Remove-AzDataTableEntity @HistoryTable -Entity $HistoryEntities + Remove-AzDataTableEntity -Force @HistoryTable -Entity $HistoryEntities } $Instance = Get-CIPPAzDataTableEntity @InstancesTable -Filter "PartitionKey eq '$($Request.Query.PartitionKey)'" -Property RowKey, PartitionKey if ($Instance) { - Remove-AzDataTableEntity @InstancesTable -Entity $Instance + Remove-AzDataTableEntity -Force @InstancesTable -Entity $Instance } $Body = [PSCustomObject]@{ Results = 'Orchestrator {0} purged successfully' -f $Request.Query.PartitionKey diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 index cadb2f70a770..841895a7b16c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecPartnerWebhook.ps1 @@ -42,15 +42,13 @@ function Invoke-ExecPartnerWebhook { } $Results = New-CIPPGraphSubscription @Webhook - if ($Request.Body.standardsExcludeAllTenants -eq $true) { - $ConfigTable = Get-CIPPTable -TableName Config - $PartnerWebhookOnboarding = [PSCustomObject]@{ - PartitionKey = 'Config' - RowKey = 'PartnerWebhookOnboarding' - StandardsExcludeAllTenants = $true - } - Add-CIPPAzDataTableEntity @ConfigTable -Entity $PartnerWebhookOnboarding -Force | Out-Null + $ConfigTable = Get-CIPPTable -TableName Config + $PartnerWebhookOnboarding = [PSCustomObject]@{ + PartitionKey = 'Config' + RowKey = 'PartnerWebhookOnboarding' + StandardsExcludeAllTenants = $Request.Body.standardsExcludeAllTenants } + Add-CIPPAzDataTableEntity @ConfigTable -Entity $PartnerWebhookOnboarding -Force | Out-Null } 'SendTest' { $Results = New-GraphPOSTRequest -uri 'https://api.partnercenter.microsoft.com/webhooks/v1/registration/validationEvents' -tenantid $env:TenantID -NoAuthCheck $true -scope 'https://api.partnercenter.microsoft.com/.default' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecSetCIPPAutoBackup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecSetCIPPAutoBackup.ps1 index b705c1da9fc5..798975625766 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecSetCIPPAutoBackup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecSetCIPPAutoBackup.ps1 @@ -17,7 +17,7 @@ Function Invoke-ExecSetCIPPAutoBackup { RowKey = $AutomatedCIPPBackupTask.RowKey PartitionKey = 'ScheduledTask' } - Remove-AzDataTableEntity @Table -Entity $task | Out-Null + Remove-AzDataTableEntity -Force @Table -Entity $task | Out-Null $TaskBody = [pscustomobject]@{ TenantFilter = 'AllTenants' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 index 2da498adaf36..26b0d4153cc3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 @@ -18,7 +18,7 @@ Function Invoke-RemoveScheduledItem { PartitionKey = 'ScheduledTask' } $Table = Get-CIPPTable -TableName 'ScheduledTasks' - Remove-AzDataTableEntity @Table -Entity $task + Remove-AzDataTableEntity -Force @Table -Entity $task Write-LogMessage -user $User -API $APINAME -message "Task removed: $($task.RowKey)" -Sev 'Info' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 index 44c87fd92425..b4614cd96b40 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomRole.ps1 @@ -25,7 +25,7 @@ function Invoke-ExecCustomRole { 'Delete' { Write-LogMessage -user $Request.Headers.'x-ms-client-principal' -API 'ExecCustomRole' -message "Deleted custom role $($Request.Body.RoleName)" -Sev 'Info' $Role = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$($Request.Body.RoleName)'" -Property RowKey, PartitionKey - Remove-AzDataTableEntity @Table -Entity $Role + Remove-AzDataTableEntity -Force @Table -Entity $Role $Body = @{Results = 'Custom role deleted' } } default { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 index 147855eab44c..d575cdab9956 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecDnsConfig.ps1 @@ -95,7 +95,7 @@ Function Invoke-ExecDnsConfig { 'RemoveDomain' { $Filter = "RowKey eq '{0}'" -f $Request.Query.Domain $DomainRow = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @DomainTable -Entity $DomainRow + Remove-AzDataTableEntity -Force @DomainTable -Entity $DomainRow Write-LogMessage -API $APINAME -tenant 'Global' -user $request.headers.'x-ms-client-principal' -message "Removed Domain - $($Request.Query.Domain) " -Sev 'Info' $body = [pscustomobject]@{ 'Results' = "Domain removed - $($Request.Query.Domain)" } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 index 8b18bb186e4a..063e26bb0d4b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeLicenses.ps1 @@ -55,7 +55,7 @@ Function Invoke-ExecExcludeLicenses { if ($Request.Query.RemoveExclusion) { $Filter = "RowKey eq '{0}' and PartitionKey eq 'License'" -f $Request.Query.Guid $Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $Entity + Remove-AzDataTableEntity -Force @Table -Entity $Entity Write-LogMessage -API $APINAME -user $request.headers.'x-ms-client-principal' -message "Removed exclusion $($Request.Query.GUID)" -Sev 'Info' $body = [pscustomobject]@{'Results' = "Success. We've removed $($Request.query.guid) from the excluded list." } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRemoveTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRemoveTenant.ps1 index 8e036778fb2d..72f227659de1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRemoveTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRemoveTenant.ps1 @@ -16,7 +16,7 @@ function Invoke-ExecRemoveTenant { $Tenant = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'Tenants' and RowKey eq '$($Request.Body.TenantID)'" -Property RowKey, PartitionKey, customerId, displayName if ($Tenant) { try { - Remove-AzDataTableEntity @Table -Entity $Tenant + Remove-AzDataTableEntity -Force @Table -Entity $Tenant $Body = @{Results = "$($Tenant.displayName) ($($Tenant.customerId)) deleted from CIPP. Note: This does not remove the GDAP relationship, see the Tenant Offboarding wizard to perform that action." } $StatusCode = [HttpStatusCode]::OK } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 index 476fffa02389..00cb9bd38a36 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecRestoreBackup.ps1 @@ -17,7 +17,7 @@ Function Invoke-ExecRestoreBackup { Write-Host ($line) $Table = Get-CippTable -tablename $line.table $ht2 = @{} - $line.psobject.properties | ForEach-Object { $ht2[$_.Name] = [string]$_.Value } + $line.psobject.properties | Where-Object { $_.Name -ne 'table' } | ForEach-Object { $ht2[$_.Name] = [string]$_.Value } $Table.Entity = $ht2 Add-CIPPAzDataTableEntity @Table -Force diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecWebhookSubscriptions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecWebhookSubscriptions.ps1 index 95c8b94f5fc9..35d6278e4649 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecWebhookSubscriptions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecWebhookSubscriptions.ps1 @@ -14,7 +14,7 @@ function Invoke-ExecWebhookSubscriptions { $Webhook = Get-AzDataTableEntity @Table -Filter "RowKey eq '$($Request.Query.WebhookID)'" -Property PartitionKey, RowKey if ($Webhook) { Remove-CIPPGraphSubscription -TenantFilter $Webhook.PartitionKey -CIPPID $Webhook.RowKey - Remove-AzDataTableEntity @Table -Entity $Webhook + Remove-AzDataTableEntity -Force @Table -Entity $Webhook Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @{ Results = "Deleted subscription $($Webhook.RowKey) for $($Webhook.PartitionKey)" } @@ -48,7 +48,7 @@ function Invoke-ExecWebhookSubscriptions { return } Remove-CIPPGraphSubscription @Unsubscribe - Remove-AzDataTableEntity @Table -Entity $Webhook + Remove-AzDataTableEntity -Force @Table -Entity $Webhook Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @{ Results = "Unsubscribed from $($Webhook.Resource) for $($Webhook.PartitionKey)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 index 05a909a9346b..b480e9222627 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Setup/Invoke-ExecSAMSetup.ps1 @@ -235,7 +235,7 @@ Function Invoke-ExecSAMSetup { } 4 { - Remove-AzDataTableEntity @Table -Entity $Rows + Remove-AzDataTableEntity -Force @Table -Entity $Rows $step = 5 $Results = @{'message' = 'setup completed.'; step = $step diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddRoomMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddRoomMailbox.ps1 index bc99ed1bc881..11b662d34d47 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddRoomMailbox.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddRoomMailbox.ps1 @@ -12,6 +12,7 @@ Function Invoke-AddRoomMailbox { $APIName = $TriggerMetadata.FunctionName $User = $request.headers.'x-ms-client-principal' + Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' # Write to the Azure Functions log stream. @@ -20,6 +21,7 @@ Function Invoke-AddRoomMailbox { $Results = [System.Collections.Generic.List[Object]]::new() $MailboxObject = $Request.body + $Tenant = $MailboxObject.tenantid $AddRoomParams = [pscustomobject]@{ Name = $MailboxObject.username DisplayName = $MailboxObject.displayName @@ -30,30 +32,30 @@ Function Invoke-AddRoomMailbox { } # Interact with query parameters or the body of the request. try { - $AddRoomRequest = New-ExoRequest -tenantid $($MailboxObject.tenantid) -cmdlet 'New-Mailbox' -cmdparams $AddRoomParams + $AddRoomRequest = New-ExoRequest -tenantid $Tenant -cmdlet 'New-Mailbox' -cmdparams $AddRoomParams $Results.Add("Successfully created room: $($MailboxObject.DisplayName).") - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Created room $($MailboxObject.DisplayName) with id $($AddRoomRequest.id)" -Sev 'Info' + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Created room $($MailboxObject.DisplayName) with id $($AddRoomRequest.id)" -Sev 'Info' # Block sign-in for the mailbox try { - $Request = Set-CIPPSignInState -userid $AddRoomRequest.ExternalDirectoryObjectId -TenantFilter $($MailboxObject.tenantid) -APIName $APINAME -ExecutingUser $User -AccountEnabled $false + $Request = Set-CIPPSignInState -userid $AddRoomRequest.ExternalDirectoryObjectId -TenantFilter $Tenant -APIName $APINAME -ExecutingUser $User -AccountEnabled $false $Results.add("Blocked sign-in for Room mailbox; $($MailboxObject.userPrincipalName)") } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $Results.add("Failed to block sign-in for Room mailbox: $($MailboxObject.userPrincipalName). Error: $ErrorMessage") + $ErrorMessage = Get-CippException -Exception $_ + $Results.add("Failed to block sign-in for Room mailbox: $($MailboxObject.userPrincipalName). Error: $($ErrorMessage.NormalizedError)") } - + $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-CippException -Exception $_ - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Failed to create room: $($MailboxObject.DisplayName). Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Failed to create room: $($MailboxObject.DisplayName). Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage $Results.Add("Failed to create Room mailbox $($MailboxObject.userPrincipalName). $($ErrorMessage.NormalizedError)") + $StatusCode = [HttpStatusCode]::Forbidden } - $Body = [pscustomobject] @{ 'Results' = @($Results) } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK + StatusCode = $StatusCode Body = $Body }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 index a21880ce1369..acf3d26dc1bf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-AddSharedMailbox.ps1 @@ -15,12 +15,14 @@ Function Invoke-AddSharedMailbox { Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' + $Results = [System.Collections.ArrayList]@() $MailboxObject = $Request.body + $Tenant = $MailboxObject.tenantid $Aliases = $MailboxObject.addedAliases -Split '\n' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' try { $Email = "$($MailboxObject.username)@$($MailboxObject.domain)" @@ -30,48 +32,51 @@ Function Invoke-AddSharedMailbox { 'primarySMTPAddress' = $Email Shared = $true } - $AddSharedRequest = New-ExoRequest -tenantid $MailboxObject.tenantid -cmdlet 'New-Mailbox' -cmdparams $BodyToShip + $AddSharedRequest = New-ExoRequest -tenantid $Tenant -cmdlet 'New-Mailbox' -cmdparams $BodyToShip $Body = $Results.add("Successfully created shared mailbox: $Email.") - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Created shared mailbox $($MailboxObject.displayname) with email $Email" -Sev 'Info' + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Created shared mailbox $($MailboxObject.displayname) with email $Email" -Sev 'Info' # Block sign-in for the mailbox try { - $null = Set-CIPPSignInState -userid $AddSharedRequest.ExternalDirectoryObjectId -TenantFilter $($MailboxObject.tenantid) -APIName $APINAME -ExecutingUser $User -AccountEnabled $false + $null = Set-CIPPSignInState -userid $AddSharedRequest.ExternalDirectoryObjectId -TenantFilter $Tenant -APIName $APINAME -ExecutingUser $User -AccountEnabled $false $Body = $Results.add("Blocked sign-in for shared mailbox $Email") } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - $Body = $Results.add("Failed to block sign-in for shared mailbox $Email. Error: $ErrorMessage") + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Failed to block sign-in for shared mailbox $Email. Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $Body = $Results.add("Failed to block sign-in for shared mailbox $Email. Error: $($ErrorMessage.NormalizedError)") } - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Failed to create shared mailbox. Error: $ErrorMessage" -Sev 'Error' - $Body = $Results.add("Failed to create Shared Mailbox. $ErrorMessage") - } + # Add aliases to the mailbox if any are provided + if ($Aliases) { + try { + Start-Sleep 3 # Sleep since there is apparently a race condition with the mailbox creation if we don't delay for a lil bit + $AliasBodyToShip = [pscustomobject] @{ + 'Identity' = $AddSharedRequest.Guid + 'EmailAddresses' = @{'@odata.type' = '#Exchange.GenericHashTable'; Add = $Aliases } + } + $null = New-ExoRequest -tenantid $Tenant -cmdlet 'Set-Mailbox' -cmdparams $AliasBodyToShip -UseSystemMailbox $true + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Added aliases to $Email : $($Aliases -join ',')" -Sev 'Info' + $Body = $results.add("Added Aliases to $Email : $($Aliases -join ',')") - # Add aliases to the mailbox if any are provided - if ($Aliases) { - try { - Start-Sleep 3 # Sleep since there is apparently a race condition with the mailbox creation if we don't delay for a lil bit - $AliasBodyToShip = [pscustomobject] @{ - 'Identity' = $AddSharedRequest.Guid - 'EmailAddresses' = @{'@odata.type' = '#Exchange.GenericHashTable'; Add = $Aliases } + } catch { + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Failed to add aliases to $Email : $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $Body = $results.add("ERROR: Failed to add aliases to $Email : $($ErrorMessage.NormalizedError)") } - $null = New-ExoRequest -tenantid $MailboxObject.tenantid -cmdlet 'Set-Mailbox' -cmdparams $AliasBodyToShip -UseSystemMailbox $true - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Added aliases to $Email : $($Aliases -join ',')" -Sev 'Info' - $Body = $results.add("Added Aliases to $Email : $($Aliases -join ',')") - - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -user $User -API $APINAME -tenant $($MailboxObject.tenantid) -message "Failed to add aliases to $Email : $ErrorMessage" -Sev 'Error' - $Body = $results.add("ERROR: Failed to add aliases to $Email : $ErrorMessage") } + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -user $User -API $APINAME -tenant $Tenant -message "Failed to create shared mailbox. Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $Body = $Results.add("Failed to create Shared Mailbox. $($ErrorMessage.NormalizedError)") + $StatusCode = [HttpStatusCode]::Forbidden } + $Body = [pscustomobject] @{ 'Results' = @($results) } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK + StatusCode = $StatusCode Body = $Body }) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 index eebb7139649d..56102f3e2f17 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Invoke-ExecEditCalendarPermissions.ps1 @@ -11,20 +11,21 @@ Function Invoke-ExecEditCalendarPermissions { param($Request, $TriggerMetadata) $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $UserID = ($request.query.UserID) + $User = $Request.headers.'x-ms-client-principal' + Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' + + $UserID = ($Request.query.UserID) + $LoggingName = $Request.query.LoggingName $UserToGetPermissions = $Request.query.UserToGetPermissions - $Tenantfilter = $request.Query.tenantfilter + $Tenantfilter = $Request.Query.tenantfilter $Permissions = @($Request.query.permissions) $folderName = $Request.query.folderName - try { if ($Request.query.removeaccess) { - $result = Set-CIPPCalendarPermission -UserID $UserID -folderName $folderName -RemoveAccess $Request.query.removeaccess -TenantFilter $TenantFilter + $Result = Set-CIPPCalendarPermission -UserID $UserID -folderName $folderName -RemoveAccess $Request.query.removeaccess -TenantFilter $TenantFilter -LoggingName $LoggingName } else { - $result = Set-CIPPCalendarPermission -UserID $UserID -folderName $folderName -TenantFilter $Tenantfilter -UserToGetPermissions $UserToGetPermissions -Permissions $Permissions - $Result = "Successfully set permissions on folder $($CalParam.Identity). The user $UserToGetPermissions now has $Permissions permissions on this folder." + $Result = Set-CIPPCalendarPermission -UserID $UserID -folderName $folderName -TenantFilter $Tenantfilter -UserToGetPermissions $UserToGetPermissions -LoggingName $LoggingName -Permissions $Permissions } } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAppUpload.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAppUpload.ps1 index 824722a5e6de..de00263734fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAppUpload.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAppUpload.ps1 @@ -14,9 +14,9 @@ function Invoke-ExecAppUpload { if ($Config -and $Config.state -eq $true) { if ($env:CIPP_PROCESSOR -ne 'true') { $ProcessorFunction = [PSCustomObject]@{ - PartitionKey = 'Function' - RowKey = 'Start-ApplicationOrchestrator' - ProcessorFunction = 'Start-ApplicationOrchestrator' + PartitionKey = 'Function' + RowKey = 'Start-ApplicationOrchestrator' + } $ProcessorQueue = Get-CIPPTable -TableName 'ProcessorQueue' Add-AzDataTableEntity @ProcessorQueue -Entity $ProcessorFunction -Force diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 index cfa67b8bd043..f8bd672e0c43 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecBECRemediate.ps1 @@ -27,8 +27,9 @@ Function Invoke-ExecBECRemediate { $Step = 'Disable Account' Set-CIPPSignInState -userid $username -AccountEnabled $false -tenantFilter $TenantFilter -APIName $APINAME -ExecutingUser $User $Step = 'Revoke Sessions' - Revoke-CIPPSessions -userid $SuspectUser -username $request.body.username -ExecutingUser $User -APIName $APINAME -tenantFilter $TenantFilter - + Revoke-CIPPSessions -userid $SuspectUser -username $username -ExecutingUser $User -APIName $APINAME -tenantFilter $TenantFilter + $Step = 'Remove MFA methods' + Remove-CIPPUserMFA -UserPrincipalName $username -TenantFilter $TenantFilter -ExecutingUser $User $Step = 'Disable Inbox Rules' $Rules = New-ExoRequest -anchor $username -tenantid $TenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $username; IncludeHidden = $true } $RuleDisabled = 0 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 index 881f35afbf93..6c59d1cd9346 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetMFA.ps1 @@ -17,37 +17,7 @@ Function Invoke-ExecResetMFA { $TenantFilter = $Request.Query.TenantFilter $UserID = $Request.Query.ID try { - Write-Host "Getting auth methods for $UserID" - $AuthMethods = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$UserID/authentication/methods" -tenantid $TenantFilter -AsApp $true - $Requests = [System.Collections.Generic.List[object]]::new() - foreach ($Method in $AuthMethods) { - if ($Method.'@odata.type' -and $Method.'@odata.type' -ne '#microsoft.graph.passwordAuthenticationMethod') { - $MethodType = ($Method.'@odata.type' -split '\.')[-1] -replace 'Authentication', '' - $Requests.Add(@{ - id = "$MethodType-$($Method.id)" - method = 'DELETE' - url = ('users/{0}/authentication/{1}s/{2}' -f $UserID, $MethodType, $Method.id) - }) - } - } - if (($Requests | Measure-Object).Count -eq 0) { - $Results = [pscustomobject]@{'Results' = "No MFA methods found for user $($Request.Query.ID)" } - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) - return - } - - $Results = New-GraphBulkRequest -Requests $Requests -tenantid $TenantFilter -asapp $true -erroraction stop - - - if ($Results.status -eq 204) { - $Results = [pscustomobject]@{'Results' = "Successfully completed request. User $($Request.Query.ID) must supply MFA at next logon" } - } else { - $FailedAuthMethods = (($Results | Where-Object { $_.status -ne 204 }).id -split '-')[0] -join ', ' - $Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $FailedAuthMethods" } - } + $Results = Remove-CIPPUserMFA -UserPrincipalName $UserID -TenantFilter $TenantFilter -ExecutingUser $request.headers.'x-ms-client-principal' } catch { $Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $($Request.Query.ID): $(Get-NormalizedError -message $_.Exception.Message)" } Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to reset MFA for user $($Request.Query.ID): $($_.Exception.Message)" -Sev 'Error' -LogData (Get-CippException -Exception $_) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 index 3a52f5dacdfd..f916f4436a04 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-RemoveQueuedAlert.ps1 @@ -24,7 +24,7 @@ Function Invoke-RemoveQueuedAlert { try { $Filter = "RowKey eq '{0}'" -f $ID $Alert = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $Alert + Remove-AzDataTableEntity -Force @Table -Entity $Alert Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Removed application queue for $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed from queue.' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 index 10c11f90575a..4cf6b08f6cec 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOnboardTenant.ps1 @@ -19,7 +19,7 @@ function Invoke-ExecOnboardTenant { if ($Request.Query.Cancel -eq $true) { $TenantOnboarding = Get-CIPPAzDataTableEntity @OnboardTable -Filter "RowKey eq '$Id'" if ($TenantOnboarding) { - Remove-AzDataTableEntity @OnboardTable -Entity $TenantOnboarding + Remove-AzDataTableEntity -Force @OnboardTable -Entity $TenantOnboarding $Results = @{'Results' = 'Onboarding job canceled' } $StatusCode = [HttpStatusCode]::OK } else { @@ -110,4 +110,4 @@ function Invoke-ExecOnboardTenant { Body = $Results }) -} \ No newline at end of file +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 index 23426c6f1a14..05115ce42df2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 @@ -18,7 +18,7 @@ Function Invoke-ExecDeleteGDAPRoleMapping { try { $Filter = "PartitionKey eq 'Roles' and RowKey eq '{0}'" -f $Request.Query.GroupId $Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter - Remove-AzDataTableEntity @Table -Entity $Entity + Remove-AzDataTableEntity -Force @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' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 index 8e5186727b8f..66f0402b0171 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 @@ -12,8 +12,9 @@ Function Invoke-AddStandardsTemplate { $APIName = $TriggerMetadata.FunctionName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $GUID = (New-Guid).GUID - $JSON = (ConvertTo-Json -Depth 100 -InputObject ($Request.body | Select-Object standards, name)) + + $GUID = $Request.body.GUID ? $request.body.GUID : (New-Guid).GUID + $JSON = (ConvertTo-Json -Depth 100 -InputObject ($Request.body)) $Table = Get-CippTable -tablename 'templates' $Table.Force = $true Add-CIPPAzDataTableEntity @Table -Entity @{ @@ -31,4 +32,4 @@ Function Invoke-AddStandardsTemplate { Body = $body }) -} \ No newline at end of file +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecBPA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecBPA.ps1 index 3a1a16241b68..1189170809fa 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecBPA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecBPA.ps1 @@ -13,14 +13,20 @@ function Invoke-ExecBPA { if ($Config -and $Config.state -eq $true) { if ($env:CIPP_PROCESSOR -ne 'true') { + $Parameters = @{Force = $true } + if ($Request.Query.TenantFilter) { + $Parameters.TenantFilter = $Request.Query.TenantFilter + $RowKey = "Start-BPAOrchestrator-$($Request.Query.TenantFilter)" + } else { + $RowKey = 'Start-BPAOrchestrator' + } + $ProcessorQueue = Get-CIPPTable -TableName 'ProcessorQueue' $ProcessorFunction = [PSCustomObject]@{ PartitionKey = 'Function' - RowKey = "Start-BPAOrchestrator-$($Request.Query.TenantFilter)" + RowKey = $RowKey FunctionName = 'Start-BPAOrchestrator' - Parameters = [string](ConvertTo-Json -Compress -InputObject @{ - TenantFilter = $Request.Query.TenantFilter - }) + Parameters = [string](ConvertTo-Json -Compress -InputObject $Parameters) } Add-AzDataTableEntity @ProcessorQueue -Entity $ProcessorFunction -Force $Results = [pscustomobject]@{'Results' = 'BPA queued for execution' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecDomainAnalyser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecDomainAnalyser.ps1 index 2b31c6bb1d44..feebbc825d60 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecDomainAnalyser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecDomainAnalyser.ps1 @@ -14,9 +14,9 @@ function Invoke-ExecDomainAnalyser { if ($Config -and $Config.state -eq $true) { if ($env:CIPP_PROCESSOR -ne 'true') { $ProcessorFunction = [PSCustomObject]@{ - PartitionKey = 'Function' - RowKey = 'Start-DomainOrchestrator' - ProcessorFunction = 'Start-DomainOrchestrator' + PartitionKey = 'Function' + RowKey = 'Start-DomainOrchestrator' + FunctionName = 'Start-DomainOrchestrator' } $ProcessorQueue = Get-CIPPTable -TableName 'ProcessorQueue' Add-AzDataTableEntity @ProcessorQueue -Entity $ProcessorFunction -Force diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 index 2b3200bf553f..7a400591b6f0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardsRun.ps1 @@ -18,11 +18,12 @@ Function Invoke-ExecStandardsRun { if ($Config -and $Config.state -eq $true) { if ($env:CIPP_PROCESSOR -ne 'true') { + $ProcessorFunction = [PSCustomObject]@{ - PartitionKey = 'Function' - RowKey = "Invoke-CIPPStandardsRun-$tenantfilter" - ProcessorFunction = 'Invoke-CIPPStandardsRun' - Parameters = [string](ConvertTo-Json -Compress -InputObject @{ + PartitionKey = 'Function' + RowKey = "Invoke-CIPPStandardsRun-$tenantfilter" + FunctionName = 'Invoke-CIPPStandardsRun' + Parameters = [string](ConvertTo-Json -Compress -InputObject @{ TenantFilter = $tenantfilter Force = $true }) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 index e583908da1e1..ca8b373bcadc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 @@ -80,6 +80,11 @@ Function Invoke-ListBPA { $Results = [PSCustomObject]@{ Data = @($Data) Columns = @($Columns) + Keys = $Data | ForEach-Object { + $_.PSObject.Properties | + Where-Object { $_.Name -ne 'PartitionKey' -and $_.Name -ne 'RowKey' -and $_.Name -ne 'Timestamp' } | + ForEach-Object { $_.Name } + } | Select-Object -Unique Style = $Style } @@ -87,6 +92,7 @@ Function Invoke-ListBPA { $Results = @{ Columns = @( value = 'Results'; name = 'Results') Data = @(@{ Results = 'The BPA has not yet run.' }) + Keys = @() } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 index 1b17d33131a2..b866f1f814a0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1 @@ -18,8 +18,9 @@ Function Invoke-listStandardTemplates { $data = $_.JSON | ConvertFrom-Json -Depth 100 $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force $data - } | Sort-Object -Property displayName + } | Sort-Object -Property templateName + if ($Request.query.id) { $Templates = $Templates | Where-Object GUID -EQ $Request.query.id } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 index 3862e8f0672b..befe1b339f21 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1 @@ -61,7 +61,7 @@ Function Invoke-ExecGraphExplorerPreset { $Entity = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$Id'" if ($Entity.Owner -eq $Username ) { if ($Action -eq 'Delete') { - Remove-AzDataTableEntity @Table -Entity $Entity + Remove-AzDataTableEntity -Force @Table -Entity $Entity } elseif ($Action -eq 'Save') { Add-CIPPAzDataTableEntity @Table -Entity $Preset -Force } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 index 32afe59ac176..f579777b5607 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericAllTenants.ps1 @@ -15,7 +15,7 @@ Function Invoke-ListGenericAllTenants { Update-CippQueueEntry -RowKey $QueueKey -Status 'Started' $Table = Get-CIPPTable -TableName "cache$TableURLName" $fullUrl = "https://graph.microsoft.com/beta/$QueueItem" - Get-CIPPAzDataTableEntity @Table | Remove-AzDataTableEntity @table + Get-CIPPAzDataTableEntity @Table | Remove-AzDataTableEntity -Force @table $RawGraphRequest = Get-Tenants | ForEach-Object -Parallel { $domainName = $_.defaultDomainName diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 index 260241fa972f..3da81ef8f734 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxes.ps1 @@ -20,7 +20,7 @@ Function Invoke-ListMailboxes { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter try { - $Select = 'id,ExchangeGuid,ArchiveGuid,UserPrincipalName,DisplayName,PrimarySMTPAddress,RecipientType,RecipientTypeDetails,EmailAddresses,WhenSoftDeleted,IsInactiveMailbox,ForwardingSmtpAddress,DeliverToMailboxAndForward,ForwardingAddress' + $Select = 'id,ExchangeGuid,ExternalDirectoryObjectId,ArchiveGuid,UserPrincipalName,DisplayName,PrimarySMTPAddress,RecipientType,RecipientTypeDetails,EmailAddresses,WhenSoftDeleted,IsInactiveMailbox,ForwardingSmtpAddress,DeliverToMailboxAndForward,ForwardingAddress' $ExoRequest = @{ tenantid = $TenantFilter cmdlet = 'Get-Mailbox' @@ -59,7 +59,7 @@ Function Invoke-ListMailboxes { } Write-Host ($ExoRequest | ConvertTo-Json) - $GraphRequest = (New-ExoRequest @ExoRequest) | Select-Object id, ExchangeGuid, ArchiveGuid, WhenSoftDeleted, @{ Name = 'UPN'; Expression = { $_.'UserPrincipalName' } }, + $GraphRequest = (New-ExoRequest @ExoRequest) | Select-Object id, ExchangeGuid, ExternalDirectoryObjectId, ArchiveGuid, WhenSoftDeleted, @{ Name = 'UPN'; Expression = { $_.'UserPrincipalName' } }, @{ Name = 'displayName'; Expression = { $_.'DisplayName' } }, @{ Name = 'primarySmtpAddress'; Expression = { $_.'PrimarySMTPAddress' } }, diff --git a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogOrchestrator.ps1 b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogOrchestrator.ps1 index c0ccc91c3443..0f56ae4a7e99 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogOrchestrator.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogOrchestrator.ps1 @@ -9,15 +9,6 @@ function Start-AuditLogOrchestrator { $AuditLogSearchesTable = Get-CIPPTable -TableName 'AuditLogSearches' $AuditLogSearches = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "CippStatus eq 'Pending'" - $ConfigTable = Get-CippTable -TableName 'WebhookRules' - $ConfigEntries = Get-CIPPAzDataTableEntity @ConfigTable - - $TenantList = Get-Tenants -IncludeErrors - # Round time down to nearest minute - $Now = Get-Date - $StartTime = ($Now.AddSeconds(-$Now.Seconds)).AddHours(-1) - $EndTime = $Now.AddSeconds(-$Now.Seconds) - if (($AuditLogSearches | Measure-Object).Count -eq 0) { Write-Information 'No audit log searches available' } else { @@ -33,67 +24,6 @@ function Start-AuditLogOrchestrator { Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress) } } - - Write-Information 'Audit Logs: Creating new searches' - foreach ($Tenant in $TenantList) { - $Configuration = $ConfigEntries | Where-Object { ($_.Tenants -match $TenantFilter -or $_.Tenants -match 'AllTenants') } - if ($Configuration) { - $ServiceFilters = $Configuration | Select-Object -Property type | Sort-Object -Property type -Unique | ForEach-Object { $_.type.split('.')[1] } - try { - $LogSearch = @{ - StartTime = $StartTime - EndTime = $EndTime - ServiceFilters = $ServiceFilters - TenantFilter = $Tenant.defaultDomainName - ProcessLogs = $true - RecordTypeFilters = @( - 'exchangeAdmin', 'azureActiveDirectory', 'azureActiveDirectoryAccountLogon', 'dataCenterSecurityCmdlet', - 'complianceDLPSharePoint', 'complianceDLPExchange', 'azureActiveDirectoryStsLogon', 'skypeForBusinessPSTNUsage', - 'skypeForBusinessUsersBlocked', 'securityComplianceCenterEOPCmdlet', 'microsoftFlow', 'aeD', 'microsoftStream', - 'threatFinder', 'project', 'dataGovernance', 'securityComplianceAlerts', 'threatIntelligenceUrl', - 'securityComplianceInsights', 'mipLabel', 'workplaceAnalytics', 'powerAppsApp', 'powerAppsPlan', - 'threatIntelligenceAtpContent', 'labelContentExplorer', 'hygieneEvent', - 'dataInsightsRestApiAudit', 'informationBarrierPolicyApplication', 'microsoftTeamsAdmin', 'hrSignal', - 'informationWorkerProtection', 'campaign', 'dlpEndpoint', 'airInvestigation', 'quarantine', 'microsoftForms', - 'applicationAudit', 'complianceSupervisionExchange', 'customerKeyServiceEncryption', 'officeNative', - 'mipAutoLabelSharePointItem', 'mipAutoLabelSharePointPolicyLocation', 'secureScore', - 'mipAutoLabelExchangeItem', 'cortanaBriefing', 'search', 'wdatpAlerts', 'powerPlatformAdminDlp', - 'powerPlatformAdminEnvironment', 'mdatpAudit', 'sensitivityLabelPolicyMatch', 'sensitivityLabelAction', - 'sensitivityLabeledFileAction', 'attackSim', 'airManualInvestigation', 'securityComplianceRBAC', 'userTraining', - 'airAdminActionInvestigation', 'mstic', 'physicalBadgingSignal', 'aipDiscover', 'aipSensitivityLabelAction', - 'aipProtectionAction', 'aipFileDeleted', 'aipHeartBeat', 'mcasAlerts', 'onPremisesFileShareScannerDlp', - 'onPremisesSharePointScannerDlp', 'exchangeSearch', 'privacyDataMinimization', 'labelAnalyticsAggregate', - 'myAnalyticsSettings', 'securityComplianceUserChange', 'complianceDLPExchangeClassification', - 'complianceDLPEndpoint', 'mipExactDataMatch', 'msdeResponseActions', 'msdeGeneralSettings', 'msdeIndicatorsSettings', - 'ms365DCustomDetection', 'msdeRolesSettings', 'mapgAlerts', 'mapgPolicy', 'mapgRemediation', - 'privacyRemediationAction', 'privacyDigestEmail', 'mipAutoLabelSimulationProgress', 'mipAutoLabelSimulationCompletion', - 'mipAutoLabelProgressFeedback', 'dlpSensitiveInformationType', 'mipAutoLabelSimulationStatistics', - 'largeContentMetadata', 'microsoft365Group', 'cdpMlInferencingResult', 'filteringMailMetadata', - 'cdpClassificationMailItem', 'cdpClassificationDocument', 'officeScriptsRunAction', 'filteringPostMailDeliveryAction', - 'cdpUnifiedFeedback', 'tenantAllowBlockList', 'consumptionResource', 'healthcareSignal', 'dlpImportResult', - 'cdpCompliancePolicyExecution', 'multiStageDisposition', 'privacyDataMatch', 'filteringDocMetadata', - 'filteringEmailFeatures', 'powerBIDlp', 'filteringUrlInfo', 'filteringAttachmentInfo', 'coreReportingSettings', - 'complianceConnector', 'powerPlatformLockboxResourceAccessRequest', 'powerPlatformLockboxResourceCommand', - 'cdpPredictiveCodingLabel', 'cdpCompliancePolicyUserFeedback', 'webpageActivityEndpoint', 'omePortal', - 'cmImprovementActionChange', 'filteringUrlClick', 'mipLabelAnalyticsAuditRecord', 'filteringEntityEvent', - 'filteringRuleHits', 'filteringMailSubmission', 'labelExplorer', 'microsoftManagedServicePlatform', - 'powerPlatformServiceActivity', 'scorePlatformGenericAuditRecord', 'filteringTimeTravelDocMetadata', 'alert', - 'alertStatus', 'alertIncident', 'incidentStatus', 'case', 'caseInvestigation', 'recordsManagement', - 'privacyRemediation', 'dataShareOperation', 'cdpDlpSensitive', 'ehrConnector', 'filteringMailGradingResult', - 'microsoftTodoAudit', 'timeTravelFilteringDocMetadata', 'microsoftDefenderForIdentityAudit', - 'supervisoryReviewDayXInsight', 'defenderExpertsforXDRAdmin', 'cdpEdgeBlockedMessage', 'hostedRpa', - 'cdpContentExplorerAggregateRecord', 'cdpHygieneAttachmentInfo', 'cdpHygieneSummary', 'cdpPostMailDeliveryAction', - 'cdpEmailFeatures', 'cdpHygieneUrlInfo', 'cdpUrlClick', 'cdpPackageManagerHygieneEvent', 'filteringDocScan', - 'timeTravelFilteringDocScan', 'mapgOnboard' - ) - } - $NewSearch = New-CippAuditLogSearch @LogSearch - Write-Information "Created audit log search $($Tenant.defaultDomainName) - $($NewSearch.displayName)" - } catch { - Write-Information "Error creating audit log search $($Tenant.defaultDomainName) - $($_.Exception.Message)" - } - } - } } catch { Write-LogMessage -API 'Audit Logs' -message 'Error processing audit logs' -sev Error -LogData (Get-CippException -Exception $_) Write-Information ( 'Audit logs error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message) diff --git a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogSearchCreation.ps1 b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogSearchCreation.ps1 new file mode 100644 index 000000000000..e0b6e72ea843 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-AuditLogSearchCreation.ps1 @@ -0,0 +1,84 @@ +function Start-AuditLogSearchCreation { + <# + .SYNOPSIS + Start the Audit Log Searches + #> + [CmdletBinding(SupportsShouldProcess = $true)] + param() + try { + $ConfigTable = Get-CippTable -TableName 'WebhookRules' + $ConfigEntries = Get-CIPPAzDataTableEntity @ConfigTable + + $TenantList = Get-Tenants -IncludeErrors + # Round time down to nearest minute + $Now = Get-Date + $StartTime = ($Now.AddSeconds(-$Now.Seconds)).AddHours(-1) + $EndTime = $Now.AddSeconds(-$Now.Seconds) + + Write-Information 'Audit Logs: Creating new searches' + foreach ($Tenant in $TenantList) { + $Configuration = $ConfigEntries | Where-Object { ($_.Tenants -match $TenantFilter -or $_.Tenants -match 'AllTenants') } + if ($Configuration) { + $ServiceFilters = $Configuration | Select-Object -Property type | Sort-Object -Property type -Unique | ForEach-Object { $_.type.split('.')[1] } + try { + $LogSearch = @{ + StartTime = $StartTime + EndTime = $EndTime + ServiceFilters = $ServiceFilters + TenantFilter = $Tenant.defaultDomainName + ProcessLogs = $true + RecordTypeFilters = @( + 'exchangeAdmin', 'azureActiveDirectory', 'azureActiveDirectoryAccountLogon', 'dataCenterSecurityCmdlet', + 'complianceDLPSharePoint', 'complianceDLPExchange', 'azureActiveDirectoryStsLogon', 'skypeForBusinessPSTNUsage', + 'skypeForBusinessUsersBlocked', 'securityComplianceCenterEOPCmdlet', 'microsoftFlow', 'aeD', 'microsoftStream', + 'threatFinder', 'project', 'dataGovernance', 'securityComplianceAlerts', 'threatIntelligenceUrl', + 'securityComplianceInsights', 'mipLabel', 'workplaceAnalytics', 'powerAppsApp', 'powerAppsPlan', + 'threatIntelligenceAtpContent', 'labelContentExplorer', 'hygieneEvent', + 'dataInsightsRestApiAudit', 'informationBarrierPolicyApplication', 'microsoftTeamsAdmin', 'hrSignal', + 'informationWorkerProtection', 'campaign', 'dlpEndpoint', 'airInvestigation', 'quarantine', 'microsoftForms', + 'applicationAudit', 'complianceSupervisionExchange', 'customerKeyServiceEncryption', 'officeNative', + 'mipAutoLabelSharePointItem', 'mipAutoLabelSharePointPolicyLocation', 'secureScore', + 'mipAutoLabelExchangeItem', 'cortanaBriefing', 'search', 'wdatpAlerts', 'powerPlatformAdminDlp', + 'powerPlatformAdminEnvironment', 'mdatpAudit', 'sensitivityLabelPolicyMatch', 'sensitivityLabelAction', + 'sensitivityLabeledFileAction', 'attackSim', 'airManualInvestigation', 'securityComplianceRBAC', 'userTraining', + 'airAdminActionInvestigation', 'mstic', 'physicalBadgingSignal', 'aipDiscover', 'aipSensitivityLabelAction', + 'aipProtectionAction', 'aipFileDeleted', 'aipHeartBeat', 'mcasAlerts', 'onPremisesFileShareScannerDlp', + 'onPremisesSharePointScannerDlp', 'exchangeSearch', 'privacyDataMinimization', 'labelAnalyticsAggregate', + 'myAnalyticsSettings', 'securityComplianceUserChange', 'complianceDLPExchangeClassification', + 'complianceDLPEndpoint', 'mipExactDataMatch', 'msdeResponseActions', 'msdeGeneralSettings', 'msdeIndicatorsSettings', + 'ms365DCustomDetection', 'msdeRolesSettings', 'mapgAlerts', 'mapgPolicy', 'mapgRemediation', + 'privacyRemediationAction', 'privacyDigestEmail', 'mipAutoLabelSimulationProgress', 'mipAutoLabelSimulationCompletion', + 'mipAutoLabelProgressFeedback', 'dlpSensitiveInformationType', 'mipAutoLabelSimulationStatistics', + 'largeContentMetadata', 'microsoft365Group', 'cdpMlInferencingResult', 'filteringMailMetadata', + 'cdpClassificationMailItem', 'cdpClassificationDocument', 'officeScriptsRunAction', 'filteringPostMailDeliveryAction', + 'cdpUnifiedFeedback', 'tenantAllowBlockList', 'consumptionResource', 'healthcareSignal', 'dlpImportResult', + 'cdpCompliancePolicyExecution', 'multiStageDisposition', 'privacyDataMatch', 'filteringDocMetadata', + 'filteringEmailFeatures', 'powerBIDlp', 'filteringUrlInfo', 'filteringAttachmentInfo', 'coreReportingSettings', + 'complianceConnector', 'powerPlatformLockboxResourceAccessRequest', 'powerPlatformLockboxResourceCommand', + 'cdpPredictiveCodingLabel', 'cdpCompliancePolicyUserFeedback', 'webpageActivityEndpoint', 'omePortal', + 'cmImprovementActionChange', 'filteringUrlClick', 'mipLabelAnalyticsAuditRecord', 'filteringEntityEvent', + 'filteringRuleHits', 'filteringMailSubmission', 'labelExplorer', 'microsoftManagedServicePlatform', + 'powerPlatformServiceActivity', 'scorePlatformGenericAuditRecord', 'filteringTimeTravelDocMetadata', 'alert', + 'alertStatus', 'alertIncident', 'incidentStatus', 'case', 'caseInvestigation', 'recordsManagement', + 'privacyRemediation', 'dataShareOperation', 'cdpDlpSensitive', 'ehrConnector', 'filteringMailGradingResult', + 'microsoftTodoAudit', 'timeTravelFilteringDocMetadata', 'microsoftDefenderForIdentityAudit', + 'supervisoryReviewDayXInsight', 'defenderExpertsforXDRAdmin', 'cdpEdgeBlockedMessage', 'hostedRpa', + 'cdpContentExplorerAggregateRecord', 'cdpHygieneAttachmentInfo', 'cdpHygieneSummary', 'cdpPostMailDeliveryAction', + 'cdpEmailFeatures', 'cdpHygieneUrlInfo', 'cdpUrlClick', 'cdpPackageManagerHygieneEvent', 'filteringDocScan', + 'timeTravelFilteringDocScan', 'mapgOnboard' + ) + } + if ($PSCmdlet.ShouldProcess('Start-AuditLogSearchCreation', 'Creating Audit Log Search')) { + $NewSearch = New-CippAuditLogSearch @LogSearch + Write-Information "Created audit log search $($Tenant.defaultDomainName) - $($NewSearch.displayName)" + } + } catch { + Write-Information "Error creating audit log search $($Tenant.defaultDomainName) - $($_.Exception.Message)" + } + } + } + } catch { + Write-LogMessage -API 'Audit Logs' -message 'Error creating audit log searches' -sev Error -LogData (Get-CippException -Exception $_) + Write-Information ( 'Audit logs error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message) + } +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-BPAOrchestrator.ps1 b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-BPAOrchestrator.ps1 index fbe51460a0dc..2060c7113c7a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-BPAOrchestrator.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-BPAOrchestrator.ps1 @@ -9,7 +9,8 @@ function Start-BPAOrchestrator { #> [CmdletBinding(SupportsShouldProcess = $true)] param( - $TenantFilter = 'AllTenants' + $TenantFilter = 'AllTenants', + [switch]$Force ) try { @@ -45,6 +46,13 @@ function Start-BPAOrchestrator { } } + if ($Force.IsPresent) { + Write-Host 'Clearing Rerun Cache' + foreach ($Report in $BPAReports) { + $null = Test-CIPPRerun -Type BPA -Tenant $Report.Tenant -API $Report.Template -Clear + } + } + if (($BPAReports | Measure-Object).Count -eq 0) { Write-Information 'No BPA reports to run' return 0 diff --git a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPProcessorQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPProcessorQueue.ps1 index a0d340bb6c8a..6f79bcf4a4bc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPProcessorQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPProcessorQueue.ps1 @@ -10,8 +10,8 @@ function Start-CIPPProcessorQueue { $QueueItems = Get-CIPPAzDataTableEntity @QueueTable -Filter "PartitionKey eq 'Function'" foreach ($QueueItem in $QueueItems) { - if ($PSCmdlet.ShouldProcess("Processing function $($QueueItem.ProcessorFunction)")) { - Write-Information "Running queued function $($QueueItem.ProcessorFunction)" + if ($PSCmdlet.ShouldProcess("Processing function $($QueueItem.FunctionName)")) { + Write-Information "Running queued function $($QueueItem.FunctionName)" if ($QueueItem.Parameters) { try { $Parameters = $QueueItem.Parameters | ConvertFrom-Json -AsHashtable @@ -21,16 +21,16 @@ function Start-CIPPProcessorQueue { } else { $Parameters = @{} } - if (Get-Command -Name $QueueItem.ProcessorFunction -Module CIPPCore -ErrorAction SilentlyContinue) { + if (Get-Command -Name $QueueItem.FunctionName -ErrorAction SilentlyContinue) { try { - Invoke-Command -ScriptBlock { & $QueueItem.ProcessorFunction @Parameters } + Invoke-Command -ScriptBlock { & $QueueItem.FunctionName @Parameters } } catch { - Write-Warning "Failed to run function $($QueueItem.ProcessorFunction). Error: $($_.Exception.Message)" + Write-Warning "Failed to run function $($QueueItem.FunctionName). Error: $($_.Exception.Message)" } } else { - Write-Warning "Function $($QueueItem.ProcessorFunction) not found" + Write-Warning "Function $($QueueItem.FunctionName) not found" } - Remove-AzDataTableEntity @QueueTable -Entity $QueueItem + Remove-AzDataTableEntity -Force @QueueTable -Entity $QueueItem } } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-DurableCleanup.ps1 b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-DurableCleanup.ps1 new file mode 100644 index 000000000000..e0a17d97311b --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-DurableCleanup.ps1 @@ -0,0 +1,62 @@ +function Start-DurableCleanup { + <# + .SYNOPSIS + Start the durable cleanup process. + + .DESCRIPTION + Look for orchestrators running for more than the specified time and terminate them. Also, clear any queues that have items for that function app. + + .PARAMETER MaxDuration + The maximum duration an orchestrator can run before being terminated. + + .FUNCTIONALITY + Internal + #> + + [CmdletBinding(SupportsShouldProcess = $true)] + param( + [int]$MaxDuration = 3600 + ) + + $WarningPreference = 'SilentlyContinue' + $StorageContext = New-AzStorageContext -ConnectionString $env:AzureWebJobsStorage + $TargetTime = (Get-Date).ToUniversalTime().AddSeconds(-$MaxDuration) + $Context = New-AzDataTableContext -ConnectionString $env:AzureWebJobsStorage + $InstancesTables = Get-AzDataTable -Context $Context | Where-Object { $_ -match 'Instances' } + + $CleanupCount = 0 + $QueueCount = 0 + foreach ($Table in $InstancesTables) { + $Table = Get-CippTable -TableName $Table + $ClearQueues = $false + $FunctionName = $Table.TableName -replace 'Instances', '' + $Orchestrators = Get-CIPPAzDataTableEntity @Table -Filter "RuntimeStatus eq 'Running'" | Select-Object * -ExcludeProperty Input + $LongRunningOrchestrators = $Orchestrators | Where-Object { $_.CreatedTime.DateTime -lt $TargetTime } + foreach ($Orchestrator in $LongRunningOrchestrators) { + $CreatedTime = [DateTime]::SpecifyKind($Orchestrator.CreatedTime.DateTime, [DateTimeKind]::Utc) + $TimeSpan = New-TimeSpan -Start $CreatedTime -End (Get-Date).ToUniversalTime() + $RunningDuration = [math]::Round($TimeSpan.TotalMinutes, 2) + Write-Information "Orchestrator: $($Orchestrator.PartitionKey), created: $CreatedTime, running for: $RunningDuration minutes" + $ClearQueues = $true + if ($PSCmdlet.ShouldProcess($_.PartitionKey, 'Terminate Orchestrator')) { + $Orchestrator = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$($Orchestrator.PartitionKey)'" + $Orchestrator.RuntimeStatus = 'Failed' + Update-AzDataTableEntity @Table -Entity $Orchestrator + $CleanupCount++ + } + } + + if ($ClearQueues) { + $Queues = Get-AzStorageQueue -Context $StorageContext -Name ('{0}*' -f $FunctionName) | Select-Object -Property Name, ApproximateMessageCount, QueueClient + $RunningQueues = $Queues | Where-Object { $_.ApproximateMessageCount -gt 0 } + foreach ($Queue in $RunningQueues) { + Write-Information "- Removing queue: $($Queue.Name), message count: $($Queue.ApproximateMessageCount)" + if ($PSCmdlet.ShouldProcess($Queue.Name, 'Clear Queue')) { + $Queue.QueueClient.ClearMessagesAsync() | Out-Null + } + $QueueCount++ + } + } + } + Write-Information "Cleanup complete. $CleanupCount orchestrators were terminated. $QueueCount queues were cleared." +} diff --git a/Modules/CIPPCore/Public/Get-CIPPDomainAnalyser.ps1 b/Modules/CIPPCore/Public/Get-CIPPDomainAnalyser.ps1 index 1d3ba51f1dd8..fc7fcd31ba6d 100644 --- a/Modules/CIPPCore/Public/Get-CIPPDomainAnalyser.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPDomainAnalyser.ps1 @@ -17,7 +17,8 @@ function Get-CIPPDomainAnalyser { $DomainTable = Get-CIPPTable -Table 'Domains' # Get all the things - + #Transform the tenantFilter to the GUID. + $TenantFilter = (Get-Tenants -TenantFilter $tenantFilter).customerId if ($TenantFilter -ne 'AllTenants' -and ![string]::IsNullOrEmpty($TenantFilter)) { $DomainTable.Filter = "TenantGUID eq '{0}'" -f $TenantFilter } diff --git a/Modules/CIPPCore/Public/Get-CIPPTimerFunctions.ps1 b/Modules/CIPPCore/Public/Get-CIPPTimerFunctions.ps1 index 99bea5b3cd84..94b050c6065f 100644 --- a/Modules/CIPPCore/Public/Get-CIPPTimerFunctions.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPTimerFunctions.ps1 @@ -124,7 +124,7 @@ function Get-CIPPTimerFunctions { } else { if ($Status) { Write-Warning "Timer function: $($Orchestrator.Command) does not exist" - Remove-CIPPAzDataTableEntity @Table -Entity $Status + Remove-AzDataTableEntity @Table -Entity $Status } } } diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 index 446a1c5fc5ac..eb8a7c0c45fb 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Get-Tenants.ps1 @@ -66,7 +66,7 @@ function Get-Tenants { } $CurrentTenants = Get-CIPPAzDataTableEntity @TenantsTable -Filter "PartitionKey eq 'Tenants' and Excluded eq false" $CurrentTenants | Where-Object { $_.customerId -notin $GDAPList.customerId } | ForEach-Object { - Remove-AzDataTableEntity @TenantsTable -Entity $_ + Remove-AzDataTableEntity -Force @TenantsTable -Entity $_ } } $PartnerModeTable = Get-CippTable -tablename 'tenantMode' @@ -162,34 +162,32 @@ function Get-Tenants { if ($PartnerTenantState.state -eq 'PartnerTenantAvailable') { # Add partner tenant if env is set $Domains = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains?$top=999' -tenantid $env:TenantID -NoAuthCheck:$true - $IncludedTenantsCache.Add([PSCustomObject]@{ - RowKey = $env:TenantID - PartitionKey = 'Tenants' - customerId = $env:TenantID - defaultDomainName = ($Domains | Where-Object { $_.isDefault -eq $true }).id - initialDomainName = ($Domains | Where-Object { $_.isInitial -eq $true }).id - displayName = '*Partner Tenant' - domains = 'PartnerTenant' - Excluded = $false - ExcludeUser = '' - ExcludeDate = '' - GraphErrorCount = 0 - LastGraphError = '' - RequiresRefresh = [bool]$RequiresRefresh - LastRefresh = (Get-Date).ToUniversalTime() - }) | Out-Null + $PartnerTenant = [PSCustomObject]@{ + RowKey = $env:TenantID + PartitionKey = 'Tenants' + customerId = $env:TenantID + defaultDomainName = ($Domains | Where-Object { $_.isDefault -eq $true }).id + initialDomainName = ($Domains | Where-Object { $_.isInitial -eq $true }).id + displayName = '*Partner Tenant' + domains = 'PartnerTenant' + Excluded = $false + ExcludeUser = '' + ExcludeDate = '' + GraphErrorCount = 0 + LastGraphError = '' + RequiresRefresh = [bool]$RequiresRefresh + LastRefresh = (Get-Date).ToUniversalTime() + } + $IncludedTenantsCache.Add($PartnerTenant) + Add-AzDataTableEntity @TenantsTable -Entity $PartnerTenant -Force | Out-Null } - foreach ($Tenant in $TenantList | Where-Object $IncludedTenantFilter) { + foreach ($Tenant in $TenantList) { if ($Tenant.defaultDomainName -eq 'Invalid' -or [string]::IsNullOrWhiteSpace($Tenant.defaultDomainName)) { Write-LogMessage -API 'Get-Tenants' -message "We're skipping $($Tenant.displayName) as it has an invalid default domain name. Something is up with this instance." -level 'Critical' continue } - $IncludedTenantsCache.Add($Tenant) | Out-Null - } - - if ($IncludedTenantsCache) { - Add-CIPPAzDataTableEntity @TenantsTable -Entity $IncludedTenantsCache -Force | Out-Null + $IncludedTenantsCache.Add($Tenant) } } if ($PartnerTenantState.state -eq 'owntenant' -and $IncludedTenantsCache.RowKey.count -eq 0) { @@ -215,6 +213,5 @@ function Get-Tenants { Add-CIPPAzDataTableEntity @TenantsTable -Entity $IncludedTenantsCache -Force | Out-Null } } - - return ($IncludedTenantsCache | Where-Object { $null -ne $_.defaultDomainName -and ($_.defaultDomainName -notmatch 'Domain Error' -or $IncludeAll.IsPresent) } | Sort-Object -Property displayName) + return $IncludedTenantsCache | Where-Object { ($null -ne $_.defaultDomainName -and ($_.defaultDomainName -notmatch 'Domain Error' -or $IncludeAll.IsPresent)) } | Where-Object $IncludedTenantFilter | Sort-Object -Property displayName } diff --git a/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 index 8572b6494df4..cbf6c5dc1d87 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 @@ -139,7 +139,7 @@ function New-ExoRequest { Method = 'POST' Body = $ExoBody Headers = $Headers - ContentType = 'application/json' + ContentType = 'application/json; charset=utf-8' } $Return = Invoke-RestMethod @ExoRequestParams -ResponseHeadersVariable ResponseHeaders diff --git a/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 b/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 index 99057374f0de..dbd52b564c54 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 @@ -11,7 +11,7 @@ function Remove-CIPPCache { $Filter = "PartitionKey eq 'Tenants' and Excluded eq false" $ClearIncludedTenants = Get-CIPPAzDataTableEntity @TenantsTable -Filter $Filter -Property PartitionKey, RowKey if ($ClearIncludedTenants) { - Remove-AzDataTableEntity @TenantsTable -Entity $ClearIncludedTenants + Remove-AzDataTableEntity -Force @TenantsTable -Entity $ClearIncludedTenants } if ($TenantsOnly -eq 'false') { @@ -30,7 +30,7 @@ function Remove-CIPPCache { $BPATable = Get-CippTable -tablename 'cachebpav2' $ClearBPARows = Get-CIPPAzDataTableEntity @BPATable if ($ClearBPARows) { - Remove-AzDataTableEntity @BPATable -Entity $ClearBPARows + Remove-AzDataTableEntity -Force @BPATable -Entity $ClearBPARows } $ENV:SetFromProfile = $null $Script:SkipListCache = $Null diff --git a/Modules/CIPPCore/Public/Invoke-CIPPStandardsRun.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPStandardsRun.ps1 index 0c1f3b3df1d3..cb3aaf4793ff 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPStandardsRun.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPStandardsRun.ps1 @@ -6,19 +6,26 @@ function Invoke-CIPPStandardsRun { [string]$TenantFilter = 'allTenants', [switch]$Force ) - Write-Host "Starting process for standards - $($tenantFilter)" + Write-Information "Starting process for standards - $($tenantFilter)" $AllTasks = Get-CIPPStandards -TenantFilter $TenantFilter if ($Force.IsPresent) { - Write-Host 'Clearing Rerun Cache' + Write-Information 'Clearing Rerun Cache' foreach ($Task in $AllTasks) { - $null = Test-CIPPRerun -Type Standard -Tenant $Task.Tenant -Settings @{} -API $Task.Standard + $null = Test-CIPPRerun -Type Standard -Tenant $Task.Tenant -API $Task.Standard -Clear } } + $TaskCount = ($AllTasks | Measure-Object).Count + if ($TaskCount -eq 0) { + Write-Information "No tasks found for tenant filter '$TenantFilter'" + return + } + + Write-Information "Found $TaskCount tasks for tenant filter '$TenantFilter'" #For each item in our object, run the queue. - $Queue = New-CippQueueEntry -Name "Applying Standards ($TenantFilter)" -TotalTasks ($AllTasks | Measure-Object).Count + $Queue = New-CippQueueEntry -Name "Applying Standards ($TenantFilter)" -TotalTasks $TaskCount $InputObject = [PSCustomObject]@{ OrchestratorName = 'StandardsOrchestrator' @@ -31,7 +38,9 @@ function Invoke-CIPPStandardsRun { } } + Write-Information 'Starting standards orchestrator' $InstanceId = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress) - Write-Host "Started orchestration with ID = '$InstanceId'" + Write-Information "Started orchestration with ID = '$InstanceId'" #$Orchestrator = New-OrchestrationCheckStatusResponse -Request $Request -InstanceId $InstanceId + return $InstanceId } diff --git a/Modules/CIPPCore/Public/Invoke-RemoveBPATemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveBPATemplate.ps1 index 6e247411b394..1f2046b4ed9e 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveBPATemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveBPATemplate.ps1 @@ -20,7 +20,7 @@ Function Invoke-RemoveBPATemplate { $Filter = "PartitionKey eq 'BPATemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed BPA Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed BPA Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 index b3024895b3a5..1d24c2095320 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveCATemplate.ps1 @@ -20,7 +20,7 @@ Function Invoke-RemoveCATemplate { $Filter = "PartitionKey eq 'CATemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Conditional Access Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Conditional Access Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 index f603904daec4..6789c97a6c4c 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveExConnectorTemplate.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveExConnectorTemplate { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'ExConnectorTemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Exchange Connector Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Exchange Connector Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 index 51d5d9d03ce6..d7a330d0bdd9 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveGroupTemplate.ps1 @@ -22,7 +22,7 @@ Function Invoke-RemoveGroupTemplate { $Filter = "PartitionKey eq 'GroupTemplate' and RowKey eq '$id'" Write-Host $Filter $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Intune Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 index 4c66d297fc66..5880b04b7968 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveIntuneTemplate.ps1 @@ -22,7 +22,7 @@ Function Invoke-RemoveIntuneTemplate { $Filter = "PartitionKey eq 'IntuneTemplate' and RowKey eq '$id'" Write-Host $Filter $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Intune Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Intune Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 index f1de92bdeab7..ef22fb63ce82 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveQueuedApp { $Table = Get-CippTable -tablename 'apps' $Filter = "PartitionKey eq 'apps' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed application queue for $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed from queue.' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 index 8e4f8d870eed..4b8d7fa34a41 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveSpamfilterTemplate.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveSpamfilterTemplate { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'SpamfilterTemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Transport Rule Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Transport Rule Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 index 06f864c69222..af93c7a4cc95 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveStandard.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveStandard { $Table = Get-CippTable -tablename 'standards' $Filter = "PartitionKey eq 'standards' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed standards for $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed standards deployment' } diff --git a/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 index d00b4da7bffa..029c1c4e4284 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1 @@ -14,13 +14,13 @@ Function Invoke-RemoveStandardTemplate { $User = $request.headers.'x-ms-client-principal' Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $ID = $request.query.ID + $ID = $request.body.ID try { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'StandardsTemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Standards Template named $($ClearRow.name) and id $($id)" -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Template' } } catch { diff --git a/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 index f01c97da7adb..997c150e47f8 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveTransportRuleTemplate.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveTransportRuleTemplate { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'TransportTemplate' and RowKey eq '$id'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity @Table -Entity $clearRow + Remove-AzDataTableEntity -Force @Table -Entity $clearRow Write-LogMessage -user $User -API $APINAME -message "Removed Transport Rule Template with ID $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed Transport Rule Template' } } catch { diff --git a/Modules/CIPPCore/Public/New-CIPPBackup.ps1 b/Modules/CIPPCore/Public/New-CIPPBackup.ps1 index 65e55aa03455..d161967509be 100644 --- a/Modules/CIPPCore/Public/New-CIPPBackup.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPBackup.ps1 @@ -24,7 +24,7 @@ function New-CIPPBackup { ) $CSVfile = foreach ($CSVTable in $BackupTables) { $Table = Get-CippTable -tablename $CSVTable - Get-AzDataTableEntity @Table | Select-Object *, @{l = 'table'; e = { $CSVTable } } -ExcludeProperty DomainAnalyser + Get-AzDataTableEntity @Table | Select-Object * -ExcludeProperty DomainAnalyser, table | Select-Object *, @{l = 'table'; e = { $CSVTable } } } $RowKey = 'CIPPBackup' + '_' + (Get-Date).ToString('yyyy-MM-dd-HHmm') $CSVfile diff --git a/Modules/CIPPCore/Public/Remove-CIPPUserMFA.ps1 b/Modules/CIPPCore/Public/Remove-CIPPUserMFA.ps1 new file mode 100644 index 000000000000..99d141ea9bc5 --- /dev/null +++ b/Modules/CIPPCore/Public/Remove-CIPPUserMFA.ps1 @@ -0,0 +1,65 @@ +function Remove-CIPPUserMFA { + <# + .SYNOPSIS + Remove MFA methods for a user + + .DESCRIPTION + Remove MFA methods for a user using bulk requests to the Microsoft Graph API + + .PARAMETER UserPrincipalName + UserPrincipalName of the user to remove MFA methods for + + .PARAMETER TenantFilter + Tenant where the user resides + + .EXAMPLE + Remove-CIPPUserMFA -UserPrincipalName testuser@contoso.com -TenantFilter contoso.com + + #> + [CmdletBinding(SupportsShouldProcess = $true)] + Param( + [Parameter(Mandatory = $true)] + [string]$UserPrincipalName, + [Parameter(Mandatory = $true)] + [string]$TenantFilter, + [Parameter(Mandatory = $false)] + [string]$ExecutingUser = 'CIPP' + ) + + Write-Information "Getting auth methods for $UserPrincipalName" + $AuthMethods = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$UserPrincipalName/authentication/methods" -tenantid $TenantFilter -AsApp $true + $Requests = [System.Collections.Generic.List[object]]::new() + foreach ($Method in $AuthMethods) { + if ($Method.'@odata.type' -and $Method.'@odata.type' -ne '#microsoft.graph.passwordAuthenticationMethod') { + $MethodType = ($Method.'@odata.type' -split '\.')[-1] -replace 'Authentication', '' + $Requests.Add(@{ + id = "$MethodType-$($Method.id)" + method = 'DELETE' + url = ('users/{0}/authentication/{1}s/{2}' -f $UserPrincipalName, $MethodType, $Method.id) + }) + } + } + if (($Requests | Measure-Object).Count -eq 0) { + Write-LogMessage -API 'Remove-CIPPUserMFA' -tenant $TenantFilter -message "No MFA methods found for user $UserPrincipalName" -sev 'Info' + $Results = [pscustomobject]@{'Results' = "No MFA methods found for user $($Request.Query.ID)" } + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) + return + } + + if ($PSCmdlet.ShouldProcess("Remove MFA methods for $UserPrincipalName")) { + $Results = New-GraphBulkRequest -Requests $Requests -tenantid $TenantFilter -asapp $true -erroraction stop + if ($Results.status -eq 204) { + Write-LogMessage -API 'Remove-CIPPUserMFA' -tenant $TenantFilter -message "Successfully removed MFA methods for user $UserPrincipalName" -sev 'Info' + $Results = [pscustomobject]@{'Results' = "Successfully completed request. User $($Request.Query.ID) must supply MFA at next logon" } + } else { + $FailedAuthMethods = (($Results | Where-Object { $_.status -ne 204 }).id -split '-')[0] -join ', ' + Write-LogMessage -API 'Remove-CIPPUserMFA' -tenant $TenantFilter -message "Failed to remove MFA methods for $FailedAuthMethods" -sev 'Error' + $Results = [pscustomobject]@{'Results' = "Failed to reset MFA methods for $FailedAuthMethods" } + } + } + + return $Results +} diff --git a/Modules/CIPPCore/Public/Set-CIPPCalendarPermission.ps1 b/Modules/CIPPCore/Public/Set-CIPPCalendarPermission.ps1 index 03e32ece9ffe..f308188385e8 100644 --- a/Modules/CIPPCore/Public/Set-CIPPCalendarPermission.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPCalendarPermission.ps1 @@ -6,30 +6,38 @@ function Set-CIPPCalendarPermission { $UserID, $folderName, $UserToGetPermissions, + $LoggingName, $Permissions ) try { + # If a pretty logging name is not provided, use the ID instead + if ([string]::IsNullOrWhiteSpace($LoggingName) -and $RemoveAccess) { + $LoggingName = $RemoveAccess + } elseif ([string]::IsNullOrWhiteSpace($LoggingName) -and $UserToGetPermissions) { + $LoggingName = $UserToGetPermissions + } + $CalParam = [PSCustomObject]@{ Identity = "$($UserID):\$folderName" AccessRights = @($Permissions) User = $UserToGetPermissions } if ($RemoveAccess) { - if ($PSCmdlet.ShouldProcess("$UserID\$folderName", "Remove permissions for $RemoveAccess")) { + if ($PSCmdlet.ShouldProcess("$UserID\$folderName", "Remove permissions for $LoggingName")) { $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-MailboxFolderPermission' -cmdParams @{Identity = "$($UserID):\$folderName"; User = $RemoveAccess } - $Result = "Successfully removed access for $RemoveAccess from calendar $($CalParam.Identity)" - Write-LogMessage -API 'CalendarPermissions' -tenant $TenantFilter -message "Successfully removed access for $RemoveAccess from calendar $($UserID)" -sev Debug + $Result = "Successfully removed access for $LoggingName from calendar $($CalParam.Identity)" + Write-LogMessage -API 'CalendarPermissions' -tenant $TenantFilter -message "Successfully removed access for $LoggingName from calendar $($UserID)" -sev Info } } else { - if ($PSCmdlet.ShouldProcess("$UserID\$folderName", "Set permissions for $UserToGetPermissions to $Permissions")) { + if ($PSCmdlet.ShouldProcess("$UserID\$folderName", "Set permissions for $LoggingName to $Permissions")) { try { $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Set-MailboxFolderPermission' -cmdParams $CalParam -Anchor $UserID } catch { $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Add-MailboxFolderPermission' -cmdParams $CalParam -Anchor $UserID } - Write-LogMessage -API 'CalendarPermissions' -tenant $TenantFilter -message "Calendar permissions added for $UserToGetPermissions on $UserID." -sev Debug - $Result = "Successfully set permissions on folder $($CalParam.Identity). The user $UserToGetPermissions now has $Permissions permissions on this folder." + Write-LogMessage -API 'CalendarPermissions' -tenant $TenantFilter -message "Calendar permissions added for $LoggingName on $UserID." -sev Info + $Result = "Successfully set permissions on folder $($CalParam.Identity). The user $LoggingName now has $Permissions permissions on this folder." } } } catch { diff --git a/Modules/CIPPCore/Public/Set-CIPPGDAPInviteGroups.ps1 b/Modules/CIPPCore/Public/Set-CIPPGDAPInviteGroups.ps1 index bfba35fa1103..fe0f4465f179 100644 --- a/Modules/CIPPCore/Public/Set-CIPPGDAPInviteGroups.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPGDAPInviteGroups.ps1 @@ -36,7 +36,7 @@ function Set-CIPPGDAPInviteGroups { if ($PSCmdlet.ShouldProcess($Relationship.id, "Remove invite entry for $($Relationship.customer.displayName)")) { Write-LogMessage -API $APINAME -message "Groups mapped for GDAP Relationship: $($Relationship.customer.displayName) - $($Relationship.customer.displayName)" -Sev Info - Remove-AzDataTableEntity @Table -Entity $Invite + Remove-AzDataTableEntity -Force @Table -Entity $Invite } return $true } else { @@ -60,6 +60,7 @@ function Set-CIPPGDAPInviteGroups { #Write-Information ($InputObject | ConvertTo-Json) $InstanceId = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject (ConvertTo-Json -InputObject $InputObject -Depth 5 -Compress) Write-Information "Started GDAP Invite orchestration with ID = '$InstanceId'" + return $InstanceId } } } diff --git a/Modules/CIPPCore/Public/Set-CIPPIntunePolicy.ps1 b/Modules/CIPPCore/Public/Set-CIPPIntunePolicy.ps1 index 96959041a08f..f2d429fc5127 100644 --- a/Modules/CIPPCore/Public/Set-CIPPIntunePolicy.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPIntunePolicy.ps1 @@ -35,10 +35,10 @@ function Set-CIPPIntunePolicy { $JSON = $RawJSON | ConvertFrom-Json | Select-Object * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, version, 'scheduledActionsForRule@odata.context', '@odata.context' $JSON.scheduledActionsForRule = @($JSON.scheduledActionsForRule | Select-Object * -ExcludeProperty 'scheduledActionConfigurations@odata.context') if ($displayname -in $CheckExististing.displayName) { - $RawJSON = ConvertTo-Json -InputObject $JSON -Depth 20 -Compress + $RawJSON = ConvertTo-Json -InputObject ($JSON | Select-Object * -ExcludeProperty 'scheduledActionsForRule') -Depth 20 -Compress $PostType = 'edited' $ExistingID = $CheckExististing | Where-Object -Property displayName -EQ $displayname - $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL/$($ExistingID.Id)" -tenantid $tenantFilter -type PUT -body $RawJSON + $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL/$($ExistingID.Id)" -tenantid $tenantFilter -type PATCH -body $RawJSON Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantFilter) -message "Updated policy $($DisplayName) to template defaults" -Sev 'info' $CreateRequest = $CheckExististing | Where-Object -Property displayName -EQ $DisplayName } else { @@ -81,9 +81,7 @@ function Set-CIPPIntunePolicy { $CheckExististing = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL" -tenantid $tenantFilter if ($PolicyFile.displayName -in $CheckExististing.displayName) { $PostType = 'edited' - Write-Host 'hit' $ExistingID = $CheckExististing | Where-Object -Property displayName -EQ $DisplayName - Write-Host "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL/$($ExistingID.Id)" $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL/$($ExistingID.Id)" -tenantid $tenantFilter -type PATCH -body $RawJSON $CreateRequest = $CheckExististing | Where-Object -Property displayName -EQ $DisplayName Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($tenantFilter) -message "Updated policy $($DisplayName) to template defaults" -Sev 'info' diff --git a/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 b/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 index b3ec11c8c96b..4aea97d2fc9e 100644 --- a/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 +++ b/Modules/CIPPCore/Public/Standards/Get-CIPPStandards.ps1 @@ -2,7 +2,8 @@ function Get-CIPPStandards { param( [Parameter(Mandatory = $false)] [string]$TenantFilter = 'allTenants', - [switch]$ListAllTenants + [switch]$ListAllTenants, + [switch]$SkipGetTenants ) #Write-Host "Getting standards for tenant - $($tenantFilter)" @@ -12,7 +13,12 @@ function Get-CIPPStandards { $StandardsAllTenants = $Standards | Where-Object { $_.Tenant -eq 'AllTenants' } # Get tenant list based on filter - $Tenants = Get-Tenants + if ($SkipGetTenants.IsPresent) { + # Debugging flag to skip Get-Tenants + $Tenants = $Standards.Tenant | Sort-Object -Unique | ForEach-Object { [pscustomobject]@{ defaultDomainName = $_ } } + } else { + $Tenants = Get-Tenants + } if ($TenantFilter -ne 'allTenants') { $Tenants = $Tenants | Where-Object { $_.defaultDomainName -eq $TenantFilter -or $_.customerId -eq $TenantFilter } } @@ -63,8 +69,7 @@ function Get-CIPPStandards { $ComputedStandards[$StandardName] = $CurrentStandard } else { foreach ($Setting in $CurrentStandard.PSObject.Properties.Name) { - # Write-Host "$Setting - Current: $($CurrentStandard.$Setting) | Computed: $($ComputedStandards[$StandardName].$($Setting))" - if ($CurrentStandard.$Setting -ne $false -and ($CurrentStandard.$Setting -ne $ComputedStandards[$StandardName].$($Setting) -and ![string]::IsNullOrWhiteSpace($CurrentStandard.$Setting -or (Compare-Object $CurrentStandard.$Setting $ComputedStandards[$StandardName].$($Setting))))) { + if ($CurrentStandard.$Setting -ne $false -and ($CurrentStandard.$Setting -ne $ComputedStandards[$StandardName].$($Setting) -and ![string]::IsNullOrWhiteSpace($CurrentStandard.$Setting) -or ($null -ne $CurrentStandard.$Setting -and $null -ne $ComputedStandards[$StandardName].$($Setting) -and (Compare-Object $CurrentStandard.$Setting $ComputedStandards[$StandardName].$($Setting))))) { #Write-Host "Overriding $Setting for $StandardName at tenant level" if ($ComputedStandards[$StandardName].PSObject.Properties.Name -contains $Setting) { $ComputedStandards[$StandardName].$($Setting) = $CurrentStandard.$Setting diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 index c60f21c24419..cd1495d5300b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 @@ -42,12 +42,14 @@ function Invoke-CIPPStandardActivityBasedTimeout { # Backwards compatibility for v5.7.0 and older if ($null -eq $Settings.timeout ) { $Settings.timeout = '01:00:00' } - $State = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -tenantid $tenant - $StateIsCorrect = $State.definition -like "*$($Settings.timeout)*" + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -tenantid $tenant + $StateIsCorrect = if ($CurrentState.definition -like "*$($Settings.timeout)*") { $true } else { $false } If ($Settings.remediate -eq $true) { try { - if (!$StateIsCorrect) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is already enabled and set to $($Settings.timeout)" -sev Info + } else { $PolicyTemplate = @{ displayName = 'DefaultTimeoutPolicy' isOrganizationDefault = $true @@ -58,27 +60,24 @@ function Invoke-CIPPStandardActivityBasedTimeout { $body = ConvertTo-Json -InputObject $PolicyTemplate -Depth 10 -Compress # Switch between parameter sets if the policy already exists - if ($null -eq $State.id) { + if ($null -eq $CurrentState.id) { $RequestType = 'POST' $URI = 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' } else { $RequestType = 'PATCH' - $URI = "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies/$($State.id)" + $URI = "https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies/$($CurrentState.id)" } New-GraphPostRequest -tenantid $tenant -Uri $URI -Type $RequestType -Body $body -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled Activity Based Timeout with a value of $($Settings.timeout)" -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is already enabled and set to $($Settings.timeout)" -sev Info } } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Activity Based Timeout a value of $($Settings.timeout). Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Activity Based Timeout a value of $($Settings.timeout)." -sev Error -LogData $_ } } if ($Settings.alert -eq $true) { - if ($StateIsCorrect) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is enabled and set to $($Settings.timeout)" -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Activity Based Timeout is not set to $($Settings.timeout)" -sev Alert diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 index 65396b677490..b57c2a2a3576 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 @@ -51,9 +51,21 @@ function Invoke-CIPPStandardAntiPhishPolicy { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'AntiPhishPolicy' - $PolicyList = @('Default Anti-Phishing Policy', 'Office365 AntiPhish Default (Default)') + $PolicyList = @('CIPP Default Anti-Phishing Policy','Default Anti-Phishing Policy') $ExistingPolicy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AntiPhishPolicy' | Where-Object -Property Name -In $PolicyList - $PolicyName = $ExistingPolicy.Name + if ($null -eq $ExistingPolicy.Name) { + $PolicyName = $PolicyList[0] + } else { + $PolicyName = $ExistingPolicy.Name + } + $RuleList = @( 'CIPP Default Anti-Phishing Rule','CIPP Default Anti-Phishing Policy') + $ExistingRule = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AntiPhishRule' | Where-Object -Property Name -In $RuleList + if ($null -eq $ExistingRule.Name) { + $RuleName = $RuleList[0] + } else { + $RuleName = $ExistingRule.Name + } + $CurrentState = $ExistingPolicy | Select-Object Name, Enabled, PhishThresholdLevel, EnableMailboxIntelligence, EnableMailboxIntelligenceProtection, EnableSpoofIntelligence, EnableFirstContactSafetyTips, EnableSimilarUsersSafetyTips, EnableSimilarDomainsSafetyTips, EnableUnusualCharactersSafetyTips, EnableUnauthenticatedSender, EnableViaTag, AuthenticationFailAction, SpoofQuarantineTag, MailboxIntelligenceProtectionAction, MailboxIntelligenceQuarantineTag, TargetedUserProtectionAction, TargetedUserQuarantineTag, TargetedDomainProtectionAction, TargetedDomainQuarantineTag, EnableOrganizationDomainsProtection @@ -82,17 +94,17 @@ function Invoke-CIPPStandardAntiPhishPolicy { $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AntiPhishRule' | - Where-Object -Property Name -EQ "CIPP $PolicyName" | + Where-Object -Property Name -EQ $RuleName | Select-Object Name, AntiPhishPolicy, Priority, RecipientDomainIs - $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + $RuleStateIsCorrect = ($RuleState.Name -eq $RuleName) -and ($RuleState.AntiPhishPolicy -eq $PolicyName) -and ($RuleState.Priority -eq 0) -and (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) if ($Settings.remediate -eq $true) { if ($StateIsCorrect -eq $true) { - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing Policy already correctly configured' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing policy already correctly configured' -sev Info } else { $cmdparams = @{ Enabled = $true @@ -121,47 +133,46 @@ function Invoke-CIPPStandardAntiPhishPolicy { try { $cmdparams.Add('Identity', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AntiPhishPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Anti-phishing Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Anti-phishing policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Anti-phishing Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Anti-phishing policy $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-AntiPhishPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Anti-phishing Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Anti-phishing policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing policy $PolicyName." -sev Error -LogData $_ } } } if ($RuleStateIsCorrect -eq $false) { $cmdparams = @{ - AntiPhishPolicy = $PolicyName Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } - if ($RuleState.Name -eq "CIPP $PolicyName") { + if ($RuleState.AntiPhishPolicy -ne $PolicyName) { + $cmdparams.Add('AntiPhishPolicy', $PolicyName) + } + + if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', "CIPP $PolicyName") + $cmdparams.Add('Identity', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AntiPhishRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Anti-phishing Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Anti-phishing rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Anti-phishing Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Anti-phishing rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', "CIPP $PolicyName") + $cmdparams.Add('Name', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-AntiPhishRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Anti-phishing Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Anti-phishing rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing rule $RuleName." -sev Error -LogData $_ } } } @@ -170,9 +181,9 @@ function Invoke-CIPPStandardAntiPhishPolicy { if ($Settings.alert -eq $true) { if ($StateIsCorrect -eq $true) { - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing Policy is enabled' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing policy is enabled' -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing Policy is not enabled' -sev Alert + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing policy is not enabled' -sev Alert } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 index 65b3c7878a00..86f8805e3247 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 @@ -33,13 +33,13 @@ function Invoke-CIPPStandardAuditLog { ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'AuditLog' Write-Host ($Settings | ConvertTo-Json) - $AuditLogEnabled = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AdminAuditLogConfig' -Select UnifiedAuditLogIngestionEnabled).UnifiedAuditLogIngestionEnabled + $AuditLogEnabled = [bool](New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AdminAuditLogConfig' -Select UnifiedAuditLogIngestionEnabled).UnifiedAuditLogIngestionEnabled If ($Settings.remediate -eq $true) { Write-Host 'Time to remediate' $DehydratedTenant = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig' -Select IsDehydrated).IsDehydrated - if ($DehydratedTenant) { + if ($DehydratedTenant -eq $true) { try { New-ExoRequest -tenantid $Tenant -cmdlet 'Enable-OrganizationCustomization' Write-LogMessage -API 'Standards' -tenant $tenant -message 'Organization customization enabled.' -sev Info @@ -50,7 +50,7 @@ function Invoke-CIPPStandardAuditLog { } try { - if ($AuditLogEnabled) { + if ($AuditLogEnabled -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Unified Audit Log already enabled.' -sev Info } else { New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AdminAuditLogConfig' -cmdParams @{UnifiedAuditLogIngestionEnabled = $true } @@ -64,7 +64,7 @@ function Invoke-CIPPStandardAuditLog { } if ($Settings.alert -eq $true) { - if ($AuditLogEnabled) { + if ($AuditLogEnabled -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Unified Audit Log is enabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Unified Audit Log is not enabled' -sev Alert diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 index 561418da57e0..8dd565ff762c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 @@ -29,19 +29,19 @@ function Invoke-CIPPStandardDisableEmail { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'DisableEmail' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Email' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Email' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'disabled') If ($Settings.remediate -eq $true) { - if ($State) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Email' -Enabled $false - } else { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is already disabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Email' -Enabled $false } } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is enabled' -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is not enabled' -sev Info @@ -49,6 +49,6 @@ function Invoke-CIPPStandardDisableEmail { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'DisableEmail' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableEmail' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 index 27fa3455b2c7..30af4f6a7bfd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 @@ -29,19 +29,19 @@ function Invoke-CIPPStandardDisableSMS { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'DisableSMS' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/SMS' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/SMS' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'disabled') If ($Settings.remediate -eq $true) { - if ($State) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'SMS' -Enabled $false - } else { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is already disabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'SMS' -Enabled $false } } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is enabled' -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is not enabled' -sev Info @@ -49,6 +49,6 @@ function Invoke-CIPPStandardDisableSMS { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'DisableSMS' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableSMS' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 index 1101af93c9ec..00b0b1380422 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 @@ -31,34 +31,39 @@ function Invoke-CIPPStandardDisableTenantCreation { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'DisableTenantCreation' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant - $State = $CurrentInfo.defaultUserRolePermissions.allowedToCreateTenants + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.defaultUserRolePermissions.allowedToCreateTenants -eq $false) If ($Settings.remediate -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already disabled from creating tenants.' -sev Info + } else { try { - $body = '{"defaultUserRolePermissions":{"allowedToCreateTenants":false}}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json' + $GraphRequest = @{ + tenantid = $tenant + uri = 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' + AsApp = $false + Type = 'PATCH' + ContentType = 'application/json' + Body = '{"defaultUserRolePermissions":{"allowedToCreateTenants":false}}' + } + New-GraphPostRequest @GraphRequest Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating tenants.' -sev Info - $State = $false } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating tenants: $ErrorMessage" -sev 'Error' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating tenants" -sev 'Error' -LogData $_ } - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already disabled from creating tenants.' -sev Info } } - if ($Settings.alert -eq $true) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are allowed to create tenants.' -sev Alert - } else { + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not allowed to create tenants.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are allowed to create tenants.' -sev Alert } } + if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'DisableTenantCreation' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableTenantCreation' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 index 3aac080f0ede..e8accc7f686f 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 @@ -29,19 +29,19 @@ function Invoke-CIPPStandardDisableVoice { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'DisableVoice' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Voice' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Voice' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'disabled') If ($Settings.remediate -eq $true) { - if ($State) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Voice' -Enabled $false - } else { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is already disabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Voice' -Enabled $false } } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is enabled' -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is not enabled' -sev Info @@ -49,6 +49,6 @@ function Invoke-CIPPStandardDisableVoice { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'DisableVoice' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableVoice' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 index 7914097c7097..3a10f191b71e 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 @@ -29,19 +29,19 @@ function Invoke-CIPPStandardDisablex509Certificate { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'Disablex509Certificate' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/x509Certificate' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/x509Certificate' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'disabled') If ($Settings.remediate -eq $true) { - if ($State) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'x509Certificate' -Enabled $false - } else { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is already disabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'x509Certificate' -Enabled $false } } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is enabled' -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is not enabled' -sev Info @@ -49,7 +49,7 @@ function Invoke-CIPPStandardDisablex509Certificate { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'Disablex509Certificate' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'Disablex509Certificate' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 index a0f164c7e1f2..deee9286eaf4 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 @@ -29,22 +29,19 @@ function Invoke-CIPPStandardEnableFIDO2 { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'EnableFIDO2' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Fido2' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Fido2' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'enabled') If ($Settings.remediate -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is already enabled.' -sev Info } else { Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Fido2' -Enabled $true } } - if ($Settings.alert -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is enabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is not enabled' -sev Alert @@ -52,7 +49,6 @@ function Invoke-CIPPStandardEnableFIDO2 { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'EnableFIDO2' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'EnableFIDO2' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } - } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 index 62a53daef0f3..9a79fbbc3711 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 @@ -29,12 +29,11 @@ function Invoke-CIPPStandardEnableHardwareOAuth { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'EnableHardwareOAuth' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/HardwareOath' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/HardwareOath' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'enabled') If ($Settings.remediate -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is already enabled.' -sev Info } else { Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'HardwareOath' -Enabled $true @@ -42,8 +41,7 @@ function Invoke-CIPPStandardEnableHardwareOAuth { } if ($Settings.alert -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is enabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is not enabled' -sev Alert @@ -51,6 +49,6 @@ function Invoke-CIPPStandardEnableHardwareOAuth { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'EnableHardwareOAuth' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'EnableHardwareOAuth' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 new file mode 100644 index 000000000000..dfa296eb106a --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 @@ -0,0 +1,68 @@ +function Invoke-CIPPStandardGuestInvite { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) GuestInvite + .SYNOPSIS + (Label) Guest Invite settings + .DESCRIPTION + (Helptext) This setting controls who can invite guests to your directory to collaborate on resources secured by your company, such as SharePoint sites or Azure resources. + (DocsDescription) This setting controls who can invite guests to your directory to collaborate on resources secured by your company, such as SharePoint sites or Azure resources. + .NOTES + CAT + InTune Standards + TAG + "highimpact" + ADDEDCOMPONENT + IMPACT + High Impact + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/edit-standards + #> + + param($Tenant, $Settings) + + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant + + if ($null -eq $Settings.allowInvitesFrom) { $Settings.allowInvitesFrom = 'Everyone' } # none, adminsAndGuestInviters, adminsGuestInvitersAndAllMembers, everyone + $StateIsCorrect = ($CurrentState.allowInvitesFrom -eq $Settings.allowInvitesFrom) + + if ($Settings.remediate -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Guest Invite settings is already applied correctly.' -Sev Info + } else { + try { + $GraphRequest = @{ + tenantID = $Tenant + uri = "https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy" + AsApp = $false + Type = 'PATCH' + ContentType = 'application/json; charset=utf-8' + Body = [pscustomobject]@{ + allowInvitesFrom = $Settings.allowInvitesFrom + } | ConvertTo-Json -Compress + } + New-GraphPostRequest @GraphRequest + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Successfully updated Guest Invite setting to $($Settings.allowInvitesFrom)" -Sev Info + } catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to update Guest Invite setting to $($Settings.allowInvitesFrom)" -Sev Error -LogData $_ + } + } + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guest Invite settings is enabled.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guest Invite settings is not enabled.' -sev Alert + } + } + + if ($Settings.report -eq $true) { + Add-CIPPBPAField -FieldName 'GuestInvite' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant + } +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 new file mode 100644 index 000000000000..25d4b1e8eb58 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 @@ -0,0 +1,73 @@ +function Invoke-CIPPStandardIntuneComplianceSettings { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) IntuneComplianceSettings + .SYNOPSIS + (Label) InTune Compliance settings + .DESCRIPTION + (Helptext) Sets the mark devices with no compliance policy assigned as compliance/non compliant and Compliance status validity period. + (DocsDescription) Sets the mark devices with no compliance policy assigned as compliance/non compliant and Compliance status validity period. + .NOTES + CAT + InTune Standards + TAG + "lowimpact" + ADDEDCOMPONENT + IMPACT + Low Impact + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/edit-standards + #> + + param($Tenant, $Settings) + + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/deviceManagement/settings' -tenantid $Tenant + + if ($null -eq $Settings.secureByDefault) { $Settings.secureByDefault = $true } + if ($null -eq $Settings.deviceComplianceCheckinThresholdDays) { $Settings.deviceComplianceCheckinThresholdDays = $CurrentState.deviceComplianceCheckinThresholdDays } + $StateIsCorrect = ($CurrentState.secureByDefault -eq $Settings.secureByDefault) -and + ($CurrentState.deviceComplianceCheckinThresholdDays -eq $Settings.deviceComplianceCheckinThresholdDays) + + if ($Settings.remediate -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'InTune Compliance settings is already applied correctly.' -Sev Info + } else { + try { + $GraphRequest = @{ + tenantID = $Tenant + uri = "https://graph.microsoft.com/beta/deviceManagement" + AsApp = $true + Type = 'PATCH' + ContentType = 'application/json; charset=utf-8' + Body = [pscustomobject]@{ + settings = [pscustomobject]@{ + secureByDefault = $Settings.secureByDefault + deviceComplianceCheckinThresholdDays = $Settings.deviceComplianceCheckinThresholdDays + } + } | ConvertTo-Json -Compress + } + New-GraphPostRequest @GraphRequest + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully updated InTune Compliance settings.' -Sev Info + } catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to update InTune Compliance settings." -Sev Error -LogData $_ + } + } + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'InTune Compliance settings is enabled.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'InTune Compliance settings is not enabled.' -sev Alert + } + } + + if ($Settings.report -eq $true) { + Add-CIPPBPAField -FieldName 'IntuneComplianceSettings' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant + } +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 index f9cd47acee18..8992d680904c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 @@ -41,11 +41,24 @@ function Invoke-CIPPStandardMalwareFilterPolicy { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'MalwareFilterPolicy' - $PolicyName = 'Default Malware Policy' + $PolicyList = @('CIPP Default Malware Policy','Default Malware Policy') + $ExistingPolicy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MalwareFilterPolicy' | Where-Object -Property Name -In $PolicyList + if ($null -eq $ExistingPolicy.Name) { + $PolicyName = $PolicyList[0] + } else { + $PolicyName = $ExistingPolicy.Name + } + $RuleList = @( 'CIPP Default Malware Rule','CIPP Default Malware Policy') + $ExistingRule = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MalwareFilterRule' | Where-Object -Property Name -In $RuleList + if ($null -eq $ExistingRule.Name) { + $RuleName = $RuleList[0] + } else { + $RuleName = $ExistingRule.Name + } $CurrentState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MalwareFilterPolicy' | - Where-Object -Property Name -EQ $PolicyName | - Select-Object Name, EnableFileFilter, FileTypeAction, FileTypes, ZapEnabled, QuarantineTag, EnableInternalSenderAdminNotifications, InternalSenderAdminAddress, EnableExternalSenderAdminNotifications, ExternalSenderAdminAddress + Where-Object -Property Name -EQ $PolicyName | + Select-Object Name, EnableFileFilter, FileTypeAction, FileTypes, ZapEnabled, QuarantineTag, EnableInternalSenderAdminNotifications, InternalSenderAdminAddress, EnableExternalSenderAdminNotifications, ExternalSenderAdminAddress $DefaultFileTypes = @('ace', 'ani', 'apk', 'app', 'appx', 'arj', 'bat', 'cab', 'cmd', 'com', 'deb', 'dex', 'dll', 'docm', 'elf', 'exe', 'hta', 'img', 'iso', 'jar', 'jnlp', 'kext', 'lha', 'lib', 'library', 'lnk', 'lzh', 'macho', 'msc', 'msi', 'msix', 'msp', 'mst', 'pif', 'ppa', 'ppam', 'reg', 'rev', 'scf', 'scr', 'sct', 'sys', 'uif', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh', 'xll', 'xz', 'z') @@ -69,10 +82,10 @@ function Invoke-CIPPStandardMalwareFilterPolicy { $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MalwareFilterRule' | - Where-Object -Property Name -EQ "CIPP $PolicyName" | - Select-Object Name, MalwareFilterPolicy, Priority, RecipientDomainIs + Where-Object -Property Name -EQ $RuleName | + Select-Object Name, MalwareFilterPolicy, Priority, RecipientDomainIs - $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + $RuleStateIsCorrect = ($RuleState.Name -eq $RuleName) -and ($RuleState.MalwareFilterPolicy -eq $PolicyName) -and ($RuleState.Priority -eq 0) -and (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) @@ -98,47 +111,46 @@ function Invoke-CIPPStandardMalwareFilterPolicy { try { $cmdparams.Add('Identity', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-MalwareFilterPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Malware Filter Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Malware Filter policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Malware Filter Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Malware Filter policy $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-MalwareFilterPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Malware Filter Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Malware Filter policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Malware Filter Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Malware Filter policy $PolicyName." -sev Error -LogData $_ } } } if ($RuleStateIsCorrect -eq $false) { $cmdparams = @{ - MalwareFilterPolicy = $PolicyName Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } - if ($RuleState.Name -eq "CIPP $PolicyName") { + if ($RuleState.MalwareFilterPolicy -ne $PolicyName) { + $cmdparams.Add('MalwareFilterPolicy', $PolicyName) + } + + if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', "CIPP $PolicyName") + $cmdparams.Add('Identity', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-MalwareFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Malware Filter Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Malware Filter rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Malware Filter Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Malware Filter Rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', "CIPP $PolicyName") + $cmdparams.Add('Name', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-MalwareFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Malware Filter Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Malware Filter rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Malware Filter Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Malware Filter rule $RuleName." -sev Error -LogData $_ } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 index 593035bbf4a0..6ff2826da936 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 @@ -31,11 +31,13 @@ function Invoke-CIPPStandardNudgeMFA { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'NudgeMFA' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -tenantid $Tenant - $State = if ($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq $Settings.state) -and + ($CurrentState.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays -eq $Settings.snoozeDurationInDays) -and + ($CurrentState.registrationEnforcement.authenticationMethodsRegistrationCampaign.enforceRegistrationAfterAllowedSnoozes -eq $true) if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'NudgeMFA' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'NudgeMFA' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } @@ -52,23 +54,29 @@ function Invoke-CIPPStandardNudgeMFA { If ($Settings.remediate -eq $true) { - $StateName = $Settings.state.Substring(0, 1).ToUpper() + $Settings.state.Substring(1) - if ($Settings.state -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -or $Settings.snoozeDurationInDays -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays) { + if ($StatsIsCorrect -eq $false) { try { - $Body = $CurrentInfo - $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $Settings.state - $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays = $Settings.snoozeDurationInDays - $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.enforceRegistrationAfterAllowedSnoozes = $true - - $body = ConvertTo-Json -Depth 10 -InputObject ($body | Select-Object registrationEnforcement) - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -Type patch -Body $body -ContentType 'application/json' + $GraphRequest = @{ + tenantid = $tenant + uri = 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' + AsApp = $false + Type = 'PATCH' + ContentType = 'application/json' + Body = @{ + registrationEnforcement = @{ + authenticationMethodsRegistrationCampaign = @{ + state = $Settings.state + snoozeDurationInDays = $Settings.snoozeDurationInDays + enforceRegistrationAfterAllowedSnoozes = $true + } + } + } | ConvertTo-Json -Depth 10 -Compress + } + New-GraphPostRequest @GraphRequest Write-LogMessage -API 'Standards' -tenant $tenant -message "$StateName Authenticator App Nudge with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info - $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $Settings.state - $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays = $Settings.snoozeDurationInDays } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Authenticator App Nudge to $($Settings.state): $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Authenticator App Nudge to $($Settings.state)" -sev Error -LogData $_ } } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is already set to $($Settings.state) with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info @@ -76,11 +84,10 @@ function Invoke-CIPPStandardNudgeMFA { } if ($Settings.alert -eq $true) { - - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is enabled with a snooze duration of $($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Info + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is enabled with a snooze duration of $($CurrentState.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is not enabled with a snooze duration of $($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is not enabled with a snooze duration of $($CurrentState.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Alert } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 index 57eac0a60f0d..a6936f2346d2 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 @@ -31,11 +31,11 @@ function Invoke-CIPPStandardPWdisplayAppInformationRequiredState { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'PWdisplayAppInformationRequiredState' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'enabled') If ($Settings.remediate -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is already enabled.' -sev Info } else { Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'MicrosoftAuthenticator' -Enabled $true @@ -43,7 +43,7 @@ function Invoke-CIPPStandardPWdisplayAppInformationRequiredState { } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is not enabled.' -sev Alert @@ -51,6 +51,6 @@ function Invoke-CIPPStandardPWdisplayAppInformationRequiredState { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'PWdisplayAppInformationRequiredState' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'PWdisplayAppInformationRequiredState' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 index f05f04f2daa9..3142d6bee41c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 @@ -38,11 +38,24 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'SafeAttachmentPolicy' - $PolicyName = 'Default Safe Attachment Policy' + $PolicyList = @('CIPP Default Safe Attachment Policy','Default Safe Attachment Policy') + $ExistingPolicy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeAttachmentPolicy' | Where-Object -Property Name -In $PolicyList + if ($null -eq $ExistingPolicy.Name) { + $PolicyName = $PolicyList[0] + } else { + $PolicyName = $ExistingPolicy.Name + } + $RuleList = @( 'CIPP Default Safe Attachment Rule','CIPP Default Safe Attachment Policy') + $ExistingRule = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeAttachmentRule' | Where-Object -Property Name -In $RuleList + if ($null -eq $ExistingRule.Name) { + $RuleName = $RuleList[0] + } else { + $RuleName = $ExistingRule.Name + } $CurrentState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeAttachmentPolicy' | - Where-Object -Property Name -EQ $PolicyName | - Select-Object Name, Enable, Action, QuarantineTag, Redirect, RedirectAddress + Where-Object -Property Name -EQ $PolicyName | + Select-Object Name, Enable, Action, QuarantineTag, Redirect, RedirectAddress $StateIsCorrect = ($CurrentState.Name -eq $PolicyName) -and ($CurrentState.Enable -eq $true) -and @@ -54,10 +67,10 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeAttachmentRule' | - Where-Object -Property Name -EQ "CIPP $PolicyName" | - Select-Object Name, SafeAttachmentPolicy, Priority, RecipientDomainIs + Where-Object -Property Name -EQ $RuleName | + Select-Object Name, SafeAttachmentPolicy, Priority, RecipientDomainIs - $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + $RuleStateIsCorrect = ($RuleState.Name -eq $RuleName) -and ($RuleState.SafeAttachmentPolicy -eq $PolicyName) -and ($RuleState.Priority -eq 0) -and (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) @@ -79,47 +92,46 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { try { $cmdparams.Add('Identity', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeAttachmentPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Safe Attachment Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Safe Attachment policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Safe Attachment Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Safe Attachment policy $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeAttachmentPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Safe Attachment Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Safe Attachment policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment policy $PolicyName." -sev Error -LogData $_ } } } if ($RuleStateIsCorrect -eq $false) { $cmdparams = @{ - SafeAttachmentPolicy = $PolicyName Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } - if ($RuleState.Name -eq "CIPP $PolicyName") { + if ($RuleState.SafeAttachmentPolicy -ne $PolicyName) { + $cmdparams.Add('SafeAttachmentPolicy', $PolicyName) + } + + if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', "CIPP $PolicyName") + $cmdparams.Add('Identity', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeAttachmentRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Safe Attachment Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Safe Attachment rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Safe Attachment Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Safe Attachment rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', "CIPP $PolicyName") + $cmdparams.Add('Name', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeAttachmentRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created Safe Attachment Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created Safe Attachment rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment rule $RuleName." -sev Error -LogData $_ } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 index 3eded0a38efd..e8639f10ce49 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 @@ -36,11 +36,24 @@ function Invoke-CIPPStandardSafeLinksPolicy { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'SafeLinksPolicy' - $PolicyName = 'Default SafeLinks Policy' + $PolicyList = @('CIPP Default SafeLinks Policy','Default SafeLinks Policy') + $ExistingPolicy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeLinksPolicy' | Where-Object -Property Name -In $PolicyList + if ($null -eq $ExistingPolicy.Name) { + $PolicyName = $PolicyList[0] + } else { + $PolicyName = $ExistingPolicy.Name + } + $RuleList = @( 'CIPP Default SafeLinks Rule','CIPP Default SafeLinks Policy') + $ExistingRule = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeLinksRule' | Where-Object -Property Name -In $RuleList + if ($null -eq $ExistingRule.Name) { + $RuleName = $RuleList[0] + } else { + $RuleName = $ExistingRule.Name + } $CurrentState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeLinksPolicy' | - Where-Object -Property Name -EQ $PolicyName | - Select-Object Name, EnableSafeLinksForEmail, EnableSafeLinksForTeams, EnableSafeLinksForOffice, TrackClicks, AllowClickThrough, ScanUrls, EnableForInternalSenders, DeliverMessageAfterScan, DisableUrlRewrite, EnableOrganizationBranding + Where-Object -Property Name -EQ $PolicyName | + Select-Object Name, EnableSafeLinksForEmail, EnableSafeLinksForTeams, EnableSafeLinksForOffice, TrackClicks, AllowClickThrough, ScanUrls, EnableForInternalSenders, DeliverMessageAfterScan, DisableUrlRewrite, EnableOrganizationBranding $StateIsCorrect = ($CurrentState.Name -eq $PolicyName) -and ($CurrentState.EnableSafeLinksForEmail -eq $true) -and @@ -57,10 +70,10 @@ function Invoke-CIPPStandardSafeLinksPolicy { $AcceptedDomains = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-AcceptedDomain' $RuleState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SafeLinksRule' | - Where-Object -Property Name -EQ "CIPP $PolicyName" | - Select-Object Name, SafeLinksPolicy, Priority, RecipientDomainIs + Where-Object -Property Name -EQ $RuleName | + Select-Object Name, SafeLinksPolicy, Priority, RecipientDomainIs - $RuleStateIsCorrect = ($RuleState.Name -eq "CIPP $PolicyName") -and + $RuleStateIsCorrect = ($RuleState.Name -eq $RuleName) -and ($RuleState.SafeLinksPolicy -eq $PolicyName) -and ($RuleState.Priority -eq 0) -and (!(Compare-Object -ReferenceObject $RuleState.RecipientDomainIs -DifferenceObject $AcceptedDomains.Name)) @@ -87,47 +100,46 @@ function Invoke-CIPPStandardSafeLinksPolicy { try { $cmdparams.Add('Identity', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeLinksPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated SafeLink Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated SafeLink policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update SafeLink Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update SafeLink policy $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', $PolicyName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeLinksPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created SafeLink Policy' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created SafeLink policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink policy $PolicyName." -sev Error -LogData $_ } } } if ($RuleStateIsCorrect -eq $false) { $cmdparams = @{ - SafeLinksPolicy = $PolicyName Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } - if ($RuleState.Name -eq "CIPP $PolicyName") { + if ($RuleState.SafeLinksPolicy -ne $PolicyName) { + $cmdparams.Add('SafeLinksPolicy', $PolicyName) + } + + if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', "CIPP $PolicyName") + $cmdparams.Add('Identity', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeLinksRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated SafeLink Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated SafeLink rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update SafeLink Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update SafeLink rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', "CIPP $PolicyName") + $cmdparams.Add('Name', $RuleName) New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeLinksRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Created SafeLink Rule' -sev Info + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created SafeLink rule $RuleName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink rule $RuleName." -sev Error -LogData $_ } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 index c2b983accdb4..b4de133595e8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 @@ -42,8 +42,8 @@ function Invoke-CIPPStandardSpamFilterPolicy { $PolicyName = 'CIPP Default Spam Filter Policy' $CurrentState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-HostedContentFilterPolicy' | - Where-Object -Property Name -EQ $PolicyName | - Select-Object -Property * + Where-Object -Property Name -EQ $PolicyName | + Select-Object -Property * $StateIsCorrect = ($CurrentState.Name -eq $PolicyName) -and ($CurrentState.SpamAction -eq $Settings.SpamAction) -and @@ -73,8 +73,8 @@ function Invoke-CIPPStandardSpamFilterPolicy { $AcceptedDomains = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-AcceptedDomain' $RuleState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-HostedContentFilterRule' | - Where-Object -Property Name -EQ $PolicyName | - Select-Object -Property * + Where-Object -Property Name -EQ $PolicyName | + Select-Object -Property * $RuleStateIsCorrect = ($RuleState.Name -eq $PolicyName) -and ($RuleState.HostedContentFilterPolicy -eq $PolicyName) -and @@ -115,47 +115,46 @@ function Invoke-CIPPStandardSpamFilterPolicy { try { $cmdparams.Add('Identity', $PolicyName) New-ExoRequest -TenantId $Tenant -cmdlet 'Set-HostedContentFilterPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Updated Spam Filter Policy' -sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Updated Spam Filter policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to update Spam Filter Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to update Spam Filter policy $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', $PolicyName) New-ExoRequest -TenantId $Tenant -cmdlet 'New-HostedContentFilterPolicy' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Created Spam Filter Policy' -sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Created Spam Filter policy $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Spam Filter Policy. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Spam Filter policy $PolicyName." -sev Error -LogData $_ } } } if ($RuleStateIsCorrect -eq $false) { $cmdparams = @{ - HostedContentFilterPolicy = $PolicyName Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } + if ($RuleState.HostedContentFilterPolicy -ne $PolicyName) { + $cmdparams.Add('HostedContentFilterPolicy', $PolicyName) + } + if ($RuleState.Name -eq $PolicyName) { try { $cmdparams.Add('Identity', "$PolicyName") New-ExoRequest -TenantId $Tenant -cmdlet 'Set-HostedContentFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Updated Spam Filter Rule' -sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Updated Spam Filter rule $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to update Spam Filter Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to update Spam Filter rule $PolicyName." -sev Error -LogData $_ } } else { try { $cmdparams.Add('Name', "$PolicyName") New-ExoRequest -TenantId $Tenant -cmdlet 'New-HostedContentFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Created Spam Filter Rule' -sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Created Spam Filter rule $PolicyName." -sev Info } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Spam Filter Rule. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Spam Filter rule $PolicyName." -sev Error -LogData $_ } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 index 1343aa7fe806..744102a249dc 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 @@ -30,11 +30,12 @@ function Invoke-CIPPStandardTAP { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'TAP' - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'enabled') -and + ($CurrentState.isUsableOnce -eq $Settings.config) if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'TemporaryAccessPass' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'TemporaryAccessPass' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } # Input validation @@ -44,7 +45,7 @@ function Invoke-CIPPStandardTAP { } If ($Settings.remediate -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is already enabled.' -sev Info } else { Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'TemporaryAccessPass' -Enabled $true -TAPisUsableOnce $Settings.config @@ -52,7 +53,7 @@ function Invoke-CIPPStandardTAP { } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is not enabled.' -sev Alert diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEnrollUser.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEnrollUser.ps1 new file mode 100644 index 000000000000..adcf29f0fde1 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEnrollUser.ps1 @@ -0,0 +1,46 @@ +Function Invoke-CIPPStandardTeamsEnrollUser { + <# + .FUNCTIONALITY + Internal + #> + + param($Tenant, $Settings) + + $CurrentState = New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Get-CsTeamsMeetingPolicy' -CmdParams @{Identity = 'Global' } + | Select-Object EnrollUserOverride + + if ($null -eq $Settings.EnrollUserOverride) { $Settings.EnrollUserOverride = $CurrentState.EnrollUserOverride } + + $StateIsCorrect = ($CurrentState.EnrollUserOverride -eq $Settings.EnrollUserOverride) + + if ($Settings.remediate -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Teams Enroll User Override settings already set to $($Settings.EnrollUserOverride)." -sev Info + } else { + $cmdparams = @{ + Identity = 'Global' + EnrollUserOverride = $Settings.EnrollUserOverride + } + + try { + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsMeetingPolicy' -CmdParams $cmdparams + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Updated Teams Enroll User Override setting to $($Settings.EnrollUserOverride)." -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to set Teams Enroll User Override setting to $($Settings.EnrollUserOverride)." -sev Error -LogData $ErrorMessage + } + } + } + + if ($Settings.alert -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Enroll User Override settings is set correctly.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Enroll User Override settings is not set correctly.' -sev Alert + } + } + + if ($Setings.report -eq $true) { + Add-CIPPBPAField -FieldName 'TeamsEnrollUser' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $Tenant + } +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 index ee90cb769e04..4357b39bcb88 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 @@ -34,12 +34,14 @@ Function Invoke-CIPPStandardTeamsGlobalMeetingPolicy { | Select-Object AllowAnonymousUsersToJoinMeeting, AllowAnonymousUsersToStartMeeting, AutoAdmittedUsers, AllowPSTNUsersToBypassLobby, MeetingChatEnabledType, DesignatedPresenterRoleMode, AllowExternalParticipantGiveRequestControl if ($null -eq $Settings.DesignatedPresenterRoleMode) { $Settings.DesignatedPresenterRoleMode = $CurrentState.DesignatedPresenterRoleMode } + if ($null -eq $Settings.AllowAnonymousUsersToJoinMeeting) { $Settings.AllowAnonymousUsersToJoinMeeting = $CurrentState.AllowAnonymousUsersToJoinMeeting } + if ($null -eq $Settings.MeetingChatEnabledType) { $Settings.MeetingChatEnabledType = $CurrentState.MeetingChatEnabledType } # Enabled, EnabledExceptAnonymous, Disabled - $StateIsCorrect = ($CurrentState.AllowAnonymousUsersToJoinMeeting -eq $false) -and + $StateIsCorrect = ($CurrentState.AllowAnonymousUsersToJoinMeeting -eq $Settings.AllowAnonymousUsersToJoinMeeting) -and ($CurrentState.AllowAnonymousUsersToStartMeeting -eq $false) -and ($CurrentState.AutoAdmittedUsers -eq 'EveryoneInCompanyExcludingGuests') -and ($CurrentState.AllowPSTNUsersToBypassLobby -eq $false) -and - ($CurrentState.MeetingChatEnabledType -eq 'EnabledExceptAnonymous') -and + ($CurrentState.MeetingChatEnabledType -eq $Settings.MeetingChatEnabledType) -and ($CurrentState.DesignatedPresenterRoleMode -eq $Settings.DesignatedPresenterRoleMode) -and ($CurrentState.AllowExternalParticipantGiveRequestControl -eq $false) @@ -49,11 +51,11 @@ Function Invoke-CIPPStandardTeamsGlobalMeetingPolicy { } else { $cmdparams = @{ Identity = 'Global' - AllowAnonymousUsersToJoinMeeting = $false + AllowAnonymousUsersToJoinMeeting = $Settings.AllowAnonymousUsersToJoinMeeting AllowAnonymousUsersToStartMeeting = $false AutoAdmittedUsers = 'EveryoneInCompanyExcludingGuests' AllowPSTNUsersToBypassLobby = $false - MeetingChatEnabledType = 'EnabledExceptAnonymous' + MeetingChatEnabledType = $Settings.MeetingChatEnabledType DesignatedPresenterRoleMode = $Settings.DesignatedPresenterRoleMode AllowExternalParticipantGiveRequestControl = $false } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 index 1cc77638ff88..5548e1f0b6c5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 @@ -30,27 +30,32 @@ function Invoke-CIPPStandardUndoOauth { ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'UndoOauth' $CurrentState = New-GraphGetRequest -tenantid $Tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy?$select=permissionGrantPolicyIdsAssignedToDefaultUserRole' - $State = if ($CurrentState.permissionGrantPolicyIdsAssignedToDefaultUserRole -eq 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy') { $true } else { $false } + $StateIsCorrect = ($CurrentState.permissionGrantPolicyIdsAssignedToDefaultUserRole -eq 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy') If ($Settings.remediate -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is already disabled.' -sev Info } else { try { - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type PATCH -Body '{"permissionGrantPolicyIdsAssignedToDefaultUserRole":["ManagePermissionGrantsForSelf.microsoft-user-default-legacy"]}' -ContentType 'application/json' + $GraphRequest = @{ + tenantid = $tenant + uri = 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' + AsApp = $false + Type = 'PATCH' + ContentType = 'application/json' + Body = '{"permissionGrantPolicyIdsAssignedToDefaultUserRole":["ManagePermissionGrantsForSelf.microsoft-user-default-legacy"]}' + } + New-GraphPostRequest @GraphRequest Write-LogMessage -API 'Standards' -tenant $tenant -message 'Application Consent Mode has been disabled.' -sev Info - $CurrentState.permissionGrantPolicyIdsAssignedToDefaultUserRole = 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Application Consent Mode to disabled. Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Application Consent Mode to disabled." -sev Error -LogData $_ } } } if ($Settings.alert -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is disabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is not disabled.' -sev Alert @@ -58,6 +63,6 @@ function Invoke-CIPPStandardUndoOauth { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'UndoOauth' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'UndoOauth' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 index bf8077378cb0..15bd3658b861 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 @@ -29,11 +29,11 @@ function Invoke-CIPPStandardallowOAuthTokens { param($Tenant, $Settings) #$Rerun -Type Standard -Tenant $Tenant -API 'AddDKIM' -Settings $Settings - $CurrentInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/softwareOath' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + $CurrentState = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/softwareOath' -tenantid $Tenant + $StateIsCorrect = ($CurrentState.state -eq 'enabled') If ($Settings.remediate -eq $true) { - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is already enabled.' -sev Info } else { Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'softwareOath' -Enabled $true @@ -41,8 +41,7 @@ function Invoke-CIPPStandardallowOAuthTokens { } if ($Settings.alert -eq $true) { - - if ($State) { + if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is enabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is not enabled' -sev Alert @@ -50,7 +49,6 @@ function Invoke-CIPPStandardallowOAuthTokens { } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'softwareOath' -FieldValue $State -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'softwareOath' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant } - } diff --git a/Modules/CIPPCore/Public/Test-CIPPRerun.ps1 b/Modules/CIPPCore/Public/Test-CIPPRerun.ps1 index d2531f68ada2..8480f943a384 100644 --- a/Modules/CIPPCore/Public/Test-CIPPRerun.ps1 +++ b/Modules/CIPPCore/Public/Test-CIPPRerun.ps1 @@ -5,7 +5,8 @@ function Test-CIPPRerun { $Type, $API, $Settings, - $ExecutingUser + $ExecutingUser, + [switch]$Clear ) $RerunTable = Get-CIPPTable -tablename 'RerunCache' $EstimatedDifference = switch ($Type) { @@ -18,7 +19,12 @@ function Test-CIPPRerun { try { $RerunData = Get-CIPPAzDataTableEntity @RerunTable -filter "PartitionKey eq '$($TenantFilter)' and RowKey eq '$($Type)_$($API)'" - if ($RerunData) { + if ($Clear.IsPresent) { + if ($RerunData) { + Remove-AzDataTableEntity @RerunTable -Entity $RerunData + } + return $false + } elseif ($RerunData) { if ($Settings -and $RerunData.Settings) { Write-Host 'Testing rerun settings' $PreviousSettings = $RerunData.Settings diff --git a/Modules/CIPPCore/Public/Webhooks/Invoke-CIPPGraphWebhookRenewal.ps1 b/Modules/CIPPCore/Public/Webhooks/Invoke-CIPPGraphWebhookRenewal.ps1 index e26271907be0..0ac6acf10bbb 100644 --- a/Modules/CIPPCore/Public/Webhooks/Invoke-CIPPGraphWebhookRenewal.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Invoke-CIPPGraphWebhookRenewal.ps1 @@ -32,11 +32,11 @@ function Invoke-CippGraphWebhookRenewal { $CreateResult = New-CIPPGraphSubscription -TenantFilter $TenantFilter -TypeofSubscription $TypeofSubscription -BaseURL $BaseURL -Resource $Resource -EventType $EventType -ExecutingUser 'GraphSubscriptionRenewal' -Recreate if ($CreateResult -match 'Created Webhook subscription for') { - Remove-AzDataTableEntity @WebhookTable -Entity $UpdateSub + Remove-AzDataTableEntity -Force @WebhookTable -Entity $UpdateSub } - + } - + } catch { Write-LogMessage -user 'CIPP' -API 'Renew_Graph_Subscriptions' -message "Failed to renew Webhook Subscription: $($UpdateSub.SubscriptionID). Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $($_.Exception.message)" -Sev "Error" -tenant $TenantFilter diff --git a/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 b/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 index ddac44fd273a..5e26756fb04d 100644 --- a/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 @@ -19,7 +19,7 @@ Function Invoke-RemoveWebhookAlert { Write-Host "The webhook count is $($WebhookRow.count)" if ($WebhookRow.count -gt 1) { $Entity = $WebhookRow | Where-Object -Property RowKey -EQ $Request.query.ID - Remove-AzDataTableEntity @WebhookTable -Entity $Entity | Out-Null + Remove-AzDataTableEntity -Force @WebhookTable -Entity $Entity | Out-Null $Results = "Removed Alert Rule for $($Request.query.TenantFilter)" } else { if ($Request.query.TenantFilter -eq 'AllTenants') { @@ -31,7 +31,7 @@ Function Invoke-RemoveWebhookAlert { RowKey = 'AllTenantsWebhookCreation' PartitionKey = 'webhookcreation' } - Remove-AzDataTableEntity @Table -Entity $CompleteObject -ErrorAction SilentlyContinue | Out-Null + Remove-AzDataTableEntity -Force @Table -Entity $CompleteObject -ErrorAction SilentlyContinue | Out-Null } catch { Write-LogMessage -user $Request.headers.'x-ms-client-principal' -API $APIName -message "Failed to remove webhook for AllTenants. $($_.Exception.Message)" -Sev 'Error' } @@ -42,7 +42,7 @@ Function Invoke-RemoveWebhookAlert { $Results = foreach ($Tenant in $Tenants) { Remove-CIPPGraphSubscription -TenantFilter $Tenant -Type 'AuditLog' $Entity = $WebhookRow | Where-Object -Property RowKey -EQ $Request.query.ID - Remove-AzDataTableEntity @WebhookTable -Entity $Entity | Out-Null + Remove-AzDataTableEntity -Force @WebhookTable -Entity $Entity | Out-Null "Removed Alert Rule for $($Request.query.TenantFilter)" } } diff --git a/Modules/CIPPCore/Public/Webhooks/Remove-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/Webhooks/Remove-CIPPGraphSubscription.ps1 index 7b17983dadff..a9b35a01c3e6 100644 --- a/Modules/CIPPCore/Public/Webhooks/Remove-CIPPGraphSubscription.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Remove-CIPPGraphSubscription.ps1 @@ -18,7 +18,7 @@ function Remove-CIPPGraphSubscription { $AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/stop?contentType=$($sub.contentType)" -scope 'https://manage.office.com/.default' -tenantid $TenantFilter -type POST -body '{}' -verbose Try { $WebhookRow = Get-CIPPAzDataTableEntity @WebhookTable | Where-Object { $_.PartitionKey -eq $TenantFilter -and $_.Resource -eq $EventType -and $_.version -ne '2' } - $null = Remove-AzDataTableEntity @WebhookTable -Entity $Entity + $null = Remove-AzDataTableEntity -Force @WebhookTable -Entity $Entity } catch { Write-LogMessage -user $ExecutingUser -API $APIName -message 'Deleted an audit log webhook that was already removed from CIPP' -Sev 'Info' -tenant $TenantFilter @@ -41,11 +41,11 @@ function Remove-CIPPGraphSubscription { } catch { Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to remove webhook subscription at Microsoft's side: $($_.Exception.Message)" -Sev 'Error' -tenant $TenantFilter } - $null = Remove-AzDataTableEntity @WebhookTable -Entity $Entity + $null = Remove-AzDataTableEntity -Force @WebhookTable -Entity $Entity } 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 $Entity + $null = Remove-AzDataTableEntity -Force @WebhookTable -Entity $Entity } return "Removed webhook subscription to $($WebhookRow.resource) for $($TenantFilter)" } diff --git a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 index 9e588dae7a5c..94d2a83278bd 100644 --- a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 @@ -21,6 +21,7 @@ function Test-CIPPAuditLogRules { 'SAS:ProcessAuth' 'deviceAuth:ReprocessTls' 'Consent:Set' + 'Login:reprocess' ) $TrustedIPTable = Get-CIPPTable -TableName 'trustedIps' diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 1bda0cce5b84..ae942d328329 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -103,6 +103,7 @@ function Receive-CippOrchestrationTrigger { } if (($Batch | Measure-Object).Count -gt 0) { + Write-Information "Batch Count: $($Batch.Count)" $Tasks = foreach ($Item in $Batch) { $DurableActivity = @{ FunctionName = 'CIPPActivityFunction' @@ -113,7 +114,7 @@ function Receive-CippOrchestrationTrigger { } Invoke-DurableActivity @DurableActivity } - if ($NoWait) { + if ($NoWait -and $Tasks) { $null = Wait-ActivityFunction -Task $Tasks } } @@ -152,7 +153,7 @@ function Receive-CippActivityTrigger { if ($Item.FunctionName) { $FunctionName = 'Push-{0}' -f $Item.FunctionName try { - & $FunctionName -Item $Item + Invoke-Command -ScriptBlock { & $FunctionName -Item $Item } if ($TaskStatus) { $QueueTask.Status = 'Completed' @@ -219,6 +220,9 @@ function Receive-CIPPTimerTrigger { } } try { + if ($FunctionStatus.PSObject.Properties.Name -contains 'ErrorMsg') { + $FunctionStatus.ErrorMsg = '' + } $Results = Invoke-Command -ScriptBlock { & $Function.Command } if ($Results -match '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$') { $FunctionStatus.OrchestratorId = $Results @@ -228,9 +232,17 @@ function Receive-CIPPTimerTrigger { } } catch { $Status = 'Failed' + $ErrorMsg = $_.Exception.Message + if ($FunctionStatus.PSObject.Properties.Name -contains 'ErrorMsg') { + $FunctionStatus.ErrorMsg = $ErrorMsg + } else { + $FunctionStatus | Add-Member -MemberType NoteProperty -Name ErrorMsg -Value $ErrorMsg + } + Write-Information "Error in CIPPTimer for $($Function.Command): $($_.Exception.Message)" } $FunctionStatus.LastOccurrence = $UtcNow $FunctionStatus.Status = $Status + Add-CIPPAzDataTableEntity @Table -Entity $FunctionStatus -Force } } diff --git a/Modules/CippExtensions/Public/Extension Functions/Register-CippExtensionScheduledTasks.ps1 b/Modules/CippExtensions/Public/Extension Functions/Register-CippExtensionScheduledTasks.ps1 index d8b2d6cfd01f..a560660fd8eb 100644 --- a/Modules/CippExtensions/Public/Extension Functions/Register-CippExtensionScheduledTasks.ps1 +++ b/Modules/CippExtensions/Public/Extension Functions/Register-CippExtensionScheduledTasks.ps1 @@ -102,7 +102,7 @@ function Register-CIPPExtensionScheduledTasks { $PushTasks | Where-Object { $_.SyncType -eq $Extension } | ForEach-Object { Write-Information "Extension Disabled: Cleaning up scheduled task $($_.Name) for tenant $($_.Tenant)" $Entity = $_ | Select-Object -Property PartitionKey, RowKey - Remove-AzDataTableEntity @ScheduledTasksTable -Entity $Entity + Remove-AzDataTableEntity -Force @ScheduledTasksTable -Entity $Entity } } } @@ -112,14 +112,14 @@ function Register-CIPPExtensionScheduledTasks { if ($Task.Tenant -notin $MappedTenants) { Write-Information "Tenant Removed: Cleaning up scheduled task $($Task.Name) for tenant $($Task.TenantFilter)" $Entity = $Task | Select-Object -Property PartitionKey, RowKey - Remove-AzDataTableEntity @ScheduledTasksTable -Entity $Entity + Remove-AzDataTableEntity -Force @ScheduledTasksTable -Entity $Entity } } foreach ($Task in $PushTasks) { if ($Task.Tenant -notin $MappedTenants) { Write-Information "Tenant Removed: Cleaning up scheduled task $($Task.Name) for tenant $($Task.TenantFilter)" $Entity = $Task | Select-Object -Property PartitionKey, RowKey - Remove-AzDataTableEntity @ScheduledTasksTable -Entity $Entity + Remove-AzDataTableEntity -Force @ScheduledTasksTable -Entity $Entity } } } diff --git a/Modules/CippExtensions/Public/Halo/Get-HaloMapping.ps1 b/Modules/CippExtensions/Public/Halo/Get-HaloMapping.ps1 index 2a8aae7646ef..9add516bc763 100644 --- a/Modules/CippExtensions/Public/Halo/Get-HaloMapping.ps1 +++ b/Modules/CippExtensions/Public/Halo/Get-HaloMapping.ps1 @@ -15,7 +15,7 @@ function Get-HaloMapping { IntegrationId = $_.HaloPSA IntegrationName = $_.HaloPSAName } - Remove-AzDataTableEntity @CIPPMapping -Entity $_ | Out-Null + Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ | Out-Null } if (($MigrateRows | Measure-Object).Count -gt 0) { Add-CIPPAzDataTableEntity @CIPPMapping -Entity $MigrateRows -Force diff --git a/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 b/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 index 129b1578ad59..8827e099e3c3 100644 --- a/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 +++ b/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 @@ -6,7 +6,7 @@ function Set-HaloMapping { $Request ) Get-CIPPAzDataTableEntity @CIPPMapping -Filter "PartitionKey eq 'HaloMapping'" | ForEach-Object { - Remove-AzDataTableEntity @CIPPMapping -Entity $_ + Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } foreach ($Mapping in ([pscustomobject]$Request.body.mappings).psobject.properties) { $AddObject = @{ diff --git a/Modules/CippExtensions/Public/Hudu/Set-HuduMapping.ps1 b/Modules/CippExtensions/Public/Hudu/Set-HuduMapping.ps1 index 03c6dddb8fb3..d5ca71df0ae4 100644 --- a/Modules/CippExtensions/Public/Hudu/Set-HuduMapping.ps1 +++ b/Modules/CippExtensions/Public/Hudu/Set-HuduMapping.ps1 @@ -6,7 +6,7 @@ function Set-HuduMapping { $Request ) Get-CIPPAzDataTableEntity @CIPPMapping -Filter "PartitionKey eq 'HuduMapping'" | ForEach-Object { - Remove-AzDataTableEntity @CIPPMapping -Entity $_ + Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } foreach ($Mapping in ([pscustomobject]$Request.body.mappings).psobject.properties) { $AddObject = @{ diff --git a/Modules/CippExtensions/Public/NinjaOne/Get-NinjaOneFieldMapping.ps1 b/Modules/CippExtensions/Public/NinjaOne/Get-NinjaOneFieldMapping.ps1 index 8a430f372b0e..d3de5486cab7 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Get-NinjaOneFieldMapping.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Get-NinjaOneFieldMapping.ps1 @@ -66,7 +66,7 @@ function Get-NinjaOneFieldMapping { IntegrationId = $_.NinjaOne IntegrationName = $_.NinjaOneName } - Remove-AzDataTableEntity @CIPPMapping -Entity $_ + Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } if (($MappingFieldMigrate | Measure-Object).count -gt 0) { Add-CIPPAzDataTableEntity @CIPPMapping -Entity $MappingFieldMigrate -Force diff --git a/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index d45407edb06e..a17940bd369b 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -37,9 +37,9 @@ function Invoke-NinjaOneTenantSync { # Fetch Custom NinjaOne Settings - $Table = Get-CIPPTable -TableName NinjaOneSettings + $Table = Get-CIPPTable -TableName Config $NinjaSettings = (Get-CIPPAzDataTableEntity @Table) - $CIPPUrl = ($NinjaSettings | Where-Object { $_.RowKey -eq 'CIPPURL' }).SettingValue + $CIPPUrl = ($NinjaSettings | Where-Object { $_.RowKey -eq 'CIPPURL' }).Value $Customer = Get-Tenants -IncludeErrors | Where-Object { $_.customerId -eq $MappedTenant.RowKey } @@ -1367,7 +1367,7 @@ function Invoke-NinjaOneTenantSync { if (($NinjaUserCreation | Measure-Object).count -ge 100) { Write-Information 'Creating NinjaOne Users' [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100 - Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserCreation + Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity $NinjaUserCreation [System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = @() } } Catch { @@ -1379,7 +1379,7 @@ function Invoke-NinjaOneTenantSync { if (($NinjaUserUpdates | Measure-Object).count -ge 100) { Write-Information 'Updating NinjaOne Users' [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100 - Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserUpdates + Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity $NinjaUserUpdates [System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = @() } } Catch { @@ -1442,7 +1442,7 @@ function Invoke-NinjaOneTenantSync { if (($NinjaUserCreation | Measure-Object).count -ge 1) { Write-Information 'Creating NinjaOne Users' [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100 - Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserCreation + Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity $NinjaUserCreation } } Catch { @@ -1454,7 +1454,7 @@ function Invoke-NinjaOneTenantSync { if (($NinjaUserUpdates | Measure-Object).count -ge 1) { Write-Information 'Updating NinjaOne Users' [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100 - Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserUpdates + Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity $NinjaUserUpdates } } Catch { Write-Information "Bulk Update Errored, but may have been successful as only 1 record with an issue could have been the cause: $_" @@ -2310,12 +2310,12 @@ function Invoke-NinjaOneTenantSync { Write-Information 'Cleaning Users Cache' if (($ParsedUsers | Measure-Object).count -gt 0) { - Remove-AzDataTableEntity @UsersTable -Entity ($ParsedUsers | Select-Object PartitionKey, RowKey) + Remove-AzDataTableEntity -Force @UsersTable -Entity ($ParsedUsers | Select-Object PartitionKey, RowKey) } Write-Information 'Cleaning Device Cache' if (($ParsedDevices | Measure-Object).count -gt 0) { - Remove-AzDataTableEntity @DeviceTable -Entity ($ParsedDevices | Select-Object PartitionKey, RowKey) + Remove-AzDataTableEntity -Force @DeviceTable -Entity ($ParsedDevices | Select-Object PartitionKey, RowKey) } Write-Information "Total Fetch Time: $((New-TimeSpan -Start $StartTime -End $FetchEnd).TotalSeconds)" diff --git a/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 b/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 index 43b1c597e3b0..d58c6093f6f2 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 @@ -7,7 +7,7 @@ function Set-NinjaOneOrgMapping { ) Get-CIPPAzDataTableEntity @CIPPMapping -Filter "PartitionKey eq 'NinjaOneMapping'" | ForEach-Object { - Remove-AzDataTableEntity @CIPPMapping -Entity $_ + Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } foreach ($Mapping in ([pscustomobject]$Request.body.mappings).psobject.properties) { $AddObject = @{ diff --git a/version_latest.txt b/version_latest.txt index fa09f584d78e..db0785f27378 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -6.5.2 \ No newline at end of file +6.5.3