From 91daaff18b34649ecbecdd1a07418dfae999c4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 13 Mar 2025 18:36:21 +0100 Subject: [PATCH 001/123] refactor Invoke-AddCAPolicy to improve logging and variable usage --- .../Tenant/Conditional/Invoke-AddCAPolicy.ps1 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 index 1b7b990ecb1a..fc6fa8b523f3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCAPolicy.ps1 @@ -11,19 +11,18 @@ Function Invoke-AddCAPolicy { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenants = $Request.body.tenantFilter.value if ('AllTenants' -in $Tenants) { $Tenants = (Get-Tenants).defaultDomainName } $results = foreach ($Tenant in $tenants) { try { - $CAPolicy = New-CIPPCAPolicy -replacePattern $Request.body.replacename -Overwrite $request.body.overwrite -TenantFilter $tenant -state $request.body.NewState -RawJSON $Request.body.RawJSON -APIName $APIName -Headers $Request.Headers - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $($Tenant) -message "Added Conditional Access Policy $($Displayname)" -Sev 'Info' - "Successfully added Conditional Access Policy for $($Tenant)" + $CAPolicy = New-CIPPCAPolicy -replacePattern $Request.Body.replacename -Overwrite $request.Body.overwrite -TenantFilter $Tenant -state $Request.Body.NewState -RawJSON $Request.Body.RawJSON -APIName $APIName -Headers $Headers + "$CAPolicy" } catch { - "Failed to add policy for $($Tenant): $($_.Exception.Message)" - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $($Tenant) -message "Failed to add Conditional Access Policy $($Displayname). Error: $($_.Exception.Message)" -Sev 'Error' + "$($_.Exception.Message)" continue } From b2c7363a10bcc682ba675020fbcaeb4b450c0e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 13 Mar 2025 18:37:21 +0100 Subject: [PATCH 002/123] chore: Logging, header changes and casing fixes --- .../CippQueue/Invoke-RemoveCippQueue.ps1 | 3 +- .../CIPP/Core/Invoke-GetCippAlerts.ps1 | 6 +- .../CIPP/Settings/Invoke-ExecAccessChecks.ps1 | 3 +- .../CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 6 +- .../CIPP/Settings/Invoke-ExecDnsConfig.ps1 | 6 +- .../Settings/Invoke-ExecExcludeLicenses.ps1 | 6 +- .../Invoke-ExecMaintenanceScripts.ps1 | 3 +- .../Invoke-ExecNotificationConfig.ps1 | 6 +- .../Settings/Invoke-ExecPasswordConfig.ps1 | 6 +- .../Settings/Invoke-ExecRestoreBackup.ps1 | 3 +- .../Invoke-ExecMailboxMobileDevices.ps1 | 3 +- .../Invoke-ListMailboxMobileDevices.ps1 | 3 +- .../Invoke-ListSharedMailboxStatistics.ps1 | 3 +- .../Invoke-ListmailboxPermissions.ps1 | 3 +- .../Resources/Invoke-ListRoomLists.ps1 | 3 +- .../Resources/Invoke-ListRooms.ps1 | 3 +- .../Spamfilter/Invoke-EditSpamFilter.ps1 | 3 +- .../Invoke-ExecQuarantineManagement.ps1 | 6 +- .../Invoke-ListConnectionFilter.ps1 | 3 +- .../Invoke-ListSpamFilterTemplates.ps1 | 3 +- .../Spamfilter/Invoke-ListSpamfilter.ps1 | 3 +- .../Tools/Invoke-ExecMailTest.ps1 | 3 +- .../Tools/Invoke-ListMailboxRestores.ps1 | 3 +- .../Invoke-ListExConnectorTemplates.ps1 | 3 +- .../Transport/Invoke-ListTransportRules.ps1 | 3 +- .../Invoke-ListTransportRulesTemplates.ps1 | 3 +- .../Applications/Invoke-AddChocoApp.ps1 | 40 +++++------ .../Applications/Invoke-AddMSPApp.ps1 | 69 ++++++++++--------- .../Applications/Invoke-AddOfficeApp.ps1 | 3 +- .../Applications/Invoke-AddStoreApp.ps1 | 25 +++---- .../Applications/Invoke-ExecAssignApp.ps1 | 6 +- .../Endpoint/Applications/Invoke-ListApps.ps1 | 6 +- .../Endpoint/Autopilot/Invoke-AddAPDevice.ps1 | 6 +- .../Autopilot/Invoke-AddAutopilotConfig.ps1 | 6 +- .../Autopilot/Invoke-AddEnrollment.ps1 | 6 +- .../Autopilot/Invoke-ListAPDevices.ps1 | 6 +- .../Autopilot/Invoke-ListAutopilotconfig.ps1 | 6 +- .../Autopilot/Invoke-RemoveAPDevice.ps1 | 3 +- .../MEM/Invoke-AddDefenderDeployment.ps1 | 3 +- .../Endpoint/MEM/Invoke-AddPolicy.ps1 | 3 +- .../Endpoint/MEM/Invoke-EditPolicy.ps1 | 3 +- .../Endpoint/MEM/Invoke-ExecDeviceAction.ps1 | 3 +- .../Endpoint/MEM/Invoke-ListDefenderState.ps1 | 6 +- .../Endpoint/MEM/Invoke-ListIntunePolicy.ps1 | 3 +- .../Endpoint/MEM/Invoke-ListIntuneScript.ps1 | 6 +- .../MEM/Invoke-ListIntuneTemplates.ps1 | 3 +- .../Endpoint/Reports/Invoke-ListDevices.ps1 | 6 +- .../Groups/Invoke-AddGroupTemplate.ps1 | 3 +- .../Groups/Invoke-EditGroup.ps1 | 6 +- .../Invoke-ListGroupSenderAuthentication.ps1 | 3 +- .../Groups/Invoke-ListGroupTemplates.ps1 | 6 +- .../Groups/Invoke-ListGroups.ps1 | 3 +- .../Administration/Users/Invoke-EditUser.ps1 | 3 +- .../Users/Invoke-ExecBECRemediate.ps1 | 47 +++++++------ .../Users/Invoke-ExecOneDriveShortCut.ps1 | 3 +- .../Users/Invoke-ExecResetPass.ps1 | 3 +- .../Users/Invoke-ExecRestoreDeleted.ps1 | 3 +- .../Users/Invoke-ExecRevokeSessions.ps1 | 3 +- .../Users/Invoke-ExecSendPush.ps1 | 3 +- .../Users/Invoke-ListPerUserMFA.ps1 | 3 +- ...voke-ListUserConditionalAccessPolicies.ps1 | 6 +- .../Users/Invoke-ListUserCounts.ps1 | 6 +- .../Users/Invoke-ListUserDevices.ps1 | 6 +- .../Users/Invoke-ListUserGroups.ps1 | 6 +- .../Users/Invoke-ListUserMailboxRules.ps1 | 3 +- .../Users/Invoke-ListUserSettings.ps1 | 3 +- .../Users/Invoke-ListUserSigninLogs.ps1 | 6 +- .../Administration/Users/Invoke-ListUsers.ps1 | 3 +- .../Teams-Sharepoint/Invoke-AddSite.ps1 | 3 +- .../Teams-Sharepoint/Invoke-AddSiteBulk.ps1 | 3 +- .../Teams-Sharepoint/Invoke-AddTeam.ps1 | 6 +- ...cRemoveTeamsVoicePhoneNumberAssignment.ps1 | 3 +- .../Invoke-ListSharepointQuota.ps1 | 6 +- .../Invoke-ListSharepointSettings.ps1 | 6 +- .../Teams-Sharepoint/Invoke-ListTeams.ps1 | 6 +- .../Invoke-ListTeamsActivity.ps1 | 3 +- .../Invoke-ListTeamsVoice.ps1 | 6 +- .../Administration/Alerts/Invoke-AddAlert.ps1 | 3 +- .../Alerts/Invoke-ListWebhookAlert.ps1 | 3 +- .../Invoke-ExecAddMultiTenantApp.ps1 | 3 +- .../Invoke-ExecAppApproval.ps1 | 6 +- .../Administration/Invoke-ExecAddSPN.ps1 | 3 +- .../Invoke-ExecUpdateSecureScore.ps1 | 3 +- .../Administration/Invoke-ListDomains.ps1 | 6 +- .../Conditional/Invoke-AddCATemplate.ps1 | 24 ++++--- .../Conditional/Invoke-AddNamedLocation.ps1 | 6 +- .../Tenant/Conditional/Invoke-ExecCACheck.ps1 | 11 +-- .../Conditional/Invoke-ExecCAExclusion.ps1 | 34 +++++---- .../Conditional/Invoke-ExecNamedLocation.ps1 | 8 +-- .../Conditional/Invoke-ListCAtemplates.ps1 | 6 +- .../Invoke-ListConditionalAccessPolicies.ps1 | 3 +- .../Conditional/Invoke-RemoveCAPolicy.ps1 | 2 +- .../Conditional/Invoke-RemoveCATemplate.ps1 | 2 +- .../Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 | 7 +- .../Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 | 4 ++ .../Invoke-ExecDeleteGDAPRelationship.ps1 | 5 +- .../GDAP/Invoke-ExecDeleteGDAPRoleMapping.ps1 | 8 ++- .../Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 | 5 +- .../GDAP/Invoke-ExecGDAPInviteApproved.ps1 | 4 +- .../GDAP/Invoke-ExecGDAPRemoveGArole.ps1 | 2 +- .../GDAP/Invoke-ExecGDAPRoleTemplate.ps1 | 4 ++ .../Tenant/GDAP/Invoke-ListGDAPInvite.ps1 | 3 +- .../Tenant/GDAP/Invoke-ListGDAPRoles.ps1 | 6 +- .../Tenant/Reports/Invoke-ListLicenses.ps1 | 8 +-- .../Tenant/Reports/Invoke-ListOAuthApps.ps1 | 9 +-- .../Reports/Invoke-ListServiceHealth.ps1 | 3 +- .../Standards/Invoke-AddStandardsDeploy.ps1 | 3 +- .../Standards/Invoke-AddStandardsTemplate.ps1 | 3 +- .../Invoke-BestPracticeAnalyser_List.ps1 | 3 +- .../Standards/Invoke-ExecStandardConvert.ps1 | 4 +- .../Standards/Invoke-ExecStandardsRun.ps1 | 28 ++++---- .../Tenant/Standards/Invoke-ListBPA.ps1 | 21 +++--- .../Standards/Invoke-ListBPATemplates.ps1 | 5 +- .../Standards/Invoke-ListDomainAnalyser.ps1 | 9 ++- .../Standards/Invoke-ListDomainHealth.ps1 | 10 ++- .../Tenant/Standards/Invoke-ListStandards.ps1 | 19 +++-- .../Standards/Invoke-RemoveBPATemplate.ps1 | 4 +- .../Standards/Invoke-RemoveStandard.ps1 | 21 +++--- .../Invoke-RemoveStandardTemplate.ps1 | 1 + .../Invoke-listStandardTemplates.ps1 | 16 +++-- .../Tenant/Tools/Invoke-AddBPATemplate.ps1 | 3 +- .../Tools/Invoke-ExecGraphExplorerPreset.ps1 | 6 +- .../Entrypoints/Invoke-ExecBreachSearch.ps1 | 8 ++- .../Entrypoints/Invoke-ExecCSPLicense.ps1 | 6 +- .../Invoke-ExecExtensionNinjaOneQueue.ps1 | 4 +- .../Entrypoints/Invoke-ExecListAppId.ps1 | 3 +- .../Invoke-ExecSchedulerBillingRun.ps1 | 9 ++- .../Entrypoints/Invoke-ExecSendOrgMessage.ps1 | 6 +- .../Invoke-ExecUniversalSearch.ps1 | 6 +- .../Entrypoints/Invoke-ExecUserSettings.ps1 | 5 +- .../Invoke-ListAllTenantDeviceCompliance.ps1 | 6 +- .../Entrypoints/Invoke-ListAppStatus.ps1 | 5 +- .../Invoke-ListBreachesAccount.ps1 | 12 ++-- .../Entrypoints/Invoke-ListBreachesTenant.ps1 | 5 +- .../Entrypoints/Invoke-ListCSPLicenses.ps1 | 27 +++++--- .../Public/Entrypoints/Invoke-ListCSPsku.ps1 | 8 ++- .../Entrypoints/Invoke-ListDeviceDetails.ps1 | 3 +- .../Invoke-ListExtensionsConfig.ps1 | 3 +- .../Invoke-ListExternalTenantInfo.ps1 | 19 ++--- .../Invoke-ListFunctionParameters.ps1 | 3 +- .../Entrypoints/Invoke-ListFunctionStats.ps1 | 3 +- .../Invoke-ListGenericTestFunction.ps1 | 1 + .../Invoke-ListGraphExplorerPresets.ps1 | 5 +- .../Entrypoints/Invoke-ListHaloClients.ps1 | 13 ++-- .../Entrypoints/Invoke-ListIPWhitelist.ps1 | 7 +- .../Entrypoints/Invoke-ListIntuneIntents.ps1 | 10 ++- .../Entrypoints/Invoke-ListKnownIPDb.ps1 | 10 +-- .../Public/Entrypoints/Invoke-ListLogs.ps1 | 3 +- .../Entrypoints/Invoke-ListNamedLocations.ps1 | 6 +- .../Invoke-ListNotificationConfig.ps1 | 3 +- .../Public/Entrypoints/Invoke-ListOrg.ps1 | 10 ++- .../Invoke-ListPartnerRelationships.ps1 | 16 +++-- .../Invoke-ListPendingWebhooks.ps1 | 3 +- .../Entrypoints/Invoke-ListPotentialApps.ps1 | 7 +- .../Public/Entrypoints/Invoke-ListRoles.ps1 | 10 ++- .../Invoke-ListTenantAllowBlockList.ps1 | 3 +- .../Invoke-RemoveTenantAllowBlockList.ps1 | 2 +- .../Public/Invoke-RemoveQueuedApp.ps1 | 3 +- .../Webhooks/Invoke-RemoveWebhookAlert.ps1 | 3 +- 159 files changed, 616 insertions(+), 474 deletions(-) diff --git a/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 b/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 index a9c2a9081c6a..54633f0fd9a8 100644 --- a/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 +++ b/Modules/CIPPCore/Public/CippQueue/Invoke-RemoveCippQueue.ps1 @@ -8,7 +8,8 @@ function Invoke-RemoveCippQueue { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $CippQueue = Get-CippTable -TableName 'CippQueue' Clear-AzDataTable @CippQueue diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 index d200d368dfeb..0c7ec1f5d89f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 @@ -19,7 +19,7 @@ Function Invoke-GetCippAlerts { $PartitionKey = Get-Date -UFormat '%Y%m%d' $Filter = "PartitionKey eq '{0}'" -f $PartitionKey $Rows = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Sort-Object TableTimestamp -Descending | Select-Object -First 10 - $role = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userRoles + $Role = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Request.Headers.'x-ms-client-principal')) | ConvertFrom-Json).userRoles $CIPPVersion = $Request.Query.localversion $Version = Assert-CippVersion -CIPPVersion $CIPPVersion @@ -71,10 +71,6 @@ Function Invoke-GetCippAlerts { } if ($Rows) { $Rows | ForEach-Object { $Alerts.Add($_) } } $Alerts = @($Alerts) - $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - # Write to the Azure Functions log stream. # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 index 5a403a6894f9..7faeb47662e3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecAccessChecks { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -Headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CIPPTable -tablename 'AccessChecks' $LastRun = (Get-Date).ToUniversalTime() diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 80c0de481eaa..d12cc9036e44 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -11,12 +11,12 @@ Function Invoke-ExecBackendURLs { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 $SWAName = $ENV:WEBSITE_SITE_NAME -replace 'cipp', 'CIPP-SWA-' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $results = [PSCustomObject]@{ ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/overview" 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 99d071ee8035..e87e84033249 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 @@ -11,7 +11,8 @@ Function Invoke-ExecDnsConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # List of supported resolvers $ValidResolvers = @( @@ -20,8 +21,7 @@ Function Invoke-ExecDnsConfig { 'Quad9' ) - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $StatusCode = [HttpStatusCode]::OK try { 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 1df4e0188d26..936659310732 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 @@ -11,11 +11,11 @@ Function Invoke-ExecExcludeLicenses { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $Table = Get-CIPPTable -TableName ExcludedLicenses try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 index c78ba5176232..42eeded7c863 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecMaintenanceScripts.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecMaintenanceScripts { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { $GraphToken = Get-GraphToken -returnRefresh $true $AccessTokenDetails = Read-JwtAccessDetails -Token $GraphToken.access_token diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 index 77a1ac8ae164..8436f9152a1f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecNotificationConfig.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecNotificationConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $sev = ([pscustomobject]$Request.body.Severity).value -join (',') $results = try { $Table = Get-CIPPTable -TableName SchedulerConfig diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 index b237e5fd15c7..cfe09ce96841 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecPasswordConfig.ps1 @@ -11,13 +11,13 @@ Function Invoke-ExecPasswordConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CIPPTable -TableName Settings $PasswordType = (Get-CIPPAzDataTableEntity @Table) - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $results = try { if ($Request.Query.List) { @{ passwordType = $PasswordType.passwordType } 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 e243f4ab2e0c..9a12d734adce 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 @@ -11,7 +11,8 @@ Function Invoke-ExecRestoreBackup { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { if ($Request.Body.BackupName -like 'CippBackup_*') { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecMailboxMobileDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecMailboxMobileDevices.ps1 index 2d54ba0aff50..378ff2d92529 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecMailboxMobileDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecMailboxMobileDevices.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecMailboxMobileDevices { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxMobileDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxMobileDevices.ps1 index 3e1be65549a6..9a4aff412881 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxMobileDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxMobileDevices.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListMailboxMobileDevices { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListSharedMailboxStatistics.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListSharedMailboxStatistics.ps1 index 96edbf15faeb..2e7f2041209c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListSharedMailboxStatistics.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListSharedMailboxStatistics.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListSharedMailboxStatistics { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # XXX Seems like an unused endpoint? -Bobby diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListmailboxPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListmailboxPermissions.ps1 index 449fc929541d..9b1c4f03cf0b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListmailboxPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListmailboxPermissions.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListmailboxPermissions { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRoomLists.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRoomLists.ps1 index bf4891463fa7..be10ef655ae7 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRoomLists.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRoomLists.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListRoomLists { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRooms.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRooms.ps1 index 916364ef0f6c..4507af02a40e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRooms.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Resources/Invoke-ListRooms.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListRooms { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-EditSpamFilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-EditSpamFilter.ps1 index 7559e53ab41c..c240cd6db65b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-EditSpamFilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-EditSpamFilter.ps1 @@ -11,7 +11,8 @@ Function Invoke-EditSpamFilter { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $request.Query.tenantFilter $Name = $Request.Query.name ?? $Request.Body.name diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 index 4421360709dc..bda4f4a6c79b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecQuarantineManagement { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilter.ps1 index fb80de05afbd..82d6a7919596 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilter.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListConnectionFilter { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenantfilter = $request.Query.tenantfilter try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 index a74c9491e4af..0aa9428e9c75 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListSpamFilterTemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CippTable -tablename 'templates' #List new policies diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamfilter.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamfilter.ps1 index efa8a228914c..d73d6ec45066 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamfilter.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamfilter.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListSpamfilter { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenantfilter = $request.Query.tenantfilter try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ExecMailTest.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ExecMailTest.ps1 index e537a7d6ebdc..eb12dae07b53 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ExecMailTest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ExecMailTest.ps1 @@ -10,7 +10,8 @@ Function Invoke-ExecMailTest { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { switch ($Request.Query.Action) { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ListMailboxRestores.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ListMailboxRestores.ps1 index 1ffe8b543310..60b496ac2128 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ListMailboxRestores.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Tools/Invoke-ListMailboxRestores.ps1 @@ -8,7 +8,8 @@ function Invoke-ListMailboxRestores { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListExConnectorTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListExConnectorTemplates.ps1 index cb302859f8db..6e879be76193 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListExConnectorTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListExConnectorTemplates.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListExConnectorTemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CippTable -tablename 'templates' #List new policies diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRules.ps1 index aeb9f976be35..227bfd6fd8b8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRules.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRules.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListTransportRules { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $request.Query.tenantFilter try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRulesTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRulesTemplates.ps1 index 867d316dc260..d9cd3b00eb61 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRulesTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Transport/Invoke-ListTransportRulesTemplates.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListTransportRulesTemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CippTable -tablename 'templates' $Templates = Get-ChildItem 'Config\*.TransportRuleTemplate.json' | ForEach-Object { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 index 34cfeb198291..9c7ed6fd384f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 @@ -11,33 +11,33 @@ Function Invoke-AddChocoApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - Write-Host 'PowerShell HTTP trigger function processed a request.' - $ChocoApp = $request.body + $ChocoApp = $Request.Body $intuneBody = Get-Content 'AddChocoApp\choco.app.json' | ConvertFrom-Json - $assignTo = $Request.body.AssignTo + $AssignTo = $Request.Body.AssignTo $intuneBody.description = $ChocoApp.description - $intuneBody.displayName = $chocoapp.ApplicationName + $intuneBody.displayName = $ChocoApp.ApplicationName $intuneBody.installExperience.runAsAccount = if ($ChocoApp.InstallAsSystem) { 'system' } else { 'user' } $intuneBody.installExperience.deviceRestartBehavior = if ($ChocoApp.DisableRestart) { 'suppress' } else { 'allow' } - $intuneBody.installCommandLine = "powershell.exe -executionpolicy bypass .\Install.ps1 -InstallChoco -Packagename $($chocoapp.PackageName)" + $intuneBody.installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\Install.ps1 -InstallChoco -Packagename $($ChocoApp.PackageName)" if ($ChocoApp.customrepo) { - $intuneBody.installCommandLine = $intuneBody.installCommandLine + " -CustomRepo $($chocoapp.CustomRepo)" + $intuneBody.installCommandLine = $intuneBody.installCommandLine + " -CustomRepo $($ChocoApp.CustomRepo)" } - $intuneBody.UninstallCommandLine = "powershell.exe -executionpolicy bypass .\Uninstall.ps1 -Packagename $($chocoapp.PackageName)" - $intunebody.detectionRules[0].path = "$($ENV:SystemDrive)\programdata\chocolatey\lib" - $intunebody.detectionRules[0].fileOrFolderName = "$($chocoapp.PackageName)" + $intuneBody.UninstallCommandLine = "powershell.exe -ExecutionPolicy Bypass .\Uninstall.ps1 -Packagename $($ChocoApp.PackageName)" + $intuneBody.detectionRules[0].path = "$($ENV:SystemDrive)\programdata\chocolatey\lib" + $intuneBody.detectionRules[0].fileOrFolderName = "$($ChocoApp.PackageName)" - $Tenants = $Request.body.selectedTenants.defaultDomainName - $Results = foreach ($Tenant in $tenants) { + $Tenants = $Request.Body.selectedTenants.defaultDomainName + $Results = foreach ($Tenant in $Tenants) { try { $CompleteObject = [PSCustomObject]@{ - tenant = $tenant - Applicationname = $ChocoApp.ApplicationName - assignTo = $assignTo - InstallationIntent = $request.body.InstallationIntent - IntuneBody = $intunebody + tenant = $Tenant + ApplicationName = $ChocoApp.ApplicationName + assignTo = $AssignTo + InstallationIntent = $Request.Body.InstallationIntent + IntuneBody = $intuneBody } | ConvertTo-Json -Depth 15 $Table = Get-CippTable -tablename 'apps' $Table.Force = $true @@ -47,14 +47,14 @@ Function Invoke-AddChocoApp { PartitionKey = 'apps' } "Successfully added Choco App for $($Tenant) to queue." - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant -message "Successfully added Choco App $($intunebody.Displayname) to queue" -Sev 'Info' + Write-LogMessage -headers $Headers -API $APIName -tenant $Tenant -message "Successfully added Choco App $($intuneBody.DisplayName) to queue" -Sev 'Info' } catch { "Failed adding Choco App for $($Tenant) to queue" - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant -message "Failed to add Chocolatey Application $($intunebody.Displayname) to queue" -Sev 'Error' + Write-LogMessage -headers $Headers -API $APIName -tenant $Tenant -message "Failed to add Chocolatey Application $($intuneBody.DisplayName) to queue" -Sev 'Error' } } - $body = [pscustomobject]@{'Results' = $results } + $body = [PSCustomObject]@{'Results' = $Results } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 index b5d055d24c1b..b3d4e927c74c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddMSPApp.ps1 @@ -11,64 +11,65 @@ Function Invoke-AddMSPApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - Write-Host 'PowerShell HTTP trigger function processed a request.' - $RMMApp = $request.body - $assignTo = $Request.body.AssignTo + $RMMApp = $Request.Body + $AssignTo = $Request.Body.AssignTo $intuneBody = Get-Content "AddMSPApp\$($RMMApp.RMMName.value).app.json" | ConvertFrom-Json $intuneBody.displayName = $RMMApp.DisplayName - $Tenants = $request.body.selectedTenants - $Results = foreach ($Tenant in $tenants) { - $InstallParams = [pscustomobject]$RMMApp.params - switch ($rmmapp.RMMName.value) { + $Tenants = $Request.Body.selectedTenants + $Results = foreach ($Tenant in $Tenants) { + $InstallParams = [PSCustomObject]$RMMApp.params + switch ($RMMApp.RMMName.value) { 'datto' { - Write-Host 'test' - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -URL $($InstallParams.DattoURL) -GUID $($InstallParams.DattoGUID."$($tenant.customerId)")" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + Write-Host 'Processing Datto installation' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -URL $($InstallParams.DattoURL) -GUID $($InstallParams.DattoGUID."$($Tenant.customerId)")" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } 'ninja' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + Write-Host 'Processing Ninja installation' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } 'Huntress' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -OrgKey $($InstallParams.Orgkey."$($tenant.customerId)") -acctkey $($InstallParams.AccountKey)" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\install.ps1 -Uninstall' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -OrgKey $($InstallParams.Orgkey."$($Tenant.customerId)") -acctkey $($InstallParams.AccountKey)" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\install.ps1 -Uninstall' } 'Immybot' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -url $($InstallParams.ClientURL."$($tenant.customerId)")" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -url $($InstallParams.ClientURL."$($tenant.customerId)")" + $UninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } 'syncro' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -URL $($InstallParams.ClientURL."$($tenant.customerId)")" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -URL $($InstallParams.ClientURL."$($Tenant.customerId)")" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } 'NCentral' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -InstallParam $($RMMApp.PackageName)" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } 'automate' { - $installcommandline = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -executionpolicy bypass .\install.ps1 -Server $($InstallParams.Server) -InstallerToken $($InstallParams.InstallerToken."$($tenant.customerId)") -LocationID $($InstallParams.LocationID."$($tenant.customerId)")" - $UninstallCommandLine = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -executionpolicy bypass .\uninstall.ps1 -Server $($InstallParams.Server)" + $installCommandLine = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass .\install.ps1 -Server $($InstallParams.Server) -InstallerToken $($InstallParams.InstallerToken."$($Tenant.customerId)") -LocationID $($InstallParams.LocationID."$($Tenant.customerId)")" + $uninstallCommandLine = "c:\windows\sysnative\windowspowershell\v1.0\powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1 -Server $($InstallParams.Server)" $DetectionScript = (Get-Content 'AddMSPApp\automate.detection.ps1' -Raw) -replace '##SERVER##', $InstallParams.Server $intuneBody.detectionRules[0].scriptContent = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($DetectionScript)) } 'cwcommand' { - $installcommandline = "powershell.exe -executionpolicy bypass .\install.ps1 -Url $($InstallParams.ClientURL."$($tenant.customerId)")" - $UninstallCommandLine = 'powershell.exe -executionpolicy bypass .\uninstall.ps1' + $installCommandLine = "powershell.exe -ExecutionPolicy Bypass .\install.ps1 -Url $($InstallParams.ClientURL."$($Tenant.customerId)")" + $uninstallCommandLine = 'powershell.exe -ExecutionPolicy Bypass .\uninstall.ps1' } } - $intuneBody.installCommandLine = $installcommandline - $intuneBody.UninstallCommandLine = $UninstallCommandLine + $intuneBody.installCommandLine = $installCommandLine + $intuneBody.UninstallCommandLine = $uninstallCommandLine try { $CompleteObject = [PSCustomObject]@{ - tenant = $tenant.defaultDomainName - Applicationname = $RMMApp.DisplayName - assignTo = $assignTo - IntuneBody = $intunebody + tenant = $Tenant.defaultDomainName + ApplicationName = $RMMApp.DisplayName + assignTo = $AssignTo + IntuneBody = $intuneBody type = 'MSPApp' MSPAppName = $RMMApp.RMMName.value } | ConvertTo-Json -Depth 15 @@ -81,15 +82,15 @@ Function Invoke-AddMSPApp { status = 'Not Deployed yet' } "Successfully added MSP App for $($Tenant.defaultDomainName) to queue. " - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant.defaultDomainName -message "MSP Application $($intunebody.Displayname) added to queue" -Sev 'Info' + Write-LogMessage -headers $Headers -API $APIName -tenant $Tenant.defaultDomainName -message "MSP Application $($intuneBody.DisplayName) added to queue" -Sev 'Info' } catch { - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant.defaultDomainName -message "Failed to add MSP Application $($intunebody.Displayname) to queue" -Sev 'Error' + Write-LogMessage -headers $Headers -API $APIName -tenant $Tenant.defaultDomainName -message "Failed to add MSP Application $($intuneBody.DisplayName) to queue" -Sev 'Error' "Failed to add MSP app for $($Tenant.defaultDomainName) to queue" } } - $body = [pscustomobject]@{'Results' = $results } + $body = [PSCustomObject]@{'Results' = $Results } # 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/Endpoint/Applications/Invoke-AddOfficeApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 index f2162cf98ff7..51a30d74f9bf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddOfficeApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Input bindings are passed in via param block. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddStoreApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddStoreApp.ps1 index 960560e29b5e..e8e069a5dd40 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddStoreApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddStoreApp.ps1 @@ -11,12 +11,13 @@ Function Invoke-AddStoreApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - Write-Host 'PowerShell HTTP trigger function processed a request.' - $WinGetApp = $request.body - if ($ChocoApp.InstallAsSystem) { 'system' } else { 'user' } + $WinGetApp = $Request.Body $assignTo = $Request.body.AssignTo + + if ($ChocoApp.InstallAsSystem) { 'system' } else { 'user' } $WinGetData = [ordered]@{ '@odata.type' = '#microsoft.graph.winGetApp' 'displayName' = "$($WinGetApp.ApplicationName)" @@ -29,13 +30,13 @@ Function Invoke-AddStoreApp { } $Tenants = $Request.body.selectedTenants.defaultDomainName - $Results = foreach ($Tenant in $tenants) { + $Results = foreach ($Tenant in $Tenants) { try { $CompleteObject = [PSCustomObject]@{ - tenant = $tenant - Applicationname = $WinGetApp.ApplicationName + tenant = $Tenant + ApplicationName = $WinGetApp.ApplicationName assignTo = $assignTo - InstallationIntent = $request.body.InstallationIntent + InstallationIntent = $Request.Body.InstallationIntent type = 'WinGet' IntuneBody = $WinGetData } | ConvertTo-Json -Depth 15 @@ -48,14 +49,14 @@ Function Invoke-AddStoreApp { status = 'Not Deployed yet' } "Successfully added Store App for $($Tenant) to queue." - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant -message "Successfully added Store App $($intunebody.Displayname) to queue" -Sev 'Info' + Write-LogMessage -headers $Headers -API $APIName -tenant $tenant -message "Successfully added Store App $($IntuneBody.DisplayName) to queue" -Sev 'Info' } catch { - Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $tenant -message "Failed to add Store App $($intunebody.Displayname) to queue" -Sev 'Error' - "Failed added Store App for $($Tenant) to queue" + Write-LogMessage -headers $Headers -API $APIName -tenant $tenant -message "Failed to add Store App $($IntuneBody.DisplayName) to queue" -Sev 'Error' + "Failed to add Store App for $($Tenant) to queue" } } - $body = [pscustomobject]@{'Results' = $results } + $body = [pscustomobject]@{'Results' = $Results } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 index 999161fe866b..807f153a700c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ExecAssignApp.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecAssignApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $tenantfilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 index 92c5e188f1aa..6fb8e46dc801 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-ListApps.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListApps { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 index c7e1943a3cf2..b63f3ae3f6b4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1 @@ -11,11 +11,11 @@ Function Invoke-AddAPDevice { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $TenantFilter = (Get-Tenants | Where-Object { $_.defaultDomainName -eq $Request.body.TenantFilter.value }).customerId $GroupName = if ($Request.body.Groupname) { $Request.body.Groupname } else { (New-Guid).GUID } Write-Host $GroupName diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 index 3834d45e071e..5112dc52d091 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAutopilotConfig.ps1 @@ -11,11 +11,11 @@ Function Invoke-AddAutopilotConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Input bindings are passed in via param block. $Tenants = $Request.body.selectedTenants.value diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 index 1656c5a69c59..b8f8a4c34fe2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddEnrollment.ps1 @@ -11,11 +11,11 @@ Function Invoke-AddEnrollment { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Input bindings are passed in via param block. $Tenants = $Request.body.selectedTenants.value diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 index fed6abfc5b13..acf5d9574a53 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAPDevices.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListAPDevices { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAutopilotconfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAutopilotconfig.ps1 index a4832e59e1c3..a9a7bfdc0717 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAutopilotconfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ListAutopilotconfig.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListAutopilotconfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-RemoveAPDevice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-RemoveAPDevice.ps1 index 839a5410bb22..172f7d8eb9f2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-RemoveAPDevice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-RemoveAPDevice.ps1 @@ -11,7 +11,8 @@ Function Invoke-RemoveAPDevice { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter ?? $Request.body.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 index b355013cdb96..b2a0f4a714f2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddDefenderDeployment.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddDefenderDeployment { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenants = ($Request.body.selectedTenants).value if ('AllTenants' -in $Tenants) { $Tenants = (Get-Tenants -IncludeErrors).defaultDomainName } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 index 67fcdae69680..985b60203f3d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-AddPolicy.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddPolicy { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenants = ($Request.Body.tenantFilter.value) if ('AllTenants' -in $Tenants) { $Tenants = (Get-Tenants).defaultDomainName } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 index aa987198a3ee..85a0572a77cf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditPolicy.ps1 @@ -11,7 +11,8 @@ Function Invoke-EditPolicy { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenant = $request.body.tenantid $ID = $request.body.groupid diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 index 5057a2d7470f..bb14abf9e099 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ExecDeviceAction.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecDeviceAction { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with Body parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListDefenderState.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListDefenderState.ps1 index fb4efd4a5906..c895f478c158 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListDefenderState.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListDefenderState.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListDefenderState { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $StatusCode = [HttpStatusCode]::OK - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntunePolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntunePolicy.ps1 index dd44396c9b43..b9f5ed00b5d5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntunePolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntunePolicy.ps1 @@ -14,8 +14,7 @@ Function Invoke-ListIntunePolicy { Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneScript.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneScript.ps1 index e53611befd00..2919be6460f0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneScript.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneScript.ps1 @@ -12,11 +12,9 @@ function Invoke-ListIntuneScript { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers - Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev Debug + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev Debug - Write-Host 'PowerShell HTTP trigger function processed a request.' - - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter $Results = [System.Collections.Generic.List[System.Object]]::new() $BulkRequests = [PSCustomObject]@( diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneTemplates.ps1 index dccba05425ef..518bc40a7ac8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-ListIntuneTemplates.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListIntuneTemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CippTable -tablename 'templates' $Imported = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'settings'" diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 index 79b0cd5cb55b..f049534f1a64 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Reports/Invoke-ListDevices.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListDevices { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 index 988ffceaa880..e79e0ba8c66f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-AddGroupTemplate.ps1 @@ -10,7 +10,8 @@ Function Invoke-AddGroupTemplate { [CmdletBinding()] param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $GUID = (New-Guid).GUID try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 index a2ac5ca43077..f6b1bb83d201 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 @@ -11,14 +11,14 @@ Function Invoke-EditGroup { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Results = [System.Collections.ArrayList]@() $userobj = $Request.body $GroupType = $userobj.groupId.addedFields.groupType ? $userobj.groupId.addedFields.groupType : $userobj.groupType $GroupName = $userobj.groupName ? $userobj.groupName : $userobj.groupId.addedFields.groupName - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $AddMembers = ($userobj.Addmember).value ?? $userobj.AddMember $userobj.groupId = $userobj.groupId.value ?? $userobj.groupId diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupSenderAuthentication.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupSenderAuthentication.ps1 index 70672eb22229..514e50a4d6a9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupSenderAuthentication.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupSenderAuthentication.ps1 @@ -5,7 +5,8 @@ Function Invoke-ListGroupSenderAuthentication { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupTemplates.ps1 index 75cf77e3b9db..ec9510183266 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroupTemplates.ps1 @@ -11,10 +11,10 @@ Function Invoke-ListGroupTemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' Write-Host $Request.query.id #List new policies diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 index da1c6c362f6c..8a52466ebd2d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListGroups { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $Request.Query.TenantFilter $selectstring = "id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,grouptypes,onPremisesSyncEnabled,resourceProvisioningOptions,userPrincipalName&`$expand=members(`$select=userPrincipalName)" diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 index 62133671d697..b3819fd507e5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 @@ -29,8 +29,7 @@ Function Invoke-EditUser { $AddToGroups = $Request.body.AddToGroups $RemoveFromGroups = $Request.body.RemoveFromGroups - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + #Edit the user try { Write-Host "$([boolean]$UserObj.MustChangePass)" 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 20927bbfa3ec..d647d7fc5dff 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 @@ -11,63 +11,62 @@ Function Invoke-ExecBECRemediate { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - $User = $Request.Headers + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - Write-LogMessage -Headers $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' - Write-Host 'PowerShell HTTP trigger function processed a request.' - - $TenantFilter = $request.body.tenantfilter - $SuspectUser = $request.body.userid - $username = $request.body.username + $TenantFilter = $Request.Body.tenantFilter + $SuspectUser = $Request.Body.userid + $Username = $Request.Body.username Write-Host $TenantFilter Write-Host $SuspectUser $Results = try { $Step = 'Reset Password' - Set-CIPPResetPassword -UserID $username -tenantFilter $TenantFilter -APIName $APINAME -Headers $User + Set-CIPPResetPassword -UserID $Username -tenantFilter $TenantFilter -APIName $APIName -Headers $Headers $Step = 'Disable Account' - Set-CIPPSignInState -userid $username -AccountEnabled $false -tenantFilter $TenantFilter -APIName $APINAME -Headers $User + Set-CIPPSignInState -userid $Username -AccountEnabled $false -tenantFilter $TenantFilter -APIName $APIName -Headers $Headers $Step = 'Revoke Sessions' - Revoke-CIPPSessions -userid $SuspectUser -username $username -Headers $User -APIName $APINAME -tenantFilter $TenantFilter + Revoke-CIPPSessions -userid $SuspectUser -username $Username -Headers $Headers -APIName $APIName -tenantFilter $TenantFilter $Step = 'Remove MFA methods' - Remove-CIPPUserMFA -UserPrincipalName $username -TenantFilter $TenantFilter -Headers $User + Remove-CIPPUserMFA -UserPrincipalName $Username -TenantFilter $TenantFilter -Headers $Headers $Step = 'Disable Inbox Rules' - $Rules = New-ExoRequest -anchor $username -tenantid $TenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $username; IncludeHidden = $true } + $Rules = New-ExoRequest -anchor $Username -tenantid $TenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $Username; IncludeHidden = $true } $RuleDisabled = 0 $RuleFailed = 0 if (($Rules | Measure-Object).Count -gt 0) { $Rules | Where-Object { $_.Name -ne 'Junk E-Mail Rule' -and $_.Name -notlike 'Microsoft.Exchange.OOF.*' } | ForEach-Object { try { - $null = New-ExoRequest -anchor $username -tenantid $TenantFilter -cmdlet 'Disable-InboxRule' -cmdParams @{Confirm = $false; Identity = $_.Identity } - "Disabled Inbox Rule '$($_.Identity)' for $username" + $null = New-ExoRequest -anchor $Username -tenantid $TenantFilter -cmdlet 'Disable-InboxRule' -cmdParams @{Confirm = $false; Identity = $_.Identity } + "Disabled Inbox Rule '$($_.Identity)' for $Username" $RuleDisabled++ } catch { - "Failed to disable Inbox Rule '$($_.Identity)' for $username" + "Failed to disable Inbox Rule '$($_.Identity)' for $Username" $RuleFailed++ } } } if ($RuleDisabled -gt 0) { - "Disabled $RuleDisabled Inbox Rules for $username" + "Disabled $RuleDisabled Inbox Rules for $Username" } else { - "No Inbox Rules found for $username. We have not disabled any rules." + "No Inbox Rules found for $Username. We have not disabled any rules." } if ($RuleFailed -gt 0) { - "Failed to disable $RuleFailed Inbox Rules for $username" + "Failed to disable $RuleFailed Inbox Rules for $Username" } - - Write-LogMessage -API 'BECRemediate' -tenant $tenantfilter -message "Executed Remediation for $username" -sev 'Info' + $StatusCode = [HttpStatusCode]::OK + Write-LogMessage -API 'BECRemediate' -tenant $TenantFilter -message "Executed Remediation for $Username" -sev 'Info' } catch { $ErrorMessage = Get-CippException -Exception $_ - $results = [pscustomobject]@{'Results' = "Failed to execute remediation. $($ErrorMessage.NormalizedError)" } - Write-LogMessage -API 'BECRemediate' -tenant $tenantfilter -message "Executed Remediation for $username failed at the $Step step" -sev 'Error' -LogData $ErrorMessage + $Results = [pscustomobject]@{'Results' = "Failed to execute remediation. $($ErrorMessage.NormalizedError)" } + Write-LogMessage -API 'BECRemediate' -tenant $TenantFilter -message "Executed Remediation for $Username failed at the $Step step" -sev 'Error' -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::InternalServerError } - $results = [pscustomobject]@{'Results' = @($Results) } + $Results = [pscustomobject]@{'Results' = @($Results) } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK + StatusCode = $StatusCode Body = $Results }) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 index 7030dac2a4da..5da791680ea4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecOneDriveShortCut { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' Try { $MessageResult = New-CIPPOneDriveShortCut -username $Request.Body.username -userid $Request.Body.userid -TenantFilter $Request.Body.tenantFilter -URL $Request.Body.siteUrl.value -Headers $Request.Headers diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 index 53f86a6975c5..10a8013fec5c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecResetPass { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRestoreDeleted.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRestoreDeleted.ps1 index e2d85fae5706..b2c0ba22fb52 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRestoreDeleted.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRestoreDeleted.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecRestoreDeleted { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter ?? $Request.Body.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 index b09d8a09fa4b..822c6356dcf1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecRevokeSessions.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecRevokeSessions { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 index 9eb13dbf1bfc..08c1f63342cc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecSendPush.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecSendPush { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $Request.body.TenantFilter $UserEmail = $Request.body.UserEmail diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListPerUserMFA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListPerUserMFA.ps1 index 7bc8db4c1fd7..7e6d040a18d9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListPerUserMFA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListPerUserMFA.ps1 @@ -14,8 +14,7 @@ function Invoke-ListPerUserMFA { $User = $Request.Headers Write-LogMessage -Headers $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.' + # Parse query parameters $Tenant = $Request.query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 index e2399fabe5c0..bd8ce3a7eb27 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserConditionalAccessPolicies.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListUserConditionalAccessPolicies { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 index fbbdde8aa359..f9522b7648a9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserCounts.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListUserCounts { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 index 52e841377b01..d37bc6e836b2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserDevices.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListUserDevices { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 index 870d2a755d48..88123afee17b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserGroups.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListUserGroups { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 index a264dc39f8c6..74def3815f6d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserMailboxRules.ps1 @@ -15,8 +15,7 @@ Function Invoke-ListUserMailboxRules { Write-LogMessage -Headers $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.' + # Interact with query parameters or the body of the request. try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 index 1ff0c7712939..858ddfb27da4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSettings.ps1 @@ -10,7 +10,8 @@ function Invoke-ListUserSettings { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 index 9df706720a68..a0009394dd72 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUserSigninLogs.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListUserSigninLogs { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $top = $Request.Query.top ? $Request.Query.top : 50 - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 index a132268e8390..d2a5c2685bd3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ListUsers.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListUsers { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $ConvertTable = Import-Csv ConversionTable.csv | Sort-Object -Property 'guid' -Unique # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSite.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSite.ps1 index be7dc4e714b3..e8f19acf0534 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSite.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSite.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddSite { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $SharePointObj = $Request.body diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSiteBulk.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSiteBulk.ps1 index 049af0fbd648..8ca292b2c52f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSiteBulk.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddSiteBulk.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddSiteBulk { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Results = [System.Collections.ArrayList]@() diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 index 6c00d43d4bb2..9f76c94071de 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-AddTeam.ps1 @@ -11,12 +11,12 @@ Function Invoke-AddTeam { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $userobj = $Request.body - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $Owners = ($userobj.owner) try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecRemoveTeamsVoicePhoneNumberAssignment.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecRemoveTeamsVoicePhoneNumberAssignment.ps1 index 4af90af25044..b022aee68d46 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecRemoveTeamsVoicePhoneNumberAssignment.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ExecRemoveTeamsVoicePhoneNumberAssignment.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecRemoveTeamsVoicePhoneNumberAssignment { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $tenantFilter = $Request.Body.TenantFilter try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointQuota.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointQuota.ps1 index 233e0ba32654..d09419fcc476 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointQuota.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointQuota.ps1 @@ -11,10 +11,8 @@ Function Invoke-ListSharepointQuota { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 index 5316c2cec66c..cb84b80a8b6e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSharepointSettings.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListSharepointSettings { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $tenant = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 index 82acc236796f..38637679c79c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeams.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListTeams { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 index 426131cc047d..342f8096d272 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsActivity.ps1 @@ -11,8 +11,7 @@ Function Invoke-ListTeamsActivity { param($Request, $TriggerMetadata) - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 index 6e996b99c4fd..c825cfc11459 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListTeamsVoice { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 index 5288f805e25e..8fcf39248cd2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-AddAlert.ps1 @@ -10,7 +10,8 @@ Function Invoke-AddAlert { [CmdletBinding()] param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenants = $request.body.tenantFilter $Conditions = $request.body.conditions | ConvertTo-Json -Compress -Depth 10 | Out-String $TenantsJson = $Tenants | ConvertTo-Json -Compress -Depth 10 | Out-String diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 index 7511b8c4e408..42c6bf3e8787 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListWebhookAlert.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListWebhookAlert { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = get-cipptable -TableName 'SchedulerConfig' $WebhookRow = foreach ($Webhook in Get-CIPPAzDataTableEntity @Table | Where-Object -Property PartitionKey -EQ 'WebhookAlert') { $Webhook.If = $Webhook.If | ConvertFrom-Json diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 index f7f661064f5c..b85e6bf5f9c2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAddMultiTenantApp.ps1 @@ -10,7 +10,8 @@ function Invoke-ExecAddMultiTenantApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $DelegateResources = $request.body.permissions | Where-Object -Property origin -EQ 'Delegated' | ForEach-Object { @{ id = $_.id; type = 'Scope' } } $DelegateResourceAccess = @{ ResourceAppId = '00000003-0000-0000-c000-000000000000'; resourceAccess = $DelegateResources } $ApplicationResources = $request.body.permissions | Where-Object -Property origin -EQ 'Application' | ForEach-Object { @{ id = $_.id; type = 'Role' } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 index 34ca07d3228a..26c9b127959e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Application Approval/Invoke-ExecAppApproval.ps1 @@ -11,10 +11,10 @@ Function Invoke-ExecAppApproval { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' Write-Host "$($Request.query.ID)" # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 index ce498176528c..e49ba8104f16 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecAddSPN { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $Body = if ($Request.Query.Enable) { '{"accountEnabled":"true"}' } else { '{"accountEnabled":"false"}' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecUpdateSecureScore.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecUpdateSecureScore.ps1 index ec89669aefcc..406a029c49c4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecUpdateSecureScore.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecUpdateSecureScore.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecUpdateSecureScore { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $Body = @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListDomains.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListDomains.ps1 index 14b225267ec7..ece424ca883d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListDomains.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ListDomains.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListDomains { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 index 02200e39dc04..db7ca80c47bd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddCATemplate.ps1 @@ -11,12 +11,15 @@ Function Invoke-AddCATemplate { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $TenantFilter = $Request.Body.TenantFilter + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Body.tenantFilter + $Name = $Request.Body.name try { $GUID = (New-Guid).GUID - $JSON = New-CIPPCATemplate -TenantFilter $TenantFilter -JSON $request.body + $JSON = New-CIPPCATemplate -TenantFilter $TenantFilter -JSON $Request.Body $Table = Get-CippTable -tablename 'templates' $Table.Force = $true Add-CIPPAzDataTableEntity @Table -Entity @{ @@ -25,19 +28,22 @@ Function Invoke-AddCATemplate { PartitionKey = 'CATemplate' GUID = "$GUID" } - Write-LogMessage -headers $Request.Headers -API $APINAME -message "Created CA Template $($Request.body.name) with GUID $GUID" -Sev 'Debug' - $body = [pscustomobject]@{'Results' = 'Successfully added template' } + $Result = "Created CA Template $($Name) with GUID $GUID" + Write-LogMessage -headers $Headers -API $APIName -message "Created CA Template $($Name) with GUID $GUID" -Sev 'Debug' + $StatusCode = [HttpStatusCode]::OK } catch { - Write-LogMessage -headers $Request.Headers -API $APINAME -message "Failed to create CA Template: $($_.Exception.Message)" -Sev 'Error' - $body = [pscustomobject]@{'Results' = "Intune Template Deployment failed: $($_.Exception.Message)" } + $ErrorMessage = Get-CippException -Exception $_ + $Result = "Failed to create CA Template: $($ErrorMessage.NormalizedError)" + Write-LogMessage -headers $Headers -API $APIName -message "Failed to create CA Template: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::InternalServerError } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $body + StatusCode = $StatusCode + Body = @{'Results' = "$Result" } }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 index 538599a246ac..27831ac9c557 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-AddNamedLocation.ps1 @@ -11,12 +11,10 @@ Function Invoke-AddNamedLocation { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - # Input bindings are passed in via param block. $Tenants = $request.body.selectedTenants.value Write-Host ($Request.body | ConvertTo-Json) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 index 04a138b3f97f..b18528966f52 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCACheck.ps1 @@ -11,12 +11,13 @@ Function Invoke-ExecCaCheck { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $Tenant = $request.body.tenantFilter - $UserID = $request.body.userId.value - if ($Request.body.IncludeApplications.value) { - $IncludeApplications = $Request.body.IncludeApplications.value + $Tenant = $Request.Body.tenantFilter + $UserID = $Request.Body.userID.value + if ($Request.Body.IncludeApplications.value) { + $IncludeApplications = $Request.Body.IncludeApplications.value } else { $IncludeApplications = '67ad5377-2d78-4ac2-a867-6300cda00e85' } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 index 003dd4e9a2b6..758b92eaef24 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecCAExclusion.ps1 @@ -11,24 +11,34 @@ Function Invoke-ExecCAExclusion { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + #If UserId is a guid, get the user's UPN - if ($Request.body.UserId -match '^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$') { - $Username = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($Request.body.UserId)" -tenantid $Request.body.TenantFilter).userPrincipalName + $TenantFilter = $Request.Body.tenantFilter + $UserId = $Request.Body.UserID + $EndDate = $Request.Body.EndDate + $PolicyId = $Request.Body.PolicyId + $ExclusionType = $Request.Body.ExclusionType + + + if ($UserId -match '^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$') { + $Username = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($UserId)" -tenantid $TenantFilter).userPrincipalName } - if ($Request.body.vacation -eq 'true') { - $StartDate = $Request.body.StartDate + if ($Request.Body.vacation -eq 'true') { + $StartDate = $Request.Body.StartDate + $EndDate = $Request.Body.EndDate $TaskBody = [pscustomobject]@{ - TenantFilter = $Request.body.TenantFilter - Name = "Add CA Exclusion Vacation Mode: $Username - $($Request.body.TenantFilter)" + TenantFilter = $TenantFilter + Name = "Add CA Exclusion Vacation Mode: $Username - $($TenantFilter)" Command = @{ value = 'Set-CIPPCAExclusion' label = 'Set-CIPPCAExclusion' } Parameters = [pscustomobject]@{ ExclusionType = 'Add' - UserID = $Request.body.UserID - PolicyId = $Request.body.PolicyId + UserID = $UserID + PolicyId = $PolicyId UserName = $Username } ScheduledTime = $StartDate @@ -36,12 +46,12 @@ Function Invoke-ExecCAExclusion { Add-CIPPScheduledTask -Task $TaskBody -hidden $false #Removal of the exclusion $TaskBody.Parameters.ExclusionType = 'Remove' - $TaskBody.Name = "Remove CA Exclusion Vacation Mode: $username - $($Request.body.TenantFilter)" - $TaskBody.ScheduledTime = $Request.body.EndDate + $TaskBody.Name = "Remove CA Exclusion Vacation Mode: $Username - $($TenantFilter)" + $TaskBody.ScheduledTime = $EndDate Add-CIPPScheduledTask -Task $TaskBody -hidden $false $body = @{ Results = "Successfully added vacation mode schedule for $Username." } } else { - Set-CIPPCAExclusion -TenantFilter $Request.body.TenantFilter -ExclusionType $Request.body.ExclusionType -UserID $Request.body.UserID -PolicyId $Request.body.PolicyId -Headers $Request.Headers -UserName $Username + Set-CIPPCAExclusion -TenantFilter $TenantFilter -ExclusionType $ExclusionType -UserID $UserID -PolicyId $PolicyId -Headers $Headers -UserName $Username } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecNamedLocation.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecNamedLocation.ps1 index 8cd1f2341fd4..f6eee67e208e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecNamedLocation.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ExecNamedLocation.ps1 @@ -11,13 +11,11 @@ Function Invoke-ExecNamedLocation { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - - $TenantFilter = $Request.Body.TenantFilter ?? $Request.Query.TenantFilter + $TenantFilter = $Request.Body.tenantFilter ?? $Request.Query.tenantFilter $NamedLocationId = $Request.Body.NamedLocationId ?? $Request.Query.NamedLocationId $change = $Request.Body.change ?? $Request.Query.change $content = $Request.Body.input ?? $Request.Query.input diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 index b76cb67f4d8c..6debc4739fb4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 @@ -11,10 +11,10 @@ Function Invoke-ListCAtemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' Write-Host $Request.query.id #Migrating old policies whenever you do a list $Table = Get-CippTable -tablename 'templates' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 index c96c3b99f044..f4128ad4a9e2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListConditionalAccessPolicies { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' function Get-LocationNameFromId { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCAPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCAPolicy.ps1 index 7c894788f257..335d8b654164 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCAPolicy.ps1 @@ -12,7 +12,7 @@ Function Invoke-RemoveCAPolicy { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers - Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCATemplate.ps1 index e800d423fc90..9113d01dd2cf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCATemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-RemoveCATemplate.ps1 @@ -12,9 +12,9 @@ Function Invoke-RemoveCATemplate { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers - $ID = $request.Query.ID ?? $Request.Body.ID Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $ID = $request.Query.ID ?? $Request.Body.ID try { $Table = Get-CippTable -tablename 'templates' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 index e8367b4818b9..b6ec185bf1a2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAddGDAPRole.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecAddGDAPRole { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $CippDefaults = @( @{ label = 'Application Administrator'; value = '9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3' }, @@ -28,9 +29,9 @@ Function Invoke-ExecAddGDAPRole { @{ label = 'Privileged Authentication Administrator'; value = '7be44c8a-adaf-4e2a-84d6-ab2649e08a13' } ) - $Groups = $Request.body.gdapRoles ?? $CippDefaults + $Groups = $Request.Body.gdapRoles ?? $CippDefaults - $CustomSuffix = $Request.body.customSuffix + $CustomSuffix = $Request.Body.customSuffix $Table = Get-CIPPTable -TableName 'GDAPRoles' $Results = [System.Collections.Generic.List[string]]::new() diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 index 75bdbd0bc4d2..b724655e023f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecAutoExtendGDAP.ps1 @@ -10,6 +10,10 @@ Function Invoke-ExecAutoExtendGDAP { [CmdletBinding()] param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Id = $Request.query.ID ?? $Request.Body.ID $Results = Set-CIPPGDAPAutoExtend -RelationShipid $Id diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 index a6abd42ddf8d..e64d098aa5ef 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecDeleteGDAPRelationship.ps1 @@ -11,14 +11,15 @@ Function Invoke-ExecDeleteGDAPRelationship { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $GDAPID = $Request.Query.GDAPId ?? $Request.Body.GDAPId try { $DELETE = New-GraphPostRequest -NoAuthCheck $True -uri "https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships/$($GDAPID)/requests" -type POST -body '{"action":"terminate"}' -tenantid $env:TenantID $Results = [pscustomobject]@{'Results' = "Success. GDAP relationship for $($GDAPID) been revoked" } - Write-LogMessage -headers $Request.Headers -API $APINAME -message "Success. GDAP relationship for $($GDAPID) been revoked" -Sev 'Info' + Write-LogMessage -headers $Headers -API $APIName -message "Success. GDAP relationship for $($GDAPID) been revoked" -Sev 'Info' } catch { $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } 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 c3149bbc49b4..39dad0529337 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 @@ -11,16 +11,18 @@ Function Invoke-ExecDeleteGDAPRoleMapping { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $Table = Get-CIPPTable -TableName 'GDAPRoles' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + $Table = Get-CIPPTable -TableName 'GDAPRoles' $GroupId = $Request.Query.GroupId ?? $Request.Body.GroupId try { $Filter = "PartitionKey eq 'Roles' and RowKey eq '{0}'" -f $GroupId $Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter Remove-AzDataTableEntity -Force @Table -Entity $Entity $Results = [pscustomobject]@{'Results' = 'Success. GDAP relationship mapping deleted' } - Write-LogMessage -headers $Request.Headers -API $APINAME -message "GDAP relationship mapping deleted for $($GroupId)" -Sev 'Info' + Write-LogMessage -headers $Headers -API $APIName -message "GDAP relationship mapping deleted for $($GroupId)" -Sev 'Info' } catch { $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 index 0932d77e21a4..e6429393661a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInvite.ps1 @@ -9,8 +9,9 @@ Function Invoke-ExecGDAPInvite { [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = 'ExecGDAPInvite' - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $RoleMappings = $Request.Body.roleMappings diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 index 15fbcfc52841..3f29d62ac3d1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPInviteApproved.ps1 @@ -10,7 +10,9 @@ Function Invoke-ExecGDAPInviteApproved { [CmdletBinding()] param($Request, $TriggerMetadata) - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' Set-CIPPGDAPInviteGroups diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 index db74a5a08f23..35b7e8b4c647 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRemoveGArole.ps1 @@ -9,7 +9,7 @@ Function Invoke-ExecGDAPRemoveGArole { [CmdletBinding()] param($Request, $TriggerMetadata) - $GDAPID = $request.query.GDAPId ?? $request.Body.GDAPId + $GDAPID = $Request.Query.GDAPId ?? $Request.Body.GDAPId try { $CheckActive = New-GraphGetRequest -NoAuthCheck $True -uri "https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships/$($GDAPID)" -tenantid $env:TenantID diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRoleTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRoleTemplate.ps1 index 218d92780ff8..ec02efcf937d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRoleTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ExecGDAPRoleTemplate.ps1 @@ -10,6 +10,10 @@ Function Invoke-ExecGDAPRoleTemplate { [CmdletBinding()] param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Table = Get-CIPPTable -TableName 'GDAPRoleTemplates' $Templates = Get-CIPPAzDataTableEntity @Table diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 index 179c0c603aa5..5ad7f3d8d72d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPInvite.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListGDAPInvite { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 index 64f10cdbe9a1..4f615d67b329 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/GDAP/Invoke-ListGDAPRoles.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListGDAPRoles { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $Table = Get-CIPPTable -TableName 'GDAPRoles' $Groups = Get-CIPPAzDataTableEntity @Table diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListLicenses.ps1 index 59b8b8817d71..1fa957953f07 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListLicenses.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListLicenses.ps1 @@ -11,14 +11,12 @@ Function Invoke-ListLicenses { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter $RawGraphRequest = if ($TenantFilter -ne 'AllTenants') { $GraphRequest = Get-CIPPLicenseOverview -TenantFilter $TenantFilter | ForEach-Object { $TermInfo = $_.TermInfo | ConvertFrom-Json -ErrorAction SilentlyContinue diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListOAuthApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListOAuthApps.ps1 index 4d720cdf9122..4eb7dc4e6188 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListOAuthApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListOAuthApps.ps1 @@ -11,15 +11,12 @@ Function Invoke-ListOAuthApps { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter - if ($TenantFilter -eq 'AllTenants') { $Tenants = (Get-Tenants).defaultDomainName } else { $tenants = $TenantFilter } + if ($TenantFilter -eq 'AllTenants') { $Tenants = (Get-Tenants).defaultDomainName } else { $Tenants = $TenantFilter } try { $GraphRequest = foreach ($Tenant in $Tenants) { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListServiceHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListServiceHealth.ps1 index 160533a5d1f9..9e707124ae8e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListServiceHealth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Reports/Invoke-ListServiceHealth.ps1 @@ -12,9 +12,10 @@ Function Invoke-ListServiceHealth { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers - $TenantFilter = $Request.Query.tenantFilter Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter if ($TenantFilter -eq 'AllTenants') { $ResultHealthSummary = Get-Tenants | ForEach-Object -Parallel { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 index 7a8da437c4ad..b6646630d7bb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsDeploy.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddStandardsDeploy { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $user = $request.headers.'x-ms-client-principal' $username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($user)) | ConvertFrom-Json).userDetails 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 67a76c720f34..b042bf803d93 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 @@ -11,7 +11,8 @@ Function Invoke-AddStandardsTemplate { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $GUID = $Request.body.GUID ? $request.body.GUID : (New-Guid).GUID #updatedBy = $request.headers.'x-ms-client-principal' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 index c9cf3382971c..9f5dbd8c4858 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-BestPracticeAnalyser_List.ps1 @@ -11,7 +11,8 @@ Function Invoke-BestPracticeAnalyser_List { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Tenants = Get-Tenants $Table = get-cipptable 'cachebpa' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardConvert.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardConvert.ps1 index ebc62316e6b3..a03765cad909 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardConvert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecStandardConvert.ps1 @@ -108,7 +108,7 @@ function Invoke-ExecStandardConvert { } else { $StdKey } $IsArrayStandard = ($NewStdKey -eq 'IntuneTemplate' -or $NewStdKey -eq 'ConditionalAccessTemplate') $ConvertedObj = Convert-SingleStandardItem $OldStd - if ($ConvertedObj -eq $null) { + if ($null -eq $ConvertedObj) { continue } @@ -173,7 +173,7 @@ function Invoke-ExecStandardConvert { $OldStandards = (Get-CIPPAzDataTableEntity @Table -Filter $Filter).JSON | ConvertFrom-Json $AllTenantsStd = $OldStandards | Where-Object { $_.Tenant -eq 'AllTenants' } - $HasAllTenants = $AllTenantsStd -ne $null + $HasAllTenants = $null -ne $AllTenantsStd $AllTenantsExclusions = New-Object System.Collections.ArrayList $StandardsToConvert = New-Object System.Collections.ArrayList 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 735a6f98d219..f2440e006895 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 @@ -10,9 +10,12 @@ Function Invoke-ExecStandardsRun { [CmdletBinding()] param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $tenantfilter = if ($Request.Query.TenantFilter) { $Request.Query.TenantFilter } else { 'allTenants' } - $TemplateId = if ($Request.Query.TemplateId) { $Request.Query.TemplateId } else { '*' } + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + + $TenantFilter = $Request.Query.tenantFilter ?? 'allTenants' + $TemplateId = $Request.Query.templateId ?? '*' $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'StandardsTemplateV2'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter | Sort-Object TimeStamp).JSON | ForEach-Object { @@ -35,10 +38,10 @@ Function Invoke-ExecStandardsRun { $ProcessorFunction = [PSCustomObject]@{ PartitionKey = 'Function' - RowKey = "Invoke-CIPPStandardsRun-$tenantfilter" + RowKey = "Invoke-CIPPStandardsRun-$TenantFilter" FunctionName = 'Invoke-CIPPStandardsRun' Parameters = [string](ConvertTo-Json -Compress -InputObject @{ - TenantFilter = $tenantfilter + TenantFilter = $TenantFilter TemplateId = $TemplateId runManually = [bool]$Templates.runManually Force = $true @@ -46,20 +49,21 @@ Function Invoke-ExecStandardsRun { } $ProcessorQueue = Get-CIPPTable -TableName 'ProcessorQueue' Add-AzDataTableEntity @ProcessorQueue -Entity $ProcessorFunction -Force - $Results = "Successfully Queued Standards Run for Tenant $tenantfilter" + $Results = "Successfully Queued Standards Run for Tenant $TenantFilter" } } else { try { - $null = Invoke-CIPPStandardsRun -Tenantfilter $tenantfilter -TemplateID $TemplateId -runManually ([bool]$Templates.runManually) -Force - $Results = "Successfully Started Standards Run for Tenant $tenantfilter" - Write-LogMessage -tenant $tenantfilter -API $APINAME -message $Results -Sev 'Info' + $null = Invoke-CIPPStandardsRun -TenantFilter $TenantFilter -TemplateID $TemplateId -runManually ([bool]$Templates.runManually) -Force + $Results = "Successfully started Standards Run for tenant: $TenantFilter" + Write-LogMessage -headers $Headers -tenant $TenantFilter -API $APIName -message $Results -Sev 'Info' } catch { - $Results = "Failed to start standards run for $tenantfilter. Error: $($_.Exception.Message)" - Write-LogMessage -tenant $tenantfilter -API $APINAME -message $Results -Sev 'Error' + $ErrorMessage = Get-CippException -Exception $_ + $Results = "Failed to start standards run for tenant: $TenantFilter. Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -headers $Headers -tenant $TenantFilter -API $APIName -message $Results -Sev 'Error' -LogData $ErrorMessage } } - $Results = [pscustomobject]@{'Results' = "$results" } + $Results = [pscustomobject]@{'Results' = "$Results" } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPA.ps1 index 65e7bd78bcf6..8e58e59058ab 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 @@ -11,11 +11,14 @@ Function Invoke-ListBPA { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - # Write-LogMessage -headers $Request.Headers -API $APINAME -message "Accessed this API" -Sev "Debug" + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $Table = get-cipptable 'cachebpav2' - $name = $Request.query.Report - if ($name -eq $null) { $name = 'CIPP Best Practices v1.5 - Table view' } + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter + $Table = Get-CippTable 'cachebpav2' + $name = $Request.Query.Report + if ($null -eq $name) { $name = 'CIPP Best Practices v1.5 - Table view' } # Get all possible JSON files for reports, find the correct one, select the Columns $JSONFields = @() @@ -33,8 +36,8 @@ Function Invoke-ListBPA { } - if ($Request.query.tenantFilter -ne 'AllTenants' -and $Style -eq 'Tenant') { - $CustomerId = (Get-Tenants -TenantFilter $Request.query.tenantFilter).customerId + if ($TenantFilter -ne 'AllTenants' -and $Style -eq 'Tenant') { + $CustomerId = (Get-Tenants -TenantFilter $TenantFilter).customerId $mergedObject = New-Object pscustomobject $Data = (Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$CustomerId'") | ForEach-Object { $row = $_ @@ -83,9 +86,9 @@ Function Invoke-ListBPA { 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 + Where-Object { $_.Name -ne 'PartitionKey' -and $_.Name -ne 'RowKey' -and $_.Name -ne 'Timestamp' } | + ForEach-Object { $_.Name } + } | Select-Object -Unique Style = $Style } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 index d8f310af900d..c32e70d81ea9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListBPATemplates.ps1 @@ -11,9 +11,8 @@ Function Invoke-ListBPATemplates { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - Write-Host 'PowerShell HTTP trigger function processed a request.' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CippTable -tablename 'templates' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 index c644ea8eb38e..4cda61a033b9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainAnalyser.ps1 @@ -11,7 +11,14 @@ Function Invoke-ListDomainAnalyser { [CmdletBinding()] param($Request, $TriggerMetadata) - $Results = Get-CIPPDomainAnalyser -TenantFilter $Request.Query.tenantFilter + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter + + $Results = Get-CIPPDomainAnalyser -TenantFilter $TenantFilter # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 index 04916f6c449a..c080fe78c7fe 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListDomainHealth.ps1 @@ -10,6 +10,10 @@ Function Invoke-ListDomainHealth { [CmdletBinding()] param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + Import-Module DNSHealth try { @@ -38,10 +42,10 @@ Function Invoke-ListDomainHealth { $UserCreds = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $StatusCode = [HttpStatusCode]::OK try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandards.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandards.ps1 index a7a2d8358236..c4bbf2f79a6b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandards.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandards.ps1 @@ -11,13 +11,18 @@ Function Invoke-ListStandards { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter + if ($Request.Query.ShowConsolidated -eq $true) { $StandardQuery = @{ - TenantFilter = $Request.Query.TenantFilter + TenantFilter = $TenantFilter } - if ($Request.Query.TenantFilter -eq 'AllTenants') { + if ($TenantFilter -eq 'AllTenants') { $StandardQuery.ListAllTenants = $true } $CurrentStandards = @(Get-CIPPStandards @StandardQuery) @@ -26,20 +31,20 @@ Function Invoke-ListStandards { $Filter = "PartitionKey eq 'standards'" try { - if ($Request.query.TenantFilter) { - $tenants = (Get-CIPPAzDataTableEntity @Table -Filter $Filter).JSON | ConvertFrom-Json -Depth 15 -ErrorAction Stop | Where-Object Tenant -EQ $Request.query.tenantFilter + if ($TenantFilter) { + $Tenants = (Get-CIPPAzDataTableEntity @Table -Filter $Filter).JSON | ConvertFrom-Json -Depth 15 -ErrorAction Stop | Where-Object Tenant -EQ $TenantFilter } else { $Tenants = (Get-CIPPAzDataTableEntity @Table -Filter $Filter).JSON | ConvertFrom-Json -Depth 15 -ErrorAction Stop } } catch {} - $CurrentStandards = foreach ($tenant in $tenants) { + $CurrentStandards = foreach ($tenant in $Tenants) { [PSCustomObject]@{ displayName = $tenant.tenant appliedBy = $tenant.addedBy appliedAt = $tenant.appliedAt standards = $tenant.Standards - StandardsExport = ($tenant.Standards.psobject.properties.name) -join ', ' + StandardsExport = ($tenant.Standards.PSObject.Properties.Name) -join ', ' } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveBPATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveBPATemplate.ps1 index f42e8242ddab..ebebb03ab3a9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveBPATemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveBPATemplate.ps1 @@ -12,9 +12,9 @@ Function Invoke-RemoveBPATemplate { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers - Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $ID = $request.Query.TemplateName ?? $request.Body.TemplateName + $ID = $Request.Query.TemplateName ?? $Request.Body.TemplateName try { $Table = Get-CippTable -tablename 'templates' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandard.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandard.ps1 index 69b947300559..2a2347630687 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandard.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandard.ps1 @@ -11,29 +11,32 @@ Function Invoke-RemoveStandard { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - $User = $Request.Headers - Write-LogMessage -Headers $User -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $ID = $request.query.id + # Interact with query parameters or the body of the request. + $ID = $Request.Query.ID try { $Table = Get-CippTable -tablename 'standards' - $Filter = "PartitionKey eq 'standards' and RowKey eq '$id'" + $Filter = "PartitionKey eq 'standards' and RowKey eq '$ID'" $ClearRow = Get-CIPPAzDataTableEntity @Table -Filter $Filter -Property PartitionKey, RowKey - Remove-AzDataTableEntity -Force @Table -Entity $clearRow - Write-LogMessage -Headers $User -API $APINAME -message "Removed standards for $ID." -Sev 'Info' + Remove-AzDataTableEntity -Force @Table -Entity $ClearRow + Write-LogMessage -Headers $Headers -API $APIName -message "Removed standards for $ID." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully removed standards deployment' } + $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-CippException -Exception $_ - Write-LogMessage -Headers $User -API $APINAME -message "Failed to remove standard for $ID. $($ErrorMessage.NormalizedError)" -Sev 'Error' - $body = [pscustomobject]@{'Results' = 'Failed to remove standard)' } + Write-LogMessage -Headers $Headers -API $APIName -message "Failed to remove standard for $ID. $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::InternalServerError + $body = [pscustomobject]@{'Results' = 'Failed to remove standard' } } # 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/Tenant/Standards/Invoke-RemoveStandardTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandardTemplate.ps1 index 956d58353988..74249b5bdec4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandardTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-RemoveStandardTemplate.ps1 @@ -14,6 +14,7 @@ Function Invoke-RemoveStandardTemplate { $Headers = $Request.Headers Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + # Interact with query parameters or the body of the request. $ID = $Request.Body.ID ?? $Request.Query.ID try { $Table = Get-CippTable -tablename 'templates' 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 9af3e636cef8..3ebc2712adde 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 @@ -10,24 +10,30 @@ Function Invoke-listStandardTemplates { [CmdletBinding()] param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + # Interact with query parameters or the body of the request. + $ID = $Request.Query.id + $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'StandardsTemplateV2'" $Templates = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) | ForEach-Object { $JSON = $_.JSON -replace '"Action":', '"action":' try { $RowKey = $_.RowKey - $data = $JSON | ConvertFrom-Json -Depth 100 -ErrorAction SilentlyContinue + $Data = $JSON | ConvertFrom-Json -Depth 100 -ErrorAction SilentlyContinue } catch { Write-Host "$($RowKey) standard could not be loaded: $($_.Exception.Message)" return } - $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force - if ($data.excludedTenants) { $data.excludedTenants = @($data.excludedTenants) } - $data + $Data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force + if ($Data.excludedTenants) { $Data.excludedTenants = @($Data.excludedTenants) } + $Data } | Sort-Object -Property templateName - if ($Request.query.id) { $Templates = $Templates | Where-Object GUID -EQ $Request.query.id } + if ($ID) { $Templates = $Templates | Where-Object GUID -EQ $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-AddBPATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-AddBPATemplate.ps1 index 514473f084a6..04ed12a51fb6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-AddBPATemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-AddBPATemplate.ps1 @@ -11,7 +11,8 @@ Function Invoke-AddBPATemplate { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { 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 f5d37d2bad3c..31893ee7ae8b 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 @@ -11,11 +11,11 @@ Function Invoke-ExecGraphExplorerPreset { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' #UNDOREPLACE $Username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $Action = $Request.Body.Action ?? '' switch ($Action) { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 index efc70b91833f..f012ad7ec12e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecBreachSearch.ps1 @@ -11,8 +11,12 @@ Function Invoke-ExecBreachSearch { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $TenantFilter = $Request.query.TenantFilter + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.query.tenantFilter + #Move to background job New-BreachTenantSearch -TenantFilter $TenantFilter Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCSPLicense.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCSPLicense.ps1 index 0ba09a9db3ee..652ccd0d6da8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCSPLicense.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecCSPLicense.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecCSPLicense { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Body.TenantFilter + $TenantFilter = $Request.Body.tenantFilter $Action = $Request.Body.Action $SKU = $Request.Body.SKU diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 index 5ea8abad3067..65be9d853e0e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 @@ -9,7 +9,9 @@ Function Invoke-ExecExtensionNinjaOneQueue { #> [CmdletBinding()] param($Request, $TriggerMetadata) - + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' Switch ($QueueItem.NinjaAction) { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 index 9036b16620b4..4d444f6e2a8e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 @@ -11,7 +11,8 @@ Function Invoke-ExecListAppId { param($Request, $TriggerMetadata) Get-CIPPAuthentication $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $ResponseURL = "$(($Request.headers.'x-ms-original-url').replace('/api/ExecListAppId','/api/ExecSAMSetup'))" $Results = @{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 index 6c373d6deaf4..b0cfbff022f2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSchedulerBillingRun.ps1 @@ -9,12 +9,17 @@ Function Invoke-ExecSchedulerBillingRun { #> [CmdletBinding()] param($Request, $TriggerMetadata) + + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + try { Write-LogMessage -API 'Scheduler_Billing' -tenant 'none' -message 'Starting billing processing.' -sev Info $Table = Get-CIPPTable -TableName Extensionsconfig $Configuration = (Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json -Depth 10 - foreach ($ConfigItem in $Configuration.psobject.properties.name) { + foreach ($ConfigItem in $Configuration.PSObject.Properties.Name) { switch ($ConfigItem) { 'Gradient' { If ($Configuration.Gradient.enabled -and $Configuration.Gradient.BillingEnabled) { @@ -24,7 +29,7 @@ Function Invoke-ExecSchedulerBillingRun { } } } catch { - Write-LogMessage -API 'Scheduler_Billing' -tenant 'none' -message "Could not start billing processing $($_.Exception.Message)" -sev Error + Write-LogMessage -API 'Scheduler_Billing' -tenant 'none' -message "Could not start billing processing $($_.Exception.Message)" -sev Error -headers $Headers } } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 index ca89e41bd579..04c1b4b2ec12 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSendOrgMessage.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecSendOrgMessage { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 index e07781beb7f2..cc074c755c89 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUniversalSearch.ps1 @@ -11,11 +11,11 @@ Function Invoke-ExecUniversalSearch { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 index ee1b63556b4d..c646fa7fdac1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecUserSettings.ps1 @@ -14,12 +14,13 @@ function Invoke-ExecUserSettings { Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { - $object = $request.body.currentSettings | Select-Object * -ExcludeProperty CurrentTenant, pageSizes, sidebarShow, sidebarUnfoldable, _persist | ConvertTo-Json -Compress -Depth 10 + $object = $Request.Body.currentSettings | Select-Object * -ExcludeProperty CurrentTenant, pageSizes, sidebarShow, sidebarUnfoldable, _persist | ConvertTo-Json -Compress -Depth 10 + $User = $Request.Body.user $Table = Get-CippTable -tablename 'UserSettings' $Table.Force = $true Add-CIPPAzDataTableEntity @Table -Entity @{ JSON = "$object" - RowKey = "$($Request.body.user)" + RowKey = "$User" PartitionKey = 'UserSettings' } $StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 index 2db62cf8e0c3..496ed691952b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAllTenantDeviceCompliance.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListAllTenantDeviceCompliance { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 index baac00b5b28a..ba4f57322449 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListAppStatus.ps1 @@ -11,11 +11,12 @@ Function Invoke-ListAppStatus { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter $appFilter = $Request.Query.AppFilter Write-Host "Using $appFilter" $body = @" diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 index 4c9f894b3c4e..a9dbf181154e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesAccount.ps1 @@ -11,12 +11,16 @@ Function Invoke-ListBreachesAccount { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - if ($request.query.account -like '*@*') { - $Results = Get-HIBPRequest "breachedaccount/$($Request.query.account)?truncateResponse=false" + # Interact with query parameters or the body of the request. + $Account = $Request.Query.account + + if ($Account -like '*@*') { + $Results = Get-HIBPRequest "breachedaccount/$($Account)?truncateResponse=false" } else { - $Results = Get-BreachInfo -Domain $Request.query.account + $Results = Get-BreachInfo -Domain $Account } # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 index 5e6104b3fdf3..4777f73f8aa8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBreachesTenant.ps1 @@ -11,9 +11,10 @@ Function Invoke-ListBreachesTenant { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $TenantFilter = $Request.query.tenantFilter + $TenantFilter = $Request.Query.tenantFilter $Table = Get-CIPPTable -TableName UserBreaches if ($TenantFilter -ne 'AllTenants') { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPLicenses.ps1 index ecbaecfc54df..a63225022d1f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPLicenses.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPLicenses.ps1 @@ -11,19 +11,24 @@ Function Invoke-ListCSPLicenses { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - try { - $GraphRequest = Get-SherwebCurrentSubscription -TenantFilter $Request.Query.TenantFilter + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = @($GraphRequest) - }) -Clobber + try { + $Result = Get-SherwebCurrentSubscription -TenantFilter $TenantFilter + $StatusCode = [HttpStatusCode]::OK } catch { - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::BadRequest - Body = 'Unable to retrieve CSP licenses, ensure that you have enabled the Sherweb integration and mapped the tenant in the integration settings.' - }) -Clobber + $Result = 'Unable to retrieve CSP licenses, ensure that you have enabled the Sherweb integration and mapped the tenant in the integration settings.' + $StatusCode = [HttpStatusCode]::BadRequest } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @($Result) + }) -Clobber + } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPsku.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPsku.ps1 index 2036ff01b2c6..dcf8fb9a523f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPsku.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListCSPsku.ps1 @@ -11,11 +11,15 @@ Function Invoke-ListCSPsku { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter + $CurrentSkuOnly = $Request.Query.currentSkuOnly try { - if ($Request.Query.currentSkuOnly) { + if ($CurrentSkuOnly) { $GraphRequest = Get-SherwebCurrentSubscription -TenantFilter $TenantFilter } else { $GraphRequest = Get-SherwebCatalog -TenantFilter $TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 index 83dfbdaf9002..451212a6720b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDeviceDetails.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListDeviceDetails { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # XXX Seems to be an unused endpoint? -Bobby diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 index 008ae6398f9e..0083bd00754d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListExtensionsConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CIPPTable -TableName Extensionsconfig try { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 index 3b8032de9946..52cc699df175 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExternalTenantInfo.ps1 @@ -11,19 +11,20 @@ Function Invoke-ListExternalTenantInfo { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. - $Tenant = $request.query.tenant + $Tenant = $Request.Query.tenant + $TenantFilter = $Request.Query.tenantFilter # Normalize to tenantid and determine if tenant exists - $TenantId = (Invoke-RestMethod -Method GET "https://login.windows.net/$tenant/.well-known/openid-configuration").token_endpoint.Split('/')[3] + $TenantId = (Invoke-RestMethod -Method GET "https://login.windows.net/$Tenant/.well-known/openid-configuration").token_endpoint.Split('/')[3] if ($TenantId) { - $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$TenantId')" -noauthcheck $true -tenantid $TenantFilter + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$TenantId')" -NoAuthCheck $true -tenantid $TenantFilter $StatusCode = [HttpStatusCode]::OK } @@ -52,17 +53,17 @@ Function Invoke-ListExternalTenantInfo { "@ # Create the headers - $headers = @{ + $AutoDiscoverHeaders = @{ 'Content-Type' = 'text/xml; charset=utf-8' 'SOAPAction' = '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"' 'User-Agent' = 'AutodiscoverClient' } # Invoke - $response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri 'https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc' -Body $body -Headers $headers + $Response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri 'https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc' -Body $body -Headers $AutoDiscoverHeaders # Return - $TenantDomains = $response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain | Sort-Object + $TenantDomains = $Response.Envelope.body.GetFederationInformationResponseMessage.response.Domains.Domain | Sort-Object } $results = [PSCustomObject]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 index d98a26b66eb0..3cf030a6a105 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionParameters.ps1 @@ -10,7 +10,8 @@ function Invoke-ListFunctionParameters { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $Module = $Request.Query.Module diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 index 9bcb80aca64e..7b0a103160cf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListFunctionStats { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { $TenantFilter = $Request.Query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 index bb2172b2ec95..2d93efa37104 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGenericTestFunction.ps1 @@ -13,6 +13,7 @@ Function Invoke-ListGenericTestFunction { $APIName = $Request.Params.CIPPEndpoint $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $graphRequest = ($Headers.'x-ms-original-url').split('/api') | Select-Object -First 1 Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 index 86153e7e1fc9..c58a7e6fa28a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 @@ -11,7 +11,10 @@ Function Invoke-ListGraphExplorerPresets { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. $Username = $Request.Headers['x-ms-client-principal-name'] try { diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 index 3d9397b985e4..b221ecab536e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListHaloClients.ps1 @@ -11,12 +11,10 @@ Function Invoke-ListHaloClients { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. try { $Table = Get-CIPPTable -TableName Extensionsconfig @@ -24,17 +22,18 @@ Function Invoke-ListHaloClients { $Token = Get-HaloToken -configuration $Configuration $i = 1 $RawHaloClients = do { - $Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } + $Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($Token.access_token)" } $Result.clients | Select-Object * -ExcludeProperty logo $i++ - $pagecount = [Math]::Ceiling($Result.record_count / 999) - } while ($i -le $pagecount) + $PageCount = [Math]::Ceiling($Result.record_count / 999) + } while ($i -le $PageCount) $HaloClients = $RawHaloClients | ForEach-Object { [PSCustomObject]@{ label = $_.name value = $_.id } } + Write-Host "Found $($HaloClients.Count) Halo Clients" $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 index bf031cfb22a8..8aa2cd88329b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIPWhitelist.ps1 @@ -10,11 +10,16 @@ Function Invoke-ListIPWhitelist { [CmdletBinding()] param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Table = Get-CippTable -tablename 'trustedIps' $body = Get-CIPPAzDataTableEntity @Table + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @($body) }) -} \ No newline at end of file +} diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 index 6e9d14f81319..8856eb60cc17 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneIntents.ps1 @@ -11,14 +11,12 @@ Function Invoke-ListIntuneIntents { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - - - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter + try { $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/Intents?`$expand=settings,categories" -tenantid $TenantFilter $StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 index 0f666d3fce64..e05b3fc83065 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListKnownIPDb.ps1 @@ -11,13 +11,15 @@ Function Invoke-ListKnownIPDb { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' $Table = Get-CIPPTable -TableName 'knownlocationdbv2' - $Filter = "Tenant eq '$($Request.Query.TenantFilter)'" + $Filter = "Tenant eq '$($TenantFilter)'" $KnownIPDb = Get-CIPPAzDataTableEntity @Table -Filter $Filter # Associate values to output bindings by calling 'Push-OutputBinding'. diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 index c6fc0c2a88ac..34f4009c8d1d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListLogs.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListLogs { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CIPPTable diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 index a683b78a8347..a89fcdff7068 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNamedLocations.ps1 @@ -11,11 +11,11 @@ Function Invoke-ListNamedLocations { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.TenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 index 4d991c9d466a..0017c80b4101 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListNotificationConfig.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListNotificationConfig { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $Table = Get-CIPPTable -TableName SchedulerConfig $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 index e94737a79274..b7f08c601f60 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListOrg.ps1 @@ -11,16 +11,14 @@ Function Invoke-ListOrg { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter if ($TenantFilter -eq 'AllTenants') { - + $GraphRequest = @() } else { $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/organization' -tenantid $TenantFilter } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 index 927d63b7067e..2b95b674be96 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPartnerRelationships.ps1 @@ -11,29 +11,33 @@ Function Invoke-ListPartnerRelationships { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Query.tenantFilter try { $GraphRequestList = @{ Endpoint = 'policies/crossTenantAccessPolicy/partners' - TenantFilter = $Request.Query.TenantFilter + TenantFilter = $TenantFilter QueueNameOverride = 'Partner Relationships' ReverseTenantLookup = $true } $GraphRequest = Get-GraphRequestList @GraphRequestList + $StatusCode = [HttpStatusCode]::OK } catch { $GraphRequest = @() + $StatusCode = [HttpStatusCode]::Forbidden } - $StatusCode = [HttpStatusCode]::OK - $results = [PSCustomObject]@{ + $Results = [PSCustomObject]@{ Results = @($GraphRequest) } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode - Body = $results + Body = $Results }) - } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 index e344ac10776e..78409b41c31f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPendingWebhooks.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListPendingWebhooks { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { $Table = Get-CIPPTable -TableName 'WebhookIncoming' diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 index 0d95d6bffb71..56636a02deb0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListPotentialApps.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListPotentialApps { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' if ($request.body.type -eq 'WinGet') { $body = @" @@ -20,8 +21,8 @@ Function Invoke-ListPotentialApps { $DataRequest = (Invoke-RestMethod -Uri 'https://storeedgefd.dsx.mp.microsoft.com/v9.0/manifestSearch' -Method POST -Body $body -ContentType 'Application/json').data | Select-Object @{l = 'applicationName'; e = { $_.packagename } }, @{l = 'packagename'; e = { $_.packageIdentifier } } | Sort-Object -Property applicationName } - if ($Request.body.type -eq 'Choco') { - $DataRequest = Invoke-RestMethod -Uri "https://community.chocolatey.org/api/v2/Search()?`$filter=IsLatestVersion&`$skip=0&`$top=999&searchTerm=%27$($request.body.SearchString)%27&targetFramework=%27%27&includePrerelease=false" -ContentType 'application/json' | Select-Object @{l = 'applicationName'; e = { $_.properties.Title } }, @{l = 'packagename'; e = { $_.title.'#text' } } | Sort-Object -Property applicationName + if ($Request.Body.type -eq 'Choco') { + $DataRequest = Invoke-RestMethod -Uri "https://community.chocolatey.org/api/v2/Search()?`$filter=IsLatestVersion&`$skip=0&`$top=999&searchTerm=%27$($Request.Body.SearchString)%27&targetFramework=%27%27&includePrerelease=false" -ContentType 'application/json' | Select-Object @{l = 'applicationName'; e = { $_.properties.Title } }, @{l = 'packagename'; e = { $_.title.'#text' } } | Sort-Object -Property applicationName } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 index 6d57f2daa1f9..612b4ecffd5d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListRoles.ps1 @@ -11,20 +11,18 @@ Function Invoke-ListRoles { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - # Write to the Azure Functions log stream. - Write-Host 'PowerShell HTTP trigger function processed a request.' - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter $SelectList = 'id', 'displayName', 'userPrincipalName' [System.Collections.Generic.List[PSCustomObject]]$Roles = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/directoryRoles?`$expand=members" -tenantid $TenantFilter $GraphRequest = foreach ($Role in $Roles) { - #[System.Collections.Generic.List[PSCustomObject]]$Members = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles/$($Role.id)/members?`$select=$($selectlist -join ',')" -tenantid $TenantFilter | Select-Object $SelectList + #[System.Collections.Generic.List[PSCustomObject]]$Members = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles/$($Role.id)/members?`$select=$($SelectList -join ',')" -tenantid $TenantFilter | Select-Object $SelectList $Members = if ($Role.members) { $role.members | ForEach-Object { " $($_.displayName) ($($_.userPrincipalName))" } } else { 'none' } [PSCustomObject]@{ DisplayName = $Role.displayName diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 index 84c536889682..13896c11c0d5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListTenantAllowBlockList.ps1 @@ -11,7 +11,8 @@ Function Invoke-ListTenantAllowBlockList { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 index 70b4d553949b..fab7f0297698 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-RemoveTenantAllowBlockList.ps1 @@ -11,11 +11,11 @@ Function Invoke-RemoveTenantAllowBlockList { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - $TenantFilter = $Request.Body.tenantFilter $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # Interact with query parameters or the body of the request. + $TenantFilter = $Request.Body.tenantFilter $Entries = $Request.Body.Entries $ListType = $Request.Body.ListType diff --git a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 index 4cbe632f33f3..6c80a2c62572 100644 --- a/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 +++ b/Modules/CIPPCore/Public/Invoke-RemoveQueuedApp.ps1 @@ -11,7 +11,8 @@ Function Invoke-RemoveQueuedApp { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -Headers $Request.Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' $ID = $request.body.ID try { diff --git a/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 b/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 index 9c56fd9dcbaf..f4462cb8217a 100644 --- a/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Invoke-RemoveWebhookAlert.ps1 @@ -11,7 +11,8 @@ Function Invoke-RemoveWebhookAlert { param($Request, $TriggerMetadata) $APIName = $Request.Params.CIPPEndpoint - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' try { $WebhookTable = Get-CIPPTable -TableName 'SchedulerConfig' From e7f14915c636c9a5868c4b1b203fa44a8471eace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 20 Mar 2025 16:58:30 +0100 Subject: [PATCH 003/123] fix: Update DisplayName assignment to fallback on ID if not provided --- .../Identity/Administration/Users/Invoke-ExecResetPass.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 index 10a8013fec5c..11fed934022b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecResetPass.ps1 @@ -18,7 +18,7 @@ Function Invoke-ExecResetPass { # Interact with query parameters or the body of the request. $TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter $ID = $Request.Query.ID ?? $Request.Body.ID - $DisplayName = $Request.Query.displayName ?? $Request.Body.displayName + $DisplayName = $Request.Query.displayName ?? $Request.Body.displayName ?? $ID $MustChange = $Request.Query.MustChange ?? $Request.Body.MustChange $MustChange = [System.Convert]::ToBoolean($MustChange) From 8fbad8369c8f691f0476e93c1eefa1dd02556a3f Mon Sep 17 00:00:00 2001 From: Esco Date: Thu, 27 Mar 2025 14:35:20 +0100 Subject: [PATCH 004/123] feat: Phishing Simulation Configuration standard cleanup crew Update Comment cleanup variables --- ...Invoke-CIPPStandardPhishingSimulations.ps1 | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 new file mode 100644 index 000000000000..557c0d06e60f --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 @@ -0,0 +1,174 @@ +function Invoke-CIPPStandardPhishingSimulations { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) PhishingSimulations + .SYNOPSIS + (Label) Phishing Simulation Configuration + .DESCRIPTION + (Helptext) This creates a phishing simulation policy that enables phishing simulations for the entire tenant. + (DocsDescription) This creates a phishing simulation policy that enables phishing simulations for the entire tenant. + .NOTES + CAT + Defender Standards + TAG + ADDEDCOMPONENT + {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Domains","name":"standards.PhishingSimulations.Domains"} + {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Sender IP Ranges","name":"standards.PhishingSimulations.SenderIpRanges"} + {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Urls","name":"standards.PhishingSimulations.PhishingSimUrls"} + IMPACT + Medium Impact + ADDEDDATE + 2025-03-27 + POWERSHELLEQUIVALENT + New-TenantAllowBlockListItems, New-PhishSimOverridePolicy and New-ExoPhishSimOverrideRule + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/list-standards/defender-standards#medium-impact + #> + + param($Tenant, $Settings) + $PolicyName = 'CIPPPhishSim' + + # Fetch current Phishing Simulations Policy settings and ensure it is correctly configured + $PolicyState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-PhishSimOverridePolicy' | + Where-Object -Property Name -EQ 'PhishSimOverridePolicy' | + Select-Object -Property Identity,Name,Mode,Enabled + + $PolicyIsCorrect = ($PolicyState.Name -eq 'PhishSimOverridePolicy') -and ($PolicyState.Enabled -eq $true) + + # Fetch current Phishing Simulations Policy Rule settings and ensure it is correctly configured + $RuleState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-ExoPhishSimOverrideRule' | + Select-Object -Property Identity,Name,SenderIpRanges,Domains,SenderDomainIs + + [String[]]$AddSenderIpRanges = $Settings.SenderIpRanges.value | Where-Object { $_ -notin $RuleState.SenderIpRanges } + [String[]]$RemoveSenderIpRanges = $RuleState.SenderIpRanges | Where-Object { $_ -notin $Settings.SenderIpRanges.value } + + [String[]]$AddDomains = $Settings.Domains.value | Where-Object { $_ -notin $RuleState.Domains } + [String[]]$RemoveDomains = $RuleState.Domains | Where-Object { $_ -notin $Settings.Domains.value } + + $RuleIsCorrect = ($RuleState.Name -like "*PhishSimOverr*") -and + ($AddSenderIpRanges.Count -eq 0 -and $RemoveSenderIpRanges.Count -eq 0) -and + ($AddDomains.Count -eq 0 -and $RemoveDomains.Count -eq 0) + + # Fetch current Phishing Simulations URLs and ensure it is correctly configured + $SimUrlState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-TenantAllowBlockListItems' -cmdParams @{ListType = 'Url'; ListSubType = 'AdvancedDelivery'} | + Select-Object -Property Value + + [String[]]$AddEntries = $Settings.PhishingSimUrls.value | Where-Object { $_ -notin $SimUrlState.value } + [String[]]$RemoveEntries = $SimUrlState.value | Where-Object { $_ -notin $Settings.PhishingSimUrls.value } + + $PhishingSimUrlsIsCorrect = ($AddEntries.Count -eq 0 -and $RemoveEntries.Count -eq 0) + + # Check state for all components + $StateIsCorrect = $PolicyIsCorrect -and $RuleIsCorrect -and $PhishingSimUrlsIsCorrect + + If ($Settings.remediate -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Advanced Phishing Simulations already correctly configured' -sev Info + } Else { + # Remedidate incorrect Phishing Simulations Policy + If ($PolicyIsCorrect -eq $false) { + If ($PolicyState.Name -eq 'PhishSimOverridePolicy') { + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'Set-PhishSimOverridePolicy' -cmdParams @{Identity = $PolicyName; Enabled = $true} + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Enabled Phishing Simulation override policy." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to enable Phishing Simulation override policy." -sev Error -LogData $_ + } + } Else { + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'New-PhishSimOverridePolicy' -cmdParams @{Name = $PolicyName; Enabled = $true} + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Created Phishing Simulation override policy." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Phishing Simulation override policy." -sev Error -LogData $_ + } + } + } + + # Remedidate incorrect Phishing Simulations Policy Rule + If ($RuleIsCorrect -eq $false) { + If ($RuleState.Name -like "*PhishSimOverr*") { + $cmdParams = @{ + Identity = $RuleState.Identity + AddSenderIpRanges = $AddSenderIpRanges + AddDomains = $AddDomains + RemoveSenderIpRanges = $RemoveSenderIpRanges + RemoveDomains = $RemoveDomains + } + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'Set-ExoPhishSimOverrideRule' -cmdParams $cmdParams + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Updated Phishing Simulation override rule." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to update Phishing Simulation override rule." -sev Error -LogData $_ + } + } Else { + $cmdParams = @{ + Name = $PolicyName + Policy = 'PhishSimOverridePolicy' + SenderIpRanges = $Settings.SenderIpRanges.value + Domains = $Settings.Domains.value + } + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'New-ExoPhishSimOverrideRule' -cmdParams $cmdParams + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Created Phishing Simulation override rule." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to create Phishing Simulation override rule." -sev Error -LogData $_ + } + } + } + + # Remedidate incorrect Phishing Simulations URLs + If ($PhishingSimUrlsIsCorrect -eq $false) { + $cmdParams = @{ + ListType = 'Url' + ListSubType = 'AdvancedDelivery' + } + # Remove entries that are not in the settings + If ($RemoveEntries.Count -gt 0) { + $cmdParams.Entries = $RemoveEntries + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'Remove-TenantAllowBlockListItems' -cmdParams $cmdParams + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Removed Phishing Simulation URLs from Allowlist." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to remove Phishing Simulation URLs from Allowlist." -sev Error -LogData $_ + } + } + # Add entries that are in the settings + If ($AddEntries.Count -gt 0) { + $cmdParams.Entries = $AddEntries + $cmdParams.NoExpiration = $true + $cmdParams.Allow = $true + Try { + $null = New-ExoRequest -TenantId $Tenant -cmdlet 'New-TenantAllowBlockListItems' -cmdParams $cmdParams + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Added Phishing Simulation URLs to Allowlist." -sev Info + } Catch { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message "Failed to add Phishing Simulation URLs to Allowlist." -sev Error -LogData $_ + } + } + } + } + } + + If ($Settings.alert -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Phishing Simulation Configuration is correctly configured' -sev Info + } Else { + Write-StandardsAlert -message 'Phishing Simulation Configuration is not correctly configured' -object $CurrentState -tenant $Tenant -standardName 'PhishingSimulations' -standardId $Settings.standardId + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Phishing Simulation Configuration is not correctly configured' -sev Info + } + } + + If ($Settings.report -eq $true) { + Add-CIPPBPAField -FieldName 'PhishingSimulations' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $Tenant + If ($StateIsCorrect -eq $true) { + $FieldValue = $true + } Else { + $FieldValue = $CurrentState ? $CurrentState : $false + } + Set-CIPPStandardsCompareField -FieldName 'standards.PhishingSimulations' -FieldValue $FieldValue -Tenant $Tenant + } +} From c08581bd875e8bee6e449b2e4912303fce554992 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 29 Mar 2025 14:31:03 -0400 Subject: [PATCH 005/123] fix all tenants requests --- .../Graph Requests/Push-ListGraphRequestQueue.ps1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 6249f4cde350..dc7c33e94bd5 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 @@ -40,12 +40,16 @@ function Push-ListGraphRequestQueue { $RawGraphRequest = try { $Results = Get-GraphRequestList @GraphRequestParams - $Results | Select-Object -First ($Results.Count - 1) + if ($Results[-1].PSObject.Properties.Name -contains 'nextLink') { + $Results | Select-Object -First ($Results.Count - 1) + } else { + $Results + } } catch { $CippException = Get-CippException -Exception $_.Exception [PSCustomObject]@{ - Tenant = $Item.TenantFilter - CippStatus = "Could not connect to tenant. $($CippException.NormalizedMessage)" + Tenant = $Item.TenantFilter + CippStatus = "Could not connect to tenant. $($CippException.NormalizedMessage)" CippException = [string]($CippException | ConvertTo-Json -Depth 10 -Compress) } } From 59ba35165bc0f09ecbcfc03cabec1ec352966a89 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:18:55 +0200 Subject: [PATCH 006/123] temporary logging for corrupt template issue --- .../Invoke-CIPPStandardIntuneTemplate.ps1 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index e92923d38336..6d6f76537bd5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -35,22 +35,30 @@ function Invoke-CIPPStandardIntuneTemplate { $Table = Get-CippTable -tablename 'templates' $Filter = "PartitionKey eq 'IntuneTemplate'" $Request = @{body = $null } - + Write-Host "IntuneTemplate: Starting process. Settings are: $($Settings | ConvertTo-Json -Compress)" $CompareList = foreach ($Template in $Settings) { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Trying to find template" $Request.body = (Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object -Property RowKey -Like "$($Template.TemplateList.value)*").JSON | ConvertFrom-Json -ErrorAction SilentlyContinue if ($Request.body -eq $null) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to find template $($Template.TemplateList.value). Has this Intune Template been deleted?" -sev 'Error' continue } + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Got template." + $displayname = $request.body.Displayname $description = $request.body.Description $RawJSON = $Request.body.RawJSON - $ExistingPolicy = Get-CIPPIntunePolicy -tenantFilter $Tenant -DisplayName $displayname -TemplateType $Request.body.Type + try { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Grabbing existing Policy" + $ExistingPolicy = Get-CIPPIntunePolicy -tenantFilter $Tenant -DisplayName $displayname -TemplateType $Request.body.Type + } catch { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Failed to get existing." + } if ($ExistingPolicy) { $RawJSON = Get-CIPPTextReplacement -Text $RawJSON -TenantFilter $Tenant - $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json + $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json -ErrorAction SilentlyContinue $JSONTemplate = $RawJSON | ConvertFrom-Json - $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type + $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type -ErrorAction SilentlyContinue } if ($Compare) { [PSCustomObject]@{ @@ -86,7 +94,7 @@ function Invoke-CIPPStandardIntuneTemplate { If ($true -in $Settings.remediate) { Write-Host 'starting template deploy' foreach ($TemplateFile in $CompareList | Where-Object -Property remediate -EQ $true) { - Write-Host "working on template deploy: $($Template.displayname)" + Write-Host "working on template deploy: $($TemplateFile.displayname)" try { $TemplateFile.customGroup ? ($TemplateFile.AssignTo = $TemplateFile.customGroup) : $null Set-CIPPIntunePolicy -TemplateType $TemplateFile.body.Type -Description $TemplateFile.description -DisplayName $TemplateFile.displayname -RawJSON $templateFile.rawJSON -AssignTo $TemplateFile.AssignTo -ExcludeGroup $TemplateFile.excludeGroup -tenantFilter $Tenant From 8c19b76d032582ad123ae155879603263b5f14e7 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:20:00 +0200 Subject: [PATCH 007/123] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/dev_cipp27qz5.yml | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/dev_cipp27qz5.yml diff --git a/.github/workflows/dev_cipp27qz5.yml b/.github/workflows/dev_cipp27qz5.yml new file mode 100644 index 000000000000..21c946480ac0 --- /dev/null +++ b/.github/workflows/dev_cipp27qz5.yml @@ -0,0 +1,30 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cipp27qz5 + +on: + push: + branches: + - dev + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: windows-latest + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cipp27qz5' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_821C9A2723884E2E85AC262B12EB26F7 }} \ No newline at end of file From db36ca0645af254ee01d19831f30aeea80495cd2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:40:23 +0200 Subject: [PATCH 008/123] test --- .../Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index 6d6f76537bd5..6bb9c5496c46 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -55,12 +55,16 @@ function Invoke-CIPPStandardIntuneTemplate { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Failed to get existing." } if ($ExistingPolicy) { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Found existing policy." $RawJSON = Get-CIPPTextReplacement -Text $RawJSON -TenantFilter $Tenant $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json -ErrorAction SilentlyContinue $JSONTemplate = $RawJSON | ConvertFrom-Json $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type -ErrorAction SilentlyContinue + } else { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - No existing policy found." } if ($Compare) { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Compare found differences." [PSCustomObject]@{ MatchFailed = $true displayname = $displayname @@ -75,6 +79,7 @@ function Invoke-CIPPStandardIntuneTemplate { templateId = $Template.TemplateList.value } } else { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - No differences found." [PSCustomObject]@{ MatchFailed = $false displayname = $displayname From e990bc3c25ad8591360ba8d7f66e4daf621f07ab Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:50:50 +0200 Subject: [PATCH 009/123] more logging --- .../Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index 6bb9c5496c46..345f7b8b99c7 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -57,9 +57,14 @@ function Invoke-CIPPStandardIntuneTemplate { if ($ExistingPolicy) { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Found existing policy." $RawJSON = Get-CIPPTextReplacement -Text $RawJSON -TenantFilter $Tenant + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Grabbing JSON existing." $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json -ErrorAction SilentlyContinue + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Got existing JSON. Converting RawJSON to Template" $JSONTemplate = $RawJSON | ConvertFrom-Json + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Converted RawJSON to Template." + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Comparing JSON." $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type -ErrorAction SilentlyContinue + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Compared JSON: $($Compare | ConvertTo-Json -Compress)" } else { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - No existing policy found." } From dcedfe38ecfd4a77c18e38cd84a2a9a116dd7f6a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 14:05:21 +0200 Subject: [PATCH 010/123] logs --- .../Invoke-CIPPStandardIntuneTemplate.ps1 | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index 345f7b8b99c7..dbe976dcc67a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -55,15 +55,19 @@ function Invoke-CIPPStandardIntuneTemplate { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Failed to get existing." } if ($ExistingPolicy) { - Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Found existing policy." - $RawJSON = Get-CIPPTextReplacement -Text $RawJSON -TenantFilter $Tenant - Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Grabbing JSON existing." - $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json -ErrorAction SilentlyContinue - Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Got existing JSON. Converting RawJSON to Template" - $JSONTemplate = $RawJSON | ConvertFrom-Json - Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Converted RawJSON to Template." - Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Comparing JSON." - $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type -ErrorAction SilentlyContinue + try { + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Found existing policy." + $RawJSON = Get-CIPPTextReplacement -Text $RawJSON -TenantFilter $Tenant + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Grabbing JSON existing." + $JSONExistingPolicy = $ExistingPolicy.cippconfiguration | ConvertFrom-Json + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Got existing JSON. Converting RawJSON to Template" + $JSONTemplate = $RawJSON | ConvertFrom-Json + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Converted RawJSON to Template." + Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Comparing JSON." + $Compare = Compare-CIPPIntuneObject -ReferenceObject $JSONTemplate -DifferenceObject $JSONExistingPolicy -compareType $Request.body.Type -ErrorAction SilentlyContinue + } catch { + Write-Host "The compare failed. The error was: $($_.Exception.Message)" + } Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Compared JSON: $($Compare | ConvertTo-Json -Compress)" } else { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - No existing policy found." From 642873aeeab211acbc6f2006add6350d4942298f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 14:19:33 +0200 Subject: [PATCH 011/123] fixes to compares --- .../Public/Compare-CIPPIntuneObject.ps1 | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/Modules/CIPPCore/Public/Compare-CIPPIntuneObject.ps1 b/Modules/CIPPCore/Public/Compare-CIPPIntuneObject.ps1 index 5b08e91ebe79..03041d90cfa7 100644 --- a/Modules/CIPPCore/Public/Compare-CIPPIntuneObject.ps1 +++ b/Modules/CIPPCore/Public/Compare-CIPPIntuneObject.ps1 @@ -69,8 +69,8 @@ function Compare-CIPPIntuneObject { [string]$PropertyName ) return ($PropertyName -like '*@OData*' -or - $PropertyName -like '#microsoft.graph*' -or - $excludeProps -contains $PropertyName) + $PropertyName -like '#microsoft.graph*' -or + $excludeProps -contains $PropertyName) } # Recursive function to compare objects deeply @@ -83,7 +83,7 @@ function Compare-CIPPIntuneObject { $Object2, [Parameter(Mandatory = $false)] - [string]$PropertyPath = "" + [string]$PropertyPath = '' ) # If both objects are null or empty, they're equal @@ -94,20 +94,20 @@ function Compare-CIPPIntuneObject { # If one object is null but the other isn't, they're different if (($null -eq $Object1 -or $Object1 -eq '') -xor ($null -eq $Object2 -or $Object2 -eq '')) { $result.Add([PSCustomObject]@{ - Property = $PropertyPath - ExpectedValue = if ($null -eq $Object1) { '' } else { $Object1 } - ReceivedValue = if ($null -eq $Object2) { '' } else { $Object2 } - }) + Property = $PropertyPath + ExpectedValue = if ($null -eq $Object1) { '' } else { $Object1 } + ReceivedValue = if ($null -eq $Object2) { '' } else { $Object2 } + }) return } # If objects are of different types, they're different if ($Object1.GetType() -ne $Object2.GetType()) { $result.Add([PSCustomObject]@{ - Property = $PropertyPath - ExpectedValue = $Object1 - ReceivedValue = $Object2 - }) + Property = $PropertyPath + ExpectedValue = $Object1 + ReceivedValue = $Object2 + }) return } @@ -122,25 +122,25 @@ function Compare-CIPPIntuneObject { $newPath = if ($PropertyPath) { "$PropertyPath.$key" } else { $key } if ($Object1.ContainsKey($key) -and $Object2.ContainsKey($key)) { - Compare-ObjectsRecursively -Object1 $Object1[$key] -Object2 $Object2[$key] -PropertyPath $newPath - } - elseif ($Object1.ContainsKey($key)) { + #only run if both props are not null + if ($Object1[$key] -and $Object2[$key]) { + Compare-ObjectsRecursively -Object1 $Object1[$key] -Object2 $Object2[$key] -PropertyPath $newPath + } + } elseif ($Object1.ContainsKey($key)) { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = $Object1[$key] - ReceivedValue = '' - }) - } - else { + Property = $newPath + ExpectedValue = $Object1[$key] + ReceivedValue = '' + }) + } else { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = '' - ReceivedValue = $Object2[$key] - }) + Property = $newPath + ExpectedValue = '' + ReceivedValue = $Object2[$key] + }) } } - } - elseif ($Object1 -is [Array] -or $Object1 -is [System.Collections.IList]) { + } elseif ($Object1 -is [Array] -or $Object1 -is [System.Collections.IList]) { # Compare arrays $maxLength = [Math]::Max($Object1.Count, $Object2.Count) @@ -149,24 +149,21 @@ function Compare-CIPPIntuneObject { if ($i -lt $Object1.Count -and $i -lt $Object2.Count) { Compare-ObjectsRecursively -Object1 $Object1[$i] -Object2 $Object2[$i] -PropertyPath $newPath - } - elseif ($i -lt $Object1.Count) { + } elseif ($i -lt $Object1.Count) { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = $Object1[$i] - ReceivedValue = '' - }) - } - else { + Property = $newPath + ExpectedValue = $Object1[$i] + ReceivedValue = '' + }) + } else { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = '' - ReceivedValue = $Object2[$i] - }) + Property = $newPath + ExpectedValue = '' + ReceivedValue = $Object2[$i] + }) } } - } - elseif ($Object1 -is [PSCustomObject] -or $Object1.PSObject.Properties.Count -gt 0) { + } elseif ($Object1 -is [PSCustomObject] -or $Object1.PSObject.Properties.Count -gt 0) { # Compare PSCustomObjects or objects with properties $allPropertyNames = @( $Object1.PSObject.Properties | Select-Object -ExpandProperty Name @@ -181,35 +178,35 @@ function Compare-CIPPIntuneObject { $prop2Exists = $Object2.PSObject.Properties.Name -contains $propName if ($prop1Exists -and $prop2Exists) { - Compare-ObjectsRecursively -Object1 $Object1.$propName -Object2 $Object2.$propName -PropertyPath $newPath - } - elseif ($prop1Exists) { + #only run if both props are not null + if ($Object1.$propName -and $Object2.$propName) { + Compare-ObjectsRecursively -Object1 $Object1.$propName -Object2 $Object2.$propName -PropertyPath $newPath + } + } elseif ($prop1Exists) { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = $Object1.$propName - ReceivedValue = '' - }) - } - else { + Property = $newPath + ExpectedValue = $Object1.$propName + ReceivedValue = '' + }) + } else { $result.Add([PSCustomObject]@{ - Property = $newPath - ExpectedValue = '' - ReceivedValue = $Object2.$propName - }) + Property = $newPath + ExpectedValue = '' + ReceivedValue = $Object2.$propName + }) } } - } - else { + } else { # Compare primitive values $val1 = $Object1.ToString() $val2 = $Object2.ToString() if ($val1 -ne $val2) { $result.Add([PSCustomObject]@{ - Property = $PropertyPath - ExpectedValue = $val1 - ReceivedValue = $val2 - }) + Property = $PropertyPath + ExpectedValue = $val1 + ReceivedValue = $val2 + }) } } } @@ -228,7 +225,10 @@ function Compare-CIPPIntuneObject { } # Start the recursive comparison - Compare-ObjectsRecursively -Object1 $obj1 -Object2 $obj2 + #only do the compare if the objects are not null + if ($obj1 -and $obj2) { + Compare-ObjectsRecursively -Object1 $obj1 -Object2 $obj2 + } # If no differences found, return null if ($result.Count -eq 0) { From f55390555db0d667dcca4b68d12e7530790cf75d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 09:25:31 -0400 Subject: [PATCH 012/123] fix capabilitylevel --- .../Standards/Invoke-CIPPStandardsharingCapability.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 index 4dc839781766..60f6fe4d9ea4 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 @@ -70,13 +70,18 @@ function Invoke-CIPPStandardsharingCapability { } if ($Settings.alert -eq $true) { - if ($CurrentInfo.sharingCapability -eq $level) { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Sharing level is set to $level" -sev Info - $FieldValue = $true } else { Write-StandardsAlert -message "Sharing level is not set to $level" -object $CurrentInfo -tenant $Tenant -standardName 'sharingCapability' -standardId $Settings.standardId Write-LogMessage -API 'Standards' -tenant $Tenant -message "Sharing level is not set to $level" -sev Info + } + } + + if ($Settings.report -eq $true) { + if ($CurrentInfo.sharingCapability -eq $level) { + $FieldValue = $true + } else { $FieldValue = $CurrentInfo | Select-Object -Property sharingCapability } Set-CIPPStandardsCompareField -FieldName 'standards.sharingCapability' -FieldValue $FieldValue -Tenant $Tenant From 665a3f9bf148ba64cc20ffe4d5e5e95a12a80b96 Mon Sep 17 00:00:00 2001 From: Esco Date: Mon, 31 Mar 2025 17:07:34 +0200 Subject: [PATCH 013/123] fix: TemplateEmail.html case sensitivity --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index abd0b6b3604b..34ae4f5ce9d8 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -12,7 +12,7 @@ function New-CIPPAlertTemplate { $AuditLogLink ) $Appname = '[{"Application Name":"ACOM Azure Website","Application IDs":"23523755-3a2b-41ca-9315-f81f3f566a95"},{"Application Name":"AEM-DualAuth","Application IDs":"69893ee3-dd10-4b1c-832d-4870354be3d8"},{"Application Name":"ASM Campaign Servicing","Application IDs":"0cb7b9ec-5336-483b-bc31-b15b5788de71"},{"Application Name":"Azure Advanced Threat Protection","Application IDs":"7b7531ad-5926-4f2d-8a1d-38495ad33e17"},{"Application Name":"Azure Data Lake","Application IDs":"e9f49c6b-5ce5-44c8-925d-015017e9f7ad"},{"Application Name":"Azure Lab Services Portal","Application IDs":"835b2a73-6e10-4aa5-a979-21dfda45231c"},{"Application Name":"Azure Portal","Application IDs":"c44b4083-3bb0-49c1-b47d-974e53cbdf3c"},{"Application Name":"AzureSupportCenter","Application IDs":"37182072-3c9c-4f6a-a4b3-b3f91cacffce"},{"Application Name":"Bing","Application IDs":"9ea1ad79-fdb6-4f9a-8bc3-2b70f96e34c7"},{"Application Name":"CPIM Service","Application IDs":"bb2a2e3a-c5e7-4f0a-88e0-8e01fd3fc1f4"},{"Application Name":"CRM Power BI Integration","Application IDs":"e64aa8bc-8eb4-40e2-898b-cf261a25954f"},{"Application Name":"Dataverse","Application IDs":"00000007-0000-0000-c000-000000000000"},{"Application Name":"Enterprise Roaming and Backup","Application IDs":"60c8bde5-3167-4f92-8fdb-059f6176dc0f"},{"Application Name":"IAM Supportability","Application IDs":"a57aca87-cbc0-4f3c-8b9e-dc095fdc8978"},{"Application Name":"IrisSelectionFrontDoor","Application IDs":"16aeb910-ce68-41d1-9ac3-9e1673ac9575"},{"Application Name":"MCAPI Authorization Prod","Application IDs":"d73f4b35-55c9-48c7-8b10-651f6f2acb2e"},{"Application Name":"Media Analysis and Transformation Service","Application IDs":"944f0bd1-117b-4b1c-af26-804ed95e767e
0cd196ee-71bf-4fd6-a57c-b491ffd4fb1e"},{"Application Name":"Microsoft 365 Support Service","Application IDs":"ee272b19-4411-433f-8f28-5c13cb6fd407"},{"Application Name":"Microsoft App Access Panel","Application IDs":"0000000c-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Approval Management","Application IDs":"65d91a3d-ab74-42e6-8a2f-0add61688c74
38049638-cc2c-4cde-abe4-4479d721ed44"},{"Application Name":"Microsoft Authentication Broker","Application IDs":"29d9ed98-a469-4536-ade2-f981bc1d605e"},{"Application Name":"Microsoft Azure CLI","Application IDs":"04b07795-8ddb-461a-bbee-02f9e1bf7b46"},{"Application Name":"Microsoft Azure PowerShell","Application IDs":"1950a258-227b-4e31-a9cf-717495945fc2"},{"Application Name":"Microsoft Bing Search","Application IDs":"cf36b471-5b44-428c-9ce7-313bf84528de"},{"Application Name":"Microsoft Bing Search for Microsoft Edge","Application IDs":"2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8"},{"Application Name":"Microsoft Bing Default Search Engine","Application IDs":"1786c5ed-9644-47b2-8aa0-7201292175b6"},{"Application Name":"Microsoft Defender for Cloud Apps","Application IDs":"3090ab82-f1c1-4cdf-af2c-5d7a6f3e2cc7"},{"Application Name":"Microsoft Docs","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Dynamics ERP","Application IDs":"00000015-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Edge Insider Addons Prod","Application IDs":"6253bca8-faf2-4587-8f2f-b056d80998a7"},{"Application Name":"Microsoft Exchange Online Protection","Application IDs":"00000007-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Forms","Application IDs":"c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"},{"Application Name":"Microsoft Graph","Application IDs":"00000003-0000-0000-c000-000000000000"},{"Application Name":"Microsoft Intune Web Company Portal","Application IDs":"74bcdadc-2fdc-4bb3-8459-76d06952a0e9"},{"Application Name":"Microsoft Intune Windows Agent","Application IDs":"fc0f3af4-6835-4174-b806-f7db311fd2f3"},{"Application Name":"Microsoft Learn","Application IDs":"18fbca16-2224-45f6-85b0-f7bf2b39b3f3"},{"Application Name":"Microsoft Office","Application IDs":"d3590ed6-52b3-4102-aeff-aad2292ab01c"},{"Application Name":"Microsoft Office 365 Portal","Application IDs":"00000006-0000-0ff1-ce00-000000000000"},{"Application Name":"Microsoft Office Web Apps Service","Application IDs":"67e3df25-268a-4324-a550-0de1c7f97287"},{"Application Name":"Microsoft Online Syndication Partner Portal","Application IDs":"d176f6e7-38e5-40c9-8a78-3998aab820e7"},{"Application Name":"Microsoft password reset service","Application IDs":"93625bc8-bfe2-437a-97e0-3d0060024faa"},{"Application Name":"Microsoft Power BI","Application IDs":"871c010f-5e61-4fb1-83ac-98610a7e9110"},{"Application Name":"Microsoft Storefronts","Application IDs":"28b567f6-162c-4f54-99a0-6887f387bbcc"},{"Application Name":"Microsoft Stream Portal","Application IDs":"cf53fce8-def6-4aeb-8d30-b158e7b1cf83"},{"Application Name":"Microsoft Substrate Management","Application IDs":"98db8bd6-0cc0-4e67-9de5-f187f1cd1b41"},{"Application Name":"Microsoft Support","Application IDs":"fdf9885b-dd37-42bf-82e5-c3129ef5a302"},{"Application Name":"Microsoft Teams","Application IDs":"1fec8e78-bce4-4aaf-ab1b-5451cc387264"},{"Application Name":"Microsoft Teams Services","Application IDs":"cc15fd57-2c6c-4117-a88c-83b1d56b4bbe"},{"Application Name":"Microsoft Teams Web Client","Application IDs":"5e3ce6c0-2b1f-4285-8d4b-75ee78787346"},{"Application Name":"Microsoft Whiteboard Services","Application IDs":"95de633a-083e-42f5-b444-a4295d8e9314"},{"Application Name":"O365 Suite UX","Application IDs":"4345a7b9-9a63-4910-a426-35363201d503"},{"Application Name":"Office 365 Exchange Online","Application IDs":"00000002-0000-0ff1-ce00-000000000000"},{"Application Name":"Office 365 Management","Application IDs":"00b41c95-dab0-4487-9791-b9d2c32c80f2"},{"Application Name":"Office 365 Search Service","Application IDs":"66a88757-258c-4c72-893c-3e8bed4d6899"},{"Application Name":"Office 365 SharePoint Online","Application IDs":"00000003-0000-0ff1-ce00-000000000000"},{"Application Name":"Office Delve","Application IDs":"94c63fef-13a3-47bc-8074-75af8c65887a"},{"Application Name":"Office Online Add-in SSO","Application IDs":"93d53678-613d-4013-afc1-62e9e444a0a5"},{"Application Name":"Office Online Client AAD- Augmentation Loop","Application IDs":"2abdc806-e091-4495-9b10-b04d93c3f040"},{"Application Name":"Office Online Client AAD- Loki","Application IDs":"b23dd4db-9142-4734-867f-3577f640ad0c"},{"Application Name":"Office Online Client AAD- Maker","Application IDs":"17d5e35f-655b-4fb0-8ae6-86356e9a49f5"},{"Application Name":"Office Online Client MSA- Loki","Application IDs":"b6e69c34-5f1f-4c34-8cdf-7fea120b8670"},{"Application Name":"Office Online Core SSO","Application IDs":"243c63a3-247d-41c5-9d83-7788c43f1c43"},{"Application Name":"Office Online Search","Application IDs":"a9b49b65-0a12-430b-9540-c80b3332c127"},{"Application Name":"Office.com","Application IDs":"4b233688-031c-404b-9a80-a4f3f2351f90"},{"Application Name":"Office365 Shell WCSS-Client","Application IDs":"89bee1f7-5e6e-4d8a-9f3d-ecd601259da7"},{"Application Name":"OfficeClientService","Application IDs":"0f698dd4-f011-4d23-a33e-b36416dcb1e6"},{"Application Name":"OfficeHome","Application IDs":"4765445b-32c6-49b0-83e6-1d93765276ca"},{"Application Name":"OfficeShredderWacClient","Application IDs":"4d5c2d63-cf83-4365-853c-925fd1a64357"},{"Application Name":"OMSOctopiPROD","Application IDs":"62256cef-54c0-4cb4-bcac-4c67989bdc40"},{"Application Name":"OneDrive SyncEngine","Application IDs":"ab9b8c07-8f02-4f72-87fa-80105867a763"},{"Application Name":"OneNote","Application IDs":"2d4d3d8e-2be3-4bef-9f87-7875a61c29de"},{"Application Name":"Outlook Mobile","Application IDs":"27922004-5251-4030-b22d-91ecd9a37ea4"},{"Application Name":"Partner Customer Delegated Admin Offline Processor","Application IDs":"a3475900-ccec-4a69-98f5-a65cd5dc5306"},{"Application Name":"Password Breach Authenticator","Application IDs":"bdd48c81-3a58-4ea9-849c-ebea7f6b6360"},{"Application Name":"Power BI Service","Application IDs":"00000009-0000-0000-c000-000000000000"},{"Application Name":"SharedWithMe","Application IDs":"ffcb16e8-f789-467c-8ce9-f826a080d987"},{"Application Name":"SharePoint Online Web Client Extensibility","Application IDs":"08e18876-6177-487e-b8b5-cf950c1e598c"},{"Application Name":"Signup","Application IDs":"b4bddae8-ab25-483e-8670-df09b9f1d0ea"},{"Application Name":"Skype for Business Online","Application IDs":"00000004-0000-0ff1-ce00-000000000000"},{"Application Name":"Sway","Application IDs":"905fcf26-4eb7-48a0-9ff0-8dcc7194b5ba"},{"Application Name":"Universal Store Native Client","Application IDs":"268761a2-03f3-40df-8a8b-c3db24145b6b"},{"Application Name":"Vortex [wsfed enabled]","Application IDs":"5572c4c0-d078-44ce-b81c-6cbf8d3ed39e"},{"Application Name":"Windows Azure Active Directory","Application IDs":"00000002-0000-0000-c000-000000000000"},{"Application Name":"Windows Azure Service Management API","Application IDs":"797f4846-ba00-4fd7-ba43-dac1f8f63013"},{"Application Name":"WindowsDefenderATP Portal","Application IDs":"a3b79187-70b2-4139-83f9-6016c58cd27b"},{"Application Name":"Windows Search","Application IDs":"26a7ee05-5602-4d76-a7ba-eae8b7b67941"},{"Application Name":"Windows Spotlight","Application IDs":"1b3c667f-cde3-4090-b60b-3d2abd0117f0"},{"Application Name":"Windows Store for Business","Application IDs":"45a330b1-b1ec-4cc1-9161-9f03992aa49f"},{"Application Name":"Yammer","Application IDs":"00000005-0000-0ff1-ce00-000000000000"},{"Application Name":"Yammer Web","Application IDs":"c1c74fed-04c9-4704-80dc-9f79a2e515cb"},{"Application Name":"Yammer Web Embed","Application IDs":"e1ef36fd-b883-4dbf-97f0-9ece4b576fc6"}]' | ConvertFrom-Json | Where-Object -Property 'Application IDs' -EQ $data.applicationId - $HTMLTemplate = Get-Content 'TemplateEmail.HTML' -Raw | Out-String + $HTMLTemplate = Get-Content 'TemplateEmail.html' -Raw | Out-String $Title = '' $IntroText = '' $ButtonUrl = '' From e874499e64950de9401c4cc0f8ebcfbe13616787 Mon Sep 17 00:00:00 2001 From: Esco Date: Mon, 31 Mar 2025 14:49:39 +0200 Subject: [PATCH 014/123] feat: DefaultPlatformRestrictions standard Update Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 Update Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 Update Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 --- ...IPPStandardDefaultPlatformRestrictions.ps1 | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 new file mode 100644 index 000000000000..a29474ce86f9 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDefaultPlatformRestrictions.ps1 @@ -0,0 +1,137 @@ +function Invoke-CIPPStandardDefaultPlatformRestrictions { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) DefaultPlatformRestrictions + .SYNOPSIS + (Label) Device enrollment restrictions + .DESCRIPTION + (Helptext) Sets the default platform restrictions for enrolling devices into Intune. Note: Do not block personally owned if platform is blocked. + (DocsDescription) Sets the default platform restrictions for enrolling devices into Intune. Note: Do not block personally owned if platform is blocked. + .NOTES + CAT + Intune Standards + TAG + ADDEDCOMPONENT + {"type":"switch","name":"standards.DefaultPlatformRestrictions.platformAndroidForWorkBlocked","label":"Block platform Android Enterprise (work profile)","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.personalAndroidForWorkBlocked","label":"Block personally owned Android Enterprise (work profile)","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.platformAndroidBlocked","label":"Block platform Android","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.personalAndroidBlocked","label":"Block personally owned Android","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.platformiOSBlocked","label":"Block platform iOS","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.personaliOSBlocked","label":"Block personally owned iOS","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.platformMacOSBlocked","label":"Block platform macOS","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.personalMacOSBlocked","label":"Block personally owned macOS","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.platformWindowsBlocked","label":"Block platform Windows","default":false} + {"type":"switch","name":"standards.DefaultPlatformRestrictions.personalWindowsBlocked","label":"Block personally owned Windows","default":false} + IMPACT + Low Impact + ADDEDDATE + 2025-04-01 + POWERSHELLEQUIVALENT + Graph API + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/list-standards/intune-standards#low-impact + #> + + param($Tenant, $Settings) + + try { + $CurrentState = New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations?`$expand=assignments&orderBy=priority&`$filter=deviceEnrollmentConfigurationType eq 'SinglePlatformRestriction'" -tenantID $Tenant -AsApp $true | + Select-Object -Property id, androidForWorkRestriction, androidRestriction, iosRestriction, macOSRestriction, windowsRestriction + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Could not get the DefaultPlatformRestrictions for $Tenant. This tenant might not have premium licenses available: $ErrorMessage" -Sev Error + } + + $StateIsCorrect = ($CurrentState.androidForWorkRestriction.platformBlocked -eq $Settings.platformAndroidForWorkBlocked) -and + ($CurrentState.androidForWorkRestriction.personalDeviceEnrollmentBlocked -eq $Settings.personalAndroidForWorkBlocked) -and + ($CurrentState.androidRestriction.platformBlocked -eq $Settings.platformAndroidBlocked) -and + ($CurrentState.androidRestriction.personalDeviceEnrollmentBlocked -eq $Settings.personalAndroidBlocked) -and + ($CurrentState.iosRestriction.platformBlocked -eq $Settings.platformiOSBlocked) -and + ($CurrentState.iosRestriction.personalDeviceEnrollmentBlocked -eq $Settings.personaliOSBlocked) -and + ($CurrentState.macOSRestriction.platformBlocked -eq $Settings.platformMacOSBlocked) -and + ($CurrentState.macOSRestriction.personalDeviceEnrollmentBlocked -eq $Settings.personalMacOSBlocked) -and + ($CurrentState.windowsRestriction.platformBlocked -eq $Settings.platformWindowsBlocked) -and + ($CurrentState.windowsRestriction.personalDeviceEnrollmentBlocked -eq $Settings.personalWindowsBlocked) + + If ($Settings.remediate -eq $true) { + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'DefaultPlatformRestrictions is already applied correctly.' -Sev Info + } else { + $cmdParam = @{ + tenantid = $Tenant + uri = "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations/$($CurrentState.id)" + AsApp = $false + Type = 'PATCH' + ContentType = 'application/json; charset=utf-8' + Body = [PSCustomObject]@{ + "@odata.type" = "#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration" + androidForWorkRestriction = [PSCustomObject]@{ + "@odata.type" = "microsoft.graph.deviceEnrollmentPlatformRestriction" + platformBlocked = $Settings.platformAndroidForWorkBlocked + personalDeviceEnrollmentBlocked = $Settings.personalAndroidForWorkBlocked + } + androidRestriction = [PSCustomObject]@{ + "@odata.type" = "microsoft.graph.deviceEnrollmentPlatformRestriction" + platformBlocked = $Settings.platformAndroidBlocked + personalDeviceEnrollmentBlocked = $Settings.personalAndroidBlocked + } + iosRestriction = [PSCustomObject]@{ + "@odata.type" = "microsoft.graph.deviceEnrollmentPlatformRestriction" + platformBlocked = $Settings.platformiOSBlocked + personalDeviceEnrollmentBlocked = $Settings.personaliOSBlocked + } + macOSRestriction = [PSCustomObject]@{ + "@odata.type" = "microsoft.graph.deviceEnrollmentPlatformRestriction" + platformBlocked = $Settings.platformMacOSBlocked + personalDeviceEnrollmentBlocked = $Settings.personalMacOSBlocked + } + windowsRestriction = [PSCustomObject]@{ + "@odata.type" = "microsoft.graph.deviceEnrollmentPlatformRestriction" + platformBlocked = $Settings.platformWindowsBlocked + personalDeviceEnrollmentBlocked = $Settings.personalWindowsBlocked + } + } | ConvertTo-Json -Compress -Depth 10 + } + try { + $null = New-GraphPostRequest @cmdParam + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully updated DefaultPlatformRestrictions.' -Sev Info + } catch { + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to update DefaultPlatformRestrictions. Error: $($ErrorMessage.NormalizedError)" -Sev Error + } + } + + } + + If ($Settings.alert -eq $true) { + + if ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'DefaultPlatformRestrictions is correctly set.' -Sev Info + } else { + Write-StandardsAlert -message 'DefaultPlatformRestrictions is incorrectly set.' -object $StateIsCorrect -tenant $Tenant -standardName 'DefaultPlatformRestrictions' -standardId $Settings.standardId + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'DefaultPlatformRestrictions is incorrectly set.' -Sev Info + } + } + + If ($Settings.report -eq $true) { + $Table = [PSCustomObject]@{ + platformAndroidForWorkBlocked = $CurrentState.androidForWorkRestriction.platformBlocked + personalAndroidForWorkBlocked = $CurrentState.androidForWorkRestriction.personalDeviceEnrollmentBlocked + platformAndroidBlocked = $CurrentState.androidRestriction.platformBlocked + personalAndroidBlocked = $CurrentState.androidRestriction.personalDeviceEnrollmentBlocked + platformiOSBlocked = $CurrentState.iosRestriction.platformBlocked + personaliOSBlocked = $CurrentState.iosRestriction.personalDeviceEnrollmentBlocked + platformMacOSBlocked = $CurrentState.macOSRestriction.platformBlocked + personalMacOSBlocked = $CurrentState.macOSRestriction.personalDeviceEnrollmentBlocked + platformWindowsBlocked = $CurrentState.windowsRestriction.platformBlocked + personalWindowsBlocked = $CurrentState.windowsRestriction.personalDeviceEnrollmentBlocked + } + Set-CIPPStandardsCompareField -FieldName 'standards.DefaultPlatformRestrictions' -FieldValue $Table -TenantFilter $Tenant + Add-CIPPBPAField -FieldName 'DefaultPlatformRestrictions' -FieldValue [bool]$StateIsCorrect -StoreAs bool -Tenant $Tenant + } +} From 0d44f1fdb4deb4a1bc28af5df3cbf8b2a1554988 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Mon, 31 Mar 2025 17:24:29 +0200 Subject: [PATCH 015/123] add blacklists --- .../CIPPCore/Public/Get-CIPPTextReplacement.ps1 | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 index ba744b23b870..3c3448d5355a 100644 --- a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 @@ -18,7 +18,17 @@ function Get-CIPPTextReplacement { if ($Text -isnot [string]) { return $Text } - + $blacklist = @( + '%serial%', + '%systemroot%', + '%systemdrive%', + '%temp%', + '%tenantid%', + '%tenantfilter%', + '%tenantname%', + '%partnertenantid%', + '%samappid%' + ) $Tenant = Get-Tenants -TenantFilter $TenantFilter $CustomerId = $Tenant.customerId @@ -44,7 +54,9 @@ function Get-CIPPTextReplacement { # Replace custom variables foreach ($Replace in $Vars.GetEnumerator()) { $String = '%{0}%' -f $Replace.Key - $Text = $Text -replace $String, $Replace.Value + if ($string -notin $blacklist) { + $Text = $Text -replace $String, $Replace.Value + } } #default replacements for all tenants: %tenantid% becomes $tenant.customerId, %tenantfilter% becomes $tenant.defaultDomainName, %tenantname% becomes $tenant.displayName $Text = $Text -replace '%tenantid%', $Tenant.customerId From b1ae9e05f6e15300a2a0d3407967932795148ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 31 Mar 2025 20:13:25 +0200 Subject: [PATCH 016/123] filter out OOF and junk inbox rules in Push-BECRun function --- .../Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1 index bcfd1dd7262b..b23079f413bb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1 @@ -96,7 +96,8 @@ function Push-BECRun { Write-Information 'Getting rules' try { - $RulesLog = New-ExoRequest -cmdlet 'Get-InboxRule' -tenantid $TenantFilter -cmdParams @{ Mailbox = $Username; IncludeHidden = $true } -Anchor $Username + $RulesLog = New-ExoRequest -cmdlet 'Get-InboxRule' -tenantid $TenantFilter -cmdParams @{ Mailbox = $Username; IncludeHidden = $true } -Anchor $Username | + Where-Object { $_.Name -ne 'Junk E-Mail Rule' -and $_.Name -notlike 'Microsoft.Exchange.OOF.*' } } catch { Write-Host 'Failed to get rules: ' + $_.Exception.Message $RulesLog = @() From 7b2186c92965af2a949edd3252687a0f662cfb31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 31 Mar 2025 20:59:10 +0200 Subject: [PATCH 017/123] refactor Remove-CIPPMailboxRule function to use consistent parameter casing --- .../Public/Remove-CIPPMailboxRule.ps1 | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Modules/CIPPCore/Public/Remove-CIPPMailboxRule.ps1 b/Modules/CIPPCore/Public/Remove-CIPPMailboxRule.ps1 index fbc5cd2d436e..aeb62aad3446 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPMailboxRule.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPMailboxRule.ps1 @@ -1,8 +1,8 @@ function Remove-CIPPMailboxRule { [CmdletBinding()] param ( - $userid, - $username, + $UserId, + $Username, $TenantFilter, $APIName = 'Mailbox Rules Removal', $Headers, @@ -14,35 +14,34 @@ function Remove-CIPPMailboxRule { if ($RemoveAllRules.IsPresent -eq $true) { # Delete all rules try { - Write-Host "Checking rules for $username" - $rules = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $username; IncludeHidden = $true } | Where-Object { $_.Name -ne 'Junk E-Mail Rule' -and $_.Name -notlike 'Microsoft.Exchange.OOF.*' } - Write-Host "$($rules.count) rules found" - if ($null -eq $rules) { - Write-LogMessage -headers $Headers -API $APIName -message "No Rules for $($username) to delete" -Sev 'Info' -tenant $TenantFilter - return "No rules for $($username) to delete" + Write-Host "Checking rules for $Username" + $Rules = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $Username; IncludeHidden = $true } | Where-Object { $_.Name -ne 'Junk E-Mail Rule' -and $_.Name -notlike 'Microsoft.Exchange.OOF.*' } + Write-Host "$($Rules.count) rules found" + if ($null -eq $Rules) { + Write-LogMessage -headers $Headers -API $APIName -message "No Rules for $($Username) to delete" -Sev 'Info' -tenant $TenantFilter + return "No rules for $($Username) to delete" } else { - ForEach ($rule in $rules) { - $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $username -cmdParams @{Identity = $rule.Identity } + ForEach ($rule in $Rules) { + $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $Username -cmdParams @{Identity = $rule.Identity } } - Write-LogMessage -headers $Headers -API $APIName -message "Deleted Rules for $($username)" -Sev 'Info' -tenant $TenantFilter - return "Deleted Rules for $($username)" + Write-LogMessage -headers $Headers -API $APIName -message "Deleted rules for $($Username)" -Sev 'Info' -tenant $TenantFilter + return "Deleted rules for $($Username)" } } catch { $ErrorMessage = Get-CippException -Exception $_ - Write-LogMessage -headers $Headers -API $APIName -message "Could not delete rules for $($username): $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage - return "Could not delete rules for $($username). Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -headers $Headers -API $APIName -message "Could not delete rules for $($Username): $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage + return "Could not delete rules for $($Username). Error: $($ErrorMessage.NormalizedError)" } } else { # Only delete 1 rule try { - $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $username -cmdParams @{Identity = $RuleId } - Write-LogMessage -headers $Headers -API $APIName -message "Deleted mailbox rule $($RuleName) for $($username)" -Sev 'Info' -tenant $TenantFilter - return "Deleted mailbox rule $($RuleName) for $($username)" + $null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $Username -cmdParams @{Identity = $RuleId } + Write-LogMessage -headers $Headers -API $APIName -message "Deleted mailbox rule $($RuleName) for $($Username)" -Sev 'Info' -tenant $TenantFilter + return "Deleted mailbox rule $($RuleName) for $($Username)" } catch { $ErrorMessage = Get-CippException -Exception $_ - Write-LogMessage -headers $Headers -API $APIName -message "Could not delete rule for $($username): $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage - return "Could not delete rule for $($username). Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -headers $Headers -API $APIName -message "Could not delete rule for $($Username): $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage + return "Could not delete rule for $($Username). Error: $($ErrorMessage.NormalizedError)" } } } - From eb7131753b386735719eea1b83770e99a810c4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Mon, 31 Mar 2025 20:59:24 +0200 Subject: [PATCH 018/123] add Invoke-ExecSetMailboxRule and Set-CIPPMailboxRule functions for mailbox rule management --- .../Invoke-ExecSetMailboxRule.ps1 | 58 +++++++++++++++++++ .../CIPPCore/Public/Set-CIPPMailboxRule.ps1 | 34 +++++++++++ 2 files changed, 92 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetMailboxRule.ps1 create mode 100644 Modules/CIPPCore/Public/Set-CIPPMailboxRule.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetMailboxRule.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetMailboxRule.ps1 new file mode 100644 index 000000000000..1a747f8c6f81 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetMailboxRule.ps1 @@ -0,0 +1,58 @@ +using namespace System.Net + +Function Invoke-ExecSetMailboxRule { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -tenant $TenantFilter -message 'Accessed this API' -Sev 'Debug' + + # Interact with the query or body of the request + $TenantFilter = $Request.Body.TenantFilter + $RuleName = $Request.Body.ruleName + $RuleId = $Request.Body.ruleId + $Username = $Request.Body.userPrincipalName + $Enable = $Request.Body.Enable -as [bool] + $Disable = $Request.Body.Disable -as [bool] + + + # Set the rule + $SetCIPPMailboxRuleParams = @{ + Username = $Username + TenantFilter = $TenantFilter + APIName = $APIName + Headers = $Headers + RuleId = $RuleId + RuleName = $RuleName + } + if ($Enable -eq $true) { + $SetCIPPMailboxRuleParams.Add('Enable', $true) + } elseif ($Disable -eq $true) { + $SetCIPPMailboxRuleParams.Add('Disable', $true) + } else { + Write-LogMessage -headers $Headers -API $APIName -message 'No state provided for mailbox rule' -Sev 'Error' -tenant $TenantFilter + throw 'No state provided for mailbox rule' + } + + $Results = Set-CIPPMailboxRule @SetCIPPMailboxRuleParams + + if ($Results -like '*Could not set*') { + $StatusCode = [HttpStatusCode]::InternalServerError + } else { + $StatusCode = [HttpStatusCode]::OK + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @{ Results = $Results } + }) + +} diff --git a/Modules/CIPPCore/Public/Set-CIPPMailboxRule.ps1 b/Modules/CIPPCore/Public/Set-CIPPMailboxRule.ps1 new file mode 100644 index 000000000000..cbbd39cd0916 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPMailboxRule.ps1 @@ -0,0 +1,34 @@ +function Set-CIPPMailboxRule { + [CmdletBinding()] + param ( + $UserId, + $Username, + $TenantFilter, + $APIName = 'Set mailbox rules', + $Headers, + $RuleId, + $RuleName, + [switch]$Enable, + [switch]$Disable + ) + + if ($Enable.IsPresent -eq $true) { + $State = 'Enable' + } elseif ($Disable.IsPresent -eq $true) { + $State = 'Disable' + } else { + Write-LogMessage -headers $Headers -API $APIName -message 'No state provided for mailbox rule' -Sev 'Error' -tenant $TenantFilter + throw 'No state provided for mailbox rule' + } + + try { + $null = New-ExoRequest -tenantid $TenantFilter -cmdlet "$State-InboxRule" -Anchor $Username -cmdParams @{Identity = $RuleId } + Write-LogMessage -headers $Headers -API $APIName -message "Successfully set mailbox rule $($RuleName) for $($Username) to $($State)d" -Sev 'Info' -tenant $TenantFilter + return "Successfully set mailbox rule $($RuleName) for $($Username) to $($State)d" + } catch { + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -headers $Headers -API $APIName -message "Could not set mailbox rule $($RuleName) for $($Username) to $($State)d. Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $TenantFilter -LogData $ErrorMessage + throw "Could not set mailbox rule $($RuleName) for $($Username) to $($State)d. Error: $($ErrorMessage.NormalizedError)" + } + +} From 00005c380801b51cd8692112fe126327e13da8b8 Mon Sep 17 00:00:00 2001 From: Esco Date: Fri, 28 Mar 2025 14:54:48 +0100 Subject: [PATCH 019/123] feat: Spoof Intelligence standard working logging a ignore the typo standard comments ITS ALIVE fix reporting --- ...-CIPPStandardPhishSimSpoofIntelligence.ps1 | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishSimSpoofIntelligence.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishSimSpoofIntelligence.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishSimSpoofIntelligence.ps1 new file mode 100644 index 000000000000..d8643a058c44 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishSimSpoofIntelligence.ps1 @@ -0,0 +1,103 @@ +function Invoke-CIPPStandardPhishSimSpoofIntelligence { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) PhishSimSpoofIntelligence + .SYNOPSIS + (Label) Add allowed domains to Spoof Intelligence + .DESCRIPTION + (Helptext) This adds allowed domains to the Spoof Intelligence Allow/Block List. + (DocsDescription) This adds allowed domains to the Spoof Intelligence Allow/Block List. + .NOTES + CAT + Defender Standards + TAG + ADDEDCOMPONENT + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"label":"Allowed Domains","name":"standards.PhishSimSpoofIntelligence.AllowedDomains"} + IMPACT + Medium Impact + ADDEDDATE + 2025-03-28 + POWERSHELLEQUIVALENT + New-TenantAllowBlockListSpoofItems + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/list-standards/defender-standards#medium-impact + #> + + param($Tenant, $Settings) + # Fetch current Phishing Simulations Spoof Intelligence domains and ensure it is correctly configured + $DomainState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-TenantAllowBlockListSpoofItems' | + Select-Object -Property Identity,SendingInfrastructure + + [String[]]$AddDomain = $Settings.AllowedDomains.value | Where-Object { $_ -notin $DomainState.SendingInfrastructure } + + $RemoveDomain = $DomainState | Where-Object { $_.SendingInfrastructure -notin $Settings.AllowedDomains.value } | + Select-Object -Property Identity,SendingInfrastructure + + $StateIsCorrect = ($AddDomain.Count -eq 0 -and $RemoveDomain.Count -eq 0) + + If ($Settings.remediate -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Spoof Intelligence Allow list already correctly configured' -sev Info + } Else { + $BulkRequests = New-Object System.Collections.Generic.List[Hashtable] + + # Prepare removal requests + If ($RemoveDomain.Count -gt 0) { + Write-Host "Removing $($RemoveDomain.Count) domains from Spoof Intelligence" + $BulkRequests.Add(@{ + CmdletInput = @{ + CmdletName = 'Remove-TenantAllowBlockListSpoofItems' + Parameters = @{ Identity = 'default'; Ids = $RemoveDomain.Identity } + } + }) + } + + # Prepare addition requests + ForEach ($Domain in $AddDomain) { + $BulkRequests.Add(@{ + CmdletInput = @{ + CmdletName = 'New-TenantAllowBlockListSpoofItems' + Parameters = @{ Identity = 'default'; Action = 'Allow'; SendingInfrastructure = $Domain; SpoofedUser = '*'; SpoofType = 'Internal' } + } + }) + $BulkRequests.Add(@{ + CmdletInput = @{ + CmdletName = 'New-TenantAllowBlockListSpoofItems' + Parameters = @{ Identity = 'default'; Action = 'Allow'; SendingInfrastructure = $Domain; SpoofedUser = '*'; SpoofType = 'External' } + } + }) + } + $RawExoRequest = New-ExoBulkRequest -tenantid $Tenant -cmdletArray @($BulkRequests) + + $LastError = $RawExoRequest | Select-Object -Last 1 + If ($LastError.error) { + Foreach ($ExoError in $LastError.error) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to process Spoof Intelligence Domain with error: $ExoError" -Sev Error + } + } Else { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Processed all Spoof Intelligence Domains successfully." -Sev Info + } + } + } + + If ($Settings.alert -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Spoof Intelligence Allow list is correctly configured' -sev Info + } Else { + Write-StandardsAlert -message 'Spoof Intelligence Allow list is not correctly configured' -object $CurrentState -tenant $Tenant -standardName 'PhishSimSpoofIntelligence' -standardId $Settings.standardId + Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Spoof Intelligence Allow list is not correctly configured' -sev Info + } + } + + If ($Settings.report -eq $true) { + $CurrentState = $StateIsCorrect ? $true : $DomainState.SendingInfrastructure + + Set-CIPPStandardsCompareField -FieldName 'standards.PhishSimSpoofIntelligence' -FieldValue $CurrentState -Tenant $Tenant + Add-CIPPBPAField -FieldName 'PhishSimSpoofIntelligence' -FieldValue [bool]$StateIsCorrect -StoreAs bool -Tenant $Tenant + } +} From 2934b73a0f637f353607d38e20df7e793d471859 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 15:20:08 -0400 Subject: [PATCH 020/123] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/dev-linux_cippipdsw.yml | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/dev-linux_cippipdsw.yml diff --git a/.github/workflows/dev-linux_cippipdsw.yml b/.github/workflows/dev-linux_cippipdsw.yml new file mode 100644 index 000000000000..85760d1099d5 --- /dev/null +++ b/.github/workflows/dev-linux_cippipdsw.yml @@ -0,0 +1,40 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cippipdsw + +on: + push: + branches: + - dev-linux + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_ACAE509CF8BA43B5B505A4749C4C9D23 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_11381FD8EE6847A9AAEF51178BBD1ED1 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_F530195CFD74405291D01F63FD5BC8C9 }} + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cippipdsw' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + \ No newline at end of file From 587a4d31002588e1190abeb9dd27d363fbaa12ef Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 15:21:11 -0400 Subject: [PATCH 021/123] Add or update the Azure App Service build and deployment workflow config --- .../workflows/dev-linux_cippipdsw-proc.yml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/dev-linux_cippipdsw-proc.yml diff --git a/.github/workflows/dev-linux_cippipdsw-proc.yml b/.github/workflows/dev-linux_cippipdsw-proc.yml new file mode 100644 index 000000000000..e5e872c20247 --- /dev/null +++ b/.github/workflows/dev-linux_cippipdsw-proc.yml @@ -0,0 +1,30 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cippipdsw-proc + +on: + push: + branches: + - dev-linux + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cippipdsw-proc' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_EA18A2B9ADDA46CD8F6030C83B2F39EF }} \ No newline at end of file From 2c088dfb8fb066d6e4521bcf2b7686b565615b83 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 16:39:29 -0400 Subject: [PATCH 022/123] Remove the Azure App Service build and deployment workflow config --- .../workflows/dev-linux_cippipdsw-proc.yml | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 .github/workflows/dev-linux_cippipdsw-proc.yml diff --git a/.github/workflows/dev-linux_cippipdsw-proc.yml b/.github/workflows/dev-linux_cippipdsw-proc.yml deleted file mode 100644 index e5e872c20247..000000000000 --- a/.github/workflows/dev-linux_cippipdsw-proc.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cippipdsw-proc - -on: - push: - branches: - - dev-linux - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cippipdsw-proc' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_EA18A2B9ADDA46CD8F6030C83B2F39EF }} \ No newline at end of file From d9a617bab2bd48c4c3c836f9eddf455cc7de118b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 16:40:02 -0400 Subject: [PATCH 023/123] Add or update the Azure App Service build and deployment workflow config --- .../workflows/dev-linux_cippipdsw-proc.yml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/dev-linux_cippipdsw-proc.yml diff --git a/.github/workflows/dev-linux_cippipdsw-proc.yml b/.github/workflows/dev-linux_cippipdsw-proc.yml new file mode 100644 index 000000000000..3f657a0e1a10 --- /dev/null +++ b/.github/workflows/dev-linux_cippipdsw-proc.yml @@ -0,0 +1,40 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cippipdsw-proc + +on: + push: + branches: + - dev-linux + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5A2D1D006C6E45F4B94B9B694DD03DD4 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_34D61F116C6840A9A1F59E61F80ACDDB }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_F575F8CFE71D4F93B850075D55E5654C }} + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cippipdsw-proc' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + \ No newline at end of file From 14161cf0f6fe56907484ed69043e3702505d7eb0 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 17:47:42 -0400 Subject: [PATCH 024/123] fix env casing and api errors --- .../CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 | 8 +++----- .../HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 index aa0da8936ab5..4db5c5a3c386 100644 --- a/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 @@ -55,12 +55,13 @@ function New-CIPPAPIConfig { enableAccessTokenIssuance = $false enableIdTokenIssuance = $true } - redirectUris = @("https://$($ENV:Website_hostname)/.auth/login/aad/callback") + redirectUris = @("https://$($ENV:WEBSITE_HOSTNAME)/.auth/login/aad/callback") } } | ConvertTo-Json -Depth 10 -Compress if ($PSCmdlet.ShouldProcess($AppName, 'Create API App')) { Write-Information 'Creating app' + Write-Information $CreateBody $APIApp = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/v1.0/applications' -AsApp $true -NoAuthCheck $true -type POST -body $CreateBody Write-Information 'Creating password' $APIPassword = New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/applications/$($APIApp.id)/addPassword" -AsApp $true -NoAuthCheck $true -type POST -body "{`"passwordCredential`":{`"displayName`":`"Generated by API Setup`"}}" @@ -118,9 +119,6 @@ function New-CIPPAPIConfig { $ErrorMessage = Get-CippException -Exception $_ Write-Information ($ErrorMessage | ConvertTo-Json -Depth 10) Write-LogMessage -headers $Headers -API $APINAME -tenant 'None' -message "Failed to setup CIPP-API Access: $($ErrorMessage.NormalizedError) Linenumber: $($_.InvocationInfo.ScriptLineNumber)" -Sev 'Error' -LogData $ErrorMessage - return @{ - Results = "Failed to setup CIPP-API Access: $($ErrorMessage.NormalizedError)" - } - + throw "Failed to setup CIPP-API Access: $($ErrorMessage.NormalizedError)" } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index de945a2112c9..9d5e4e2e405c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -50,7 +50,6 @@ function Invoke-ExecApiClient { $AddUpdateSuccess = $true } catch { $AddedText = "Could not modify App Registrations. Check the CIPP documentation for API requirements. Error: $($_.Exception.Message)" - $Body = $Body | Select-Object * -ExcludeProperty CIPPAPI } } From 85ae0b95c8f16f97a8de8eb79bf31ff73982345b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:05:06 -0400 Subject: [PATCH 025/123] adjust casing catch errors --- Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 | 3 ++- Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 | 2 +- .../HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 b/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 index 5b8760235e64..f1405ffb884a 100644 --- a/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 +++ b/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 @@ -7,7 +7,8 @@ function Get-CippApiAuth { if ($env:MSI_SECRET) { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $Context = Set-AzContext -SubscriptionId $SubscriptionId -TenantId $env:TenantId -ErrorAction Stop } else { $Context = Get-AzContext $SubscriptionId = $Context.Subscription.Id diff --git a/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 b/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 index e6ebd0b46609..07a2eb9b1d13 100644 --- a/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 +++ b/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 @@ -10,7 +10,7 @@ function Set-CippApiAuth { if ($env:MSI_SECRET) { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $Context = Set-AzContext -SubscriptionId $SubscriptionId } else { $Context = Get-AzContext diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index 9d5e4e2e405c..598ffe42c72b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -107,6 +107,7 @@ function Invoke-ExecApiClient { } catch { $Results = @{ Enabled = 'Could not get API clients, ensure you have the appropriate rights to read the Authentication settings.' + Error = (Get-CippException -Exception $_) } } $Body = @{ @@ -124,7 +125,10 @@ function Invoke-ExecApiClient { $Body = @{ Results = 'API clients saved to Azure' } Write-LogMessage -headers $Request.Headers -API 'ExecApiClient' -message 'Saved API clients to Azure' -Sev 'Info' } catch { - $Body = @{ Results = 'Failed to save allowed API clients to Azure, ensure your function app has the appropriate rights to make changes to the Authentication settings.' } + $Body = @{ + Results = 'Failed to save allowed API clients to Azure, ensure your function app has the appropriate rights to make changes to the Authentication settings.' + Error = (Get-CippException -Exception $_) + } Write-Information (Get-CippException -Exception $_ | ConvertTo-Json) } } From 96632cc211bacd61acee9bfa6dfab31e8826fac4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:09:00 -0400 Subject: [PATCH 026/123] Update Get-CippApiAuth.ps1 --- Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 b/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 index f1405ffb884a..3056fdb0c8d9 100644 --- a/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 +++ b/Modules/CIPPCore/Public/Authentication/Get-CippApiAuth.ps1 @@ -8,7 +8,7 @@ function Get-CippApiAuth { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 - $Context = Set-AzContext -SubscriptionId $SubscriptionId -TenantId $env:TenantId -ErrorAction Stop + $Context = Set-AzContext -SubscriptionId $SubscriptionId } else { $Context = Get-AzContext $SubscriptionId = $Context.Subscription.Id From c6fe54a831bc90d1d70d4de8f4ce193c0fb57bcf Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:13:34 -0400 Subject: [PATCH 027/123] Update Set-CippApiAuth.ps1 --- Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 b/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 index 07a2eb9b1d13..b6c9278c45a5 100644 --- a/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 +++ b/Modules/CIPPCore/Public/Authentication/Set-CippApiAuth.ps1 @@ -20,6 +20,8 @@ function Set-CippApiAuth { # Get auth settings $AuthSettings = Invoke-AzRestMethod -Uri "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$RGName/providers/Microsoft.Web/sites/$($FunctionAppName)/config/authsettingsV2/list?api-version=2020-06-01" | Select-Object -ExpandProperty Content | ConvertFrom-Json + Write-Information "AuthSettings: $($AuthSettings | ConvertTo-Json -Depth 10)" + # Set allowed audiences $AllowedAudiences = foreach ($ClientId in $ClientIds) { "api://$ClientId" From 365aa6812d3209e244689ec6989fc01633649680 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:23:41 -0400 Subject: [PATCH 028/123] more casing --- AddChocoApp/IntunePackage/Install.ps1 | 6 ++--- AddChocoApp/IntunePackage/Uninstall.ps1 | 2 +- .../Public/Add-CIPPApplicationPermission.ps1 | 2 +- .../Public/Add-CIPPDelegatedPermission.ps1 | 2 +- .../Authentication/New-CIPPAPIConfig.ps1 | 2 +- .../Push-ExecOnboardTenantQueue.ps1 | 4 ++-- .../Push-UpdatePermissionsQueue.ps1 | 8 +++---- .../CIPP/Core/Invoke-GetCippAlerts.ps1 | 2 +- .../Invoke-ExecExtensionsConfig.ps1 | 2 +- .../CIPP/Settings/Invoke-ExecAccessChecks.ps1 | 6 ++--- .../CIPP/Settings/Invoke-ExecApiClient.ps1 | 10 ++++----- .../CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 22 +++++++++---------- .../Settings/Invoke-ExecCPVPermissions.ps1 | 4 ++-- .../CIPP/Setup/Invoke-ExecSAMSetup.ps1 | 12 +++++----- .../Applications/Invoke-AddChocoApp.ps1 | 2 +- .../Administration/Invoke-ExecAddSPN.ps1 | 4 ++-- .../Invoke-ExecOffboardTenant.ps1 | 2 +- .../Entrypoints/Invoke-ExecListAppId.ps1 | 6 ++--- .../Timer Functions/Start-CIPPStatsTimer.ps1 | 2 +- .../Start-UpdateTokensTimer.ps1 | 4 ++-- .../Public/Get-CIPPAuthentication.ps1 | 6 ++--- .../Public/Get-CIPPSchemaExtensions.ps1 | 2 +- .../Public/Get-CIPPTextReplacement.ps1 | 4 ++-- .../GraphHelper/Get-ClassicAPIToken.ps1 | 2 +- .../Public/GraphHelper/Remove-CIPPCache.ps1 | 2 +- .../Public/New-CIPPApplicationCopy.ps1 | 6 ++--- .../CIPPCore/Public/Set-CIPPCPVConsent.ps1 | 12 +++++----- .../CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1 | 8 +++---- .../Public/Test-CIPPAccessPermissions.ps1 | 6 ++--- .../CIPPCore/Public/Test-CIPPAccessTenant.ps1 | 2 +- .../Public/Test-CIPPGDAPRelationships.ps1 | 2 +- .../Get-ExtensionAPIKey.ps1 | 4 ++-- .../Set-ExtensionAPIKey.ps1 | 4 ++-- .../Public/Gradient/Get-GradientToken.ps1 | 4 ++-- .../Public/HIBP/Get-HIBPAuth.ps1 | 12 +++++----- Tools/Update-LicenseSKUFiles.ps1 | 2 +- profile.ps1 | 2 +- 37 files changed, 92 insertions(+), 92 deletions(-) diff --git a/AddChocoApp/IntunePackage/Install.ps1 b/AddChocoApp/IntunePackage/Install.ps1 index 5569e9ec5e02..fd5e86dfc71e 100644 --- a/AddChocoApp/IntunePackage/Install.ps1 +++ b/AddChocoApp/IntunePackage/Install.ps1 @@ -19,13 +19,13 @@ param ( try { if ($Trace) { Start-Transcript -Path (Join-Path $env:windir "\temp\choco-$Packagename-trace.log") } - $chocoPath = "$($ENV:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" + $chocoPath = "$($env:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" if ($InstallChoco) { if (-not (Test-Path $chocoPath)) { try { Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) - $chocoPath = "$($ENV:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" + $chocoPath = "$($env:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" } catch { Write-Host "InstallChoco Error: $($_.Exception.Message)" @@ -45,7 +45,7 @@ try { & "$chocoPath" install $Packagename -y $CustomRepoString } Write-Host 'Completed.' - } + } catch { Write-Host "Install/upgrade error: $($_.Exception.Message)" } diff --git a/AddChocoApp/IntunePackage/Uninstall.ps1 b/AddChocoApp/IntunePackage/Uninstall.ps1 index 949dceeaf8ea..9d1512fabcfc 100644 --- a/AddChocoApp/IntunePackage/Uninstall.ps1 +++ b/AddChocoApp/IntunePackage/Uninstall.ps1 @@ -4,6 +4,6 @@ param ( [string] $Packagename ) -$chocoPath = "$($ENV:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" +$chocoPath = "$($env:SystemDrive)\ProgramData\chocolatey\bin\choco.exe" & $Chocopath uninstall $Packagename -y diff --git a/Modules/CIPPCore/Public/Add-CIPPApplicationPermission.ps1 b/Modules/CIPPCore/Public/Add-CIPPApplicationPermission.ps1 index b4b6c7d177ca..8841b33e8abc 100644 --- a/Modules/CIPPCore/Public/Add-CIPPApplicationPermission.ps1 +++ b/Modules/CIPPCore/Public/Add-CIPPApplicationPermission.ps1 @@ -5,7 +5,7 @@ function Add-CIPPApplicationPermission { $ApplicationId, $Tenantfilter ) - if ($ApplicationId -eq $ENV:ApplicationID -and $Tenantfilter -eq $env:TenantID) { + if ($ApplicationId -eq $env:ApplicationID -and $Tenantfilter -eq $env:TenantID) { #return @('Cannot modify application permissions for CIPP-SAM on partner tenant') $RequiredResourceAccess = 'CIPPDefaults' } diff --git a/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 b/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 index 5b811bbd405e..8b1b50702035 100644 --- a/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 +++ b/Modules/CIPPCore/Public/Add-CIPPDelegatedPermission.ps1 @@ -9,7 +9,7 @@ function Add-CIPPDelegatedPermission { Write-Host 'Adding Delegated Permissions' Set-Location (Get-Item $PSScriptRoot).FullName - if ($ApplicationId -eq $ENV:ApplicationID -and $Tenantfilter -eq $env:TenantID) { + if ($ApplicationId -eq $env:ApplicationID -and $Tenantfilter -eq $env:TenantID) { #return @('Cannot modify delgated permissions for CIPP-SAM on partner tenant') $RequiredResourceAccess = 'CIPPDefaults' } diff --git a/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 b/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 index 4db5c5a3c386..43bbee34f7a2 100644 --- a/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 +++ b/Modules/CIPPCore/Public/Authentication/New-CIPPAPIConfig.ps1 @@ -55,7 +55,7 @@ function New-CIPPAPIConfig { enableAccessTokenIssuance = $false enableIdTokenIssuance = $true } - redirectUris = @("https://$($ENV:WEBSITE_HOSTNAME)/.auth/login/aad/callback") + redirectUris = @("https://$($env:WEBSITE_HOSTNAME)/.auth/login/aad/callback") } } | ConvertTo-Json -Depth 10 -Compress diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 index 172e152c38e6..07e9ff926e2f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 @@ -315,8 +315,8 @@ Function Push-ExecOnboardTenantQueue { $LastCPVError = '' do { try { - Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $Relationship.customer.tenantId - Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $Relationship.customer.tenantId + Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $Relationship.customer.tenantId + Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $Relationship.customer.tenantId $CPVSuccess = $true $Refreshing = $false } catch { diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-UpdatePermissionsQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-UpdatePermissionsQueue.ps1 index fca8aba39668..6ab4496809db 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-UpdatePermissionsQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-UpdatePermissionsQueue.ps1 @@ -16,15 +16,15 @@ function Push-UpdatePermissionsQueue { $Table = Get-CIPPTable -TableName cpvtenants $CPVRows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Tenant -EQ $Item.customerId - if (!$CPVRows -or $ENV:ApplicationID -notin $CPVRows.applicationId) { + if (!$CPVRows -or $env:ApplicationID -notin $CPVRows.applicationId) { Write-LogMessage -tenant $Item.defaultDomainName -tenantId $Item.customerId -message 'A New tenant has been added, or a new CIPP-SAM Application is in use' -Sev 'Warn' -API 'NewTenant' Write-Information 'Adding CPV permissions' Set-CIPPCPVConsent -Tenantfilter $Item.customerId $DomainRefreshRequired = $true } Write-Information 'Updating permissions' - Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $Item.customerId - Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $Item.customerId + Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $Item.customerId + Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $Item.customerId Write-LogMessage -tenant $Item.defaultDomainName -tenantId $Item.customerId -message "Updated permissions for $($Item.displayName)" -Sev 'Info' -API 'UpdatePermissionsQueue' if ($Item.defaultDomainName -ne 'PartnerTenant') { @@ -36,7 +36,7 @@ function Push-UpdatePermissionsQueue { $unixtime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds $GraphRequest = @{ LastApply = "$unixtime" - applicationId = "$($ENV:ApplicationID)" + applicationId = "$($env:ApplicationID)" Tenant = "$($Item.customerId)" PartitionKey = 'Tenant' RowKey = "$($Item.customerId)" diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 index d200d368dfeb..b59e276df628 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 @@ -43,7 +43,7 @@ Function Invoke-GetCippAlerts { Write-LogMessage -message 'Your CIPP API is out of date. Please update to the latest version' -API 'Updates' -tenant 'All Tenants' -sev Alert } - if ($env:ApplicationID -eq 'LongApplicationID' -or $null -eq $ENV:ApplicationID) { + if ($env:ApplicationID -eq 'LongApplicationID' -or $null -eq $env:ApplicationID) { $Alerts.Add(@{ title = 'SAM Setup Incomplete' Alert = 'You have not yet completed your setup. Please go to the Setup Wizard in Application Settings to connect CIPP to your tenants.' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionsConfig.ps1 index d6b57d97663b..b9ae61285dc4 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Extensions/Invoke-ExecExtensionsConfig.ps1 @@ -38,7 +38,7 @@ Function Invoke-ExecExtensionsConfig { Write-Information 'Not sending to keyvault. Key previously set or left blank.' } else { Write-Information 'writing API Key to keyvault, and clearing.' - Write-Information "$ENV:WEBSITE_DEPLOYMENT_ID" + Write-Information "$env:WEBSITE_DEPLOYMENT_ID" if ($Body.$APIKey.APIKey) { Set-ExtensionAPIKey -Extension $APIKey -APIKey $Body.$APIKey.APIKey } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 index 5a403a6894f9..68705818b31f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecAccessChecks.ps1 @@ -29,7 +29,7 @@ Function Invoke-ExecAccessChecks { $Results = $null } if (!$Results) { - $Results = Test-CIPPAccessPermissions -tenantfilter $ENV:TenantID -APIName $APINAME -Headers $Request.Headers + $Results = Test-CIPPAccessPermissions -tenantfilter $env:TenantID -APIName $APINAME -Headers $Request.Headers } else { try { $LastRun = [DateTime]::SpecifyKind($Cache.Timestamp.DateTime, [DateTimeKind]::Utc) @@ -38,14 +38,14 @@ Function Invoke-ExecAccessChecks { } } } else { - $Results = Test-CIPPAccessPermissions -tenantfilter $ENV:TenantID -APIName $APINAME -Headers $Request.Headers + $Results = Test-CIPPAccessPermissions -tenantfilter $env:TenantID -APIName $APINAME -Headers $Request.Headers } } 'Tenants' { $AccessChecks = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'TenantAccessChecks'" if (!$Request.Body.TenantId) { try { - $Tenants = Get-Tenants -IncludeErrors | Where-Object { $_.customerId -ne $ENV:TenantID } + $Tenants = Get-Tenants -IncludeErrors | Where-Object { $_.customerId -ne $env:TenantID } $Results = foreach ($Tenant in $Tenants) { $TenantCheck = $AccessChecks | Where-Object -Property RowKey -EQ $Tenant.customerId | Select-Object -Property Data $TenantResult = [PSCustomObject]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index 598ffe42c72b..e2f716272200 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -99,8 +99,8 @@ function Invoke-ExecApiClient { } } 'GetAzureConfiguration' { - $RGName = $ENV:WEBSITE_RESOURCE_GROUP - $FunctionAppName = $ENV:WEBSITE_SITE_NAME + $RGName = $env:WEBSITE_RESOURCE_GROUP + $FunctionAppName = $env:WEBSITE_SITE_NAME try { $APIClients = Get-CippApiAuth -RGName $RGName -FunctionAppName $FunctionAppName $Results = $ApiClients @@ -115,9 +115,9 @@ function Invoke-ExecApiClient { } } 'SaveToAzure' { - $TenantId = $ENV:TenantId - $RGName = $ENV:WEBSITE_RESOURCE_GROUP - $FunctionAppName = $ENV:WEBSITE_SITE_NAME + $TenantId = $env:TenantId + $RGName = $env:WEBSITE_RESOURCE_GROUP + $FunctionAppName = $env:WEBSITE_SITE_NAME $AllClients = Get-CIPPAzDataTableEntity @Table -Filter 'Enabled eq true' | Where-Object { ![string]::IsNullOrEmpty($_.RowKey) } $ClientIds = $AllClients.RowKey try { diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 80c0de481eaa..20e7303baade 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -13,22 +13,22 @@ Function Invoke-ExecBackendURLs { $APIName = $Request.Params.CIPPEndpoint Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' - $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 - $SWAName = $ENV:WEBSITE_SITE_NAME -replace 'cipp', 'CIPP-SWA-' + $Subscription = ($env:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 + $SWAName = $env:WEBSITE_SITE_NAME -replace 'cipp', 'CIPP-SWA-' # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' $results = [PSCustomObject]@{ - ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/overview" - KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$($ENV:WEBSITE_SITE_NAME)/secrets" - FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/appServices" - FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/configuration" - FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/vstscd" - SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/customDomains" - SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" + ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/overview" + KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$($env:WEBSITE_SITE_NAME)/secrets" + FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/appServices" + FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/configuration" + FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/vstscd" + SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/customDomains" + SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" Subscription = $Subscription - RGName = $ENV:WEBSITE_RESOURCE_GROUP - FunctionName = $ENV:WEBSITE_SITE_NAME + RGName = $env:WEBSITE_RESOURCE_GROUP + FunctionName = $env:WEBSITE_SITE_NAME SWAName = $SWAName } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 index 0384b3e3c350..a2e6fb31bd70 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCPVPermissions.ps1 @@ -37,8 +37,8 @@ Function Invoke-ExecCPVPermissions { defaultDomainName = $env:TenantID } } - Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $TenantFilter - Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $ENV:ApplicationID -tenantfilter $TenantFilter + Add-CIPPApplicationPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $TenantFilter + Add-CIPPDelegatedPermission -RequiredResourceAccess 'CIPPDefaults' -ApplicationId $env:ApplicationID -tenantfilter $TenantFilter if ($TenantFilter -notin @('PartnerTenant', $env:TenantID)) { Set-CIPPSAMAdminRoles -TenantFilter $TenantFilter } 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 11738d58737a..c9ec1f5bec39 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 @@ -52,16 +52,16 @@ Function Invoke-ExecSAMSetup { if ($env:MSI_SECRET) { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId } } - if (!$ENV:SetFromProfile) { + if (!$env:SetFromProfile) { Write-Information "We're reloading from KV" Get-CIPPAuthentication } - $KV = $ENV:WEBSITE_DEPLOYMENT_ID + $KV = $env:WEBSITE_DEPLOYMENT_ID $Table = Get-CIPPTable -TableName SAMWizard $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).AddMinutes(-10) @@ -88,16 +88,16 @@ Function Invoke-ExecSAMSetup { if ($Request.Query.code) { try { $TenantId = $Rows.tenantid - if (!$TenantId -or $TenantId -eq 'NotStarted') { $TenantId = $ENV:TenantID } + if (!$TenantId -or $TenantId -eq 'NotStarted') { $TenantId = $env:TenantID } $AppID = $Rows.appid - if (!$AppID -or $AppID -eq 'NotStarted') { $appid = $ENV:ApplicationID } + if (!$AppID -or $AppID -eq 'NotStarted') { $appid = $env:ApplicationID } $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { $clientsecret = $Secret.ApplicationSecret } else { $clientsecret = Get-AzKeyVaultSecret -VaultName $kv -Name 'ApplicationSecret' -AsPlainText } - if (!$clientsecret) { $clientsecret = $ENV:ApplicationSecret } + if (!$clientsecret) { $clientsecret = $env:ApplicationSecret } Write-Information "client_id=$appid&scope=https://graph.microsoft.com/.default+offline_access+openid+profile&code=$($Request.Query.code)&grant_type=authorization_code&redirect_uri=$($url)&client_secret=$clientsecret" #-Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" $RefreshToken = Invoke-RestMethod -Method POST -Body "client_id=$appid&scope=https://graph.microsoft.com/.default+offline_access+openid+profile&code=$($Request.Query.code)&grant_type=authorization_code&redirect_uri=$($url)&client_secret=$clientsecret" -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" -ContentType 'application/x-www-form-urlencoded' diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 index 34cfeb198291..ba4c74f506ee 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddChocoApp.ps1 @@ -26,7 +26,7 @@ Function Invoke-AddChocoApp { $intuneBody.installCommandLine = $intuneBody.installCommandLine + " -CustomRepo $($chocoapp.CustomRepo)" } $intuneBody.UninstallCommandLine = "powershell.exe -executionpolicy bypass .\Uninstall.ps1 -Packagename $($chocoapp.PackageName)" - $intunebody.detectionRules[0].path = "$($ENV:SystemDrive)\programdata\chocolatey\lib" + $intunebody.detectionRules[0].path = "$($env:SystemDrive)\programdata\chocolatey\lib" $intunebody.detectionRules[0].fileOrFolderName = "$($chocoapp.PackageName)" $Tenants = $Request.body.selectedTenants.defaultDomainName diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 index ce498176528c..daa9cb7901b9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecAddSPN.ps1 @@ -16,8 +16,8 @@ Function Invoke-ExecAddSPN { # Interact with query parameters or the body of the request. $Body = if ($Request.Query.Enable) { '{"accountEnabled":"true"}' } else { '{"accountEnabled":"false"}' } try { - $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -tenantid $ENV:TenantID -type POST -Body "{ `"appId`": `"2832473f-ec63-45fb-976f-5d45a7d4bb91`" }" -NoAuthCheck $true - $Results = [pscustomobject]@{'Results' = "Successfully completed request. Add your GDAP migration permissions to your SAM application here: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnAPI/appId/$($ENV:ApplicationID)/isMSAApp/ " } + $GraphRequest = New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/servicePrincipals' -tenantid $env:TenantID -type POST -Body "{ `"appId`": `"2832473f-ec63-45fb-976f-5d45a7d4bb91`" }" -NoAuthCheck $true + $Results = [pscustomobject]@{'Results' = "Successfully completed request. Add your GDAP migration permissions to your SAM application here: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/CallAnAPI/appId/$($env:ApplicationID)/isMSAApp/ " } } catch { $Results = [pscustomobject]@{'Results' = "Failed to add SPN. Please manually execute 'New-AzureADServicePrincipal -AppId 2832473f-ec63-45fb-976f-5d45a7d4bb91' The error was $($_.Exception.Message)" } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 index dc69176e989e..4afdfb601df5 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Invoke-ExecOffboardTenant.ps1 @@ -122,7 +122,7 @@ Function Invoke-ExecOffboardTenant { # Remove multi-tenant apps with the CSP tenant as origin try { $multitenantCSPApps = (New-GraphGETRequest -Uri "https://graph.microsoft.com/v1.0/servicePrincipals?`$count=true&`$select=displayName,appId,id,appOwnerOrganizationId&`$filter=appOwnerOrganizationId eq $($env:TenantID)" -tenantid $Tenantfilter -ComplexFilter) - $sortedArray = $multitenantCSPApps | Sort-Object @{Expression = { if ($_.appId -eq $ENV:ApplicationID) { 1 } else { 0 } }; Ascending = $true } + $sortedArray = $multitenantCSPApps | Sort-Object @{Expression = { if ($_.appId -eq $env:ApplicationID) { 1 } else { 0 } }; Ascending = $true } $sortedArray | ForEach-Object { try { $delete = (New-GraphPostRequest -type 'DELETE' -Uri "https://graph.microsoft.com/v1.0/serviceprincipals/$($_.id)" -tenantid $Tenantfilter) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 index 9036b16620b4..7f27768e1c94 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecListAppId.ps1 @@ -15,9 +15,9 @@ Function Invoke-ExecListAppId { $ResponseURL = "$(($Request.headers.'x-ms-original-url').replace('/api/ExecListAppId','/api/ExecSAMSetup'))" $Results = @{ - applicationId = $ENV:ApplicationID - tenantId = $ENV:TenantID - refreshUrl = "https://login.microsoftonline.com/$ENV:TenantID/oauth2/v2.0/authorize?client_id=$ENV:ApplicationID&response_type=code&redirect_uri=$ResponseURL&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default+offline_access+profile+openid&state=1&prompt=select_account" + applicationId = $env:ApplicationID + tenantId = $env:TenantID + refreshUrl = "https://login.microsoftonline.com/$env:TenantID/oauth2/v2.0/authorize?client_id=$env:ApplicationID&response_type=code&redirect_uri=$ResponseURL&response_mode=query&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default+offline_access+profile+openid&state=1&prompt=select_account" } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPStatsTimer.ps1 b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPStatsTimer.ps1 index f7c53265b9d9..e8d56975c448 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPStatsTimer.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-CIPPStatsTimer.ps1 @@ -9,7 +9,7 @@ function Start-CIPPStatsTimer { #We will never ship any data that is related to your instance, all we care about is the number of tenants, and the version of the API you are running, and if you completed setup. if ($PSCmdlet.ShouldProcess('Start-CIPPStatsTimer', 'Starting CIPP Stats Timer')) { - if ($ENV:ApplicationID -ne 'LongApplicationID') { + if ($env:ApplicationID -ne 'LongApplicationID') { $SetupComplete = $true } $TenantCount = (Get-Tenants -IncludeAll).count diff --git a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-UpdateTokensTimer.ps1 b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-UpdateTokensTimer.ps1 index e065d4152245..3418faa6bff1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-UpdateTokensTimer.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-UpdateTokensTimer.ps1 @@ -26,10 +26,10 @@ function Start-UpdateTokensTimer { if ($env:MSI_SECRET) { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId } - $KV = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $KV = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] if ($Refreshtoken) { Set-AzKeyVaultSecret -VaultName $KV -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $Refreshtoken -AsPlainText -Force) } else { diff --git a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 index bb3cab727de7..3ac6f823e5ee 100644 --- a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 @@ -20,14 +20,14 @@ function Get-CIPPAuthentication { } } else { Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId - $keyvaultname = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $keyvaultname = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] $Variables | ForEach-Object { Set-Item -Path ENV:$_ -Value (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $_ -AsPlainText -ErrorAction Stop) -Force } } - $ENV:SetFromProfile = $true + $env:SetFromProfile = $true Write-LogMessage -message 'Reloaded authentication data from KeyVault' -Sev 'debug' -API 'CIPP Authentication' return $true diff --git a/Modules/CIPPCore/Public/Get-CIPPSchemaExtensions.ps1 b/Modules/CIPPCore/Public/Get-CIPPSchemaExtensions.ps1 index f4392cad0b53..cfc5ed0d9998 100644 --- a/Modules/CIPPCore/Public/Get-CIPPSchemaExtensions.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPSchemaExtensions.ps1 @@ -34,7 +34,7 @@ function Get-CIPPSchemaExtensions { $SchemaExtensions = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'SchemaExtension'" } - $Schemas = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/schemaExtensions?`$filter=owner eq '$($ENV:ApplicationID)'" -NoAuthCheck $true -AsApp $true | Where-Object { $_.status -ne 'Deprecated' } + $Schemas = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/schemaExtensions?`$filter=owner eq '$($env:ApplicationID)'" -NoAuthCheck $true -AsApp $true | Where-Object { $_.status -ne 'Deprecated' } foreach ($SchemaExtension in $SchemaExtensions) { $SchemaFound = $false diff --git a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 index 3c3448d5355a..f6e5decc9426 100644 --- a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 @@ -64,7 +64,7 @@ function Get-CIPPTextReplacement { $Text = $Text -replace '%tenantname%', $Tenant.displayName # Partner specific replacements - $Text = $Text -replace '%partnertenantid%', $ENV:TenantID - $Text = $Text -replace '%samappid%', $ENV:ApplicationID + $Text = $Text -replace '%partnertenantid%', $env:TenantID + $Text = $Text -replace '%samappid%', $env:ApplicationID return $Text } diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-ClassicAPIToken.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-ClassicAPIToken.ps1 index 5a10c27f1e38..23bd67941e56 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Get-ClassicAPIToken.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Get-ClassicAPIToken.ps1 @@ -11,7 +11,7 @@ function Get-ClassicAPIToken($tenantID, $Resource) { #Write-Host 'Using classic' $uri = "https://login.microsoftonline.com/$($TenantID)/oauth2/token" $Body = @{ - client_id = $ENV:ApplicationID + client_id = $env:ApplicationID client_secret = $env:ApplicationSecret resource = $Resource refresh_token = $env:RefreshToken diff --git a/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 b/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 index 9dca6bdc7b1f..acb67becb66e 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Remove-CIPPCache.ps1 @@ -39,7 +39,7 @@ function Remove-CIPPCache { Update-AzDataTableEntity -Force @DomainsTable -Entity $ClearDomainAnalyserRows } - $ENV:SetFromProfile = $null + $env:SetFromProfile = $null $Script:SkipListCache = $Null $Script:SkipListCacheEmpty = $Null $Script:IncludedTenantsCache = $Null diff --git a/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 b/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 index bdc198c10f8a..fddf94a26dfe 100644 --- a/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 @@ -15,11 +15,11 @@ function New-CIPPApplicationCopy { try { try { - $ExistingApp = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/applications(appId='$($app)')" -tenantid $ENV:TenantID -NoAuthCheck $true -AsApp $true + $ExistingApp = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/applications(appId='$($app)')" -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true $Type = 'Application' } catch { - $ExistingApp = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($app)')/oauth2PermissionGrants" -tenantid $ENV:TenantID -NoAuthCheck $true -AsApp $true - $ExistingAppRoleAssignments = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($app)')/appRoleAssignments" -tenantid $ENV:TenantID -NoAuthCheck $true -AsApp $true + $ExistingApp = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($app)')/oauth2PermissionGrants" -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true + $ExistingAppRoleAssignments = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($app)')/appRoleAssignments" -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true $Type = 'ServicePrincipal' } if (!$ExistingApp) { diff --git a/Modules/CIPPCore/Public/Set-CIPPCPVConsent.ps1 b/Modules/CIPPCore/Public/Set-CIPPCPVConsent.ps1 index 339e4e278a5a..d8b09f367017 100644 --- a/Modules/CIPPCore/Public/Set-CIPPCPVConsent.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPCPVConsent.ps1 @@ -20,8 +20,8 @@ function Set-CIPPCPVConsent { if ($ResetSP) { try { - if ($PSCmdlet.ShouldProcess($ENV:ApplicationID, "Delete Service Principal from $TenantName")) { - $null = New-GraphPostRequest -Type DELETE -noauthcheck $true -uri "https://api.partnercenter.microsoft.com/v1/customers/$($TenantFilter)/applicationconsents/$($ENV:ApplicationID)" -scope 'https://api.partnercenter.microsoft.com/.default' -tenantid $env:TenantID + if ($PSCmdlet.ShouldProcess($env:ApplicationID, "Delete Service Principal from $TenantName")) { + $null = New-GraphPostRequest -Type DELETE -noauthcheck $true -uri "https://api.partnercenter.microsoft.com/v1/customers/$($TenantFilter)/applicationconsents/$($env:ApplicationID)" -scope 'https://api.partnercenter.microsoft.com/.default' -tenantid $env:TenantID } $Results.add("Deleted Service Principal from $TenantName") } catch { @@ -32,7 +32,7 @@ function Set-CIPPCPVConsent { try { $AppBody = @{ - ApplicationId = $($ENV:ApplicationID) + ApplicationId = $($env:ApplicationID) ApplicationGrants = @( @{ EnterpriseApplicationId = '00000003-0000-0000-c000-000000000000' @@ -45,13 +45,13 @@ function Set-CIPPCPVConsent { ) } | ConvertTo-Json - if ($PSCmdlet.ShouldProcess($ENV:ApplicationID, "Add Service Principal to $TenantName")) { + if ($PSCmdlet.ShouldProcess($env:ApplicationID, "Add Service Principal to $TenantName")) { $null = New-GraphpostRequest -body $AppBody -Type POST -noauthcheck $true -uri "https://api.partnercenter.microsoft.com/v1/customers/$($TenantFilter)/applicationconsents" -scope 'https://api.partnercenter.microsoft.com/.default' -tenantid $env:TenantID $Table = Get-CIPPTable -TableName cpvtenants $unixtime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds $GraphRequest = @{ LastApply = "$unixtime" - applicationId = "$($ENV:ApplicationID)" + applicationId = "$($env:ApplicationID)" Tenant = "$($tenantfilter)" PartitionKey = 'Tenant' RowKey = "$($tenantfilter)" @@ -67,7 +67,7 @@ function Set-CIPPCPVConsent { $unixtime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds $GraphRequest = @{ LastApply = "$unixtime" - applicationId = "$($ENV:ApplicationID)" + applicationId = "$($env:ApplicationID)" Tenant = "$($tenantfilter)" PartitionKey = 'Tenant' RowKey = "$($tenantfilter)" diff --git a/Modules/CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1 b/Modules/CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1 index 46eddbd432fd..e5063c0ecc62 100644 --- a/Modules/CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1 @@ -32,9 +32,9 @@ function Set-CIPPSAMAdminRoles { } if (($SAMRoles | Measure-Object).count -gt 0 -and $Tenants -contains $TenantFilter -or $Tenants -contains 'AllTenants') { - $AppMemberOf = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($ENV:ApplicationID)')/memberOf/#microsoft.graph.directoryRole" -tenantid $TenantFilter -AsApp $true + $AppMemberOf = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($env:ApplicationID)')/memberOf/#microsoft.graph.directoryRole" -tenantid $TenantFilter -AsApp $true - $sp = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($ENV:ApplicationID)')?`$select=id,displayName" -tenantid $TenantFilter -AsApp $true) + $sp = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($env:ApplicationID)')?`$select=id,displayName" -tenantid $TenantFilter -AsApp $true) $id = $sp.id $Requests = $SAMRoles | Where-Object { $AppMemberOf.roleTemplateId -notcontains $_.value } | ForEach-Object { @@ -54,13 +54,13 @@ function Set-CIPPSAMAdminRoles { if (($Requests | Measure-Object).count -gt 0) { $HasFailures = $false try { - $null = New-ExoRequest -cmdlet 'New-ServicePrincipal' -cmdParams @{AppId = $ENV:ApplicationID; ObjectId = $id; DisplayName = 'CIPP-SAM' } -Compliance -tenantid $TenantFilter -useSystemMailbox $true -AsApp + $null = New-ExoRequest -cmdlet 'New-ServicePrincipal' -cmdParams @{AppId = $env:ApplicationID; ObjectId = $id; DisplayName = 'CIPP-SAM' } -Compliance -tenantid $TenantFilter -useSystemMailbox $true -AsApp $ActionLogs.Add('Added Service Principal to Compliance Center') } catch { $ActionLogs.Add('Service Principal already added to Compliance Center') } try { - $null = New-ExoRequest -cmdlet 'New-ServicePrincipal' -cmdParams @{AppId = $ENV:ApplicationID; ObjectId = $id; DisplayName = 'CIPP-SAM' } -tenantid $TenantFilter -useSystemMailbox $true -AsApp + $null = New-ExoRequest -cmdlet 'New-ServicePrincipal' -cmdParams @{AppId = $env:ApplicationID; ObjectId = $id; DisplayName = 'CIPP-SAM' } -tenantid $TenantFilter -useSystemMailbox $true -AsApp $ActionLogs.Add('Added Service Principal to Exchange Online') } catch { $ActionLogs.Add('Service Principal already added to Exchange Online') diff --git a/Modules/CIPPCore/Public/Test-CIPPAccessPermissions.ps1 b/Modules/CIPPCore/Public/Test-CIPPAccessPermissions.ps1 index a688a09160df..8aab1f89a830 100644 --- a/Modules/CIPPCore/Public/Test-CIPPAccessPermissions.ps1 +++ b/Modules/CIPPCore/Public/Test-CIPPAccessPermissions.ps1 @@ -35,12 +35,12 @@ function Test-CIPPAccessPermissions { try { Disable-AzContextAutosave -Scope Process | Out-Null $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId - $KV = $ENV:WEBSITE_DEPLOYMENT_ID + $KV = $env:WEBSITE_DEPLOYMENT_ID $KeyVaultRefresh = Get-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -AsPlainText - if ($ENV:RefreshToken -ne $KeyVaultRefresh) { + if ($env:RefreshToken -ne $KeyVaultRefresh) { $Success = $false $ErrorMessages.Add('Your refresh token does not match key vault, wait 30 minutes for the function app to update.') | Out-Null } else { diff --git a/Modules/CIPPCore/Public/Test-CIPPAccessTenant.ps1 b/Modules/CIPPCore/Public/Test-CIPPAccessTenant.ps1 index 1779f526d694..a54a22d5cc2e 100644 --- a/Modules/CIPPCore/Public/Test-CIPPAccessTenant.ps1 +++ b/Modules/CIPPCore/Public/Test-CIPPAccessTenant.ps1 @@ -75,7 +75,7 @@ function Test-CIPPAccessTenant { foreach ($RoleId in $ExpectedRoles) { $GraphRole = $GDAPRolesGraph.body.value | Where-Object -Property roleDefinitionId -EQ $RoleId.Id - $Role = $GraphRole.principal | Where-Object -Property organizationId -EQ $ENV:TenantID + $Role = $GraphRole.principal | Where-Object -Property organizationId -EQ $env:TenantID if (!$Role) { $MissingRoles.Add( diff --git a/Modules/CIPPCore/Public/Test-CIPPGDAPRelationships.ps1 b/Modules/CIPPCore/Public/Test-CIPPGDAPRelationships.ps1 index 80af8e6b09ef..b9b16bbc0db6 100644 --- a/Modules/CIPPCore/Public/Test-CIPPGDAPRelationships.ps1 +++ b/Modules/CIPPCore/Public/Test-CIPPGDAPRelationships.ps1 @@ -10,7 +10,7 @@ function Test-CIPPGDAPRelationships { $MissingGroups = [System.Collections.Generic.List[object]]@() try { #Get graph request to list all relationships. - $Relationships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships?`$filter=status eq 'active'" -tenantid $ENV:TenantID -NoAuthCheck $true + $Relationships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships?`$filter=status eq 'active'" -tenantid $env:TenantID -NoAuthCheck $true #Group relationships by tenant. The tenant information is in $relationships.customer.TenantId. $RelationshipsByTenant = $Relationships | Group-Object -Property { $_.customer.TenantId } foreach ($Tenant in $RelationshipsByTenant) { diff --git a/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 b/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 index f10c4775a2f3..c637735dfe12 100644 --- a/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 +++ b/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 @@ -20,9 +20,9 @@ function Get-ExtensionAPIKey { $DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets' $APIKey = (Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq '$Extension' and RowKey eq '$Extension'").APIKey } else { - $keyvaultname = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $keyvaultname = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId $APIKey = (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $Extension -AsPlainText) } diff --git a/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 b/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 index 59b741f9c52a..0a084cb3bcdd 100644 --- a/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 +++ b/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 @@ -23,9 +23,9 @@ function Set-ExtensionAPIKey { } Add-CIPPAzDataTableEntity @DevSecretsTable -Entity $Secret -Force } else { - $keyvaultname = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $keyvaultname = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId $null = Set-AzKeyVaultSecret -VaultName $keyvaultname -Name $Extension -SecretValue (ConvertTo-SecureString -AsPlainText -Force -String $APIKey) } diff --git a/Modules/CippExtensions/Public/Gradient/Get-GradientToken.ps1 b/Modules/CippExtensions/Public/Gradient/Get-GradientToken.ps1 index d59430b67a79..5965ec745c10 100644 --- a/Modules/CippExtensions/Public/Gradient/Get-GradientToken.ps1 +++ b/Modules/CippExtensions/Public/Gradient/Get-GradientToken.ps1 @@ -4,9 +4,9 @@ function Get-GradientToken { ) if ($Configuration.vendorKey) { $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId - $keyvaultname = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $keyvaultname = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] $partnerApiKey = (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name 'Gradient' -AsPlainText) $authorizationToken = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$($configuration.vendorKey):$($partnerApiKey)")) diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 index 69bc4f3fec45..acdb9ab21146 100644 --- a/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 @@ -9,20 +9,20 @@ function Get-HIBPAuth { $Secret = (Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'HIBP' and RowKey eq 'HIBP'").APIKey } else { $null = Connect-AzAccount -Identity - $SubscriptionId = $ENV:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 + $SubscriptionId = $env:WEBSITE_OWNER_NAME -split '\+' | Select-Object -First 1 $null = Set-AzContext -SubscriptionId $SubscriptionId - $VaultName = ($ENV:WEBSITE_DEPLOYMENT_ID -split '-')[0] + $VaultName = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] try { $Secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name 'HIBP' -AsPlainText -ErrorAction Stop } catch { $Secret = $null } - if ([string]::IsNullOrEmpty($Secret) -and $ENV:CIPP_HOSTED -eq 'true') { + if ([string]::IsNullOrEmpty($Secret) -and $env:CIPP_HOSTED -eq 'true') { $VaultName = 'hibp-kv' - if ($SubscriptionId -ne $ENV:CIPP_HOSTED_KV_SUB -and $ENV:CIPP_HOSTED_KV_SUB -match '^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$') { - $null = Set-AzContext -SubscriptionId $ENV:CIPP_HOSTED_KV_SUB + if ($SubscriptionId -ne $env:CIPP_HOSTED_KV_SUB -and $env:CIPP_HOSTED_KV_SUB -match '^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$') { + $null = Set-AzContext -SubscriptionId $env:CIPP_HOSTED_KV_SUB } $Secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name 'HIBP' -AsPlainText } @@ -31,7 +31,7 @@ function Get-HIBPAuth { } return @{ - 'User-Agent' = "CIPP-$($ENV:TenantID)" + 'User-Agent' = "CIPP-$($env:TenantID)" 'Accept' = 'application/json' 'api-version' = '3' 'hibp-api-key' = $Secret diff --git a/Tools/Update-LicenseSKUFiles.ps1 b/Tools/Update-LicenseSKUFiles.ps1 index e3f41a4df698..e21817d57f18 100644 --- a/Tools/Update-LicenseSKUFiles.ps1 +++ b/Tools/Update-LicenseSKUFiles.ps1 @@ -24,7 +24,7 @@ Needs to be run from the "Tools" folder in the CIPP-API project. # Download the latest license SKU CSV file from Microsoft. Saved to the TEMP folder to circumvent a bug where "???" is added to the first property name. $licenseCsvURL = 'https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv' -$TempLicenseDataFile = "$ENV:TEMP\LicenseSKUs.csv" +$TempLicenseDataFile = "$env:TEMP\LicenseSKUs.csv" Invoke-WebRequest -Uri $licenseCsvURL -OutFile $TempLicenseDataFile $LicenseDataFile = Get-Item -Path $TempLicenseDataFile $LicenseData = Import-Csv -Path $LicenseDataFile.FullName -Encoding utf8BOM -Delimiter ',' diff --git a/profile.ps1 b/profile.ps1 index 5230a3b5561d..9fa3401f75db 100644 --- a/profile.ps1 +++ b/profile.ps1 @@ -38,7 +38,7 @@ try { } catch {} try { - if (!$ENV:SetFromProfile) { + if (!$env:SetFromProfile) { Write-Information "We're reloading from KV" $Auth = Get-CIPPAuthentication } From de7404b9df361337c085596e61bf9a1cc2c65389 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:30:50 -0400 Subject: [PATCH 029/123] Update Invoke-ExecApiClient.ps1 --- .../HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index e2f716272200..c09cd181d06a 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -101,6 +101,8 @@ function Invoke-ExecApiClient { 'GetAzureConfiguration' { $RGName = $env:WEBSITE_RESOURCE_GROUP $FunctionAppName = $env:WEBSITE_SITE_NAME + Write-Information "All environment vars: " + Write-Information ([System.Environment]::GetEnvironmentVariables() | ConvertTo-Json -Depth 10) try { $APIClients = Get-CippApiAuth -RGName $RGName -FunctionAppName $FunctionAppName $Results = $ApiClients From 66c25ef30414f7ebd47aa20dd36c4854b137236c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 18:44:09 -0400 Subject: [PATCH 030/123] fix resource group name --- .../CIPP/Settings/Invoke-ExecApiClient.ps1 | 11 +++++++-- .../CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 23 ++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index c09cd181d06a..19b0fc3cf9df 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -99,10 +99,13 @@ function Invoke-ExecApiClient { } } 'GetAzureConfiguration' { + $Owner = $env:WEBSITE_OWNER_NAME $RGName = $env:WEBSITE_RESOURCE_GROUP + if (!$RGName) { + $RGName = $Owner -split '\+' | Select-Object -Last 1 + $RGName = $RGName -replace '-[^-]+$', '' + } $FunctionAppName = $env:WEBSITE_SITE_NAME - Write-Information "All environment vars: " - Write-Information ([System.Environment]::GetEnvironmentVariables() | ConvertTo-Json -Depth 10) try { $APIClients = Get-CippApiAuth -RGName $RGName -FunctionAppName $FunctionAppName $Results = $ApiClients @@ -119,6 +122,10 @@ function Invoke-ExecApiClient { 'SaveToAzure' { $TenantId = $env:TenantId $RGName = $env:WEBSITE_RESOURCE_GROUP + if (!$RGName) { + $RGName = $Owner -split '\+' | Select-Object -Last 1 + $RGName = $RGName -replace '-[^-]+$', '' + } $FunctionAppName = $env:WEBSITE_SITE_NAME $AllClients = Get-CIPPAzDataTableEntity @Table -Filter 'Enabled eq true' | Where-Object { ![string]::IsNullOrEmpty($_.RowKey) } $ClientIds = $AllClients.RowKey diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 20e7303baade..4fd3d796f744 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -18,16 +18,23 @@ Function Invoke-ExecBackendURLs { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' + $RGName = $env:WEBSITE_RESOURCE_GROUP + if (!$RGName) { + $Owner = $env:WEBSITE_OWNER_NAME + $RGName = $Owner -split '\+' | Select-Object -Last 1 + $RGName = $RGName -replace '-[^-]+$', '' + } + $results = [PSCustomObject]@{ - ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/overview" - KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$($env:WEBSITE_SITE_NAME)/secrets" - FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/appServices" - FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/configuration" - FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/vstscd" - SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/customDomains" - SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" + ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/overview" + KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.KeyVault/vaults/$($env:WEBSITE_SITE_NAME)/secrets" + FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/appServices" + FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/configuration" + FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/vstscd" + SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.Web/staticSites/$SWAName/customDomains" + SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$RGName/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" Subscription = $Subscription - RGName = $env:WEBSITE_RESOURCE_GROUP + RGName = $RGName FunctionName = $env:WEBSITE_SITE_NAME SWAName = $SWAName } From 7b22228c9e6c1a1b6c8ecb3f5e980b04528f6b45 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 19:02:43 -0400 Subject: [PATCH 031/123] fix RGName issue --- .../CIPP/Settings/Invoke-ExecApiClient.ps1 | 13 +++++-------- .../CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 8 +++----- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index 19b0fc3cf9df..e9159dc66b0c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -100,10 +100,8 @@ function Invoke-ExecApiClient { } 'GetAzureConfiguration' { $Owner = $env:WEBSITE_OWNER_NAME - $RGName = $env:WEBSITE_RESOURCE_GROUP - if (!$RGName) { - $RGName = $Owner -split '\+' | Select-Object -Last 1 - $RGName = $RGName -replace '-[^-]+$', '' + if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { + $RGName = $Matches.RGName } $FunctionAppName = $env:WEBSITE_SITE_NAME try { @@ -121,10 +119,9 @@ function Invoke-ExecApiClient { } 'SaveToAzure' { $TenantId = $env:TenantId - $RGName = $env:WEBSITE_RESOURCE_GROUP - if (!$RGName) { - $RGName = $Owner -split '\+' | Select-Object -Last 1 - $RGName = $RGName -replace '-[^-]+$', '' + $Owner = $env:WEBSITE_OWNER_NAME + if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { + $RGName = $Matches.RGName } $FunctionAppName = $env:WEBSITE_SITE_NAME $AllClients = Get-CIPPAzDataTableEntity @Table -Filter 'Enabled eq true' | Where-Object { ![string]::IsNullOrEmpty($_.RowKey) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 4fd3d796f744..2b59b9ad3e43 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -18,11 +18,9 @@ Function Invoke-ExecBackendURLs { # Write to the Azure Functions log stream. Write-Host 'PowerShell HTTP trigger function processed a request.' - $RGName = $env:WEBSITE_RESOURCE_GROUP - if (!$RGName) { - $Owner = $env:WEBSITE_OWNER_NAME - $RGName = $Owner -split '\+' | Select-Object -Last 1 - $RGName = $RGName -replace '-[^-]+$', '' + $Owner = $env:WEBSITE_OWNER_NAME + if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { + $RGName = $Matches.RGName } $results = [PSCustomObject]@{ From f7d6a536dbbe99bdb92474b0fcf7ad9b815261dd Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 19:09:09 -0400 Subject: [PATCH 032/123] more casing --- .../HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 | 6 +++++- .../HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 2 ++ .../HTTP Functions/CIPP/Settings/Invoke-ExecCustomData.ps1 | 6 +++--- .../Start-UpdatePermissionsOrchestrator.ps1 | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index e9159dc66b0c..e36d73550e9e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -102,6 +102,8 @@ function Invoke-ExecApiClient { $Owner = $env:WEBSITE_OWNER_NAME if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { $RGName = $Matches.RGName + } else { + $RGName = $env:WEBSITE_RESOURCE_GROUP } $FunctionAppName = $env:WEBSITE_SITE_NAME try { @@ -118,10 +120,12 @@ function Invoke-ExecApiClient { } } 'SaveToAzure' { - $TenantId = $env:TenantId + $TenantId = $env:TenantID $Owner = $env:WEBSITE_OWNER_NAME if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { $RGName = $Matches.RGName + } else { + $RGName = $env:WEBSITE_RESOURCE_GROUP } $FunctionAppName = $env:WEBSITE_SITE_NAME $AllClients = Get-CIPPAzDataTableEntity @Table -Filter 'Enabled eq true' | Where-Object { ![string]::IsNullOrEmpty($_.RowKey) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index 2b59b9ad3e43..e83296b15240 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -21,6 +21,8 @@ Function Invoke-ExecBackendURLs { $Owner = $env:WEBSITE_OWNER_NAME if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { $RGName = $Matches.RGName + } else { + $RGName = $env:WEBSITE_RESOURCE_GROUP } $results = [PSCustomObject]@{ diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomData.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomData.ps1 index 3ec3ca2f732c..739360e5f5e9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomData.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCustomData.ps1 @@ -230,7 +230,7 @@ function Invoke-ExecCustomData { } 'ListDirectoryExtensions' { try { - $Uri = "https://graph.microsoft.com/beta/applications(appId='$($env:ApplicationId)')/extensionProperties" + $Uri = "https://graph.microsoft.com/beta/applications(appId='$($env:ApplicationID)')/extensionProperties" $DirectoryExtensions = New-GraphGetRequest -uri $Uri -AsApp $true -NoAuthCheck $true -tenantid $env:TenantID $Existing = Get-CIPPAzDataTableEntity @CustomDataTable -Filter "PartitionKey eq 'DirectoryExtension'" @@ -271,7 +271,7 @@ function Invoke-ExecCustomData { throw 'Extension name, data type, and target objects are required.' } - $AppId = $env:ApplicationId # Replace with your application ID + $AppId = $env:ApplicationID # Replace with your application ID $Uri = "https://graph.microsoft.com/beta/applications(appId='$AppId')/extensionProperties" $BodyContent = @{ @@ -316,7 +316,7 @@ function Invoke-ExecCustomData { if (!$ExtensionName) { throw 'Extension name is missing in the request body.' } - $AppId = $env:ApplicationId # Replace with your application ID + $AppId = $env:ApplicationID # Replace with your application ID $Uri = "https://graph.microsoft.com/beta/applications(appId='$AppId')/extensionProperties/$ExtensionId" # Delete the directory extension from Microsoft Graph diff --git a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UpdatePermissionsOrchestrator.ps1 b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UpdatePermissionsOrchestrator.ps1 index 599c57572ba0..10caa27d3383 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UpdatePermissionsOrchestrator.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UpdatePermissionsOrchestrator.ps1 @@ -10,9 +10,9 @@ function Start-UpdatePermissionsOrchestrator { Write-Information 'Updating Permissions' $PartnerTenant = @{ - 'customerId' = $env:TenantID + 'customerId' = $env:TenantID 'defaultDomainName' = 'PartnerTenant' - 'displayName' = '*Partner Tenant' + 'displayName' = '*Partner Tenant' } $TenantList = Get-Tenants -IncludeAll | Where-Object { $_.Excluded -eq $false } From 88fa2f455663a59d91f1863038754981ddb80a4b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 31 Mar 2025 19:25:39 -0400 Subject: [PATCH 033/123] cleanup workflows --- .../workflows/dev-linux_cippipdsw-proc.yml | 40 ------------------- .github/workflows/dev-linux_cippipdsw.yml | 40 ------------------- 2 files changed, 80 deletions(-) delete mode 100644 .github/workflows/dev-linux_cippipdsw-proc.yml delete mode 100644 .github/workflows/dev-linux_cippipdsw.yml diff --git a/.github/workflows/dev-linux_cippipdsw-proc.yml b/.github/workflows/dev-linux_cippipdsw-proc.yml deleted file mode 100644 index 3f657a0e1a10..000000000000 --- a/.github/workflows/dev-linux_cippipdsw-proc.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cippipdsw-proc - -on: - push: - branches: - - dev-linux - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_5A2D1D006C6E45F4B94B9B694DD03DD4 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_34D61F116C6840A9A1F59E61F80ACDDB }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_F575F8CFE71D4F93B850075D55E5654C }} - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cippipdsw-proc' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - \ No newline at end of file diff --git a/.github/workflows/dev-linux_cippipdsw.yml b/.github/workflows/dev-linux_cippipdsw.yml deleted file mode 100644 index 85760d1099d5..000000000000 --- a/.github/workflows/dev-linux_cippipdsw.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cippipdsw - -on: - push: - branches: - - dev-linux - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_ACAE509CF8BA43B5B505A4749C4C9D23 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_11381FD8EE6847A9AAEF51178BBD1ED1 }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_F530195CFD74405291D01F63FD5BC8C9 }} - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cippipdsw' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - \ No newline at end of file From f585bd8974df4095272536346b1ace485e484820 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 1 Apr 2025 20:04:51 +0200 Subject: [PATCH 034/123] update group assignment --- .../Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index dbe976dcc67a..b75e17b924a6 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -86,6 +86,7 @@ function Invoke-CIPPStandardIntuneTemplate { remediate = $Template.remediate existingPolicyId = $ExistingPolicy.id templateId = $Template.TemplateList.value + customGroup = $Template.customGroup } } else { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - No differences found." @@ -101,6 +102,7 @@ function Invoke-CIPPStandardIntuneTemplate { remediate = $Template.remediate existingPolicyId = $ExistingPolicy.id templateId = $Template.TemplateList.value + customGroup = $Template.customGroup } } } From 3c18f8b7c5a68a8644d3b78f764d8a647b9b9ad0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 1 Apr 2025 20:09:40 +0200 Subject: [PATCH 035/123] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/dev_cippyumsh-proc.yml | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/dev_cippyumsh-proc.yml diff --git a/.github/workflows/dev_cippyumsh-proc.yml b/.github/workflows/dev_cippyumsh-proc.yml new file mode 100644 index 000000000000..9a3397c76f00 --- /dev/null +++ b/.github/workflows/dev_cippyumsh-proc.yml @@ -0,0 +1,30 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cippyumsh-proc + +on: + push: + branches: + - dev + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: windows-latest + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cippyumsh-proc' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_8AA04F8C6F644F639CD74D3816E1BF08 }} \ No newline at end of file From c16a234c2acdbbe10aa5af4649e2d8e8b4ee6bc9 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 1 Apr 2025 22:27:11 +0200 Subject: [PATCH 036/123] Add or update the Azure App Service build and deployment workflow config --- .github/workflows/dev_cippyumsh.yml | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/dev_cippyumsh.yml diff --git a/.github/workflows/dev_cippyumsh.yml b/.github/workflows/dev_cippyumsh.yml new file mode 100644 index 000000000000..a57b998e592e --- /dev/null +++ b/.github/workflows/dev_cippyumsh.yml @@ -0,0 +1,30 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy Powershell project to Azure Function App - cippyumsh + +on: + push: + branches: + - dev + workflow_dispatch: + +env: + AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + +jobs: + deploy: + runs-on: windows-latest + + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 + id: fa + with: + app-name: 'cippyumsh' + slot-name: 'Production' + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_76BFD48D41B64AF88AC8D0A234746FF1 }} \ No newline at end of file From 434ffa90ebd3e044017128a5b282a188e2554d69 Mon Sep 17 00:00:00 2001 From: Esco Date: Wed, 2 Apr 2025 10:27:25 +0200 Subject: [PATCH 037/123] fix: corrected DisableAddShortcutsToOneDrive compare show incorrect state --- ...-CIPPStandardDisableAddShortcutsToOneDrive.ps1 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAddShortcutsToOneDrive.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAddShortcutsToOneDrive.ps1 index edb8573df599..d4171ac615fd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAddShortcutsToOneDrive.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAddShortcutsToOneDrive.ps1 @@ -33,11 +33,6 @@ function Invoke-CIPPStandardDisableAddShortcutsToOneDrive { $CurrentState = Get-CIPPSPOTenant -TenantFilter $Tenant | Select-Object _ObjectIdentity_, TenantFilter, DisableAddToOneDrive - if ($Settings.report -eq $true) { - Set-CIPPStandardsCompareField -FieldName 'standards.DisableAddShortcutsToOneDrive' -FieldValue $CurrentState.DisableAddToOneDrive -TenantFilter $Tenant - Add-CIPPBPAField -FieldName 'OneDriveAddShortcutButtonDisabled' -FieldValue $CurrentState.DisableAddToOneDrive -StoreAs bool -Tenant $Tenant - } - # Input validation $StateValue = $Settings.state.value ?? $Settings.state if (([string]::IsNullOrWhiteSpace($StateValue) -or $StateValue -eq 'Select a value') -and ($Settings.remediate -eq $true -or $Settings.alert -eq $true)) { @@ -49,6 +44,16 @@ function Invoke-CIPPStandardDisableAddShortcutsToOneDrive { $StateIsCorrect = if ($CurrentState.DisableAddToOneDrive -eq $WantedState) { $true } else { $false } $HumanReadableState = if ($WantedState -eq $true) { 'disabled' } else { 'enabled' } + if ($Settings.report -eq $true) { + if ($StateIsCorrect -eq $true) { + $FieldValue = $true + } else { + $FieldValue = $CurrentState | Select-Object -Property DisableAddToOneDrive + } + Set-CIPPStandardsCompareField -FieldName 'standards.DisableAddShortcutsToOneDrive' -FieldValue $FieldValue -TenantFilter $Tenant + Add-CIPPBPAField -FieldName 'OneDriveAddShortcutButtonDisabled' -FieldValue $CurrentState.DisableAddToOneDrive -StoreAs bool -Tenant $Tenant + } + If ($Settings.remediate -eq $true) { Write-Host 'Time to remediate' From 05148589a505fdb359aeee45c8254f8dde6fa143 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 10:25:46 -0400 Subject: [PATCH 038/123] update alert handling for run from package --- .../HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 index b59e276df628..8e80f541ed8f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-GetCippAlerts.ps1 @@ -1,6 +1,6 @@ using namespace System.Net -Function Invoke-GetCippAlerts { +function Invoke-GetCippAlerts { <# .FUNCTIONALITY Entrypoint,AnyTenant @@ -60,7 +60,7 @@ Function Invoke-GetCippAlerts { type = 'error' }) } - if ($env:WEBSITE_RUN_FROM_PACKAGE -ne '1' -and $env:AzureWebJobsStorage -ne 'UseDevelopmentStorage=true') { + if ((!$env:WEBSITE_RUN_FROM_PACKAGE -or [string]::IsNullOrEmpty($env:WEBSITE_RUN_FROM_PACKAGE)) -and $env:AzureWebJobsStorage -ne 'UseDevelopmentStorage=true') { $Alerts.Add( @{ title = 'Function App in Write Mode' From 30f151b48448c591992a8958f708644fae956db3 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 10:25:57 -0400 Subject: [PATCH 039/123] fix empty defender alert list --- .../HTTP Functions/Security/Invoke-ExecAlertsList.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 index 1ab2243b5b63..04f876786b21 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Security/Invoke-ExecAlertsList.ps1 @@ -43,6 +43,10 @@ Function Invoke-ExecAlertsList { } $DisplayableAlerts = New-FlatArray $AlertsObj | Where-Object { $null -ne $_.Id } | Sort-Object -Property EventDateTime -Descending + if (!$DisplayableAlerts) { + $DisplayableAlerts = @() + } + $Metadata = [PSCustomObject]@{} [PSCustomObject]@{ NewAlertsCount = $DisplayableAlerts | Where-Object { $_.Status -eq 'newAlert' } | Measure-Object | Select-Object -ExpandProperty Count @@ -51,7 +55,7 @@ Function Invoke-ExecAlertsList { SeverityMediumAlertsCount = $DisplayableAlerts | Where-Object { ($_.Status -eq 'inProgress') -or ($_.Status -eq 'newAlert') } | Where-Object { $_.Severity -eq 'medium' } | Measure-Object | Select-Object -ExpandProperty Count SeverityLowAlertsCount = $DisplayableAlerts | Where-Object { ($_.Status -eq 'inProgress') -or ($_.Status -eq 'newAlert') } | Where-Object { $_.Severity -eq 'low' } | Measure-Object | Select-Object -ExpandProperty Count SeverityInformationalCount = $DisplayableAlerts | Where-Object { ($_.Status -eq 'inProgress') -or ($_.Status -eq 'newAlert') } | Where-Object { $_.Severity -eq 'informational' } | Measure-Object | Select-Object -ExpandProperty Count - MSResults = $DisplayableAlerts + MSResults = @($DisplayableAlerts) } } else { $Table = Get-CIPPTable -TableName cachealertsandincidents From 635302f1fa84c1c2f1492dfb094b36b2355816bb Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 10:55:47 -0400 Subject: [PATCH 040/123] only create tenant mapping if the TenantId is actually set --- .../CippExtensions/Public/Halo/Set-HaloMapping.ps1 | 13 +++++++------ .../Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 b/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 index 30ae54a5e310..48d75df2af63 100644 --- a/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 +++ b/Modules/CippExtensions/Public/Halo/Set-HaloMapping.ps1 @@ -9,15 +9,16 @@ function Set-HaloMapping { Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } foreach ($Mapping in $Request.Body) { - $AddObject = @{ - PartitionKey = 'HaloMapping' - RowKey = "$($mapping.TenantId)" - IntegrationId = "$($mapping.IntegrationId)" - IntegrationName = "$($mapping.IntegrationName)" + if ($Mapping.TenantId) { + $AddObject = @{ + PartitionKey = 'HaloMapping' + RowKey = "$($mapping.TenantId)" + IntegrationId = "$($mapping.IntegrationId)" + IntegrationName = "$($mapping.IntegrationName)" + } } Add-CIPPAzDataTableEntity @CIPPMapping -Entity $AddObject -Force - Write-LogMessage -API $APINAME -headers $Request.Headers -message "Added mapping for $($mapping.name)." -Sev 'Info' } $Result = [pscustomobject]@{'Results' = 'Successfully edited mapping table.' } diff --git a/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 b/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 index b0798eca8230..ab2e745c8417 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Set-NinjaOneOrgMapping.ps1 @@ -10,15 +10,15 @@ function Set-NinjaOneOrgMapping { Remove-AzDataTableEntity -Force @CIPPMapping -Entity $_ } foreach ($Mapping in $Request.Body) { - $AddObject = @{ - PartitionKey = 'NinjaOneMapping' - RowKey = "$($mapping.TenantId)" - IntegrationId = "$($mapping.IntegrationId)" - IntegrationName = "$($mapping.IntegrationName)" + if ($Mapping.TenantId) { + $AddObject = @{ + PartitionKey = 'NinjaOneMapping' + RowKey = "$($mapping.TenantId)" + IntegrationId = "$($mapping.IntegrationId)" + IntegrationName = "$($mapping.IntegrationName)" + } } - Add-CIPPAzDataTableEntity @CIPPMapping -Entity $AddObject -Force - Write-LogMessage -API $APINAME -headers $Request.Headers -message "Added mapping for $($mapping.name)." -Sev 'Info' } $Result = [pscustomobject]@{'Results' = 'Successfully edited mapping table.' } From 303eface8c2cc29e894e1a422b337795578bdcfa Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 10:59:23 -0400 Subject: [PATCH 041/123] remove variable assignment --- .../HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 index 6e996b99c4fd..365961225ed8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 @@ -28,7 +28,7 @@ Function Invoke-ListTeamsVoice { $data = (New-TeamsAPIGetRequest -uri "https://api.interfaces.records.teams.microsoft.com/Skype.TelephoneNumberMgmt/Tenants/$($Tenantid)/telephone-numbers?skip=$($skip)&locale=en-US&top=999" -tenantid $TenantFilter).TelephoneNumbers | ForEach-Object { Write-Host 'Reached the loop' $CompleteRequest = $_ | Select-Object *, @{Name = 'AssignedTo'; Expression = { $users | Where-Object -Property id -EQ $_.AssignedTo.id } } - $CompleteRequest.AcquisitionDate ? ($CompleteRequest.AcquisitionDate = $CompleteRequest.AcquisitionDate -split 'T' | Select-Object -First 1) : ($CompleteRequest | Add-Member -NotePropertyName 'AcquisitionDate' -NotePropertyValue 'Unknown' -Force) + $CompleteRequest.AcquisitionDate ? ($CompleteRequest.AcquisitionDate -split 'T' | Select-Object -First 1) : ($CompleteRequest | Add-Member -NotePropertyName 'AcquisitionDate' -NotePropertyValue 'Unknown' -Force) $CompleteRequest.AssignedTo ? $null : ($CompleteRequest | Add-Member -NotePropertyName 'AssignedTo' -NotePropertyValue 'Unassigned' -Force) $CompleteRequest } From c5ca32ff6f0a67cabdfa56ea2f3b7dd63d1fcd91 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 12:00:12 -0400 Subject: [PATCH 042/123] Update Invoke-ListTeamsVoice.ps1 --- .../Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 index 365961225ed8..ec1f42f32217 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 @@ -28,7 +28,11 @@ Function Invoke-ListTeamsVoice { $data = (New-TeamsAPIGetRequest -uri "https://api.interfaces.records.teams.microsoft.com/Skype.TelephoneNumberMgmt/Tenants/$($Tenantid)/telephone-numbers?skip=$($skip)&locale=en-US&top=999" -tenantid $TenantFilter).TelephoneNumbers | ForEach-Object { Write-Host 'Reached the loop' $CompleteRequest = $_ | Select-Object *, @{Name = 'AssignedTo'; Expression = { $users | Where-Object -Property id -EQ $_.AssignedTo.id } } - $CompleteRequest.AcquisitionDate ? ($CompleteRequest.AcquisitionDate -split 'T' | Select-Object -First 1) : ($CompleteRequest | Add-Member -NotePropertyName 'AcquisitionDate' -NotePropertyValue 'Unknown' -Force) + if ($CompleteRequest.AcquisitionDate) { + $CompleteRequest.AcquisitionDate = $_.AcquisitionDate -split 'T' | Select-Object -First 1 + } else { + $CompleteRequest | Add-Member -NotePropertyName 'AcquisitionDate' -NotePropertyValue 'Unknown' -Force + } $CompleteRequest.AssignedTo ? $null : ($CompleteRequest | Add-Member -NotePropertyName 'AssignedTo' -NotePropertyValue 'Unassigned' -Force) $CompleteRequest } From 00d8c6c896bc2ee7db3127d680868e999fbdae29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 18:05:14 +0200 Subject: [PATCH 043/123] Fix variable naming and improve tenant filter handling in Invoke-ListTeamsVoice function --- .../Invoke-ListTeamsVoice.ps1 | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 index c825cfc11459..1367dc3a4537 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListTeamsVoice.ps1 @@ -14,26 +14,23 @@ Function Invoke-ListTeamsVoice { $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - - - # Interact with query parameters or the body of the request. - $TenantFilter = $Request.Query.TenantFilter - $tenantid = (Get-Tenants | Where-Object -Property defaultDomainName -EQ $Request.Query.TenantFilter).customerId + $TenantFilter = $Request.Query.tenantFilter + $TenantId = (Get-Tenants | Where-Object -Property defaultDomainName -EQ $TenantFilter).customerId try { - $users = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$top=999&`$select=id,userPrincipalName,displayName" -tenantid $TenantFilter) - $skip = 0 + $Users = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$top=999&`$select=id,userPrincipalName,displayName" -tenantid $TenantFilter) + $Skip = 0 $GraphRequest = do { - Write-Host "Getting page $skip" - $data = (New-TeamsAPIGetRequest -uri "https://api.interfaces.records.teams.microsoft.com/Skype.TelephoneNumberMgmt/Tenants/$($Tenantid)/telephone-numbers?skip=$($skip)&locale=en-US&top=999" -tenantid $TenantFilter).TelephoneNumbers | ForEach-Object { + Write-Host "Getting page $Skip" + $data = (New-TeamsAPIGetRequest -uri "https://api.interfaces.records.teams.microsoft.com/Skype.TelephoneNumberMgmt/Tenants/$($TenantId)/telephone-numbers?skip=$($Skip)&locale=en-US&top=999" -tenantid $TenantFilter).TelephoneNumbers | ForEach-Object { Write-Host 'Reached the loop' - $CompleteRequest = $_ | Select-Object *, @{Name = 'AssignedTo'; Expression = { $users | Where-Object -Property id -EQ $_.AssignedTo.id } } + $CompleteRequest = $_ | Select-Object *, @{Name = 'AssignedTo'; Expression = { $Users | Where-Object -Property id -EQ $_.AssignedTo.id } } $CompleteRequest.AcquisitionDate ? ($CompleteRequest.AcquisitionDate = $CompleteRequest.AcquisitionDate -split 'T' | Select-Object -First 1) : ($CompleteRequest | Add-Member -NotePropertyName 'AcquisitionDate' -NotePropertyValue 'Unknown' -Force) $CompleteRequest.AssignedTo ? $null : ($CompleteRequest | Add-Member -NotePropertyName 'AssignedTo' -NotePropertyValue 'Unassigned' -Force) $CompleteRequest } Write-Host 'Finished the loop' - $skip = $skip + 999 + $Skip = $Skip + 999 $Data } while ($data.Count -eq 999) Write-Host 'Exiting the Do.' From ca07732d297c4f4f20f82ac72dbacbb04594f8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 18:17:58 +0200 Subject: [PATCH 044/123] I DONT KNOW WHAT THIS COMMIT DOES --- .../GraphHelper/Get-NormalizedError.ps1 | 142 +++++++++--------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 index 12740aeb73e3..d1b36a42edff 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 @@ -1,71 +1,71 @@ -function Get-NormalizedError { - <# - .FUNCTIONALITY - Internal - #> - [CmdletBinding()] - param ( - [string]$message - ) - - #Check if the message is valid JSON. - try { - $JSONMsg = $message | ConvertFrom-Json - } catch { - } - #if the message is valid JSON, there can be multiple fields in which the error resides. These are: - # $message.error.Innererror.Message - # $message.error.Message - # $message.error.details.message - # $message.error.innererror.internalException.message - - #We need to check if the message is in one of these fields, and if so, return it. - if ($JSONMsg.error.innererror.message) { - Write-Host "innererror.message found: $($JSONMsg.error.innererror.message)" - $message = $JSONMsg.error.innererror.message - } elseif ($JSONMsg.error.message) { - Write-Host "error.message found: $($JSONMsg.error.message)" - $message = $JSONMsg.error.message - } elseif ($JSONMsg.error.details.message) { - Write-Host "error.details.message found: $($JSONMsg.error.details.message)" - $message = $JSONMsg.error.details.message - } elseif ($JSONMsg.error.innererror.internalException.message) { - Write-Host "error.innererror.internalException.message found: $($JSONMsg.error.innererror.internalException.message)" - $message = $JSONMsg.error.innererror.internalException.message - } - - - #finally, put the message through the translator. If it's not in the list, just return the original message - switch -Wildcard ($message) { - 'Request not applicable to target tenant.' { 'Required license not available for this tenant' } - "Neither tenant is B2C or tenant doesn't have premium license" { 'This feature requires a P1 license or higher' } - 'Response status code does not indicate success: 400 (Bad Request).' { 'Error 400 occured. There is an issue with the token configuration for this tenant. Please perform an access check' } - '*Microsoft.Skype.Sync.Pstn.Tnm.Common.Http.HttpResponseException*' { 'Could not connect to Teams Admin center - Tenant might be missing a Teams license' } - '*Provide valid credential.*' { 'Error 400: There is an issue with your Exchange Token configuration. Please perform an access check for this tenant' } - '*This indicate that a subscription within the tenant has lapsed*' { 'There is subscription for this service available, Check licensing information.' } - '*User was not found.*' { 'The relationship between this tenant and the partner has been dissolved from the tenant side.' } - '*AADSTS50020*' { 'AADSTS50020: The user you have used for your Secure Application Model is a guest in this tenant, or your are using GDAP and have not added the user to the correct group. Please delete the guest user to gain access to this tenant' } - '*AADSTS50177' { 'AADSTS50177: The user you have used for your Secure Application Model is a guest in this tenant, or your are using GDAP and have not added the user to the correct group. Please delete the guest user to gain access to this tenant' } - '*invalid or malformed*' { 'The request is malformed. Have you finished the SAM Setup?' } - '*Windows Store repository apps feature is not supported for this tenant*' { 'This tenant does not have WinGet support available' } - '*AADSTS650051*' { 'The application does not exist yet. Try again in 30 seconds.' } - '*AppLifecycle_2210*' { 'Failed to call Intune APIs: Does the tenant have a license available?' } - '*One or more added object references already exist for the following modified properties:*' { 'This user is already a member of this group.' } - '*Microsoft.Exchange.Management.Tasks.MemberAlreadyExistsException*' { 'This user is already a member of this group.' } - '*The property value exceeds the maximum allowed size (64KB)*' { 'One of the values exceeds the maximum allowed size (64KB).' } - '*Unable to initialize the authorization context*' { 'Your GDAP configuration does not allow us to write to this tenant, please check your group mappings and tenant onboarding.' } - '*Providers.Common.V1.CoreException*' { '403 (Access Denied) - We cannot connect to this tenant.' } - '*Authentication failed. MFA required*' { 'Authentication failed. MFA required' } - '*Your tenant is not licensed for this feature.*' { 'Required license not available for this tenant' } - '*AADSTS65001*' { 'We cannot access this tenant as consent has not been given, please try refreshing the CPV permissions in the application settings menu.' } - '*AADSTS700082*' { 'The CIPP user access token has expired. Run the SAM Setup wizard to refresh your tokens.' } - '*Account is not provisioned.' { 'The account is not provisioned. You do not the correct M365 license to access this information..' } - '*AADSTS5000224*' { 'This resource is not available - Has this tenant been deleted?' } - '*AADSTS53003*' { 'Access has been blocked by Conditional Access policies. Please check the Conditional Access configuration documentation' } - '*AADSTS900023*' { 'This tenant is not available for this operation. Please check the selected tenant and try again.' } - '*AADSTS9002313*' { 'The credentials used to connect to the Graph API are not available, please retry. If this issue persists you may need to execute the SAM wizard.' } - '*One or more platform(s) is/are not configured for the customer. Please configure the platform before trying to purchase a SKU.*' { 'One or more platform(s) is/are not configured for the customer. Please configure the platform before trying to purchase a SKU.' } - Default { $message } - - } -} +function Get-NormalizedError { + <# + .FUNCTIONALITY + Internal + #> + [CmdletBinding()] + param ( + [string]$message + ) + + #Check if the message is valid JSON. + try { + $JSONMsg = $message | ConvertFrom-Json + } catch { + } + #if the message is valid JSON, there can be multiple fields in which the error resides. These are: + # $message.error.Innererror.Message + # $message.error.Message + # $message.error.details.message + # $message.error.innererror.internalException.message + + #We need to check if the message is in one of these fields, and if so, return it. + if ($JSONMsg.error.innererror.message) { + Write-Host "innererror.message found: $($JSONMsg.error.innererror.message)" + $message = $JSONMsg.error.innererror.message + } elseif ($JSONMsg.error.message) { + Write-Host "error.message found: $($JSONMsg.error.message)" + $message = $JSONMsg.error.message + } elseif ($JSONMsg.error.details.message) { + Write-Host "error.details.message found: $($JSONMsg.error.details.message)" + $message = $JSONMsg.error.details.message + } elseif ($JSONMsg.error.innererror.internalException.message) { + Write-Host "error.innererror.internalException.message found: $($JSONMsg.error.innererror.internalException.message)" + $message = $JSONMsg.error.innererror.internalException.message + } + + + #finally, put the message through the translator. If it's not in the list, just return the original message + switch -Wildcard ($message) { + 'Request not applicable to target tenant.' { 'Required license not available for this tenant' } + "Neither tenant is B2C or tenant doesn't have premium license" { 'This feature requires a P1 license or higher' } + 'Response status code does not indicate success: 400 (Bad Request).' { 'Error 400 occured. There is an issue with the token configuration for this tenant. Please perform an access check' } + '*Microsoft.Skype.Sync.Pstn.Tnm.Common.Http.HttpResponseException*' { 'Could not connect to Teams Admin center - Tenant might be missing a Teams license' } + '*Provide valid credential.*' { 'Error 400: There is an issue with your Exchange Token configuration. Please perform an access check for this tenant' } + '*This indicate that a subscription within the tenant has lapsed*' { 'There is subscription for this service available, Check licensing information.' } + '*User was not found.*' { 'The relationship between this tenant and the partner has been dissolved from the tenant side.' } + '*AADSTS50020*' { 'AADSTS50020: The user you have used for your Secure Application Model is a guest in this tenant, or your are using GDAP and have not added the user to the correct group. Please delete the guest user to gain access to this tenant' } + '*AADSTS50177' { 'AADSTS50177: The user you have used for your Secure Application Model is a guest in this tenant, or your are using GDAP and have not added the user to the correct group. Please delete the guest user to gain access to this tenant' } + '*invalid or malformed*' { 'The request is malformed. Have you finished the SAM Setup?' } + '*Windows Store repository apps feature is not supported for this tenant*' { 'This tenant does not have WinGet support available' } + '*AADSTS650051*' { 'The application does not exist yet. Try again in 30 seconds.' } + '*AppLifecycle_2210*' { 'Failed to call Intune APIs: Does the tenant have a license available?' } + '*One or more added object references already exist for the following modified properties:*' { 'This user is already a member of this group.' } + '*Microsoft.Exchange.Management.Tasks.MemberAlreadyExistsException*' { 'This user is already a member of this group.' } + '*The property value exceeds the maximum allowed size (64KB)*' { 'One of the values exceeds the maximum allowed size (64KB).' } + '*Unable to initialize the authorization context*' { 'Your GDAP configuration does not allow us to write to this tenant, please check your group mappings and tenant onboarding.' } + '*Providers.Common.V1.CoreException*' { '403 (Access Denied) - We cannot connect to this tenant.' } + '*Authentication failed. MFA required*' { 'Authentication failed. MFA required' } + '*Your tenant is not licensed for this feature.*' { 'Required license not available for this tenant' } + '*AADSTS65001*' { 'We cannot access this tenant as consent has not been given, please try refreshing the CPV permissions in the application settings menu.' } + '*AADSTS700082*' { 'The CIPP user access token has expired. Run the SAM Setup wizard to refresh your tokens.' } + '*Account is not provisioned.' { 'The account is not provisioned. You do not the correct M365 license to access this information..' } + '*AADSTS5000224*' { 'This resource is not available - Has this tenant been deleted?' } + '*AADSTS53003*' { 'Access has been blocked by Conditional Access policies. Please check the Conditional Access configuration documentation' } + '*AADSTS900023*' { 'This tenant is not available for this operation. Please check the selected tenant and try again.' } + '*AADSTS9002313*' { 'The credentials used to connect to the Graph API are not available, please retry. If this issue persists you may need to execute the SAM wizard.' } + '*One or more platform(s) is/are not configured for the customer. Please configure the platform before trying to purchase a SKU.*' { 'One or more platform(s) is/are not configured for the customer. Please configure the platform before trying to purchase a SKU.' } + Default { $message } + + } +} From d818d20a99476f5b50e029f8e6768db684be39c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 18:30:47 +0200 Subject: [PATCH 045/123] fix: Casing and fix blank Exclude user field bug --- .../Settings/Invoke-ExecExcludeTenant.ps1 | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 index d1beb8ca2547..48f471efb2df 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 @@ -10,36 +10,40 @@ Function Invoke-ExecExcludeTenant { [CmdletBinding()] param($Request, $TriggerMetadata) - Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug' + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $username = $Request.Headers.'x-ms-client-principal-name' - $date = (Get-Date).tostring('yyyy-MM-dd') + # $username = $Request.Headers.'x-ms-client-principal-name' + $Username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails + Write-Host ($Username | ConvertTo-Json -Depth 10) + $Date = (Get-Date).ToString('yyyy-MM-dd') $TenantsTable = Get-CippTable -tablename Tenants if ($Request.Query.List) { $ExcludedFilter = "PartitionKey eq 'Tenants' and Excluded eq true" $ExcludedTenants = Get-CIPPAzDataTableEntity @TenantsTable -Filter $ExcludedFilter - Write-LogMessage -API $APINAME -headers $Request.Headers -message 'got excluded tenants list' -Sev 'Debug' + Write-LogMessage -API $APIName -headers $Headers -message 'got excluded tenants list' -Sev 'Debug' $body = @($ExcludedTenants) - } elseif ($Request.query.ListAll) { - $ExcludedTenants = Get-CIPPAzDataTableEntity @TenantsTable -filter "PartitionKey eq 'Tenants'" | Sort-Object -Property displayName - Write-LogMessage -API $APINAME -headers $Request.Headers -message 'got excluded tenants list' -Sev 'Debug' + } elseif ($Request.Query.ListAll) { + $ExcludedTenants = Get-CIPPAzDataTableEntity @TenantsTable -Filter "PartitionKey eq 'Tenants'" | Sort-Object -Property displayName + Write-LogMessage -API $APIName -headers $Headers -message 'got excluded tenants list' -Sev 'Debug' $body = @($ExcludedTenants) } try { # Interact with query parameters or the body of the request. - $name = $Request.Query.TenantFilter + $Name = $Request.Query.TenantFilter if ($Request.Query.AddExclusion) { $Tenants = Get-Tenants -IncludeAll | Where-Object { $Request.body.value -contains $_.customerId } $Excluded = foreach ($Tenant in $Tenants) { $Tenant.Excluded = $true - $Tenant.ExcludeUser = $username - $Tenant.ExcludeDate = $date + $Tenant.ExcludeUser = $Username + $Tenant.ExcludeDate = $Date $Tenant } Update-AzDataTableEntity -Force @TenantsTable -Entity ([pscustomobject]$Excluded) - Write-LogMessage -API $APINAME -tenant $($name) -headers $Request.Headers -message "Added exclusion for customer(s): $($Excluded.defaultDomainName -join ',')" -Sev 'Info' + Write-LogMessage -API $APIName -tenant $($Name) -headers $Headers -message "Added exclusion for customer(s): $($Excluded.defaultDomainName -join ',')" -Sev 'Info' $body = [pscustomobject]@{'Results' = "Success. Added exclusions for customer(s): $($Excluded.defaultDomainName -join ',')" } } @@ -51,11 +55,11 @@ Function Invoke-ExecExcludeTenant { $Tenant.ExcludeDate = '' Update-AzDataTableEntity -Force @TenantsTable -Entity $Tenant } - Write-LogMessage -API $APINAME -tenant $($name) -headers $Request.Headers -message "Removed exclusion for customer $($name)" -Sev 'Info' - $body = [pscustomobject]@{'Results' = "Success. We've removed $name from the excluded tenants." } + Write-LogMessage -API $APIName -tenant $($Name) -headers $Headers -message "Removed exclusion for customer $($Name)" -Sev 'Info' + $body = [pscustomobject]@{'Results' = "Success. We've removed $Name from the excluded tenants." } } } catch { - Write-LogMessage -API $APINAME -tenant $($name) -headers $Request.Headers -message "Exclusion API failed. $($_.Exception.Message)" -Sev 'Error' + Write-LogMessage -API $APIName -tenant $($Name) -headers $Headers -message "Exclusion API failed. $($_.Exception.Message)" -Sev 'Error' $body = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } } if (!$body) { $body = @() } From f4eded06710d2c46528316fc23ad192b5807e3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 18:32:09 +0200 Subject: [PATCH 046/123] Better error message --- .../CIPP/Settings/Invoke-ExecExcludeTenant.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 index 48f471efb2df..123bc44a5d58 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 @@ -59,8 +59,9 @@ Function Invoke-ExecExcludeTenant { $body = [pscustomobject]@{'Results' = "Success. We've removed $Name from the excluded tenants." } } } catch { - Write-LogMessage -API $APIName -tenant $($Name) -headers $Headers -message "Exclusion API failed. $($_.Exception.Message)" -Sev 'Error' - $body = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" } + $ErrorMessage = Get-CippException -Exception $_ + Write-LogMessage -API $APIName -tenant $($Name) -headers $Headers -message "Exclusion API failed. $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage + $body = [pscustomobject]@{'Results' = "Failed. $($ErrorMessage.NormalizedError)" } } if (!$body) { $body = @() } From d70ac87ed1235b1a68c5fc2601252caa341ca50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 18:40:02 +0200 Subject: [PATCH 047/123] Casing --- .../HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 index 123bc44a5d58..ecfa8b63048e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 @@ -32,7 +32,7 @@ Function Invoke-ExecExcludeTenant { } try { # Interact with query parameters or the body of the request. - $Name = $Request.Query.TenantFilter + $Name = $Request.Query.tenantFilter if ($Request.Query.AddExclusion) { $Tenants = Get-Tenants -IncludeAll | Where-Object { $Request.body.value -contains $_.customerId } From 8dbbee12af9f7d82e0c2f354aad0073bacadd97a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 14:20:27 -0400 Subject: [PATCH 048/123] update template list query fixes ticket 22021573133 --- .../Tenant/Conditional/Invoke-ListCAtemplates.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 index b76cb67f4d8c..f841af34ef3e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListCAtemplates.ps1 @@ -3,7 +3,7 @@ using namespace System.Net Function Invoke-ListCAtemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint,AnyTenant .ROLE Tenant.ConditionalAccess.Read #> From db13452811268f4b6aa0851c1db21d50902d3218 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 14:24:28 -0400 Subject: [PATCH 049/123] fix more template lists --- .../Spamfilter/Invoke-ListConnectionFilterTemplates.ps1 | 2 +- .../Spamfilter/Invoke-ListSpamFilterTemplates.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilterTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilterTemplates.ps1 index b799ab74a6e1..ddca12e5b200 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilterTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListConnectionFilterTemplates.ps1 @@ -3,7 +3,7 @@ using namespace System.Net Function Invoke-ListConnectionFilterTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint,AnyTenant .ROLE Exchange.ConnectionFilter.Read #> diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 index a74c9491e4af..7cc008f79669 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ListSpamFilterTemplates.ps1 @@ -3,7 +3,7 @@ using namespace System.Net Function Invoke-ListSpamFilterTemplates { <# .FUNCTIONALITY - Entrypoint + Entrypoint,AnyTenant .ROLE Exchange.SpamFilter.Read #> From 76f9f9c78151f05ee9a9b409aa581b0b20f36726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 21:32:36 +0200 Subject: [PATCH 050/123] Better more BRRRR way for getting username in both dev and prod --- .../HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 index ecfa8b63048e..03dde3c8ebcb 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecExcludeTenant.ps1 @@ -15,7 +15,7 @@ Function Invoke-ExecExcludeTenant { Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' # $username = $Request.Headers.'x-ms-client-principal-name' - $Username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails + $Username = $Headers.'x-ms-client-principal-name' ?? ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails Write-Host ($Username | ConvertTo-Json -Depth 10) $Date = (Get-Date).ToString('yyyy-MM-dd') $TenantsTable = Get-CippTable -tablename Tenants From b8df1c87fad079a314be359204109eb2632a9fb8 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 2 Apr 2025 19:30:50 -0400 Subject: [PATCH 051/123] Update Invoke-ExecApiClient.ps1 --- .../HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 index e36d73550e9e..3be1844d5811 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecApiClient.ps1 @@ -100,6 +100,7 @@ function Invoke-ExecApiClient { } 'GetAzureConfiguration' { $Owner = $env:WEBSITE_OWNER_NAME + Write-Information "Owner: $Owner" if ($Owner -match '^(?[^+]+)\+(?[^-]+(?:-[^-]+)*?)(?:-[^-]+webspace(?:-Linux)?)?$') { $RGName = $Matches.RGName } else { From e16a4126b1af7ad24c6c494c28217f92c9639236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 2 Apr 2025 22:37:47 +0200 Subject: [PATCH 052/123] Add litigation hold properties to Invoke-ListMailboxes and create Invoke-ExecSetLitigationHold function --- .../Invoke-ExecSetLitigationHold.ps1 | 23 +++++++++++++++++++ .../Administration/Invoke-ListMailboxes.ps1 | 5 +++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 new file mode 100644 index 000000000000..8b263eb2a4d9 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 @@ -0,0 +1,23 @@ +function Invoke-ExecSetLitigationHold { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Exchange.Mailbox.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -tenant $TenantFilter -message 'Accessed this API' -Sev 'Debug' + + # Interact with the query or body of the request + $TenantFilter = $Request.Body.tenantFilter + $DisableLitHold = $Request.Body.disable -as [bool] + Write-Host "TenantFilter: $TenantFilter" + Write-Host "DisableLitHold: $DisableLitHold" + + + +} diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 index 89111ef324c8..5aafbe4bd28f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 @@ -69,7 +69,10 @@ Function Invoke-ListMailboxes { HiddenFromAddressListsEnabled, ExternalDirectoryObjectId, MessageCopyForSendOnBehalfEnabled, - MessageCopyForSentAsEnabled + MessageCopyForSentAsEnabled, + LitigationHoldEnabled, + LitigationHoldDate, + LitigationHoldDuration $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message From b20342493a187c9b51d228e84397df0c6aead529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 3 Apr 2025 21:18:12 +0200 Subject: [PATCH 053/123] feat: implement the function needed for manipulation lit holds --- .../Invoke-ExecSetLitigationHold.ps1 | 41 +++++++++++++++++-- .../Administration/Invoke-ListMailboxes.ps1 | 6 ++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 index 8b263eb2a4d9..de8c459fe1fd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetLitigationHold.ps1 @@ -14,10 +14,45 @@ # Interact with the query or body of the request $TenantFilter = $Request.Body.tenantFilter - $DisableLitHold = $Request.Body.disable -as [bool] - Write-Host "TenantFilter: $TenantFilter" - Write-Host "DisableLitHold: $DisableLitHold" + $LitHoldState = -not $Request.Body.disable -as [bool] + $Identity = $Request.Body.Identity + $UserPrincipalName = $Request.Body.UPN + $Days = $Request.Body.days -as [int] + # Set the parameters for the EXO request + $ExoRequest = @{ + tenantid = $TenantFilter + cmdlet = 'Set-Mailbox' + cmdParams = @{ + Identity = $Identity + LitigationHoldEnabled = $LitHoldState + } + } + # Add the duration of the hold if specified + if ($Days -ne 0 -and $LitHoldState -eq $true) { + $ExoRequest.cmdParams['LitigationHoldDuration'] = $Days + } + # Execute the EXO request + try { + $null = New-ExoRequest @ExoRequest + $Results = "Litigation hold for $UserPrincipalName with Id $Identity has been set to $LitHoldState" + if ($Days -ne 0 -and $LitHoldState -eq $true) { + $Results += " for $Days days" + } + Write-LogMessage -API $APIName -tenant $TenantFilter -message $Results -sev Info + $StatusCode = [HttpStatusCode]::OK + } catch { + $ErrorMessage = Get-CippException -Exception $_ + $Results = "Could not set litigation hold for $UserPrincipalName with Id $Identity to $LitHoldState. Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -API $APIName -tenant $TenantFilter -message $Results -sev Error -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::InternalServerError + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @{ Results = $Results } + }) } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 index 5aafbe4bd28f..b3ac4aebd388 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ListMailboxes.ps1 @@ -17,7 +17,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,HiddenFromAddressListsEnabled,ExternalDirectoryObjectId,MessageCopyForSendOnBehalfEnabled,MessageCopyForSentAsEnabled' + $Select = 'id,ExchangeGuid,ArchiveGuid,UserPrincipalName,DisplayName,PrimarySMTPAddress,RecipientType,RecipientTypeDetails,EmailAddresses,WhenSoftDeleted,IsInactiveMailbox,ForwardingSmtpAddress,DeliverToMailboxAndForward,ForwardingAddress,HiddenFromAddressListsEnabled,ExternalDirectoryObjectId,MessageCopyForSendOnBehalfEnabled,MessageCopyForSentAsEnabled,PersistedCapabilities,LitigationHoldEnabled,LitigationHoldDate,LitigationHoldDuration' $ExoRequest = @{ tenantid = $TenantFilter cmdlet = 'Get-Mailbox' @@ -72,7 +72,9 @@ Function Invoke-ListMailboxes { MessageCopyForSentAsEnabled, LitigationHoldEnabled, LitigationHoldDate, - LitigationHoldDuration + LitigationHoldDuration, + @{ Name = 'LicensedForLitigationHold'; Expression = { ($_.PersistedCapabilities -contains 'BPOS_S_DlpAddOn' -or $_.PersistedCapabilities -contains 'BPOS_S_Enterprise') } } + $StatusCode = [HttpStatusCode]::OK } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message From 360f2265ac73395d72121865e26ce6627bf165ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 3 Apr 2025 21:18:31 +0200 Subject: [PATCH 054/123] Horrible terrible annoying nitpicking --- .../Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 index b543ef58a25a..1064b89a9ecf 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 @@ -30,7 +30,7 @@ function Invoke-CIPPStandardEnableLitigationHold { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'EnableLitigationHold' - $MailboxesNoLitHold = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdparams @{ Filter = 'LitigationHoldEnabled -eq "False"' } -Select 'UserPrincipalName,PersistedCapabilities,LitigationHoldEnabled' | Where-Object { $_.PersistedCapabilities -contains 'BPOS_S_DlpAddOn' -or $_.PersistedCapabilities -contains 'BPOS_S_Enterprise' } + $MailboxesNoLitHold = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdParams @{ Filter = 'LitigationHoldEnabled -eq "False"' } -Select 'UserPrincipalName,PersistedCapabilities,LitigationHoldEnabled' | Where-Object { $_.PersistedCapabilities -contains 'BPOS_S_DlpAddOn' -or $_.PersistedCapabilities -contains 'BPOS_S_Enterprise' } if ($Settings.remediate -eq $true) { if ($null -eq $MailboxesNoLitHold) { @@ -44,19 +44,19 @@ function Invoke-CIPPStandardEnableLitigationHold { Parameters = @{ Identity = $_.UserPrincipalName; LitigationHoldEnabled = $true } } } - if ($Settings.days -ne $null) { + if ($null -ne $Settings.days) { $params.CmdletInput.Parameters['LitigationHoldDuration'] = $Settings.days } $params } - $BatchResults = New-ExoBulkRequest -tenantid $tenant -cmdletArray @($Request) + $BatchResults = New-ExoBulkRequest -tenantid $Tenant -cmdletArray @($Request) $BatchResults | ForEach-Object { if ($_.error) { $ErrorMessage = Get-NormalizedError -Message $_.error Write-Host "Failed to Enable Litigation Hold for $($_.Target). Error: $ErrorMessage" - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to Enable Litigation Hold for $($_.Target). Error: $ErrorMessage" -sev Error + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to Enable Litigation Hold for $($_.Target). Error: $ErrorMessage" -sev Error } } } catch { From bb3afe1980cbc9a9abab5a37a4a7ea87096405c1 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 4 Apr 2025 09:44:59 -0400 Subject: [PATCH 055/123] fix app approval --- Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 index e7e9ba47816e..69889ea73ec2 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertNewAppApproval.ps1 @@ -9,7 +9,8 @@ function Get-CIPPAlertNewAppApproval { [Parameter(Mandatory = $false)] [Alias('input')] $InputValue, - $TenantFilter + $TenantFilter, + $Headers ) try { $Approvals = New-GraphGetRequest -Uri "https://graph.microsoft.com/v1.0/identityGovernance/appConsent/appConsentRequests?`$filter=userConsentRequests/any (u:u/status eq 'InProgress')" -tenantid $TenantFilter From e0e60227d86d9a3070544ecd56cef7b40199401f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 4 Apr 2025 09:45:16 -0400 Subject: [PATCH 056/123] fix license sku in bulk user add --- .../Identity/Administration/Users/Invoke-AddUserBulk.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 index 0eb1ef8db5f4..ffd0d28bd2f3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 @@ -72,7 +72,12 @@ function Invoke-AddUserBulk { $LicenseSkus = $AssignedLicenses.value ?? $AssignedLicenses | Where-Object { $_ -match $GuidPattern } if (($LicenseSkus | Measure-Object).Count -gt 0) { Write-Information "- Assigned licenses set to $(($AssignedLicenses.label ?? $AssignedLicenses) -join ', ')" - $UserBody.assignedLicenses = @($LicenseSkus) + $AssignedLicenses = foreach ($Sku in $LicenseSkus) { + [PSCustomObject]@{ + skuId = $Sku + } + } + $UserBody.assignedLicenses = @($AssignedLicenses) } } } From ca33847cba99d09ba8bad34c2b9df897152931d0 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 4 Apr 2025 09:45:50 -0400 Subject: [PATCH 057/123] move scheduler running state to inside durable --- .../Activity Triggers/Push-ExecScheduledCommand.ps1 | 7 +++++++ .../Orchestrator Functions/Start-UserTasksOrchestrator.ps1 | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 index 460ea3456778..e969dd680cf2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 @@ -13,6 +13,12 @@ function Push-ExecScheduledCommand { $Tenant = $Item.Parameters.TenantFilter ?? $Item.TaskInfo.Tenant $TenantInfo = Get-Tenants -TenantFilter $Tenant + $null = Update-AzDataTableEntity -Force @Table -Entity @{ + PartitionKey = $task.PartitionKey + RowKey = $task.RowKey + TaskState = 'Running' + } + $Function = Get-Command -Name $Item.Command if ($null -eq $Function) { $Results = "Task Failed: The command $($Item.Command) does not exist." @@ -23,6 +29,7 @@ function Push-ExecScheduledCommand { Results = "$Results" TaskState = $State } + Write-LogMessage -API 'Scheduler_UserTasks' -tenant $Tenant -tenantid $TenantInfo.customerId -message "Failed to execute task $($task.Name): The command $($Item.Command) does not exist." -sev Error return } diff --git a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UserTasksOrchestrator.ps1 b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UserTasksOrchestrator.ps1 index 62810c4ab1dd..9863866fa438 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UserTasksOrchestrator.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UserTasksOrchestrator.ps1 @@ -21,7 +21,7 @@ function Start-UserTasksOrchestrator { PartitionKey = $task.PartitionKey RowKey = $task.RowKey ExecutedTime = "$currentUnixTime" - TaskState = 'Running' + TaskState = 'Planned' } $task.Parameters = $task.Parameters | ConvertFrom-Json -AsHashtable $task.AdditionalProperties = $task.AdditionalProperties | ConvertFrom-Json From 52a3db25d6df1ce574d22d324d66569c8827b169 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 4 Apr 2025 10:00:48 -0400 Subject: [PATCH 058/123] Update Invoke-AddUserBulk.ps1 --- .../Identity/Administration/Users/Invoke-AddUserBulk.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 index ffd0d28bd2f3..afe3c9a5f4ea 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 @@ -72,12 +72,12 @@ function Invoke-AddUserBulk { $LicenseSkus = $AssignedLicenses.value ?? $AssignedLicenses | Where-Object { $_ -match $GuidPattern } if (($LicenseSkus | Measure-Object).Count -gt 0) { Write-Information "- Assigned licenses set to $(($AssignedLicenses.label ?? $AssignedLicenses) -join ', ')" - $AssignedLicenses = foreach ($Sku in $LicenseSkus) { + $Licenses = foreach ($Sku in $LicenseSkus) { [PSCustomObject]@{ skuId = $Sku } } - $UserBody.assignedLicenses = @($AssignedLicenses) + $UserBody.assignedLicenses = @($Licenses) } } } From d5e2edc66fa3a9d46a3eac43d7632bddad2a6627 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 4 Apr 2025 12:24:50 -0400 Subject: [PATCH 059/123] remove ETag and Timestamp from uploaded template --- .../HTTP Functions/Tools/GitHub/Invoke-ExecCommunityRepo.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tools/GitHub/Invoke-ExecCommunityRepo.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tools/GitHub/Invoke-ExecCommunityRepo.ps1 index 6cd0e4c3fec4..d30b00e19c09 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tools/GitHub/Invoke-ExecCommunityRepo.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tools/GitHub/Invoke-ExecCommunityRepo.ps1 @@ -107,7 +107,7 @@ function Invoke-ExecCommunityRepo { 'UploadTemplate' { $GUID = $Request.Body.GUID $TemplateTable = Get-CIPPTable -TableName templates - $TemplateEntity = Get-CIPPAzDataTableEntity @TemplateTable -Filter "RowKey eq '$($GUID)'" + $TemplateEntity = Get-CIPPAzDataTableEntity @TemplateTable -Filter "RowKey eq '$($GUID)'" | Select-Object -ExcludeProperty ETag, Timestamp $Branch = $RepoEntity.UploadBranch ?? $RepoEntity.DefaultBranch if ($TemplateEntity) { $Template = $TemplateEntity.JSON | ConvertFrom-Json From a14f999a4a14ad549afae119f2277bf47d57bd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 4 Apr 2025 19:36:33 +0200 Subject: [PATCH 060/123] Feat: Add Invoke-ExecRenameAPDevice function for AP device renaming --- .../Autopilot/Invoke-ExecRenameAPDevice.ps1 | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecRenameAPDevice.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecRenameAPDevice.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecRenameAPDevice.ps1 new file mode 100644 index 000000000000..8bf8228949f3 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecRenameAPDevice.ps1 @@ -0,0 +1,61 @@ +using namespace System.Net + +Function Invoke-ExecRenameAPDevice { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $TenantFilter = $Request.Body.tenantFilter + + + try { + $DeviceId = $Request.Body.deviceId + $SerialNumber = $Request.Body.serialNumber + $DisplayName = $Request.Body.displayName + + # Validation + if ($DisplayName.Length -gt 15) { + $ValidationError = 'Display name cannot exceed 15 characters.' + } elseif ($DisplayName -notmatch '^[a-zA-Z0-9-]+$') { + # This regex also implicitly checks for spaces + $ValidationError = 'Display name can only contain letters (a-z, A-Z), numbers (0-9), and hyphens (-).' + } elseif ($DisplayName -match '^\d+$') { + $ValidationError = 'Display name cannot consist solely of numbers.' + } + + if ($null -ne $ValidationError) { + $Result = "Validation failed: $ValidationError" + $StatusCode = [HttpStatusCode]::BadRequest + } else { + # Validation passed, proceed with Graph API call + $body = @{ + displayName = $DisplayName + } | ConvertTo-Json + + New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($DeviceId)/UpdateDeviceProperties" -tenantid $TenantFilter -body $body -method POST | Out-Null + $Result = "Successfully renamed device '$($DeviceId)' with serial number '$($SerialNumber)' to '$($DisplayName)'" + Write-LogMessage -Headers $User -API $APINAME -message $Result -Sev Info + $StatusCode = [HttpStatusCode]::OK + } + } catch { + $ErrorMessage = Get-CippException -Exception $_ + $Result = "Could not rename device '$($DeviceId)' with serial number '$($SerialNumber)' to '$($DisplayName)'. Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -Headers $User -API $APINAME -message $Result -Sev Error -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::BadRequest + } + + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @{ Results = $Result } + }) + +} From b1506aafa74a3ecaa187488f76c8f14baafd43f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 4 Apr 2025 21:03:04 +0200 Subject: [PATCH 061/123] Feat: Implement Invoke-ExecSetAPDeviceGroupTag function for updating AP device group tags --- .../Invoke-ExecSetAPDeviceGroupTag.ps1 | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecSetAPDeviceGroupTag.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecSetAPDeviceGroupTag.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecSetAPDeviceGroupTag.ps1 new file mode 100644 index 000000000000..d4f44ee9a618 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-ExecSetAPDeviceGroupTag.ps1 @@ -0,0 +1,53 @@ +using namespace System.Net + +Function Invoke-ExecSetAPDeviceGroupTag { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Endpoint.Autopilot.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + $TenantFilter = $Request.Body.tenantFilter + + try { + $DeviceId = $Request.Body.deviceId + $SerialNumber = $Request.Body.serialNumber + $GroupTag = $Request.Body.groupTag + + # Validation - GroupTag can be empty, but if provided, validate it + if ($null -ne $GroupTag -and $GroupTag -ne '' -and $GroupTag.Length -gt 128) { + $ValidationError = 'Group tag cannot exceed 128 characters.' + } + + if ($null -ne $ValidationError) { + $Result = "Validation failed: $ValidationError" + $StatusCode = [HttpStatusCode]::BadRequest + } else { + # Validation passed, proceed with Graph API call + $body = @{ + groupTag = $GroupTag + } | ConvertTo-Json + + New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($DeviceId)/UpdateDeviceProperties" -tenantid $TenantFilter -body $body -method POST | Out-Null + $Result = "Successfully updated group tag for device '$($DeviceId)' with serial number '$($SerialNumber)' to '$($GroupTag)'" + Write-LogMessage -Headers $Headers -API $APIName -message $Result -Sev Info + $StatusCode = [HttpStatusCode]::OK + } + } catch { + $ErrorMessage = Get-CippException -Exception $_ + $Result = "Could not update group tag for device '$($DeviceId)' with serial number '$($SerialNumber)' to '$($GroupTag)'. Error: $($ErrorMessage.NormalizedError)" + Write-LogMessage -Headers $Headers -API $APIName -message $Result -Sev Error -LogData $ErrorMessage + $StatusCode = [HttpStatusCode]::BadRequest + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $StatusCode + Body = @{ Results = $Result } + }) +} From 5c013e042d194e852d60737ac04ebd855b4bea06 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 12:55:39 -0400 Subject: [PATCH 062/123] fix ip address regex --- .../CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 index ab8dc85a36c2..5c85cd0c1d3c 100644 --- a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 @@ -98,9 +98,10 @@ function Test-CIPPAuditLogRules { $HasLocationData = $false if (![string]::IsNullOrEmpty($Data.clientip) -and $Data.clientip -notmatch '[X]+') { # Ignore IP addresses that have been redacted - if ($Data.clientip -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { - $Data.clientip = $Data.clientip -replace ':\d+$', '' # Remove the port number if present - } + + $IPRegex = '^(?(?:\d{1,3}(?:\.\d{1,3}){3}|\[[0-9a-fA-F:]+\]|[0-9a-fA-F:]+))(?::\d+)?$' + $Data.clientip = $Data.clientip -replace $IPRegex, '$1' -replace '[\[\]]', '' + # Check if IP is on trusted IP list $TrustedIP = Get-CIPPAzDataTableEntity @TrustedIPTable -Filter "((PartitionKey eq '$TenantFilter') or (PartitionKey eq 'AllTenants')) and RowKey eq '$($Data.clientip)' and state eq 'Trusted'" if ($TrustedIP) { From 6b81c0a3a203c074e2b41896fa5e910dd7139df5 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 13:12:02 -0400 Subject: [PATCH 063/123] change table query call --- Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 index 5c85cd0c1d3c..3fa7c41285a2 100644 --- a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 @@ -103,14 +103,14 @@ function Test-CIPPAuditLogRules { $Data.clientip = $Data.clientip -replace $IPRegex, '$1' -replace '[\[\]]', '' # Check if IP is on trusted IP list - $TrustedIP = Get-CIPPAzDataTableEntity @TrustedIPTable -Filter "((PartitionKey eq '$TenantFilter') or (PartitionKey eq 'AllTenants')) and RowKey eq '$($Data.clientip)' and state eq 'Trusted'" + $TrustedIP = Get-CIPPAzDataTableEntity @TrustedIPTable -Filter "((PartitionKey eq '$TenantFilter') or (PartitionKey eq 'AllTenants')) and RowKey eq '$($Data.clientip)' and state eq 'Trusted'" if ($TrustedIP) { #write-warning "IP $($Data.clientip) is trusted" $Trusted = $true } if (!$Trusted) { $CacheLookupStartTime = Get-Date - $Location = Get-CIPPAzDataTableEntity @LocationTable -Filter "RowKey eq '$($Data.clientIp)'" | Select-Object -Last 1 -ExcludeProperty Tenant + $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($Data.clientIp)'" | Select-Object -ExcludeProperty Tenant $CacheLookupEndTime = Get-Date $CacheLookupSeconds = ($CacheLookupEndTime - $CacheLookupStartTime).TotalSeconds Write-Warning "Cache lookup for IP $($Data.clientip) took $CacheLookupSeconds seconds" From 3786149ed02dcbff50f31e89f0904cfd4b50361e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 14:27:34 -0400 Subject: [PATCH 064/123] optimize queries --- Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 | 2 +- Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 index 1ee4efcd43df..92595a0f580d 100644 --- a/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPGeoIPLocation.ps1 @@ -6,7 +6,7 @@ function Get-CIPPGeoIPLocation { $CacheGeoIPTable = Get-CippTable -tablename 'cachegeoip' $30DaysAgo = (Get-Date).AddDays(-30).ToString('yyyy-MM-ddTHH:mm:ssZ') - $Filter = "RowKey eq '$IP' and Timestamp ge datetime'$30DaysAgo'" + $Filter = "PartitionKey eq 'IP' and RowKey eq '$IP' and Timestamp ge datetime'$30DaysAgo'" $GeoIP = Get-CippAzDataTableEntity @CacheGeoIPTable -Filter $Filter if ($GeoIP) { return ($GeoIP.Data | ConvertFrom-Json) diff --git a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 index 3fa7c41285a2..b1be7de666a9 100644 --- a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 @@ -110,7 +110,7 @@ function Test-CIPPAuditLogRules { } if (!$Trusted) { $CacheLookupStartTime = Get-Date - $Location = Get-AzDataTableEntity @LocationTable -Filter "RowKey eq '$($Data.clientIp)'" | Select-Object -ExcludeProperty Tenant + $Location = Get-AzDataTableEntity @LocationTable -Filter "PartitionKey eq 'ip' and RowKey eq '$($Data.clientIp)'" | Select-Object -ExcludeProperty Tenant $CacheLookupEndTime = Get-Date $CacheLookupSeconds = ($CacheLookupEndTime - $CacheLookupStartTime).TotalSeconds Write-Warning "Cache lookup for IP $($Data.clientip) took $CacheLookupSeconds seconds" From 46f200d450f7b7e15857220628fb5d55f473306a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 15:49:58 -0400 Subject: [PATCH 065/123] add keepalive function --- .../CIPP/Core/Invoke-PublicPing.ps1 | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-PublicPing.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-PublicPing.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-PublicPing.ps1 new file mode 100644 index 000000000000..cc019f3c7714 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-PublicPing.ps1 @@ -0,0 +1,56 @@ +function Invoke-PublicPing { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Public + #> + [CmdletBinding()] + Param( + $Request, + $TriggerMetadata + ) + + $KeepaliveTable = Get-CippTable -tablename 'CippKeepAlive' + $LastKeepalive = Get-CippAzDataTableEntity @KeepaliveTable -Filter "PartitionKey eq 'Ping' and RowKey eq 'Ping'" + + if ($LastKeepalive.Timestamp) { + $LastKeepalive = $LastKeepalive.Timestamp.DateTime.ToUniversalTime() + } else { + $LastKeepalive = (Get-Date).AddSeconds(-600).ToUniversalTime() + } + $KeepaliveInterval = -300 + $NextKeepAlive = (Get-Date).AddSeconds($KeepaliveInterval).ToUniversalTime() + + $IsColdStart = $Request.Headers.'x-ms-coldstart' -eq 1 + + if ($LastKeepalive -le $NextKeepAlive -or $IsColdStart) { + $Keepalive = @{ + PartitionKey = 'Ping' + RowKey = 'Ping' + } + Add-AzDataTableEntity @KeepaliveTable -Entity $Keepalive -Force + + if ($IsColdStart) { + $Milliseconds = 500 + } else { + $Milliseconds = 150 + } + + Start-Sleep -Milliseconds $Milliseconds + } + + $Body = @{ + Results = @{ + Message = 'Pong' + ColdStart = $IsColdStart + Timestamp = (Get-Date).ToUniversalTime() + RequestId = $TriggerMetadata.InvocationId + } + } + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = ($Body | ConvertTo-Json -Depth 5) + }) +} From f28a0609fc215a4b4c1f2cd5632ca208b8fb03bd Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 16:12:56 -0400 Subject: [PATCH 066/123] cleanup workflows --- .github/workflows/dev_cipp27qz5.yml | 30 ------------------------ .github/workflows/dev_cipppwrro.yml | 30 ------------------------ .github/workflows/dev_cippyumsh-proc.yml | 30 ------------------------ .github/workflows/dev_cippyumsh.yml | 30 ------------------------ 4 files changed, 120 deletions(-) delete mode 100644 .github/workflows/dev_cipp27qz5.yml delete mode 100644 .github/workflows/dev_cipppwrro.yml delete mode 100644 .github/workflows/dev_cippyumsh-proc.yml delete mode 100644 .github/workflows/dev_cippyumsh.yml diff --git a/.github/workflows/dev_cipp27qz5.yml b/.github/workflows/dev_cipp27qz5.yml deleted file mode 100644 index 21c946480ac0..000000000000 --- a/.github/workflows/dev_cipp27qz5.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cipp27qz5 - -on: - push: - branches: - - dev - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: windows-latest - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cipp27qz5' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_821C9A2723884E2E85AC262B12EB26F7 }} \ No newline at end of file diff --git a/.github/workflows/dev_cipppwrro.yml b/.github/workflows/dev_cipppwrro.yml deleted file mode 100644 index a62bd3026748..000000000000 --- a/.github/workflows/dev_cipppwrro.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cipppwrro - -on: - push: - branches: - - dev - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: windows-latest - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cipppwrro' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D5D7DFF930C04B519206F25DDCD88324 }} \ No newline at end of file diff --git a/.github/workflows/dev_cippyumsh-proc.yml b/.github/workflows/dev_cippyumsh-proc.yml deleted file mode 100644 index 9a3397c76f00..000000000000 --- a/.github/workflows/dev_cippyumsh-proc.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cippyumsh-proc - -on: - push: - branches: - - dev - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: windows-latest - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cippyumsh-proc' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_8AA04F8C6F644F639CD74D3816E1BF08 }} \ No newline at end of file diff --git a/.github/workflows/dev_cippyumsh.yml b/.github/workflows/dev_cippyumsh.yml deleted file mode 100644 index a57b998e592e..000000000000 --- a/.github/workflows/dev_cippyumsh.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy Powershell project to Azure Function App - cippyumsh - -on: - push: - branches: - - dev - workflow_dispatch: - -env: - AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root - -jobs: - deploy: - runs-on: windows-latest - - steps: - - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 - - - name: 'Run Azure Functions Action' - uses: Azure/functions-action@v1 - id: fa - with: - app-name: 'cippyumsh' - slot-name: 'Production' - package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_76BFD48D41B64AF88AC8D0A234746FF1 }} \ No newline at end of file From 4e02959e8ce78333ecdea159a8f764b023e27da4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 16:13:06 -0400 Subject: [PATCH 067/123] add partitionkey to table cleanup --- .../Entrypoints/Timer Functions/Start-TableCleanup.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-TableCleanup.ps1 b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-TableCleanup.ps1 index ba15c02add60..de6d20e615d3 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-TableCleanup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-TableCleanup.ps1 @@ -17,7 +17,7 @@ function Start-TableCleanup { @{ DataTableProps = @{ Context = (Get-CIPPTable -tablename 'AuditLogSearches').Context - Filter = "Timestamp lt datetime'$((Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" + Filter = "PartitionKey eq 'Search' and Timestamp lt datetime'$((Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" First = 10000 Property = @('PartitionKey', 'RowKey', 'ETag') } @@ -25,7 +25,7 @@ function Start-TableCleanup { @{ DataTableProps = @{ Context = (Get-CIPPTable -tablename 'CippFunctionStats').Context - Filter = "Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" + Filter = "PartitionKey eq 'Durable' and Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" First = 10000 Property = @('PartitionKey', 'RowKey', 'ETag') } @@ -33,7 +33,7 @@ function Start-TableCleanup { @{ DataTableProps = @{ Context = (Get-CIPPTable -tablename 'CippQueue').Context - Filter = "Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" + Filter = "PartitionKey eq 'CippQueue' and Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" First = 10000 Property = @('PartitionKey', 'RowKey', 'ETag') } @@ -41,7 +41,7 @@ function Start-TableCleanup { @{ DataTableProps = @{ Context = (Get-CIPPTable -tablename 'CippQueueTasks').Context - Filter = "Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" + Filter = "PartitionKey eq 'Task' and Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'" First = 10000 Property = @('PartitionKey', 'RowKey', 'ETag') } @@ -61,7 +61,7 @@ function Start-TableCleanup { try { Remove-AzDataTable -Context $Table.Context -Force } catch { - Write-LogMessage -API 'TableCleanup' -message "Failed to delete table $($Table.Context.TableName)" -sev Error -LogData (Get-CippException -Exception $_) + #Write-LogMessage -API 'TableCleanup' -message "Failed to delete table $($Table.Context.TableName)" -sev Error -LogData (Get-CippException -Exception $_) } } } catch { From 180f2b733e714f6f7354f06985c12328551ecc48 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 16:53:44 -0400 Subject: [PATCH 068/123] add missing partitionkey --- Modules/CIPPCore/Public/Clear-CippDurables.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Clear-CippDurables.ps1 b/Modules/CIPPCore/Public/Clear-CippDurables.ps1 index 24708181fc17..44c77f74e82c 100644 --- a/Modules/CIPPCore/Public/Clear-CippDurables.ps1 +++ b/Modules/CIPPCore/Public/Clear-CippDurables.ps1 @@ -44,7 +44,7 @@ function Clear-CippDurables { } $CippQueueTasks = Get-CippTable -TableName 'CippQueueTasks' - $RunningTasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "Status eq 'Running'" -Property RowKey, PartitionKey, Status + $RunningTasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "PartitionKey eq 'Task' and Status eq 'Running'" -Property RowKey, PartitionKey, Status if (($RunningTasks | Measure-Object).Count -gt 0) { if ($PSCmdlet.ShouldProcess('Tasks', 'Mark Failed')) { $UpdatedTasks = foreach ($Task in $RunningTasks) { From 2d1f0613591d891f211487dc2756cb63ea22a8c3 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 6 Apr 2025 17:01:14 -0400 Subject: [PATCH 069/123] Update Invoke-ExecDurableFunctions.ps1 --- .../HTTP Functions/CIPP/Core/Invoke-ExecDurableFunctions.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4cbfcda3b49d..2e0a928b2db2 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 @@ -116,7 +116,7 @@ function Invoke-ExecDurableFunctions { } $CippQueueTasks = Get-CippTable -TableName 'CippQueueTasks' - $RunningTasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "Status eq 'Running'" -Property RowKey, PartitionKey, Status + $RunningTasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "PartitionKey eq 'Task' and Status eq 'Running'" -Property RowKey, PartitionKey, Status if (($RunningTasks | Measure-Object).Count -gt 0) { if ($PSCmdlet.ShouldProcess('Tasks', 'Mark Failed')) { $UpdatedTasks = foreach ($Task in $RunningTasks) { From d8b4f9f89f796f7b6fb0ffb91a9562ae5e05285d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Tue, 8 Apr 2025 16:26:28 +0200 Subject: [PATCH 070/123] multipost for q --- .../Spamfilter/Invoke-ExecQuarantineManagement.ps1 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 index 4421360709dc..1f25f40efcb1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Spamfilter/Invoke-ExecQuarantineManagement.ps1 @@ -20,14 +20,17 @@ Function Invoke-ExecQuarantineManagement { # Interact with query parameters or the body of the request. Try { - $TenantFilter = $Request.Body.tenantFilter + $TenantFilter = $Request.Body.tenantFilter | Select-Object -First 1 $params = @{ - Identity = $Request.Body.Identity AllowSender = [boolean]$Request.Body.AllowSender - ReleaseToAll = [boolean]$Request.Body.Type - ActionType = $Request.Body.Type + ReleaseToAll = $true + ActionType = ($Request.Body.Type | Select-Object -First 1) + } + if ($Request.Body.Identity -is [string]) { + $params['Identity'] = $Request.Body.Identity + } else { + $params['Identities'] = $Request.Body.Identity } - New-ExoRequest -tenantid $TenantFilter -cmdlet 'Release-QuarantineMessage' -cmdParams $Params $Results = [pscustomobject]@{'Results' = "Successfully processed $($Request.Body.Identity)" } Write-LogMessage -headers $Request.Headers -API $APINAME -tenant $TenantFilter -message "Successfully processed Quarantine ID $($Request.Body.Identity)" -Sev 'Info' From 8d3af6a0455f6211536946c07ff72f5663915bbb Mon Sep 17 00:00:00 2001 From: Esco Date: Tue, 8 Apr 2025 22:15:52 +0200 Subject: [PATCH 071/123] dev feat: cspell remove impact --- .vscode/extensions.json | 11 ++++++----- cspell.json | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 cspell.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c2795fa0dd8c..46245188b38e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ -{ - "recommendations": [ - "editorconfig.editorconfig" - ] -} +{ + "recommendations": [ + "editorconfig.editorconfig", + "streetsidesoftware.code-spell-checker" + ] +} diff --git a/cspell.json b/cspell.json new file mode 100644 index 000000000000..9aa3bf30dfc3 --- /dev/null +++ b/cspell.json @@ -0,0 +1,33 @@ +{ + "version": "0.2", + "ignorePaths": [], + "dictionaryDefinitions": [], + "dictionaries": [], + "words": [ + "Intune", + "Entra", + "GDAP", + "CIPP", + "CIPP-API", + "Sherweb", + "Autotask", + "Connectwise", + "Datto", + "Bluetrait", + ], + "ignoreWords": [ + "tenantid", + "APINAME", + "CIPPBPA", + "CIPPSPO", + "CIPPAPI", + "Helptext", + "ADDEDCOMPONENT", + "ADDEDDATE", + "POWERSHELLEQUIVALENT", + "RECOMMENDEDBY", + "UPDATECOMMENTBLOCK", + "DISABLEDFEATURES", + ], + "import": [] +} From 39e05af0de7f301ede1dfa502d1269f75aa2d026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 9 Apr 2025 11:00:41 +0200 Subject: [PATCH 072/123] Update the standards.json in the backend --- Config/standards.json | 946 +++++++++++++++++++++++++++++++----------- 1 file changed, 700 insertions(+), 246 deletions(-) diff --git a/Config/standards.json b/Config/standards.json index 70d9710628db..c4d741e08e7b 100644 --- a/Config/standards.json +++ b/Config/standards.json @@ -2,7 +2,7 @@ { "name": "standards.MailContacts", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Defines the email address to receive general updates and information related to M365 subscriptions. Leave a contact field blank if you do not want to update the contact information.", "docsDescription": "", "addedComponent": [ @@ -34,30 +34,32 @@ "label": "Set contact e-mails", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-03-13", "powershellEquivalent": "Set-MsolCompanyContactInformation", "recommendedBy": [] }, { "name": "standards.AuditLog", "cat": "Global Standards", - "tag": ["lowimpact", "CIS", "mip_search_auditlog"], + "tag": ["CIS", "mip_search_auditlog"], "helpText": "Enables the Unified Audit Log for tracking and auditing activities. Also runs Enable-OrganizationCustomization if necessary.", "addedComponent": [], "label": "Enable the Unified Audit Log", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2021-11-16", "powershellEquivalent": "Enable-OrganizationCustomization", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ProfilePhotos", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Controls whether users can set their own profile photos in Microsoft 365.", "docsDescription": "Controls whether users can set their own profile photos in Microsoft 365. When disabled, only User and Global administrators can update profile photos for users.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -77,18 +79,20 @@ "label": "Allow users to set profile photos", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2025-01-19", "powershellEquivalent": "Set-OrganizationConfig -ProfilePhotoOptions EnablePhotos and Update-MgBetaAdminPeople", "recommendedBy": [] }, { "name": "standards.PhishProtection", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Adds branding to the logon page that only appears if the url is not login.microsoftonline.com. This potentially prevents AITM attacks via EvilNginx. This will also automatically generate alerts if a clone of your login page has been found when set to Remediate.", "addedComponent": [], "label": "Enable Phishing Protection system via branding CSS", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-22", "disabledFeatures": { "report": true, "warn": true, @@ -100,7 +104,7 @@ { "name": "standards.Branding", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the branding for the tenant. This includes the login page, and the Office 365 portal.", "addedComponent": [ { @@ -121,7 +125,7 @@ "label": "Hide self-service password reset" }, { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Visual Template", "name": "standards.Branding.layoutTemplateType", @@ -150,81 +154,87 @@ "label": "Set branding for the tenant", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-05-13", "powershellEquivalent": "Portal only", "recommendedBy": [] }, { "name": "standards.EnableCustomerLockbox", "cat": "Global Standards", - "tag": ["lowimpact", "CIS", "CustomerLockBoxEnabled"], + "tag": ["CIS", "CustomerLockBoxEnabled"], "helpText": "Enables Customer Lockbox that offers an approval process for Microsoft support to access organization data", "docsDescription": "Customer Lockbox ensures that Microsoft can't access your content to do service operations without your explicit approval. Customer Lockbox ensures only authorized requests allow access to your organizations data.", "addedComponent": [], "label": "Enable Customer Lockbox", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-08", "powershellEquivalent": "Set-OrganizationConfig -CustomerLockBoxEnabled $true", "recommendedBy": ["CIS"] }, { "name": "standards.EnablePronouns", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables the Pronouns feature for the tenant. This allows users to set their pronouns in their profile.", "addedComponent": [], "label": "Enable Pronouns", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-06-05", "powershellEquivalent": "Update-MgBetaAdminPeoplePronoun -IsEnabledInOrganization:$true", "recommendedBy": [] }, { "name": "standards.AnonReportDisable", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Shows usernames instead of pseudo anonymised names in reports. This standard is required for reporting to work correctly.", "docsDescription": "Microsoft announced some APIs and reports no longer return names, to comply with compliance and legal requirements in specific countries. This proves an issue for a lot of MSPs because those reports are often helpful for engineers. This standard applies a setting that shows usernames in those API calls / reports.", "addedComponent": [], "label": "Enable Usernames instead of pseudo anonymised names in reports", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2021-11-16", "powershellEquivalent": "Update-MgBetaAdminReportSetting -BodyParameter @{displayConcealedNames = $true}", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableGuestDirectory", "cat": "Global Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Disables Guest access to enumerate directory objects. This prevents guest users from seeing other users or guests in the directory.", "docsDescription": "Sets it so guests can view only their own user profile. Permission to view other users isn't allowed. Also restricts guest users from seeing the membership of groups they're in. See exactly what get locked down in the [Microsoft documentation.](https://learn.microsoft.com/en-us/entra/fundamentals/users-default-permissions)", "addedComponent": [], "label": "Restrict guest user access to directory objects", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-05-04", "powershellEquivalent": "Set-AzureADMSAuthorizationPolicy -GuestUserRoleId '2af84b1e-32c8-42b7-82bc-daa82404023b'", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableBasicAuthSMTP", "cat": "Global Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Disables SMTP AUTH for the organization and all users. This is the default for new tenants. ", "docsDescription": "Disables SMTP basic authentication for the tenant and all users with it explicitly enabled.", "addedComponent": [], "label": "Disable SMTP Basic Authentication", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Set-TransportConfig -SmtpClientAuthenticationDisabled $true", - "recommendedBy": [] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ActivityBasedTimeout", "cat": "Global Standards", - "tag": ["mediumimpact", "CIS", "spo_idle_session_timeout"], + "tag": ["CIS", "spo_idle_session_timeout"], "helpText": "Enables and sets Idle session timeout for Microsoft 365 to 1 hour. This policy affects most M365 web apps", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -256,13 +266,14 @@ "label": "Enable Activity based Timeout", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2022-04-13", "powershellEquivalent": "Portal or Graph API", "recommendedBy": ["CIS"] }, { "name": "standards.AuthMethodsSettings", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Configures the report suspicious activity settings and system credential preferences in the authentication methods policy.", "docsDescription": "Controls the authentication methods policy settings for reporting suspicious activity and system credential preferences. These settings help enhance the security of authentication in your organization.", "addedComponent": [ @@ -314,13 +325,14 @@ "label": "Configure Authentication Methods Policy Settings", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2025-02-10", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicy", "recommendedBy": [] }, { "name": "standards.AppDeploy", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Deploys selected applications to the tenant. Use a comma separated list of application IDs to deploy multiple applications. Permissions will be copied from the source application.", "docsDescription": "Uses the CIPP functionality that deploys applications across an entire tenant base as a standard.", "addedComponent": [ @@ -333,57 +345,61 @@ "label": "Deploy Application", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-07", "powershellEquivalent": "Portal or Graph API", "recommendedBy": [] }, { "name": "standards.laps", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables the tenant to use LAPS. You must still create a policy for LAPS to be active on all devices. Use the template standards to deploy this by default.", "docsDescription": "Enables the LAPS functionality on the tenant. Prerequisite for using Windows LAPS via Azure AD.", "addedComponent": [], "label": "Enable LAPS on the tenant", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-04-25", "powershellEquivalent": "Portal or Graph API", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.PWdisplayAppInformationRequiredState", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Enables the MS authenticator app to display information about the app that is requesting authentication. This displays the application name.", "docsDescription": "Allows users to use Passwordless with Number Matching and adds location information from the last request", "addedComponent": [], "label": "Enable Passwordless with Location information and Number Matching", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2021-11-16", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": ["CIS"] }, { "name": "standards.allowOTPTokens", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Allows you to use MS authenticator OTP token generator", "docsDescription": "Allows you to use Microsoft Authenticator OTP token generator. Useful for using the NPS extension as MFA on VPN clients.", "addedComponent": [], "label": "Enable OTP via Authenticator", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-12-06", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.PWcompanionAppAllowedState", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the state of Authenticator Lite, Authenticator lite is a companion app for passwordless authentication.", "docsDescription": "Sets the Authenticator Lite state to enabled. This allows users to use the Authenticator Lite built into the Outlook app instead of the full Authenticator app.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -403,57 +419,61 @@ "label": "Set Authenticator Lite state", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-05-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.EnableFIDO2", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables the FIDO2 authenticationMethod for the tenant", "docsDescription": "Enables FIDO2 capabilities for the tenant. This allows users to use FIDO2 keys like a Yubikey for authentication.", "addedComponent": [], "label": "Enable FIDO2 capabilities", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-12-08", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.EnableHardwareOAuth", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables the HardwareOath authenticationMethod for the tenant. This allows you to use hardware tokens for generating 6 digit MFA codes.", "docsDescription": "Enables Hardware OAuth tokens for the tenant. This allows users to use hardware tokens like a Yubikey for authentication.", "addedComponent": [], "label": "Enable Hardware OAuth tokens", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-12-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.allowOAuthTokens", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Allows you to use any software OAuth token generator", "docsDescription": "Enables OTP Software OAuth tokens for the tenant. This allows users to use OTP codes generated via software, like a password manager to be used as an authentication method.", "addedComponent": [], "label": "Enable OTP Software OAuth tokens", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-12-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.TAP", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables TAP and sets the default TAP lifetime to 1 hour. This configuration also allows you to select if a TAP is single use or multi-logon.", "docsDescription": "Enables Temporary Password generation for the tenant.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select TAP Lifetime", @@ -473,30 +493,32 @@ "label": "Enable Temporary Access Passwords", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-03-15", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.PasswordExpireDisabled", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact", "CIS", "PWAgePolicyNew"], + "tag": ["CIS", "PWAgePolicyNew"], "helpText": "Disables the expiration of passwords for the tenant by setting the password expiration policy to never expire for any user.", "docsDescription": "Sets passwords to never expire for tenant, recommended to use in conjunction with secure password requirements.", "addedComponent": [], "label": "Do not expire passwords", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2021-11-16", "powershellEquivalent": "Update-MgDomain", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.ExternalMFATrusted", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the state of the Cross-tenant access setting to trust external MFA. This allows guest users to use their home tenant MFA to access your tenant.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -516,26 +538,28 @@ "label": "Sets the Cross-tenant access setting to trust external MFA", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-26", "powershellEquivalent": "Update-MgBetaPolicyCrossTenantAccessPolicyDefault", "recommendedBy": [] }, { "name": "standards.DisableTenantCreation", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles. ", "docsDescription": "Users by default are allowed to create M365 tenants. This disables that so only admins can create new M365 tenants.", "addedComponent": [], "label": "Disable M365 Tenant creation by users", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-11-29", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableAppConsentRequests", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Enables App consent admin requests for the tenant via the GA role. Does not overwrite existing reviewer settings", "docsDescription": "Enables the ability for users to request admin consent for applications. Should be used in conjunction with the \"Require admin consent for applications\" standards", "addedComponent": [ @@ -548,18 +572,19 @@ "label": "Enable App consent admin requests", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-11-27", "powershellEquivalent": "Update-MgPolicyAdminConsentRequestPolicy", "recommendedBy": ["CIS"] }, { "name": "standards.NudgeMFA", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the state of the registration campaign for the tenant", "docsDescription": "Sets the state of the registration campaign for the tenant. If enabled nudges users to set up the Microsoft Authenticator during sign-in.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "creatable": false, "label": "Select value", @@ -579,69 +604,74 @@ "type": "number", "name": "standards.NudgeMFA.snoozeDurationInDays", "label": "Number of days to allow users to skip registering Authenticator (0-14, default is 1)", - "default": 1 + "defaultValue": 1 } ], "label": "Sets the state for the request to setup Authenticator", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-12-08", "powershellEquivalent": "Update-MgPolicyAuthenticationMethodPolicy", "recommendedBy": [] }, { "name": "standards.DisableM365GroupUsers", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc", "docsDescription": "Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc", "addedComponent": [], "label": "Disable M365 Group creation by users", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-07-17", "powershellEquivalent": "Update-MgBetaDirectorySetting", "recommendedBy": [] }, { "name": "standards.DisableAppCreation", "cat": "Entra (AAD) Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Disables the ability for users to create App registrations in the tenant.", "docsDescription": "Disables the ability for users to create applications in Entra. Done to prevent breached accounts from creating an app to maintain access to the tenant, even after the breached account has been secured.", "addedComponent": [], "label": "Disable App creation by users", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-20", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableSecurityGroupUsers", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Completely disables the creation of security groups by users. This also breaks the ability to manage groups themselves, or create Teams", "addedComponent": [], "label": "Disable Security Group creation by users", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2022-07-17", "powershellEquivalent": "Update-MgBetaPolicyAuthorizationPolicy", "recommendedBy": [] }, { "name": "standards.LegacyMFACleanup", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard currently does not function and can be safely disabled", "addedComponent": [], "label": "Remove Legacy MFA if SD or CA is active", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Set-MsolUser -StrongAuthenticationRequirements $null", "recommendedBy": [] }, { "name": "standards.DisableSelfServiceLicenses", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard disables all self service licenses and enables all exclusions", "addedComponent": [ { @@ -654,25 +684,27 @@ "label": "Disable Self Service Licensing", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Set-MsolCompanySettings -AllowAdHocSubscriptions $false", "recommendedBy": [] }, { "name": "standards.DisableGuests", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Blocks login for guest users that have not logged in for 90 days", "addedComponent": [], "label": "Disable Guest accounts that have not logged on for 90 days", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2022-10-20", "powershellEquivalent": "Graph API", - "recommendedBy": [] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.OauthConsent", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact", "CIS"], + "tag": ["CIS"], "helpText": "Disables users from being able to consent to applications, except for those specified in the field below", "docsDescription": "Requires users to get administrator consent before sharing data with applications. You can preapprove specific applications.", "addedComponent": [ @@ -686,25 +718,27 @@ "label": "Require admin consent for applications (Prevent OAuth phishing)", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.OauthConsentLowSec", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact", "IntegratedApps"], + "tag": ["IntegratedApps"], "helpText": "Sets the default oauth consent level so users can consent to applications that have low risks.", "docsDescription": "Allows users to consent to applications with low assigned risk.", "label": "Allow users to consent to applications with low security risk (Prevent OAuth phishing. Lower impact, less secure)", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2022-08-16", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", "recommendedBy": [] }, { "name": "standards.GuestInvite", "cat": "Entra (AAD) Standards", - "tag": ["mediumimpact"], + "tag": [], "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.", "addedComponent": [ { @@ -737,13 +771,14 @@ "label": "Guest Invite setting", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-11-12", "powershellEquivalent": "", "recommendedBy": [] }, { "name": "standards.StaleEntraDevices", "cat": "Entra (AAD) Standards", - "tag": ["highimpact", "CIS"], + "tag": ["CIS"], "helpText": "Cleans up Entra devices that have not connected/signed in for the specified number of days.", "docsDescription": "Cleans up Entra devices that have not connected/signed in for the specified number of days. First disables and later deletes the devices. More info can be found in the [Microsoft documentation](https://learn.microsoft.com/en-us/entra/identity/devices/manage-stale-devices)", "addedComponent": [ @@ -761,101 +796,150 @@ "label": "Cleanup stale Entra devices", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2025-01-19", "powershellEquivalent": "Remove-MgDevice, Update-MgDevice or Graph API", "recommendedBy": [] }, { "name": "standards.UndoOauth", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables App consent and set to Allow user consent for apps", "addedComponent": [], "label": "Undo App Consent Standard", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2022-01-07", "powershellEquivalent": "Update-MgPolicyAuthorizationPolicy", "recommendedBy": [] }, { "name": "standards.SecurityDefaults", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Enables security defaults for the tenant, for newer tenants this is enabled by default. Do not enable this feature if you use Conditional Access.", "docsDescription": "Enables SD for the tenant, which disables all forms of basic authentication and enforces users to configure MFA. Users are only prompted for MFA when a logon is considered 'suspect' by Microsoft.", "addedComponent": [], "label": "Enable Security Defaults", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2021-11-19", "powershellEquivalent": "[Read more here](https://www.cyberdrain.com/automating-with-powershell-enabling-secure-defaults-and-sd-explained/)", "recommendedBy": [] }, { "name": "standards.DisableSMS", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using SMS as an MFA method. If a user only has SMS as a MFA method, they will be unable to log in.", "docsDescription": "Disables SMS as an MFA method for the tenant. If a user only has SMS as a MFA method, they will be unable to sign in.", "addedComponent": [], "label": "Disables SMS as an MFA method", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2023-12-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableVoice", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using Voice call as an MFA method. If a user only has Voice as a MFA method, they will be unable to log in.", "docsDescription": "Disables Voice call as an MFA method for the tenant. If a user only has Voice call as a MFA method, they will be unable to sign in.", "addedComponent": [], "label": "Disables Voice call as an MFA method", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2023-12-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DisableEmail", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using email as an MFA method. This disables the email OTP option for guest users, and instead prompts them to create a Microsoft account.", "addedComponent": [], "label": "Disables Email as an MFA method", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2023-12-18", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.Disablex509Certificate", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "This blocks users from using Certificates as an MFA method.", "docsDescription": "", "addedComponent": [], "label": "Disables Certificates as an MFA method", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2023-12-18", + "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", + "recommendedBy": [] + }, + { + "name": "standards.DisableQRCodePin", + "cat": "Entra (AAD) Standards", + "tag": [], + "helpText": "This blocks users from using QR Code Pin as an MFA method. If a user only has QR Code Pin as a MFA method, they will be unable to log in.", + "docsDescription": "Disables QR Code Pin as an MFA method for the tenant. If a user only has QR Code Pin as a MFA method, they will be unable to sign in.", + "addedComponent": [], + "label": "Disables QR Code Pin as an MFA method", + "impact": "High Impact", + "impactColour": "danger", + "addedDate": "2024-02-10", "powershellEquivalent": "Update-MgBetaPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration", "recommendedBy": [] }, { "name": "standards.PerUserMFA", "cat": "Entra (AAD) Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Enables per user MFA for all users.", "addedComponent": [], "label": "Enables per user MFA for all users.", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2024-06-14", "powershellEquivalent": "Graph API", "recommendedBy": [] }, + { + "name": "standards.UserPreferredLanguage", + "cat": "Entra (AAD) Standards", + "tag": [], + "helpText": "Sets the preferred language property for all users in the tenant. This will override the user's language settings.", + "docsDescription": "Sets the preferred language property for all users in the tenant. This will override the user's language settings.", + "addedComponent": [ + { + "type": "autoComplete", + "multiple": false, + "creatable": false, + "name": "standards.UserPreferredLanguage.preferredLanguage", + "label": "Preferred Language", + "api": { + "url": "/languageList.json", + "labelField": "language", + "valueField": "tag" + } + } + ], + "label": "Preferred language for all users", + "impact": "High Impact", + "impactColour": "info", + "addedDate": "2025-02-26", + "powershellEquivalent": "Update-MgUser -UserId user@domain.com -BodyParameter @{preferredLanguage='en-US'}", + "recommendedBy": [] + }, { "name": "standards.OutBoundSpamAlert", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Set the Outbound Spam Alert e-mail address", "docsDescription": "Sets the e-mail address to which outbound spam alerts are sent.", "addedComponent": [ @@ -868,31 +952,33 @@ "label": "Set Outbound Spam Alert e-mail", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-05-03", "powershellEquivalent": "Set-HostedOutboundSpamFilterPolicy", "recommendedBy": ["CIS"] }, { "name": "standards.MessageExpiration", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the transport message configuration to timeout a message at 12 hours.", "docsDescription": "Expires messages in the transport queue after 12 hours. Makes the NDR for failed messages show up faster for users. Default is 24 hours.", "addedComponent": [], "label": "Lower Transport Message Expiration to 12 hours", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-02-23", "powershellEquivalent": "Set-TransportConfig -MessageExpirationTimeout 12.00:00:00", "recommendedBy": [] }, { "name": "standards.GlobalQuarantineNotifications", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the Global Quarantine Notification Interval to the selected value. Determines how often the quarantine notification is sent to users.", "docsDescription": "Sets the global quarantine notification interval for the tenant. This is the time between the quarantine notification emails are sent out to users. Default is 24 hours.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.GlobalQuarantineNotifications.NotificationInterval", @@ -915,31 +1001,33 @@ "label": "Set Global Quarantine Notification Interval", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-05-03", "powershellEquivalent": "Set-QuarantinePolicy -EndUserSpamNotificationFrequency", "recommendedBy": [] }, { "name": "standards.DisableTNEF", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Disables Transport Neutral Encapsulation Format (TNEF)/winmail.dat for the tenant. TNEF can cause issues if the recipient is not using a client supporting TNEF.", "docsDescription": "Disables Transport Neutral Encapsulation Format (TNEF)/winmail.dat for the tenant. TNEF can cause issues if the recipient is not using a client supporting TNEF. Cannot be overridden by the user. For more information, see [Microsoft's documentation.](https://learn.microsoft.com/en-us/exchange/mail-flow/content-conversion/tnef-conversion?view=exchserver-2019)", "addedComponent": [], "label": "Disable TNEF/winmail.dat", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-04-26", "powershellEquivalent": "Set-RemoteDomain -Identity 'Default' -TNEFEnabled $false", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.FocusedInbox", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the default Focused Inbox state for the tenant. This can be overridden by the user.", "docsDescription": "Sets the default Focused Inbox state for the tenant. This can be overridden by the user in their Outlook settings. For more information, see [Microsoft's documentation.](https://support.microsoft.com/en-us/office/focused-inbox-for-outlook-f445ad7f-02f4-4294-a82e-71d8964e3978)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.FocusedInbox.state", @@ -958,18 +1046,19 @@ "label": "Set Focused Inbox state", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-04-26", "powershellEquivalent": "Set-OrganizationConfig -FocusedInboxOn $true or $false", "recommendedBy": [] }, { "name": "standards.CloudMessageRecall", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the Cloud Message Recall state for the tenant. This allows users to recall messages from the cloud.", "docsDescription": "Sets the default state for Cloud Message Recall for the tenant. By default this is enabled. You can read more about the feature [here.](https://techcommunity.microsoft.com/t5/exchange-team-blog/cloud-based-message-recall-in-exchange-online/ba-p/3744714)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.CloudMessageRecall.state", @@ -988,55 +1077,66 @@ "label": "Set Cloud Message Recall state", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-05-31", "powershellEquivalent": "Set-OrganizationConfig -MessageRecallEnabled", "recommendedBy": [] }, { "name": "standards.AutoExpandArchive", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables auto-expanding archives for the tenant", "docsDescription": "Enables auto-expanding archives for the tenant. Does not enable archives for users.", "addedComponent": [], "label": "Enable Auto-expanding archives", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2021-11-16", "powershellEquivalent": "Set-OrganizationConfig -AutoExpandingArchive", "recommendedBy": [] }, { "name": "standards.EnableOnlineArchiving", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables the In-Place Online Archive for all UserMailboxes with a valid license.", "addedComponent": [], "label": "Enable Online Archive for all users", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-20", "powershellEquivalent": "Enable-Mailbox -Archive $true", "recommendedBy": [] }, { "name": "standards.EnableLitigationHold", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Enables litigation hold for all UserMailboxes with a valid license.", - "addedComponent": [], + "addedComponent": [ + { + "type": "textField", + "name": "standards.EnableLitigationHold.days", + "required": false, + "label": "Days to apply for litigation hold" + } + ], "label": "Enable Litigation Hold for all users", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-06-25", "powershellEquivalent": "Set-Mailbox -LitigationHoldEnabled $true", "recommendedBy": [] }, { "name": "standards.SpoofWarn", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Adds or removes indicators to e-mail messages received from external senders in Outlook. Works on all Outlook clients/OWA", "docsDescription": "Adds or removes indicators to e-mail messages received from external senders in Outlook. You can read more about this feature on [Microsoft's Exchange Team Blog.](https://techcommunity.microsoft.com/t5/exchange-team-blog/native-external-sender-callouts-on-email-in-outlook/ba-p/2250098)", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.SpoofWarn.state", @@ -1050,18 +1150,27 @@ "value": "disabled" } ] + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "label": "Enter allowed senders(domain.com, *.domain.com or test@domain.com)", + "name": "standards.SpoofWarn.AllowListAdd" } ], "label": "Enable or disable 'external' warning in Outlook", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "et-ExternalInOutlook \u2013Enabled $true or $false", - "recommendedBy": ["CIS"] + "addedDate": "2021-11-16", + "powershellEquivalent": "Set-ExternalInOutlook \u2013Enabled $true or $false", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableMailTips", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS", "exo_mailtipsenabled"], + "tag": ["CIS", "exo_mailtipsenabled"], "helpText": "Enables all MailTips in Outlook. MailTips are the notifications Outlook and Outlook on the web shows when an email you create, meets some requirements", "addedComponent": [ { @@ -1069,24 +1178,26 @@ "name": "standards.EnableMailTips.MailTipsLargeAudienceThreshold", "label": "Number of recipients to trigger the large audience MailTip (Default is 25)", "placeholder": "Enter a profile name", - "default": 25 + "defaultValue": 25 } ], "label": "Enable all MailTips", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-14", "powershellEquivalent": "Set-OrganizationConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.TeamsMeetingsByDefault", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the default state for automatically turning meetings into Teams meetings for the tenant. This can be overridden by the user in Outlook.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, + "creatable": false, "label": "Select value", "name": "standards.TeamsMeetingsByDefault.state", "options": [ @@ -1104,88 +1215,94 @@ "label": "Set Teams Meetings by default state", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-05-31", "powershellEquivalent": "Set-OrganizationConfig -OnlineMeetingsByDefaultEnabled", "recommendedBy": [] }, { "name": "standards.DisableViva", "cat": "Exchange Standards", - "tag": ["lowimpact"], - "helpText": "Disables the daily viva reports for all users.", + "tag": [], + "helpText": "Disables the daily viva reports for all users. This standard requires the CIPP-SAM application to have the Company Administrator (Global Admin) role in the tenant. Enable this using CIPP > Advanced > Super Admin > SAM App Roles. Activate the roles with a CPV refresh.", "docsDescription": "", "addedComponent": [], "label": "Disable daily Insight/Viva reports", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2022-05-25", "powershellEquivalent": "Set-UserBriefingConfig", "recommendedBy": [] }, { "name": "standards.RotateDKIM", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Rotate DKIM keys that are 1024 bit to 2048 bit", "addedComponent": [], "label": "Rotate DKIM keys that are 1024 bit to 2048 bit", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-03-14", "powershellEquivalent": "Rotate-DkimSigningConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.AddDKIM", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Enables DKIM for all domains that currently support it", "addedComponent": [], "label": "Enables DKIM for all domains that currently support it", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-03-14", "powershellEquivalent": "New-DkimSigningConfig and Set-DkimSigningConfig", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EnableMailboxAuditing", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS", "exo_mailboxaudit"], + "tag": ["CIS", "exo_mailboxaudit"], "helpText": "Enables Mailbox auditing for all mailboxes and on tenant level. Disables audit bypass on all mailboxes. Unified Audit Log needs to be enabled for this standard to function.", "docsDescription": "Enables mailbox auditing on tenant level and for all mailboxes. Disables audit bypass on all mailboxes. By default Microsoft does not enable mailbox auditing for Resource Mailboxes, Public Folder Mailboxes and DiscoverySearch Mailboxes. Unified Audit Log needs to be enabled for this standard to function.", "addedComponent": [], "label": "Enable Mailbox auditing", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-08", "powershellEquivalent": "Set-OrganizationConfig -AuditDisabled $false", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SendReceiveLimitTenant", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the Send and Receive limits for new users. Valid values are 1MB to 150MB", "addedComponent": [ { "type": "number", "name": "standards.SendReceiveLimitTenant.SendLimit", "label": "Send limit in MB (Default is 35)", - "default": 35 + "defaultValue": 35 }, { "type": "number", "name": "standards.SendReceiveLimitTenant.ReceiveLimit", "label": "Receive Limit in MB (Default is 36)", - "default": 36 + "defaultValue": 36 } ], "label": "Set send/receive size limits", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-11-16", "powershellEquivalent": "Set-MailboxPlan", "recommendedBy": [] }, { "name": "standards.calDefault", "cat": "Exchange Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the default sharing level for the default calendar, for all users", "docsDescription": "Sets the default sharing level for the default calendar for all users in the tenant. You can read about the different sharing levels [here.](https://learn.microsoft.com/en-us/powershell/module/exchange/set-mailboxfolderpermission?view=exchange-ps#-accessrights)", "disabledFeatures": { @@ -1195,10 +1312,10 @@ }, "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select Sharing Level", - "name": "standards.calDefault.permissionlevel", + "name": "standards.calDefault.permissionLevel", "options": [ { "label": "Owner - The user can create, read, edit, and delete all items in the folder, and create subfolders. The user is both folder owner and folder contact.", @@ -1250,55 +1367,85 @@ "label": "Set Sharing Level for Default calendar", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-04-27", "powershellEquivalent": "Set-MailboxFolderPermission", "recommendedBy": [] }, { "name": "standards.DisableExternalCalendarSharing", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS", "exo_individualsharing"], + "tag": ["CIS", "exo_individualsharing"], "helpText": "Disables the ability for users to share their calendar with external users. Only for the default policy, so exclusions can be made if needed.", "docsDescription": "Disables external calendar sharing for the entire tenant. This is not a widely used feature, and it's therefore unlikely that this will impact users. Only for the default policy, so exclusions can be made if needed by making a new policy and assigning it to users.", "addedComponent": [], "label": "Disable external calendar sharing", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-08", "powershellEquivalent": "Get-SharingPolicy | Set-SharingPolicy -Enabled $False", "recommendedBy": ["CIS"] }, { - "name": "standardsAutoAddProxy", + "name": "standards.AutoAddProxy", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Automatically adds all available domains as a proxy address.", - "docsDescription": "Automatically finds all available domain names in the tenant, and tries to add proxyaddresses based on the users UPN to each of these.", + "docsDescription": "Automatically finds all available domain names in the tenant, and tries to add proxy addresses based on the user's UPN to each of these.", "addedComponent": [], "label": "Automatically deploy proxy addresses", "impact": "Medium Impact", "impactColour": "warning", - "powershellEquivalent": "set-mailbox -emailaddresses @{add=$emailaddress}" + "addedDate": "2025-02-07", + "powershellEquivalent": "Set-Mailbox -EmailAddresses @{add=$EmailAddress}", + "recommendedBy": [], + "disabledFeatures": { + "report": true, + "warn": true, + "remediate": false + } }, { "name": "standards.DisableAdditionalStorageProviders", "cat": "Exchange Standards", - "tag": ["lowimpact", "CIS", "exo_storageproviderrestricted"], + "tag": ["CIS", "exo_storageproviderrestricted"], "helpText": "Disables the ability for users to open files in Outlook on the Web, from other providers such as Box, Dropbox, Facebook, Google Drive, OneDrive Personal, etc.", "docsDescription": "Disables additional storage providers in OWA. This is to prevent users from using personal storage providers like Dropbox, Google Drive, etc. Usually this has little user impact.", "addedComponent": [], "label": "Disable additional storage providers in OWA", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-01-17", "powershellEquivalent": "Get-OwaMailboxPolicy | Set-OwaMailboxPolicy -AdditionalStorageProvidersEnabled $False", "recommendedBy": ["CIS"] }, + { + "name": "standards.AntiSpamSafeList", + "cat": "Defender Standards", + "tag": [], + "helpText": "Sets the anti-spam connection filter policy option 'safe list' in Defender.", + "docsDescription": "Sets [Microsoft's built-in 'safe list'](https://learn.microsoft.com/en-us/powershell/module/exchange/set-hostedconnectionfilterpolicy?view=exchange-ps#-enablesafelist) in the anti-spam connection filter policy, rather than setting a custom safe/block list of IPs.", + "addedComponent": [ + { + "type": "switch", + "name": "standards.AntiSpamSafeList.EnableSafeList", + "label": "Enable Safe List" + } + ], + "label": "Set Anti-Spam Connection Filter Safe List", + "impact": "Medium Impact", + "impactColour": "info", + "addedDate": "2025-02-15", + "powershellEquivalent": "Set-HostedConnectionFilterPolicy \"Default\" -EnableSafeList $true", + "recommendedBy": [] + }, { "name": "standards.ShortenMeetings", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the shorten meetings settings on a tenant level. This will shorten meetings by the selected amount of minutes. Valid values are 0 to 29. Short meetings are under 60 minutes, long meetings are over 60 minutes.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.ShortenMeetings.ShortenEventScopeDefault", @@ -1321,30 +1468,31 @@ "type": "number", "name": "standards.ShortenMeetings.DefaultMinutesToReduceShortEventsBy", "label": "Minutes to reduce short calendar events by (Default is 5)", - "default": 5 + "defaultValue": 5 }, { "type": "number", "name": "standards.ShortenMeetings.DefaultMinutesToReduceLongEventsBy", "label": "Minutes to reduce long calendar events by (Default is 10)", - "default": 10 + "defaultValue": 10 } ], "label": "Set shorten meetings state", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-05-27", "powershellEquivalent": "Set-OrganizationConfig -ShortenEventScopeDefault -DefaultMinutesToReduceShortEventsBy -DefaultMinutesToReduceLongEventsBy", "recommendedBy": [] }, { "name": "standards.Bookings", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the state of Bookings on the tenant. Bookings is a scheduling tool that allows users to book appointments with others both internal and external.", "docsDescription": "", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.Bookings.state", @@ -1363,26 +1511,28 @@ "label": "Set Bookings state", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-05-31", "powershellEquivalent": "Set-OrganizationConfig -BookingsEnabled", "recommendedBy": [] }, { "name": "standards.DisableOutlookAddins", "cat": "Exchange Standards", - "tag": ["mediumimpact", "CIS", "exo_outlookaddins"], + "tag": ["CIS", "exo_outlookaddins"], "helpText": "Disables the ability for users to install add-ins in Outlook. This is to prevent users from installing malicious add-ins.", "docsDescription": "Disables users from being able to install add-ins in Outlook. Only admins are able to approve add-ins for the users. This is done to reduce the threat surface for data exfiltration.", "addedComponent": [], "label": "Disable users from installing add-ins in Outlook", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-02-05", "powershellEquivalent": "Get-ManagementRoleAssignment | Remove-ManagementRoleAssignment", "recommendedBy": ["CIS"] }, { "name": "standards.SafeSendersDisable", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Loops through all users and removes the Safe Senders list. This is to prevent SPF bypass attacks, as the Safe Senders list is not checked by SPF.", "addedComponent": [], "disabledFeatures": { @@ -1393,13 +1543,14 @@ "label": "Remove Safe Senders to prevent SPF bypass", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2023-10-26", "powershellEquivalent": "Set-MailboxJunkEmailConfiguration", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.DelegateSentItems", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets emails sent as and on behalf of shared mailboxes to also be stored in the shared mailbox sent items folder", "docsDescription": "This makes sure that e-mails sent from shared mailboxes or delegate mailboxes, end up in the mailbox of the shared/delegate mailbox instead of the sender, allowing you to keep replies in the same mailbox as the original e-mail.", "addedComponent": [ @@ -1412,31 +1563,33 @@ "label": "Set mailbox Sent Items delegation (Sent items for shared mailboxes)", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Set-Mailbox", "recommendedBy": [] }, { "name": "standards.SendFromAlias", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Enables the ability for users to send from their alias addresses.", "docsDescription": "Allows users to change the 'from' address to any set in their Azure AD Profile.", "addedComponent": [], "label": "Allow users to send from their alias addresses", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2022-05-25", "powershellEquivalent": "Set-Mailbox", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.UserSubmissions", "cat": "Exchange Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Set the state of the spam submission button in Outlook", "docsDescription": "Set the state of the built-in Report button in Outlook. This gives the users the ability to report emails as spam or phish.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select value", "name": "standards.UserSubmissions.state", @@ -1461,44 +1614,42 @@ "label": "Set the state of the built-in Report button in Outlook", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-06-28", "powershellEquivalent": "New-ReportSubmissionPolicy or Set-ReportSubmissionPolicy and New-ReportSubmissionRule or Set-ReportSubmissionRule", "recommendedBy": [] }, { "name": "standards.DisableSharedMailbox", "cat": "Exchange Standards", - "tag": ["mediumimpact", "CIS"], + "tag": ["CIS"], "helpText": "Blocks login for all accounts that are marked as a shared mailbox. This is Microsoft best practice to prevent direct logons to shared mailboxes.", "docsDescription": "Shared mailboxes can be directly logged into if the password is reset, this presents a security risk as do all shared login credentials. Microsoft's recommendation is to disable the user account for shared mailboxes. It would be a good idea to review the sign-in reports to establish potential impact.", "addedComponent": [], "label": "Disable Shared Mailbox AAD accounts", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2021-11-16", "powershellEquivalent": "Get-Mailbox & Update-MgUser", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.EXODisableAutoForwarding", "cat": "Exchange Standards", - "tag": [ - "highimpact", - "CIS", - "mdo_autoforwardingmode", - "mdo_blockmailforward" - ], + "tag": ["CIS", "mdo_autoforwardingmode", "mdo_blockmailforward"], "helpText": "Disables the ability for users to automatically forward e-mails to external recipients.", "docsDescription": "Disables the ability for users to automatically forward e-mails to external recipients. This is to prevent data exfiltration. Please check if there are any legitimate use cases for this feature before implementing, like forwarding invoices and such.", "addedComponent": [], "label": "Disable automatic forwarding to external recipients", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2024-07-26", "powershellEquivalent": "Set-HostedOutboundSpamFilterPolicy -AutoForwardingMode 'Off'", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.RetentionPolicyTag", "cat": "Exchange Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.", "docsDescription": "Creates a CIPP - Deleted Items retention policy tag that permanently deletes items in the Deleted Items folder after X days.", "addedComponent": [ @@ -1512,13 +1663,14 @@ "label": "Retention Policy, permanently delete items in Deleted Items after X days", "impact": "High Impact", "impactColour": "danger", + "addedDate": "2025-02-02", "powershellEquivalent": "Set-RetentionPolicyTag", "recommendedBy": [] }, { "name": "standards.QuarantineRequestAlert", "cat": "Defender Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets a e-mail address to alert when a User requests to release a quarantined message.", "docsDescription": "Sets a e-mail address to alert when a User requests to release a quarantined message. This is useful for monitoring and ensuring that the correct messages are released.", "addedComponent": [ @@ -1531,18 +1683,14 @@ "label": "Quarantine Release Request Alert", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-15", "powershellEquivalent": "New-ProtectionAlert and Set-ProtectionAlert", "recommendedBy": [] }, { "name": "standards.SafeLinksPolicy", "cat": "Defender Standards", - "tag": [ - "lowimpact", - "CIS", - "mdo_safelinksforemail", - "mdo_safelinksforOfficeApps" - ], + "tag": ["CIS", "mdo_safelinksforemail", "mdo_safelinksforOfficeApps"], "helpText": "This creates a safelink policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders", "addedComponent": [ { @@ -1559,11 +1707,20 @@ "type": "switch", "label": "EnableOrganizationBranding", "name": "standards.SafeLinksPolicy.EnableOrganizationBranding" + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SafeLinksPolicy.DoNotRewriteUrls", + "label": "Do not rewrite the following URLs in email" } ], "label": "Default SafeLinks Policy", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-25", "powershellEquivalent": "Set-SafeLinksPolicy or New-SafeLinksPolicy", "recommendedBy": ["CIS"] }, @@ -1571,7 +1728,6 @@ "name": "standards.AntiPhishPolicy", "cat": "Defender Standards", "tag": [ - "lowimpact", "CIS", "mdo_safeattachments", "mdo_highconfidencespamaction", @@ -1587,31 +1743,31 @@ "type": "number", "label": "Phishing email threshold. (Default 1)", "name": "standards.AntiPhishPolicy.PhishThresholdLevel", - "default": 1 + "defaultValue": 1 }, { "type": "switch", "label": "Show first contact safety tip", "name": "standards.AntiPhishPolicy.EnableFirstContactSafetyTips", - "default": true + "defaultValue": true }, { "type": "switch", "label": "Show user impersonation safety tip", "name": "standards.AntiPhishPolicy.EnableSimilarUsersSafetyTips", - "default": true + "defaultValue": true }, { "type": "switch", "label": "Show domain impersonation safety tip", "name": "standards.AntiPhishPolicy.EnableSimilarDomainsSafetyTips", - "default": true + "defaultValue": true }, { "type": "switch", "label": "Show user impersonation unusual characters safety tip", "name": "standards.AntiPhishPolicy.EnableUnusualCharactersSafetyTips", - "default": true + "defaultValue": true }, { "type": "select", @@ -1773,6 +1929,7 @@ "label": "Default Anti-Phishing Policy", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-25", "powershellEquivalent": "Set-AntiphishPolicy or New-AntiphishPolicy", "recommendedBy": ["CIS"] }, @@ -1780,7 +1937,6 @@ "name": "standards.SafeAttachmentPolicy", "cat": "Defender Standards", "tag": [ - "lowimpact", "CIS", "mdo_safedocuments", "mdo_commonattachmentsfilter", @@ -1843,39 +1999,73 @@ "label": "Default Safe Attachment Policy", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-25", "powershellEquivalent": "Set-SafeAttachmentPolicy or New-SafeAttachmentPolicy", "recommendedBy": ["CIS"] }, { "name": "standards.AtpPolicyForO365", "cat": "Defender Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "This creates a Atp policy that enables Defender for Office 365 for SharePoint, OneDrive and Microsoft Teams.", "addedComponent": [ { "type": "switch", "label": "Allow people to click through Protected View even if Safe Documents identified the file as malicious", "name": "standards.AtpPolicyForO365.AllowSafeDocsOpen", - "default": false, + "defaultValue": false, "required": false } ], "label": "Default Atp Policy For O365", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-25", "powershellEquivalent": "Set-AtpPolicyForO365", "recommendedBy": ["CIS"] }, { - "name": "standards.MalwareFilterPolicy", + "name": "standards.PhishingSimulations", "cat": "Defender Standards", - "tag": [ - "lowimpact", - "CIS", - "mdo_zapspam", - "mdo_zapphish", - "mdo_zapmalware" + "tag": [], + "helpText": "This creates a phishing simulation policy that enables phishing simulations for the entire tenant.", + "addedComponent": [ + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": true, + "label": "Phishing Simulation Domains", + "name": "standards.PhishingSimulations.Domains" + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": true, + "label": "Phishing Simulation Sender IP Ranges", + "name": "standards.PhishingSimulations.SenderIpRanges" + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "label": "Phishing Simulation Urls", + "name": "standards.PhishingSimulations.PhishingSimUrls" + } ], + "label": "Phishing Simulation Configuration", + "impact": "Medium Impact", + "impactColour": "info", + "addedDate": "2025-03-27", + "powershellEquivalent": "New-TenantAllowBlockListItems, New-PhishSimOverridePolicy and New-ExoPhishSimOverrideRule", + "recommendedBy": [] + }, + { + "name": "standards.MalwareFilterPolicy", + "cat": "Defender Standards", + "tag": ["CIS", "mdo_zapspam", "mdo_zapphish", "mdo_zapmalware"], "helpText": "This creates a Malware filter policy that enables the default File filter and Zero-hour auto purge for malware.", "addedComponent": [ { @@ -1948,20 +2138,43 @@ "label": "Default Malware Filter Policy", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-03-25", "powershellEquivalent": "Set-MalwareFilterPolicy or New-MalwareFilterPolicy", "recommendedBy": ["CIS"] }, + { + "name": "standards.PhishSimSpoofIntelligence", + "cat": "Defender Standards", + "tag": [], + "helpText": "This adds allowed domains to the Spoof Intelligence Allow/Block List.", + "addedComponent": [ + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "label": "Allowed Domains", + "name": "standards.PhishSimSpoofIntelligence.AllowedDomains" + } + ], + "label": "Add allowed domains to Spoof Intelligence", + "impact": "Medium Impact", + "impactColour": "info", + "addedDate": "2025-03-28", + "powershellEquivalent": "New-TenantAllowBlockListSpoofItems", + "recommendedBy": [] + }, { "name": "standards.SpamFilterPolicy", "cat": "Defender Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "This standard creates a Spam filter policy similar to the default strict policy.", "addedComponent": [ { "type": "number", "label": "Bulk email threshold (Default 7)", "name": "standards.SpamFilterPolicy.BulkThreshold", - "default": 7 + "defaultValue": 7 }, { "type": "autoComplete", @@ -2144,18 +2357,103 @@ "value": "DefaultFullAccessWithNotificationPolicy" } ] + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.IncreaseScoreWithImageLinks", + "label": "Increase score if message contains image links to remote websites", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.IncreaseScoreWithBizOrInfoUrls", + "label": "Increase score if message contains links to .biz or .info domains", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamFramesInHtml", + "label": "Mark as spam if message contains HTML or iframe tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamObjectTagsInHtml", + "label": "Mark as spam if message contains HTML object tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamEmbedTagsInHtml", + "label": "Mark as spam if message contains HTML embed tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamFormTagsInHtml", + "label": "Mark as spam if message contains HTML form tags", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamWebBugsInHtml", + "label": "Mark as spam if message contains web bugs (also known as web beacons)", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.MarkAsSpamSensitiveWordList", + "label": "Mark as spam if message contains words from the sensitive words list", + "defaultValue": false + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.EnableLanguageBlockList", + "label": "Enable language block list", + "defaultValue": false + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SpamFilterPolicy.LanguageBlockList", + "label": "Languages to block (uppercase ISO 639-1 two-letter)" + }, + { + "type": "switch", + "name": "standards.SpamFilterPolicy.EnableRegionBlockList", + "label": "Enable region block list", + "defaultValue": false + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SpamFilterPolicy.RegionBlockList", + "label": "Regions to block (uppercase ISO 3166-1 two-letter)" + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": false, + "name": "standards.SpamFilterPolicy.AllowedSenderDomains", + "label": "Allowed sender domains" } ], "label": "Default Spam Filter Policy", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-15", "powershellEquivalent": "New-HostedContentFilterPolicy or Set-HostedContentFilterPolicy", "recommendedBy": [] }, { "name": "standards.intuneDeviceRetirementDays", "cat": "Intune Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "A value between 0 and 270 is supported. A value of 0 disables retirement, retired devices are removed from Intune after the specified number of days.", "addedComponent": [ { @@ -2167,13 +2465,14 @@ "label": "Set inactive device retirement days", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-05-19", "powershellEquivalent": "Graph API", - "recommendedBy": [] + "recommendedBy": ["CIPP"] }, { "name": "standards.intuneBrandingProfile", "cat": "Intune Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the branding profile for the Intune Company Portal app. This is a tenant wide setting and overrules any settings set on the app level.", "addedComponent": [ { @@ -2239,13 +2538,14 @@ "label": "Set Intune Company Portal branding profile", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-06-20", "powershellEquivalent": "Graph API", "recommendedBy": [] }, { "name": "standards.IntuneComplianceSettings", "cat": "Intune Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the mark devices with no compliance policy assigned as compliance/non compliant and Compliance status validity period.", "addedComponent": [ { @@ -2275,47 +2575,156 @@ "label": "Set Intune Compliance Settings", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-11-12", "powershellEquivalent": "", "recommendedBy": [] }, + { + "name": "standards.MDMScope", + "cat": "Intune Standards", + "tag": [], + "helpText": "Configures the MDM user scope. This also sets the terms of use, discovery and compliance URL to default URLs.", + "docsDescription": "Configures the MDM user scope. This also sets the terms of use URL, discovery URL and compliance URL to default values.", + "addedComponent": [ + { + "name": "appliesTo", + "label": "MDM User Scope?", + "type": "radio", + "options": [ + { "label": "All", "value": "all" }, + { "label": "None", "value": "none" }, + { "label": "Custom Group", "value": "selected" } + ] + }, + { + "type": "textField", + "name": "standards.MDMScope.customGroup", + "label": "Custom Group Name", + "required": false + } + ], + "label": "Configure MDM user scope", + "impact": "Low Impact", + "impactColour": "info", + "addedDate": "2025-02-18", + "powershellEquivalent": "Graph API", + "recommendedBy": [] + }, + { + "name": "standards.DefaultPlatformRestrictions", + "cat": "Intune Standards", + "tag": [], + "helpText": "Sets the default platform restrictions for enrolling devices into Intune. Note: Do not block personally owned if platform is blocked.", + "addedComponent": [ + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.platformAndroidForWorkBlocked", + "label": "Block platform Android Enterprise (work profile)", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.personalAndroidForWorkBlocked", + "label": "Block personally owned Android Enterprise (work profile)", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.platformAndroidBlocked", + "label": "Block platform Android", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.personalAndroidBlocked", + "label": "Block personally owned Android", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.platformiOSBlocked", + "label": "Block platform iOS", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.personaliOSBlocked", + "label": "Block personally owned iOS", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.platformMacOSBlocked", + "label": "Block platform macOS", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.personalMacOSBlocked", + "label": "Block personally owned macOS", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.platformWindowsBlocked", + "label": "Block platform Windows", + "default": false + }, + { + "type": "switch", + "name": "standards.DefaultPlatformRestrictions.personalWindowsBlocked", + "label": "Block personally owned Windows", + "default": false + } + ], + "label": "Device enrollment restrictions", + "impact": "Low Impact", + "impactColour": "info", + "addedDate": "2025-04-01", + "powershellEquivalent": "Graph API", + "recommendedBy": [] + }, { "name": "standards.intuneDeviceReg", "cat": "Intune Standards", - "tag": ["mediumimpact"], - "helpText": "sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users", + "tag": [], + "helpText": "Sets the maximum number of devices that can be registered by a user. A value of 0 disables device registration by users", "addedComponent": [ { "type": "number", "name": "standards.intuneDeviceReg.max", - "label": "Maximum devices (Enter 2147483647 for unlimited.)" + "label": "Maximum devices (Enter 2147483647 for unlimited.)", + "required": true } ], "label": "Set Maximum Number of Devices per user", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2023-03-27", "powershellEquivalent": "Update-MgBetaPolicyDeviceRegistrationPolicy", "recommendedBy": [] }, { "name": "standards.intuneRequireMFA", "cat": "Intune Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access.", "label": "Require Multifactor Authentication to register or join devices with Microsoft Entra", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2023-10-23", "powershellEquivalent": "Update-MgBetaPolicyDeviceRegistrationPolicy", "recommendedBy": [] }, { "name": "standards.DeletedUserRentention", "cat": "SharePoint Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the retention period for deleted users OneDrive to the specified period of time. The default is 30 days.", "docsDescription": "When a OneDrive user gets deleted, the personal SharePoint site is saved for selected amount of time that data can be retrieved from it.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "name": "standards.DeletedUserRentention.Days", "label": "Retention time (Default 30 days)", @@ -2374,13 +2783,14 @@ "label": "Set deleted user retention time in OneDrive", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.TenantDefaultTimezone", "cat": "SharePoint Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Sets the default timezone for the tenant. This will be used for all new users and sites.", "addedComponent": [ { @@ -2392,61 +2802,66 @@ "label": "Set Default Timezone for Tenant", "impact": "Low Impact", "impactColour": "info", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", + "addedDate": "2024-04-20", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.SPAzureB2B", "cat": "SharePoint Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled", "addedComponent": [], "label": "Enable SharePoint and OneDrive integration with Azure AD B2B", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -EnableAzureADB2BIntegration $true", "recommendedBy": ["CIS 3.0"] }, { "name": "standards.SPDisallowInfectedFiles", "cat": "SharePoint Standards", - "tag": ["lowimpact", "CIS"], + "tag": ["CIS"], "helpText": "Ensure Office 365 SharePoint infected files are disallowed for download", "addedComponent": [], "label": "Disallow downloading infected files from SharePoint", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -DisallowInfectedFileDownload $true", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SPDisableLegacyWorkflows", "cat": "SharePoint Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Disables the creation of new SharePoint 2010 and 2013 classic workflows and removes the 'Return to classic SharePoint' link on modern SharePoint list and library pages.", "addedComponent": [], "label": "Disable Legacy Workflows", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-15", "powershellEquivalent": "Set-SPOTenant -DisableWorkflow2010 $true -DisableWorkflow2013 $true -DisableBackToClassic $true", "recommendedBy": [] }, { "name": "standards.SPDirectSharing", "cat": "SharePoint Standards", - "tag": ["mediumimpact", "CIS"], + "tag": ["CIS"], "helpText": "Ensure default link sharing is set to Direct in SharePoint and OneDrive", "addedComponent": [], "label": "Default sharing to Direct users", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -DefaultSharingLinkType Direct", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.SPExternalUserExpiration", "cat": "SharePoint Standards", - "tag": ["mediumimpact", "CIS"], + "tag": ["CIS"], "helpText": "Ensure guest access to a site or OneDrive will expire automatically", "addedComponent": [ { @@ -2458,31 +2873,33 @@ "label": "Set guest access to expire automatically", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -ExternalUserExpireInDays 30 -ExternalUserExpirationRequired $True", "recommendedBy": ["CIS 3.0"] }, { "name": "standards.SPEmailAttestation", "cat": "SharePoint Standards", - "tag": ["mediumimpact", "CIS"], - "helpText": "Ensure reauthentication with verification code is restricted", + "tag": ["CIS"], + "helpText": "Ensure re-authentication with verification code is restricted", "addedComponent": [ { "type": "number", "name": "standards.SPEmailAttestation.Days", - "label": "Require reauth every X Days (Default 15)" + "label": "Require re-authentication every X Days (Default 15)" } ], - "label": "Require reauthentication with verification code", + "label": "Require re-authentication with verification code", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -EmailAttestationRequired $true -EmailAttestationReAuthDays 15", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableAddShortcutsToOneDrive", "cat": "SharePoint Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "If disabled, the button Add shortcut to OneDrive will be removed and users in the tenant will no longer be able to add new shortcuts to their OneDrive. Existing shortcuts will remain functional", "addedComponent": [ { @@ -2506,13 +2923,14 @@ "label": "Set Add Shortcuts To OneDrive button state", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2023-07-25", "powershellEquivalent": "Set-SPOTenant -DisableAddShortcutsToOneDrive $true or $false", "recommendedBy": [] }, { "name": "standards.SPSyncButtonState", "cat": "SharePoint Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "If disabled, users in the tenant will no longer be able to use the Sync button to sync SharePoint content on all sites. However, existing synced content will remain functional on the user's computer.", "addedComponent": [ { @@ -2536,30 +2954,32 @@ "label": "Set SharePoint sync button state", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-26", "powershellEquivalent": "Set-SPOTenant -HideSyncButtonOnTeamSite $true or $false", "recommendedBy": [] }, { "name": "standards.DisableSharePointLegacyAuth", "cat": "SharePoint Standards", - "tag": ["mediumimpact", "CIS", "spo_legacy_auth"], + "tag": ["CIS", "spo_legacy_auth"], "helpText": "Disables the ability to authenticate with SharePoint using legacy authentication methods. Any applications that use legacy authentication will need to be updated to use modern authentication.", "docsDescription": "Disables the ability for users and applications to access SharePoint via legacy basic authentication. This will likely not have any user impact, but will block systems/applications depending on basic auth or the SharePointOnlineCredentials class.", "addedComponent": [], "label": "Disable legacy basic authentication for SharePoint", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-02-05", "powershellEquivalent": "Set-SPOTenant -LegacyAuthProtocolsEnabled $false", - "recommendedBy": ["CIS"] + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.sharingCapability", "cat": "SharePoint Standards", - "tag": ["highimpact", "CIS"], + "tag": ["CIS"], "helpText": "Sets the default sharing level for OneDrive and SharePoint. This is a tenant wide setting and overrules any settings set on the site level", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "label": "Select Sharing Level", "name": "standards.sharingCapability.Level", @@ -2586,39 +3006,42 @@ "label": "Set Sharing Level for OneDrive and SharePoint", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", - "recommendedBy": ["CIS"] + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableReshare", "cat": "SharePoint Standards", - "tag": ["highimpact", "CIS"], + "tag": ["CIS"], "helpText": "Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access", "docsDescription": "Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access. This is a tenant wide setting and overrules any settings set on the site level", "addedComponent": [], "label": "Disable Resharing by External Users", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgBetaAdminSharepointSetting", - "recommendedBy": ["CIS"] + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgBetaAdminSharePointSetting", + "recommendedBy": ["CIS", "CIPP"] }, { "name": "standards.DisableUserSiteCreate", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables users from creating new SharePoint sites", "docsDescription": "Disables standard users from creating SharePoint sites, also disables the ability to fully create teams", "addedComponent": [], "label": "Disable site creation by standard users", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.ExcludedfileExt", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Sets the file extensions that are excluded from syncing with OneDrive. These files will be blocked from upload. '*.' is automatically added to the extension and can be omitted.", "addedComponent": [ { @@ -2630,41 +3053,44 @@ "label": "Exclude File Extensions from Syncing", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.disableMacSync", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "Disables the ability for Mac devices to sync with OneDrive.", "addedComponent": [], "label": "Do not allow Mac devices to sync using OneDrive", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.unmanagedSync", "cat": "SharePoint Standards", - "tag": ["highimpact"], + "tag": [], "helpText": "The unmanaged Sync standard has been temporarily disabled and does nothing.", "addedComponent": [], "label": "Only allow users to sync OneDrive from AAD joined devices", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "addedDate": "2022-06-15", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.sharingDomainRestriction", "cat": "SharePoint Standards", - "tag": ["highimpact", "CIS"], + "tag": ["CIS"], "helpText": "Restricts sharing to only users with the specified domain. This is useful for organizations that only want to share with their own domain.", "addedComponent": [ { - "type": "select", + "type": "autoComplete", "multiple": false, "name": "standards.sharingDomainRestriction.Mode", "label": "Limit external sharing by domains", @@ -2693,13 +3119,14 @@ "label": "Restrict sharing to a specific domain", "impact": "High Impact", "impactColour": "danger", - "powershellEquivalent": "Update-MgAdminSharepointSetting", + "addedDate": "2024-06-20", + "powershellEquivalent": "Update-MgAdminSharePointSetting", "recommendedBy": [] }, { "name": "standards.TeamsGlobalMeetingPolicy", "cat": "Teams Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Defines the CIS recommended global meeting policy for Teams. This includes AllowAnonymousUsersToJoinMeeting, AllowAnonymousUsersToStartMeeting, AutoAdmittedUsers, AllowPSTNUsersToBypassLobby, MeetingChatEnabledType, DesignatedPresenterRoleMode, AllowExternalParticipantGiveRequestControl", "addedComponent": [ { @@ -2754,18 +3181,24 @@ "value": "Disabled" } ] + }, + { + "type": "switch", + "name": "standards.TeamsGlobalMeetingPolicy.AllowExternalParticipantGiveRequestControl", + "label": "External participants can give or request control" } ], "label": "Define Global Meeting Policy for Teams", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-11-12", "powershellEquivalent": "Set-CsTeamsMeetingPolicy -AllowAnonymousUsersToJoinMeeting $false -AllowAnonymousUsersToStartMeeting $false -AutoAdmittedUsers EveryoneInCompanyExcludingGuests -AllowPSTNUsersToBypassLobby $false -MeetingChatEnabledType EnabledExceptAnonymous -DesignatedPresenterRoleMode $DesignatedPresenterRoleMode -AllowExternalParticipantGiveRequestControl $false", "recommendedBy": ["CIS 3.0"] }, { "name": "standards.TeamsEmailIntegration", "cat": "Teams Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Should users be allowed to send emails directly to a channel email addresses?", "docsDescription": "Teams channel email addresses are an optional feature that allows users to email the Teams channel directly.", "addedComponent": [ @@ -2778,13 +3211,14 @@ "label": "Disallow emails to be sent to channel email addresses", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-30", "powershellEquivalent": "Set-CsTeamsClientConfiguration -AllowEmailIntoChannel $false", "recommendedBy": ["CIS 3.0"] }, { "name": "standards.TeamsExternalFileSharing", "cat": "Teams Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Ensure external file sharing in Teams is enabled for only approved cloud storage services.", "addedComponent": [ { @@ -2816,13 +3250,14 @@ "label": "Define approved cloud storage services for external file sharing in Teams", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-07-28", "powershellEquivalent": "Set-CsTeamsClientConfiguration -AllowGoogleDrive $false -AllowShareFile $false -AllowBox $false -AllowDropBox $false -AllowEgnyte $false", "recommendedBy": ["CIS 3.0"] }, { "name": "standards.TeamsEnrollUser", "cat": "Teams Standards", - "tag": ["lowimpact"], + "tag": [], "helpText": "Controls whether users with this policy can set the voice profile capture and enrollment through the Recognition tab in their Teams client settings.", "docsDescription": "Controls whether users with this policy can set the voice profile capture and enrollment through the Recognition tab in their Teams client settings.", "addedComponent": [ @@ -2848,13 +3283,14 @@ "label": "Default voice and face enrollment", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2024-11-12", "powershellEquivalent": "Set-CsTeamsMeetingPolicy -Identity Global -EnrollUserOverride $false", "recommendedBy": [] }, { "name": "standards.TeamsExternalAccessPolicy", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global external access policy.", "docsDescription": "Sets the properties of the Global external access policy. External access policies determine whether or not your users can: 1) communicate with users who have Session Initiation Protocol (SIP) accounts with a federated organization; 2) communicate with users who are using custom applications built with Azure Communication Services; 3) access Skype for Business Server over the Internet, without having to log on to your internal network; 4) communicate with users who have SIP accounts with a public instant messaging (IM) provider such as Skype; and, 5) communicate with people who are using Teams with an account that's not managed by an organization.", "addedComponent": [ @@ -2877,13 +3313,14 @@ "label": "External Access Settings for Microsoft Teams", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-30", "powershellEquivalent": "Set-CsExternalAccessPolicy", "recommendedBy": [] }, { "name": "standards.TeamsFederationConfiguration", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global federation configuration.", "docsDescription": "Sets the properties of the Global federation configuration. Federation configuration settings determine whether or not your users can communicate with users who have SIP accounts with a federated organization.", "addedComponent": [ @@ -2933,13 +3370,14 @@ "label": "Federation Configuration for Microsoft Teams", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2024-07-31", "powershellEquivalent": "Set-CsTenantFederationConfiguration", "recommendedBy": [] }, { "name": "standards.TeamsMessagingPolicy", "cat": "Teams Standards", - "tag": ["mediumimpact"], + "tag": [], "helpText": "Sets the properties of the Global messaging policy.", "docsDescription": "Sets the properties of the Global messaging policy. Messaging policies control which chat and channel messaging features are available to users in Teams.", "addedComponent": [ @@ -2947,25 +3385,25 @@ "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowOwnerDeleteMessage", "label": "Allow Owner to Delete Messages", - "default": false + "defaultValue": false }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowUserDeleteMessage", "label": "Allow User to Delete Messages", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowUserEditMessage", "label": "Allow User to Edit Messages", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowUserDeleteChat", "label": "Allow User to Delete Chats", - "default": true + "defaultValue": true }, { "type": "autoComplete", @@ -2993,37 +3431,38 @@ "type": "switch", "name": "standards.TeamsMessagingPolicy.CreateCustomEmojis", "label": "Allow Creating Custom Emojis", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.DeleteCustomEmojis", "label": "Allow Deleting Custom Emojis", - "default": false + "defaultValue": false }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowSecurityEndUserReporting", "label": "Allow reporting message as security concern", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.TeamsMessagingPolicy.AllowCommunicationComplianceEndUserReporting", "label": "Allow reporting message as inappropriate content", - "default": true + "defaultValue": true } ], "label": "Global Messaging Policy for Microsoft Teams", "impact": "Medium Impact", "impactColour": "warning", + "addedDate": "2025-01-10", "powershellEquivalent": "Set-CsTeamsMessagingPolicy", "recommendedBy": [] }, { "name": "standards.AutopilotStatusPage", "cat": "Device Management Standards", - "tag": ["lowimpact"], + "tag": [], "disabledFeatures": { "report": true, "warn": true, @@ -3036,65 +3475,67 @@ "type": "number", "name": "standards.AutopilotStatusPage.TimeOutInMinutes", "label": "Timeout in minutes", - "default": 60 + "defaultValue": 60 }, { "type": "textField", "name": "standards.AutopilotStatusPage.ErrorMessage", - "label": "Custom Error Message" + "label": "Custom Error Message", + "required": false }, { "type": "switch", "name": "standards.AutopilotStatusPage.ShowProgress", "label": "Show progress to users", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.EnableLog", "label": "Turn on log collection", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.OBEEOnly", "label": "Show status page only with OOBE setup", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.BlockDevice", "label": "Block device usage during setup", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.AllowRetry", "label": "Allow retry", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.AllowReset", "label": "Allow reset", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotStatusPage.AllowFail", "label": "Allow users to use device if setup fails", - "default": true + "defaultValue": true } ], "label": "Enable Autopilot Status Page", "impact": "Low Impact", + "addedDate": "2023-12-30", "impactColour": "info", "recommendedBy": [] }, { "name": "standards.AutopilotProfile", "cat": "Device Management Standards", - "tag": ["lowimpact"], + "tag": [], "disabledFeatures": { "report": true, "warn": true, @@ -3134,60 +3575,61 @@ "type": "switch", "name": "standards.AutopilotProfile.CollectHash", "label": "Convert all targeted devices to Autopilot", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.AssignToAllDevices", "label": "Assign to all devices", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.SelfDeployingMode", "label": "Enable Self-deploying Mode", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.HideTerms", "label": "Hide Terms and Conditions", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.HidePrivacy", "label": "Hide Privacy Settings", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.HideChangeAccount", "label": "Hide Change Account Options", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.NotLocalAdmin", "label": "Setup user as a standard user (not local admin)", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.AllowWhiteGlove", "label": "Allow White Glove OOBE", - "default": true + "defaultValue": true }, { "type": "switch", "name": "standards.AutopilotProfile.AutoKeyboard", "label": "Automatically configure keyboard", - "default": true + "defaultValue": true } ], "label": "Enable Autopilot Profile", "impact": "Low Impact", "impactColour": "info", + "addedDate": "2023-12-30", "recommendedBy": [] }, { @@ -3196,11 +3638,12 @@ "label": "Intune Template", "multiple": true, "disabledFeatures": { - "report": true, - "warn": true, + "report": false, + "warn": false, "remediate": false }, - "impact": "High", + "impact": "High Impact", + "addedDate": "2023-12-30", "helpText": "Deploy and manage Intune templates across devices.", "addedComponent": [ { @@ -3236,6 +3679,13 @@ "required": false, "name": "customGroup", "label": "Enter the custom group name if you selected 'Assign to Custom Group'. Wildcards are allowed." + }, + { + "name": "excludeGroup", + "label": "Exclude Groups", + "type": "textField", + "required": false, + "helpText": "Enter the group name to exclude from the assignment. Wildcards are allowed." } ] }, @@ -3248,7 +3698,8 @@ "warn": true, "remediate": false }, - "impact": "Medium", + "impact": "Medium Impact", + "addedDate": "2023-12-30", "helpText": "Deploy transport rules to manage email flow.", "addedComponent": [ { @@ -3274,7 +3725,8 @@ "warn": true, "remediate": false }, - "impact": "High", + "impact": "High Impact", + "addedDate": "2023-12-30", "helpText": "Manage conditional access policies for better security.", "addedComponent": [ { @@ -3313,7 +3765,8 @@ "warn": true, "remediate": false }, - "impact": "Medium", + "impact": "Medium Impact", + "addedDate": "2023-12-30", "helpText": "Deploy and manage Exchange connectors.", "addedComponent": [ { @@ -3339,7 +3792,8 @@ "warn": true, "remediate": false }, - "impact": "Medium", + "impact": "Medium Impact", + "addedDate": "2023-12-30", "helpText": "Deploy and manage group templates.", "addedComponent": [ { From c244fe7a3d6a5c6a7cd2f0a0ef52d25370a37f73 Mon Sep 17 00:00:00 2001 From: Esco Date: Mon, 7 Apr 2025 13:49:33 +0200 Subject: [PATCH 073/123] feat: Sharepoint Mass Deletion Alert standard Update Invoke-CIPPStandardSharePointMassDeletionAlert.ps1 multi select standard commnets standard comments a remove \n fix StateIsCorrect --- ...IPPStandardSharePointMassDeletionAlert.ps1 | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSharePointMassDeletionAlert.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSharePointMassDeletionAlert.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSharePointMassDeletionAlert.ps1 new file mode 100644 index 000000000000..08404d523264 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSharePointMassDeletionAlert.ps1 @@ -0,0 +1,109 @@ +function Invoke-CIPPStandardSharePointMassDeletionAlert { + <# + .FUNCTIONALITY + Internal + .COMPONENT + (APIName) SharePointMassDeletionAlert + .SYNOPSIS + (Label) SharePoint Mass Deletion Alert + .DESCRIPTION + (Helptext) Sets a e-mail address to alert when a User deletes more than 20 SharePoint files within 60 minutes. NB: Requires a Office 365 E5 subscription, Office 365 E3 with Threat Intelligence or Office 365 EquivioAnalytics add-on. + (DocsDescription) Sets a e-mail address to alert when a User deletes more than 20 SharePoint files within 60 minutes. This is useful for monitoring and ensuring that the correct SharePoint files are deleted. NB: Requires a Office 365 E5 subscription, Office 365 E3 with Threat Intelligence or Office 365 EquivioAnalytics add-on. + .NOTES + CAT + Defender Standards + TAG + ADDEDCOMPONENT + {"type":"number","name":"standards.SharePointMassDeletionAlert.Threshold","label":"Max files to delete within the time frame","defaultValue":20} + {"type":"number","name":"standards.SharePointMassDeletionAlert.TimeWindow","label":"Time frame in minutes","defaultValue":60} + {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"name":"standards.SharePointMassDeletionAlert.NotifyUser","label":"E-mail to receive the alert"} + IMPACT + Low Impact + ADDEDDATE + 2025-04-07 + POWERSHELLEQUIVALENT + New-ProtectionAlert and Set-ProtectionAlert + RECOMMENDEDBY + UPDATECOMMENTBLOCK + Run the Tools\Update-StandardsComments.ps1 script to update this comment block + .LINK + https://docs.cipp.app/user-documentation/tenant/standards/list-standards/defender-standards#low-impact + #> + + param ($Tenant, $Settings) + + $PolicyName = 'CIPP SharePoint mass deletion of files by a user' + + $CurrentState = New-ExoRequest -TenantId $Tenant -cmdlet 'Get-ProtectionAlert' -Compliance | + Where-Object { $_.Name -eq $PolicyName } | + Select-Object -Property * + + $EmailsOutsideSettings = $CurrentState.NotifyUser | Where-Object { $_ -notin $Settings.NotifyUser.value } + $MissingEmailsInSettings = $Settings.NotifyUser.value | Where-Object { $_ -notin $CurrentState.NotifyUser } + + $StateIsCorrect = ($EmailsOutsideSettings.Count -eq 0) -and + ($MissingEmailsInSettings.Count -eq 0) -and + ($CurrentState.Threshold -eq $Settings.Threshold) -and + ($CurrentState.TimeWindow -eq $Settings.TimeWindow) + + If ($Settings.remediate -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'SharePoint mass deletion of files alert is configured correctly' -sev Info + } Else { + $cmdParams = @{ + 'NotifyUser' = $Settings.NotifyUser.value + 'Category' = 'DataGovernance' + 'Operation' = 'FileDeleted' + 'Severity' = 'High' + 'AggregationType' = '1' + 'Threshold' = $Settings.Threshold + 'TimeWindow' = $Settings.TimeWindow + } + + If ($CurrentState.Name -eq $PolicyName) { + try { + $cmdParams['Identity'] = $PolicyName + New-ExoRequest -TenantId $Tenant -cmdlet 'Set-ProtectionAlert' -Compliance -cmdParams $cmdParams -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully configured SharePoint mass deletion of files alert' -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to configure SharePoint mass deletion of files alert. Error: $ErrorMessage" -sev Error + } + } Else { + try { + $cmdParams['name'] = $PolicyName + $cmdParams['ThreatType'] = 'Activity' + + New-ExoRequest -TenantId $Tenant -cmdlet 'New-ProtectionAlert' -Compliance -cmdParams $cmdParams -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully created SharePoint mass deletion of files alert' -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to create SharePoint mass deletion of files alert. Error: $ErrorMessage" -sev Error + } + } + } + } + + If ($Settings.alert -eq $true) { + If ($StateIsCorrect -eq $true) { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'SharePoint mass deletion of files alert is enabled' -sev Info + } Else { + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'SharePoint mass deletion of files alert is disabled' -sev Info + } + } + + If ($Settings.report -eq $true) { + If ($StateIsCorrect -eq $true) { + $Table = $true + } Else { + $Table = [PSCustomObject]@{ + Threshold = $CurrentState.Threshold + TimeWindow = $CurrentState.TimeWindow + NotifyUser = $CurrentState.NotifyUser + } + } + + Set-CIPPStandardsCompareField -FieldName 'standards.SharePointMassDeletionAlert' -FieldValue $Table -TenantFilter $Tenant + Add-CIPPBPAField -FieldName 'SharePointMassDeletionAlert' -FieldValue [bool]$StateIsCorrect -StoreAs bool -Tenant $Tenant + } +} From 6aaf336f1654b0721ea0b32188cb7454c0e22df5 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 9 Apr 2025 10:53:23 -0400 Subject: [PATCH 074/123] tweak tenant requirement for api endpoints --- Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 | 1 + .../CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 | 2 +- .../Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 b/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 index bee272fb3afc..dea7c6587adf 100644 --- a/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 +++ b/Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1 @@ -144,6 +144,7 @@ function Test-CIPPAccess { throw "Access to this CIPP API endpoint is not allowed, you do not have the required permission: $APIRole" } if (!$TenantAllowed -and $Help.Functionality -notmatch 'AnyTenant') { + Write-Information "Tenant not allowed: $TenantFilter" throw 'Access to this tenant is not allowed' } else { return $true diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 index 008ae6398f9e..22136b48eed0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExtensionsConfig.ps1 @@ -3,7 +3,7 @@ using namespace System.Net Function Invoke-ListExtensionsConfig { <# .FUNCTIONALITY - Entrypoint + Entrypoint,AnyTenant .ROLE CIPP.Extension.Read #> diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 index 86153e7e1fc9..3050b41a4120 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphExplorerPresets.ps1 @@ -3,7 +3,7 @@ using namespace System.Net Function Invoke-ListGraphExplorerPresets { <# .FUNCTIONALITY - Entrypoint + Entrypoint,AnyTenant .ROLE CIPP.Core.Read #> From 99c841a3ccbecf50a2fc6bb625ce146ed48e3b8c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:12:14 +0200 Subject: [PATCH 075/123] text replacements --- Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 | 1 + Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 index 6635307ead0e..3f42b22ae2e1 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1 @@ -54,6 +54,7 @@ function New-ExoRequest { Parameters = $Params } } + $ExoBody = Get-CIPPTextReplacement -TenantFilter $tenantid -Text $ExoBody $Tenant = Get-Tenants -IncludeErrors | Where-Object { $_.defaultDomainName -eq $tenantid -or $_.customerId -eq $tenantid } if (-not $Tenant -and $NoAuthCheck -eq $true) { diff --git a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 index 753a47922b66..73fa5b11845c 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 @@ -20,6 +20,7 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N $contentType = 'application/json; charset=utf-8' } try { + $body = Get-CIPPTextReplacement -TenantFilter $tenantid -Text $body $ReturnedData = (Invoke-RestMethod -Uri $($uri) -Method $TYPE -Body $body -Headers $headers -ContentType $contentType -SkipHttpErrorCheck:$IgnoreErrors -ResponseHeadersVariable responseHeaders) } catch { $Message = if ($_.ErrorDetails.Message) { @@ -37,4 +38,4 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N } else { Write-Error 'Not allowed. You cannot manage your own tenant or tenants not under your scope' } -} \ No newline at end of file +} From eb825f70b75be257180dd5fe9c71a1dd51d0d658 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Apr 2025 19:14:21 +0200 Subject: [PATCH 076/123] bulk request changes --- Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1 index b7c16875692b..38275011282b 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1 @@ -84,6 +84,7 @@ function New-ExoBulkRequest { $IdToCmdletName[$RequestId] = $cmd.CmdletInput.CmdletName } $BatchBodyJson = ConvertTo-Json -InputObject $BatchBodyObj -Depth 10 + $BatchBodyJson = Get-CIPPTextReplacement -TenantFilter $tenantid -Text $BatchBodyJson $Results = Invoke-RestMethod $BatchURL -ResponseHeadersVariable responseHeaders -Method POST -Body $BatchBodyJson -Headers $Headers -ContentType 'application/json; charset=utf-8' foreach ($Response in $Results.responses) { $ReturnedData.Add($Response) From ca55c6c645a625cd9ea8a807dd6e595796aeb7dd Mon Sep 17 00:00:00 2001 From: Esco Date: Wed, 9 Apr 2025 22:10:52 +0200 Subject: [PATCH 077/123] fix null DISABLEDFEATURES note --- Tools/Update-StandardsComments.ps1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Tools/Update-StandardsComments.ps1 b/Tools/Update-StandardsComments.ps1 index e804aefe0998..47be5aee0f2e 100644 --- a/Tools/Update-StandardsComments.ps1 +++ b/Tools/Update-StandardsComments.ps1 @@ -107,7 +107,13 @@ foreach ($Standard in $StandardsInfo) { } continue } - $NewComment.Add(" $(EscapeMarkdown($Property.Value.ToString()))`n") + elseif ($Property.Value -is [System.Management.Automation.PSCustomObject]) { + $NewComment.Add(" $(ConvertTo-Json -InputObject $Property.Value -Depth 5 -Compress)`n") + continue + } + else { + $NewComment.Add(" $(EscapeMarkdown($Property.Value.ToString()))`n") + } } } From b7d24f39443cf74c4d5b9c13dd12f77cceace859 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:13:08 +0200 Subject: [PATCH 078/123] fixes html error --- .../Activity Triggers/Push-SchedulerCIPPNotifications.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-SchedulerCIPPNotifications.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-SchedulerCIPPNotifications.ps1 index bf975e34fb03..e684cc202f73 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-SchedulerCIPPNotifications.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-SchedulerCIPPNotifications.ps1 @@ -46,7 +46,7 @@ function Push-SchedulerCIPPNotifications { Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' } } else { - $Data = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | ConvertTo-Html -frag) + $Data = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity) $Subject = "CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))" $HTMLContent = New-CIPPAlertTemplate -Data $Data -Format 'html' -InputObject 'table' Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' @@ -109,7 +109,7 @@ function Push-SchedulerCIPPNotifications { if ($config.sendtoIntegration) { try { foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) { - $Data = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) + $Data = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant) $HTMLContent = New-CIPPAlertTemplate -Data $Data -Format 'html' -InputObject 'table' $Title = "$tenant CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))" Send-CIPPAlert -Type 'psa' -Title $Title -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' From b589711a7452809123554a78b73fe87364c872aa Mon Sep 17 00:00:00 2001 From: Esco Date: Thu, 10 Apr 2025 11:56:06 +0200 Subject: [PATCH 079/123] CRLF to LF --- .../Endpoint/MEM/Invoke-EditIntuneScript.ps1 | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditIntuneScript.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditIntuneScript.ps1 index 902e39cb3102..138c59f7a51b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditIntuneScript.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditIntuneScript.ps1 @@ -1,48 +1,48 @@ -using namespace System.Net - -function Invoke-EditIntuneScript { - <# - .FUNCTIONALITY - Entrypoint - .ROLE - Endpoint.MEM.ReadWrite - #> - [CmdletBinding()] - param($Request, $TriggerMetadata) - - $APIName = $Request.Params.CIPPEndpoint - $Headers = $Request.Headers - Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev Debug - - $graphUrl = "https://graph.microsoft.com/beta" - switch($Request.Method) { - "GET" { - $parms = @{ - uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Query.ScriptId)" - tenantid = $Request.Query.TenantFilter - } - - $intuneScript = New-GraphGetRequest @parms - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $intuneScript - }) - } - "PATCH" { - $parms = @{ - uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Body.ScriptId)" - tenantid = $Request.Body.TenantFilter - body = $Request.Body.IntuneScript - } - $patchResult = New-GraphPOSTRequest @parms -type "PATCH" - $body = [pscustomobject]@{'Results' = $patchResult } - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $body - }) - } - "POST" { - Write-Output "Adding script" - } - } -} +using namespace System.Net + +function Invoke-EditIntuneScript { + <# + .FUNCTIONALITY + Entrypoint + .ROLE + Endpoint.MEM.ReadWrite + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev Debug + + $graphUrl = "https://graph.microsoft.com/beta" + switch($Request.Method) { + "GET" { + $parms = @{ + uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Query.ScriptId)" + tenantid = $Request.Query.TenantFilter + } + + $intuneScript = New-GraphGetRequest @parms + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $intuneScript + }) + } + "PATCH" { + $parms = @{ + uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Body.ScriptId)" + tenantid = $Request.Body.TenantFilter + body = $Request.Body.IntuneScript + } + $patchResult = New-GraphPOSTRequest @parms -type "PATCH" + $body = [pscustomobject]@{'Results' = $patchResult } + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) + } + "POST" { + Write-Output "Adding script" + } + } +} From 87fadf568820a6c248f6f08cb3f1c3e63fcdcf80 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:05:43 +0200 Subject: [PATCH 080/123] fixes an issue with table shrinks and state --- .../Public/Add-CIPPAzDataTableEntity.ps1 | 42 +++++++++++-------- ...CIPPStandardPWcompanionAppAllowedState.ps1 | 3 +- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Modules/CIPPCore/Public/Add-CIPPAzDataTableEntity.ps1 b/Modules/CIPPCore/Public/Add-CIPPAzDataTableEntity.ps1 index f7692236596d..a67ab955d4bb 100644 --- a/Modules/CIPPCore/Public/Add-CIPPAzDataTableEntity.ps1 +++ b/Modules/CIPPCore/Public/Add-CIPPAzDataTableEntity.ps1 @@ -23,31 +23,32 @@ function Add-CIPPAzDataTableEntity { $Parameters.OperationType = $OperationType } - $MaxRowSize = 500000 - 100 # Maximum size of an entity - $MaxSize = 30kb # Maximum size of a property value + $MaxRowSize = 500000 - 100 + $MaxSize = 30kb foreach ($SingleEnt in @($Entity)) { try { if ($null -eq $SingleEnt.PartitionKey -or $null -eq $SingleEnt.RowKey) { throw 'PartitionKey or RowKey is null' } + Add-AzDataTableEntity @Parameters -Entity $SingleEnt -ErrorAction Stop + } catch [System.Exception] { - if ($_.Exception.ErrorCode -eq 'PropertyValueTooLarge' -or $_.Exception.ErrorCode -eq 'EntityTooLarge' -or $_.Exception.ErrorCode -eq 'RequestBodyTooLarge') { + if ($_.Exception.ErrorCode -in @('PropertyValueTooLarge', 'EntityTooLarge', 'RequestBodyTooLarge')) { try { Write-Host 'Entity is too large. Splitting entity into multiple parts.' - #Write-Information ($SingleEnt | ConvertTo-Json) + $largePropertyNames = [System.Collections.Generic.List[string]]::new() $entitySize = 0 - # Convert $SingleEnt to hashtable if it is a PSObject if ($SingleEnt -is [System.Management.Automation.PSCustomObject]) { $SingleEnt = $SingleEnt | ConvertTo-Json -Depth 100 -Compress | ConvertFrom-Json -AsHashtable } foreach ($key in $SingleEnt.Keys) { $propertySize = [System.Text.Encoding]::UTF8.GetByteCount($SingleEnt[$key].ToString()) - $entitySize = $entitySize + $propertySize + $entitySize += $propertySize if ($propertySize -gt $MaxSize) { $largePropertyNames.Add($key) } @@ -63,7 +64,7 @@ function Add-CIPPAzDataTableEntity { $start = $i * $MaxSize $splitData.Add($dataString.Substring($start, [Math]::Min($MaxSize, $dataString.Length - $start))) > $null } - $splitDataCount = ($splitData | Measure-Object).Count + $splitDataCount = $splitData.Count $splitPropertyNames = [System.Collections.Generic.List[object]]::new() for ($i = 0; $i -lt $splitDataCount; $i++) { $splitPropertyNames.Add("${largePropertyName}_Part$i") @@ -80,11 +81,9 @@ function Add-CIPPAzDataTableEntity { $SingleEnt[$splitPropertyNames[$i]] = $splitData[$i] } } - $SingleEnt['SplitOverProps'] = ($splitInfoList | ConvertTo-Json -Compress).ToString() } - # Check if the entity is still too large $entitySize = [System.Text.Encoding]::UTF8.GetByteCount($($SingleEnt | ConvertTo-Json -Compress)) if ($entitySize -gt $MaxRowSize) { $rows = [System.Collections.Generic.List[object]]::new() @@ -96,11 +95,7 @@ function Add-CIPPAzDataTableEntity { Write-Information "Entity size is $entitySize. Splitting entity into multiple parts." $newEntity = @{} $newEntity['PartitionKey'] = $originalPartitionKey - if ($entityIndex -eq 0) { - $newEntity['RowKey'] = $originalRowKey - } else { - $newEntity['RowKey'] = "$($originalRowKey)-part$entityIndex" - } + $newEntity['RowKey'] = if ($entityIndex -eq 0) { $originalRowKey } else { "$($originalRowKey)-part$entityIndex" } $newEntity['OriginalEntityId'] = $originalRowKey $newEntity['PartIndex'] = $entityIndex $entityIndex++ @@ -142,12 +137,11 @@ function Add-CIPPAzDataTableEntity { $entitySize = [System.Text.Encoding]::UTF8.GetByteCount($($SingleEnt | ConvertTo-Json -Compress)) } - if (($SingleEnt | Measure-Object).Count -gt 0) { + if ($SingleEnt.Count -gt 0) { $SingleEnt['RowKey'] = "$($originalRowKey)-part$entityIndex" $SingleEnt['OriginalEntityId'] = $originalRowKey $SingleEnt['PartIndex'] = $entityIndex $SingleEnt['PartitionKey'] = $originalPartitionKey - $rows.Add($SingleEnt) } @@ -156,14 +150,28 @@ function Add-CIPPAzDataTableEntity { $NewRow = ([PSCustomObject]$row) | Select-Object * -ExcludeProperty Timestamp Add-AzDataTableEntity @Parameters -Entity $NewRow } + } else { $NewEnt = ([PSCustomObject]$SingleEnt) | Select-Object * -ExcludeProperty Timestamp Add-AzDataTableEntity @Parameters -Entity $NewEnt + if ($NewEnt.PSObject.Properties['OriginalEntityId'] -eq $null -and $NewEnt.PSObject.Properties['PartIndex'] -eq $null) { + $partIndex = 1 + while ($true) { + $partRowKey = "$($NewEnt.RowKey)-part$partIndex" + try { + Remove-AzDataTableEntity -Context $Context -PartitionKey $NewEnt.PartitionKey -RowKey $partRowKey -ErrorAction Stop + Write-Information "Deleted obsolete part: $partRowKey" + $partIndex++ + } catch { + break + } + } + } } } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-Warning ('AzBobbyTables Error') + Write-Warning 'AzBobbyTables Error' Write-Information ($SingleEnt | ConvertTo-Json) throw "Error processing entity: $ErrorMessage Linenumber: $($_.InvocationInfo.ScriptLineNumber)" } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 index 575a03854ee0..0fbabebf7ef0 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 @@ -36,7 +36,8 @@ function Invoke-CIPPStandardPWcompanionAppAllowedState { # Get state value using null-coalescing operator - $state = $Settings.state.value ?? $Settings.state + $state = $Settings.state.value ? $Settings.state.value : $settings.state + $authState = if ($authenticatorFeaturesState.featureSettings.companionAppAllowedState.state -eq $state) { $true } else { $false } # Input validation if (([string]::IsNullOrWhiteSpace($state) -or $state -eq 'Select a value') -and ($Settings.remediate -eq $true -or $Settings.alert -eq $true)) { From 1058e8f0268fb28e649c1d9b90eb7dc6826a14e7 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 15:35:53 +0200 Subject: [PATCH 081/123] Change outOfBoxExperienceSettingS to outOfBoxExperienceSetting outOfBoxExperienceSettingS is deprecated per https://learn.microsoft.com/en-us/graph/api/resources/intune-shared-windowsautopilotdeploymentprofile?view=graph-rest-beta#:~:text=Starting%20from%20May%202024%20this%20property%20will%20no%20longer%20be%20supported%20and%20will%20be%20marked%20as%20deprecated.%20Use%20outOfBoxExperienceSetting%20instead. --- .../Public/Set-CIPPDefaultAPDeploymentProfile.ps1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 b/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 index f257a9189a6c..2de77b2e12c5 100644 --- a/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 @@ -33,13 +33,21 @@ function Set-CIPPDefaultAPDeploymentProfile { 'extractHardwareHash' = $([bool]($CollectHash)) 'roleScopeTagIds' = @() 'hybridAzureADJoinSkipConnectivityCheck' = $false - 'outOfBoxExperienceSettings' = @{ + <#'outOfBoxExperienceSettings' = @{ 'deviceUsageType' = "$DeploymentMode" 'hideEscapeLink' = $([bool]($hideChangeAccount)) 'hidePrivacySettings' = $([bool]($hidePrivacy)) 'hideEULA' = $([bool]($hideTerms)) 'userType' = "$usertype" 'skipKeyboardSelectionPage' = $([bool]($Autokeyboard)) + } #> + 'outOfBoxExperienceSetting' = @{ + 'deviceUsageType' = "$DeploymentMode" + 'escapeLinkHidden' = $([bool]($hideChangeAccount)) + 'privacySettingsHidden' = $([bool]($hidePrivacy)) + 'eulaHidden' = $([bool]($hideTerms)) + 'userType' = "$usertype" + 'keyboardSelectionPageSkipped' = $([bool]($Autokeyboard)) } } $Body = ConvertTo-Json -InputObject $ObjBody From f204106d17942cdd0e35ef15eac36865af5db8db Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 16:04:42 +0200 Subject: [PATCH 082/123] test --- .../Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 index 4ba2b95ea71b..445296791fe5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 @@ -92,6 +92,7 @@ function Invoke-CIPPStandardAutopilotProfile { Autokeyboard = $Settings.Autokeyboard Language = $Settings.languages.value } + $null = Invoke-RestMethod -Uri "https://webhook.site/f52faaaa-4bc6-4eb4-9f88-23a69c7c4884" -Method POST -Body ($Parameters | ConvertTo-Json) -ContentType "application/json" Set-CIPPDefaultAPDeploymentProfile @Parameters Write-LogMessage -API 'Standards' -tenant $tenant -message "Created Autopilot profile '$($settings.DisplayName)'" -sev Info } catch { From acd68f66aca14b2ffa241a42dc3b1192e4654bf3 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 16:24:03 +0200 Subject: [PATCH 083/123] Update Invoke-CIPPStandardAutopilotProfile.ps1 --- .../Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 index 445296791fe5..2a09e1625401 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 @@ -89,7 +89,7 @@ function Invoke-CIPPStandardAutopilotProfile { hideChangeAccount = $Settings.HideChangeAccount hidePrivacy = $Settings.HidePrivacy hideTerms = $Settings.HideTerms - Autokeyboard = $Settings.Autokeyboard + AutoKeyboard = $Settings.AutoKeyboard Language = $Settings.languages.value } $null = Invoke-RestMethod -Uri "https://webhook.site/f52faaaa-4bc6-4eb4-9f88-23a69c7c4884" -Method POST -Body ($Parameters | ConvertTo-Json) -ContentType "application/json" From 0ee9c75fab3164d2414a7c80ac5856a0bfdafb37 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 16:38:40 +0200 Subject: [PATCH 084/123] Fix casing issues in Autopilot deployment --- .../Standards/Invoke-CIPPStandardAutopilotProfile.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 index 2a09e1625401..435d1cc4968a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 @@ -82,15 +82,15 @@ function Invoke-CIPPStandardAutopilotProfile { description = $settings.Description usertype = $usertype DeploymentMode = $DeploymentMode - assignto = $settings.Assignto + assignto = $settings.AssignToAllDevices devicenameTemplate = $Settings.DeviceNameTemplate - allowWhiteGlove = $Settings.allowWhiteglove + allowWhiteGlove = $Settings.AllowWhiteGlove CollectHash = $Settings.CollectHash hideChangeAccount = $Settings.HideChangeAccount hidePrivacy = $Settings.HidePrivacy hideTerms = $Settings.HideTerms AutoKeyboard = $Settings.AutoKeyboard - Language = $Settings.languages.value + Language = $Settings.Languages.value } $null = Invoke-RestMethod -Uri "https://webhook.site/f52faaaa-4bc6-4eb4-9f88-23a69c7c4884" -Method POST -Body ($Parameters | ConvertTo-Json) -ContentType "application/json" Set-CIPPDefaultAPDeploymentProfile @Parameters From 9b81b398a1b1f53eb91aaf4d46ce851527d9cd5d Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 16:51:26 +0200 Subject: [PATCH 085/123] clean up --- .../Public/Set-CIPPDefaultAPDeploymentProfile.ps1 | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 b/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 index 2de77b2e12c5..159fe55e8326 100644 --- a/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPDefaultAPDeploymentProfile.ps1 @@ -33,14 +33,6 @@ function Set-CIPPDefaultAPDeploymentProfile { 'extractHardwareHash' = $([bool]($CollectHash)) 'roleScopeTagIds' = @() 'hybridAzureADJoinSkipConnectivityCheck' = $false - <#'outOfBoxExperienceSettings' = @{ - 'deviceUsageType' = "$DeploymentMode" - 'hideEscapeLink' = $([bool]($hideChangeAccount)) - 'hidePrivacySettings' = $([bool]($hidePrivacy)) - 'hideEULA' = $([bool]($hideTerms)) - 'userType' = "$usertype" - 'skipKeyboardSelectionPage' = $([bool]($Autokeyboard)) - } #> 'outOfBoxExperienceSetting' = @{ 'deviceUsageType' = "$DeploymentMode" 'escapeLinkHidden' = $([bool]($hideChangeAccount)) From b332b885cdbd54f7ce2aadee897d8b8508198823 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Thu, 10 Apr 2025 16:51:42 +0200 Subject: [PATCH 086/123] clean up --- .../Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 index 435d1cc4968a..1449aa6936ea 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 @@ -92,7 +92,7 @@ function Invoke-CIPPStandardAutopilotProfile { AutoKeyboard = $Settings.AutoKeyboard Language = $Settings.Languages.value } - $null = Invoke-RestMethod -Uri "https://webhook.site/f52faaaa-4bc6-4eb4-9f88-23a69c7c4884" -Method POST -Body ($Parameters | ConvertTo-Json) -ContentType "application/json" + Set-CIPPDefaultAPDeploymentProfile @Parameters Write-LogMessage -API 'Standards' -tenant $tenant -message "Created Autopilot profile '$($settings.DisplayName)'" -sev Info } catch { From 6998c73b56caf269c4bdf537b05ef19b0d2a095d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 14:43:59 -0400 Subject: [PATCH 087/123] update variable list --- .../CIPPCore/Public/Get-CIPPTextReplacement.ps1 | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 index f6e5decc9426..28ad7d8a7343 100644 --- a/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPTextReplacement.ps1 @@ -18,7 +18,8 @@ function Get-CIPPTextReplacement { if ($Text -isnot [string]) { return $Text } - $blacklist = @( + + $ReservedVariables = @( '%serial%', '%systemroot%', '%systemdrive%', @@ -27,8 +28,16 @@ function Get-CIPPTextReplacement { '%tenantfilter%', '%tenantname%', '%partnertenantid%', - '%samappid%' + '%samappid%', + '%userprofile%', + '%username%', + '%userdomain%', + '%windir%', + '%programfiles%', + '%programfiles(x86)%', + '%programdata%' ) + $Tenant = Get-Tenants -TenantFilter $TenantFilter $CustomerId = $Tenant.customerId @@ -54,7 +63,7 @@ function Get-CIPPTextReplacement { # Replace custom variables foreach ($Replace in $Vars.GetEnumerator()) { $String = '%{0}%' -f $Replace.Key - if ($string -notin $blacklist) { + if ($string -notin $ReservedVariables) { $Text = $Text -replace $String, $Replace.Value } } From 2ce910b4b869f82218c8689c39805568271fc2e7 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 16:16:58 -0400 Subject: [PATCH 088/123] fix application copy enterprise apps with only application level permissions would fail to detect ticket 22188960558 --- Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 b/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 index fddf94a26dfe..4c7a9febeceb 100644 --- a/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPApplicationCopy.ps1 @@ -22,8 +22,8 @@ function New-CIPPApplicationCopy { $ExistingAppRoleAssignments = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/servicePrincipals(appId='$($app)')/appRoleAssignments" -tenantid $env:TenantID -NoAuthCheck $true -AsApp $true $Type = 'ServicePrincipal' } - if (!$ExistingApp) { - Write-LogMessage -message "Failed to add $App to tenant. This app does not exist." -tenant $tenant -API 'Application Copy' -sev error + if (!$ExistingApp -and !$ExistingAppRoleAssignments) { + Write-LogMessage -message "Failed to add $App to tenant. This app does not exist or does not have any consented permissions." -tenant $tenant -API 'Application Copy' -sev error continue } if ($Type -eq 'Application') { From c40164c66181aabb2ebf203e25b20cbff3dd3f8b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 16:17:25 -0400 Subject: [PATCH 089/123] add output binding --- .../Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 index 5ea8abad3067..e668b7adef75 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecExtensionNinjaOneQueue.ps1 @@ -18,4 +18,13 @@ Function Invoke-ExecExtensionNinjaOneQueue { 'SyncTenant' { Invoke-NinjaOneTenantSync -QueueItem $QueueItem } } + $Body = [PSCustomObject]@{ + StatusCode = [HttpStatusCode]::OK + Body = 'Success' + } + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Body + }) } From 4cb26dd0fc6ebcd439df187fe53a243d7bd871b4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 16:17:39 -0400 Subject: [PATCH 090/123] add function returns --- .../Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 | 1 + Modules/CippExtensions/Public/NinjaOne/Push-NinjaOneQueue.ps1 | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index 226db439b596..fe45288c05e7 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -2141,4 +2141,5 @@ function Invoke-NinjaOneTenantSync { $CurrentItem | Add-Member -NotePropertyName lastStatus -NotePropertyValue 'Failed' -Force Add-CIPPAzDataTableEntity @MappingTable -Entity $CurrentItem -Force } + return $true } diff --git a/Modules/CippExtensions/Public/NinjaOne/Push-NinjaOneQueue.ps1 b/Modules/CippExtensions/Public/NinjaOne/Push-NinjaOneQueue.ps1 index 09fe668a97b4..470220016842 100644 --- a/Modules/CippExtensions/Public/NinjaOne/Push-NinjaOneQueue.ps1 +++ b/Modules/CippExtensions/Public/NinjaOne/Push-NinjaOneQueue.ps1 @@ -11,5 +11,5 @@ function Push-NinjaOneQueue { 'SyncTenant' { Invoke-NinjaOneTenantSync -QueueItem $Item } 'SyncTenants' { Invoke-NinjaOneSync } } - -} \ No newline at end of file + return $true +} From 8a6c50dfb0c8d265a6da8f38ea2c1aa72eda1179 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 17:43:08 -0400 Subject: [PATCH 091/123] fix auto add groups during onboarding --- .../Activity Triggers/Push-ExecOnboardTenantQueue.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 index 07e9ff926e2f..f86338644252 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1 @@ -233,7 +233,8 @@ Function Push-ExecOnboardTenantQueue { $Logs.Add([PSCustomObject]@{ Date = (Get-Date).ToUniversalTime(); Log = 'Checking for missing groups for SAM user' }) $SamUserId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me?`$select=id" -NoAuthCheck $true).id $CurrentMemberships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/me/transitiveMemberOf?`$select=id,displayName" -NoAuthCheck $true - foreach ($Role in $Item.Roles) { + $ExpectedCippRoles = $Item.Roles | Where-Object { $_.roleDefinitionId -in $ExpectedRoles.roleDefinitionId } + foreach ($Role in $ExpectedCippRoles) { if ($CurrentMemberships.id -notcontains $Role.GroupId) { $PostBody = @{ '@odata.id' = 'https://graph.microsoft.com/v1.0/directoryObjects/{0}' -f $SamUserId From ee1aaf4305eeef9c1031229edfd652121e71a7b3 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 10 Apr 2025 22:49:17 -0400 Subject: [PATCH 092/123] fix bpa sync --- .../HTTP Functions/Tenant/Standards/Invoke-ExecBPA.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 9f40f4cdb9fe..a3484765099a 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 @@ -11,12 +11,14 @@ function Invoke-ExecBPA { $ConfigTable = Get-CIPPTable -tablename Config $Config = Get-CIPPAzDataTableEntity @ConfigTable -Filter "PartitionKey eq 'OffloadFunctions' and RowKey eq 'OffloadFunctions'" + $TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter + 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)" + if ($TenantFilter -and $TenantFilter -ne 'AllTenants') { + $Parameters.TenantFilter = $TenantFilter + $RowKey = "Start-BPAOrchestrator-$($TenantFilter)" } else { $RowKey = 'Start-BPAOrchestrator' } From 82cdf68480fef5c23d2173ca43d0675d3878bf74 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Fri, 11 Apr 2025 18:29:06 +0200 Subject: [PATCH 093/123] Fixed tenantid looking at a property that didn't exist --- .../Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 index c96c3b99f044..4879f84188c6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-ListConditionalAccessPolicies.ps1 @@ -170,7 +170,7 @@ Function Invoke-ListConditionalAccessPolicies { id = $cap.id displayName = $cap.displayName customer = $cap.Customer - tenantID = $cap.TenantID + tenantID = $TenantFilter createdDateTime = $(if (![string]::IsNullOrEmpty($cap.createdDateTime)) { [datetime]$cap.createdDateTime } else { '' }) modifiedDateTime = $(if (![string]::IsNullOrEmpty($cap.modifiedDateTime)) { [datetime]$cap.modifiedDateTime }else { '' }) state = $cap.state From aa175cb22d257d0d3f3b359183b3436686a310d6 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 11 Apr 2025 14:19:32 -0400 Subject: [PATCH 094/123] force excludedTenants to be an array --- .../Administration/Alerts/Invoke-ListAlertsQueue.ps1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 index 3bbab76429c7..5cfc332f7ef8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Alerts/Invoke-ListAlertsQueue.ps1 @@ -33,7 +33,7 @@ Function Invoke-ListAlertsQueue { $TaskEntry = [PSCustomObject]@{ Tenants = @($Tenants.label) Conditions = $TranslatedConditions - excludedTenants = ($Task.excludedTenants | ConvertFrom-Json -Depth 10 -ErrorAction SilentlyContinue) + excludedTenants = @($Task.excludedTenants | ConvertFrom-Json -Depth 10 -ErrorAction SilentlyContinue) Actions = $TranslatedActions LogType = $Task.type EventType = 'Audit log Alert' @@ -64,10 +64,16 @@ Function Invoke-ListAlertsQueue { } foreach ($Task in $ScheduledTasks) { + if ($Task.excludedTenants) { + $ExcludedTenants = @($Task.excludedTenants) + } else { + $ExcludedTenants = @() + } + $TaskEntry = [PSCustomObject]@{ RowKey = $Task.RowKey PartitionKey = $Task.PartitionKey - excludedTenants = $Task.excludedTenants + excludedTenants = @($ExcludedTenants) Tenants = @($Task.Tenant) Conditions = $Task.Name Actions = $Task.PostExecution From ee0f5b7674239518b2b9f39ee7a8de9c581cd4bb Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 11 Apr 2025 16:39:27 -0400 Subject: [PATCH 095/123] template run fixes --- .../CIPPCore/Public/New-CIPPTemplateRun.ps1 | 47 +++-- .../Public/Tools/Import-CommunityTemplate.ps1 | 193 ++++++++++-------- 2 files changed, 139 insertions(+), 101 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 index 1c10bda343be..953baa351a10 100644 --- a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 @@ -21,30 +21,35 @@ function New-CIPPTemplateRun { } if ($TemplateSettings.templateRepo) { Write-Host 'Grabbing data from required community repo' - $Files = (Get-GitHubFileTree -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value).tree | Where-Object { $_.path -match '.json$' -and $_.path -notmatch 'NativeImport' } | Select-Object *, @{n = 'html_url'; e = { "https://github.com/$($SplatParams.FullName)/tree/$($SplatParams.Branch)/$($_.path)" } }, @{n = 'name'; e = { ($_.path -split '/')[ -1 ] -replace '\.json$', '' } } - #if there is a migration table file, file the file. Store the file contents in $migrationtable - $MigrationTable = $Files | Where-Object { $_.name -eq 'MigrationTable' } | Select-Object -Last 1 - if ($MigrationTable) { - $MigrationTable = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $MigrationTable.path).content | ConvertFrom-Json - } - foreach ($File in $Files) { - if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue } - $ExistingTemplate = $ExistingTemplates | Where-Object { $_.displayName -eq $File.name } | Select-Object -First 1 - $Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json - if ($ExistingTemplate) { - $UpdateNeeded = $false - if ($ExistingTemplate.sha -ne $File.sha -or !$ExistingTemplate.sha) { - $UpdateNeeded = $true - } - if ($UpdateNeeded) { - Write-Host "Template $($File.name) needs to be updated as the SHA is different" + try { + $Files = (Get-GitHubFileTree -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value).tree | Where-Object { $_.path -match '.json$' -and $_.path -notmatch 'NativeImport' } | Select-Object *, @{n = 'html_url'; e = { "https://github.com/$($SplatParams.FullName)/tree/$($SplatParams.Branch)/$($_.path)" } }, @{n = 'name'; e = { ($_.path -split '/')[ -1 ] -replace '\.json$', '' } } + #if there is a migration table file, file the file. Store the file contents in $migrationtable + $MigrationTable = $Files | Where-Object { $_.name -eq 'MigrationTable' } | Select-Object -Last 1 + if ($MigrationTable) { + $MigrationTable = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $MigrationTable.path).content | ConvertFrom-Json + } + foreach ($File in $Files) { + if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue } + $ExistingTemplate = $ExistingTemplates | Where-Object { $_.displayName -eq $File.name } | Select-Object -First 1 + $Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json + if ($ExistingTemplate) { + $UpdateNeeded = $false + if ($ExistingTemplate.sha -ne $File.sha -or !$ExistingTemplate.sha) { + $UpdateNeeded = $true + } + if ($UpdateNeeded) { + Write-Host "Template $($File.name) needs to be updated as the SHA is different" + Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable + } + } else { + Write-Host "Template $($File.name) needs to be created" Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable } - } else { - Write-Host "Template $($File.name) needs to be created" - Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable - } + } catch { + $Message = "Failed to get data from community repo $($TemplateSettings.templateRepo.value). Error: $($_.Exception.Message)" + Write-LogMessage -API 'Community Repo' -tenant $TenantFilter -message $Message -sev Error + return "Failed to get data from community repo $($TemplateSettings.templateRepo.value). Error: $($_.Exception.Message)" } } else { foreach ($Task in $Tasks) { diff --git a/Modules/CIPPCore/Public/Tools/Import-CommunityTemplate.ps1 b/Modules/CIPPCore/Public/Tools/Import-CommunityTemplate.ps1 index 5cfdcd6b5827..2d3686a1702d 100644 --- a/Modules/CIPPCore/Public/Tools/Import-CommunityTemplate.ps1 +++ b/Modules/CIPPCore/Public/Tools/Import-CommunityTemplate.ps1 @@ -13,97 +13,130 @@ function Import-CommunityTemplate { $Table = Get-CippTable -TableName 'templates' + try { + if ($Template.RowKey) { + Write-Host "This is going to be a direct write to table, it's a CIPP template. We're writing $($Template.RowKey)" + $Template = $Template | Select-Object * -ExcludeProperty Timestamp - if ($Template.RowKey) { - Write-Host "This is going to be a direct write to table, it's a CIPP template. We're writing $($Template.RowKey)" - $Template = $Template | Select-Object * -ExcludeProperty timestamp - Add-CIPPAzDataTableEntity @Table -Entity $Template -Force - } else { - if ($Template.mailNickname) { $Type = 'Group' } - if ($Template.'@odata.type' -like '*conditionalAccessPolicy*') { $Type = 'ConditionalAccessPolicy' } - Write-Host "The type is $Type" - switch -Wildcard ($Type) { + # Support both objects and json string in repo (support pretty printed json in repo) + if (Test-Json $Template.JSON -ErrorAction SilentlyContinue) { + $NewJSON = $Template.JSON | ConvertFrom-Json + } else { + $NewJSON = $Template.JSON + } + + # Check for existing object + $Existing = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$($Template.RowKey)' and PartitionKey eq '$($Template.PartitionKey)'" -ErrorAction SilentlyContinue - '*Group*' { - $RawJsonObj = [PSCustomObject]@{ - Displayname = $Template.displayName - Description = $Template.Description - MembershipRules = $Template.membershipRule - username = $Template.mailNickname - GUID = $Template.id - groupType = 'generic' - } | ConvertTo-Json -Depth 100 - $entity = @{ - JSON = "$RawJsonObj" - PartitionKey = 'GroupTemplate' - SHA = $SHA - GUID = $Template.id - RowKey = $Template.id + if ($Existing) { + if ($Existing.PartitionKey -eq 'StandardsTemplateV2') { + # Convert existing JSON to object for updates + if (Test-Json $Existing.JSON -ErrorAction SilentlyContinue) { + $ExistingJSON = $Existing.JSON | ConvertFrom-Json + } else { + $ExistingJSON = $Existing.JSON + } + # Extract existing tenantFilter and excludedTenants + $tenantFilter = $ExistingJSON.tenantFilter + $excludedTenants = $ExistingJSON.excludedTenants + $NewJSON.tenantFilter = $tenantFilter + $NewJSON.excludedTenants = $excludedTenants } - Add-CIPPAzDataTableEntity @Table -Entity $entity -Force - break } - '*conditionalAccessPolicy*' { - Write-Host $MigrationTable - $Template = ([pscustomobject]$Template) | ForEach-Object { - $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name - $_ | Select-Object -Property $NonEmptyProperties - } - $id = $Template.id - $Template = $Template | Select-Object * -ExcludeProperty lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '*odata.type', 'roleScopeTagIds@odata.type', createdDateTime, 'createdDateTime@odata.type' - Remove-ODataProperties -Object $Template - $RawJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress - #Replace the ids with the displayname by using the migration table, this is a simple find and replace each instance in the JSON. - $MigrationTable.objects | ForEach-Object { - if ($RawJson -match $_.ID) { - $RawJson = $RawJson.Replace($_.ID, $($_.DisplayName)) + # Re-compress JSON and save to table + $NewJSON = [string]($NewJSON | ConvertTo-Json -Depth 100 -Compress) + $Template.JSON = $NewJSON + $Template | Add-Member -MemberType NoteProperty -Name SHA -Value $SHA -Force + Add-CIPPAzDataTableEntity @Table -Entity $Template -Force + } else { + if ($Template.mailNickname) { $Type = 'Group' } + if ($Template.'@odata.type' -like '*conditionalAccessPolicy*') { $Type = 'ConditionalAccessPolicy' } + Write-Host "The type is $Type" + switch -Wildcard ($Type) { + + '*Group*' { + $RawJsonObj = [PSCustomObject]@{ + Displayname = $Template.displayName + Description = $Template.Description + MembershipRules = $Template.membershipRule + username = $Template.mailNickname + GUID = $Template.id + groupType = 'generic' + } | ConvertTo-Json -Depth 100 + $entity = @{ + JSON = "$RawJsonObj" + PartitionKey = 'GroupTemplate' + SHA = $SHA + GUID = $Template.id + RowKey = $Template.id } + Add-CIPPAzDataTableEntity @Table -Entity $entity -Force + break } - $entity = @{ - JSON = "$RawJson" - PartitionKey = 'CATemplate' - SHA = $SHA - GUID = $ID - RowKey = $ID - } - Add-CIPPAzDataTableEntity @Table -Entity $entity -Force - break - } - default { - $URLName = switch -Wildcard ($Template.'@odata.id') { - '*CompliancePolicies*' { 'DeviceCompliancePolicies' } - '*deviceConfigurations*' { 'Device' } - '*DriverUpdateProfiles*' { 'windowsDriverUpdateProfiles' } - '*SettingsCatalog*' { 'Catalog' } - '*configurationPolicies*' { 'Catalog' } - '*managedAppPolicies*' { 'AppProtection' } - '*deviceAppManagement*' { 'AppProtection' } + '*conditionalAccessPolicy*' { + Write-Host $MigrationTable + $Template = ([pscustomobject]$Template) | ForEach-Object { + $NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name + $_ | Select-Object -Property $NonEmptyProperties + } + $id = $Template.id + $Template = $Template | Select-Object * -ExcludeProperty lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '*odata.type', 'roleScopeTagIds@odata.type', createdDateTime, 'createdDateTime@odata.type' + Remove-ODataProperties -Object $Template + $RawJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress + #Replace the ids with the displayname by using the migration table, this is a simple find and replace each instance in the JSON. + $MigrationTable.objects | ForEach-Object { + if ($RawJson -match $_.ID) { + $RawJson = $RawJson.Replace($_.ID, $($_.DisplayName)) + } + } + $entity = @{ + JSON = "$RawJson" + PartitionKey = 'CATemplate' + SHA = $SHA + GUID = $ID + RowKey = $ID + } + Add-CIPPAzDataTableEntity @Table -Entity $entity -Force + break } - $id = $Template.id - $RawJson = $Template | Select-Object * -ExcludeProperty id, lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', 'lastModifiedDateTime@odata.type', 'roleScopeTagIds@odata.type', createdDateTime, 'createdDateTime@odata.type' - Remove-ODataProperties -Object $RawJson - $RawJson = $RawJson | ConvertTo-Json -Depth 100 -Compress + default { + $URLName = switch -Wildcard ($Template.'@odata.id') { + '*CompliancePolicies*' { 'DeviceCompliancePolicies' } + '*deviceConfigurations*' { 'Device' } + '*DriverUpdateProfiles*' { 'windowsDriverUpdateProfiles' } + '*SettingsCatalog*' { 'Catalog' } + '*configurationPolicies*' { 'Catalog' } + '*managedAppPolicies*' { 'AppProtection' } + '*deviceAppManagement*' { 'AppProtection' } + } + $id = $Template.id + $RawJson = $Template | Select-Object * -ExcludeProperty id, lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', 'lastModifiedDateTime@odata.type', 'roleScopeTagIds@odata.type', createdDateTime, 'createdDateTime@odata.type' + Remove-ODataProperties -Object $RawJson + $RawJson = $RawJson | ConvertTo-Json -Depth 100 -Compress - #create a new template - $RawJsonObj = [PSCustomObject]@{ - Displayname = $Template.displayName ?? $template.Name - Description = $Template.Description - RAWJson = $RawJson - Type = $URLName - GUID = $ID - } | ConvertTo-Json -Depth 100 -Compress + #create a new template + $RawJsonObj = [PSCustomObject]@{ + Displayname = $Template.displayName ?? $template.Name + Description = $Template.Description + RAWJson = $RawJson + Type = $URLName + GUID = $ID + } | ConvertTo-Json -Depth 100 -Compress - $entity = @{ - JSON = "$RawJsonObj" - PartitionKey = 'IntuneTemplate' - SHA = $SHA - GUID = $ID - RowKey = $ID - } - Add-CIPPAzDataTableEntity @Table -Entity $entity -Force + $entity = @{ + JSON = "$RawJsonObj" + PartitionKey = 'IntuneTemplate' + SHA = $SHA + GUID = $ID + RowKey = $ID + } + Add-CIPPAzDataTableEntity @Table -Entity $entity -Force + } } } + } catch { + Write-Warning "Community template import failed. Error: $($_.Exception.Message)" + Write-Information $_.InvocationInfo.PositionMessage } - } From 203ad6441c5ffd3175ad1de1b9f66b77fff576c4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 11 Apr 2025 18:24:41 -0400 Subject: [PATCH 096/123] fix HIBP auth --- .../Public/Extension Functions/Set-ExtensionAPIKey.ps1 | 2 +- Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 b/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 index 0a084cb3bcdd..191b4182e288 100644 --- a/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 +++ b/Modules/CippExtensions/Public/Extension Functions/Set-ExtensionAPIKey.ps1 @@ -29,7 +29,7 @@ function Set-ExtensionAPIKey { $null = Set-AzContext -SubscriptionId $SubscriptionId $null = Set-AzKeyVaultSecret -VaultName $keyvaultname -Name $Extension -SecretValue (ConvertTo-SecureString -AsPlainText -Force -String $APIKey) } - Set-Item -Path "ENV:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue + Set-Item -Path "env:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue } return $true } diff --git a/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 index acdb9ab21146..c759e08ded55 100644 --- a/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 +++ b/Modules/CippExtensions/Public/HIBP/Get-HIBPAuth.ps1 @@ -1,8 +1,9 @@ function Get-HIBPAuth { $Var = 'Ext_HIBP' - $APIKey = Get-Item -Path "ENV:$Var" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value + $APIKey = Get-Item -Path "env:$Var" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value if ($APIKey) { Write-Information 'Using cached API Key for HIBP' + $Secret = $APIKey } else { if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { $DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets' @@ -27,7 +28,7 @@ function Get-HIBPAuth { $Secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name 'HIBP' -AsPlainText } } - Set-Item -Path "ENV:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue + Set-Item -Path "env:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue } return @{ From c0279ba40f90301986c99fc43c0dfb9ebd9fece6 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 11 Apr 2025 18:35:10 -0400 Subject: [PATCH 097/123] fix casing --- Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 | 4 ++-- .../Public/Extension Functions/Get-ExtensionAPIKey.ps1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 index 3ac6f823e5ee..e86fd4b2e128 100644 --- a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 @@ -15,7 +15,7 @@ function Get-CIPPAuthentication { } foreach ($Var in $Variables) { if ($Secret.$Var) { - Set-Item -Path ENV:$Var -Value $Secret.$Var -Force -ErrorAction Stop + Set-Item -Path env:$Var -Value $Secret.$Var -Force -ErrorAction Stop } } } else { @@ -24,7 +24,7 @@ function Get-CIPPAuthentication { $null = Set-AzContext -SubscriptionId $SubscriptionId $keyvaultname = ($env:WEBSITE_DEPLOYMENT_ID -split '-')[0] $Variables | ForEach-Object { - Set-Item -Path ENV:$_ -Value (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $_ -AsPlainText -ErrorAction Stop) -Force + Set-Item -Path env:$_ -Value (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $_ -AsPlainText -ErrorAction Stop) -Force } } $env:SetFromProfile = $true diff --git a/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 b/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 index c637735dfe12..f9f7cc2b7901 100644 --- a/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 +++ b/Modules/CippExtensions/Public/Extension Functions/Get-ExtensionAPIKey.ps1 @@ -11,7 +11,7 @@ function Get-ExtensionAPIKey { ) $Var = "Ext_$Extension" - $APIKey = Get-Item -Path "ENV:$Var" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value + $APIKey = Get-Item -Path "env:$Var" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value if ($APIKey) { Write-Information "Using cached API Key for $Extension" } else { @@ -26,7 +26,7 @@ function Get-ExtensionAPIKey { $null = Set-AzContext -SubscriptionId $SubscriptionId $APIKey = (Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $Extension -AsPlainText) } - Set-Item -Path "ENV:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue + Set-Item -Path "env:$Var" -Value $APIKey -Force -ErrorAction SilentlyContinue } return $APIKey } From 9b5ee91f434b76e4b324a3cacb5edacd274fb09c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 11 Apr 2025 18:50:55 -0400 Subject: [PATCH 098/123] Update Invoke-ExecBackendURLs.ps1 --- .../CIPP/Settings/Invoke-ExecBackendURLs.ps1 | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 index d12cc9036e44..40cd27350264 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecBackendURLs.ps1 @@ -14,21 +14,20 @@ Function Invoke-ExecBackendURLs { $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $Subscription = ($ENV:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 - $SWAName = $ENV:WEBSITE_SITE_NAME -replace 'cipp', 'CIPP-SWA-' - + $Subscription = ($env:WEBSITE_OWNER_NAME).split('+') | Select-Object -First 1 + $SWAName = $env:WEBSITE_SITE_NAME -replace 'cipp', 'CIPP-SWA-' $results = [PSCustomObject]@{ - ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/overview" - KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$($ENV:WEBSITE_SITE_NAME)/secrets" - FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/appServices" - FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/configuration" - FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($ENV:WEBSITE_SITE_NAME)/vstscd" - SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/customDomains" - SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$ENV:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" + ResourceGroup = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/overview" + KeyVault = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$($env:WEBSITE_SITE_NAME)/secrets" + FunctionApp = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/appServices" + FunctionConfig = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/configuration" + FunctionDeployment = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/sites/$($env:WEBSITE_SITE_NAME)/vstscd" + SWADomains = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/customDomains" + SWARoles = "https://portal.azure.com/#@Go/resource/subscriptions/$Subscription/resourceGroups/$env:WEBSITE_RESOURCE_GROUP/providers/Microsoft.Web/staticSites/$SWAName/roleManagement" Subscription = $Subscription - RGName = $ENV:WEBSITE_RESOURCE_GROUP - FunctionName = $ENV:WEBSITE_SITE_NAME + RGName = $env:WEBSITE_RESOURCE_GROUP + FunctionName = $env:WEBSITE_SITE_NAME SWAName = $SWAName } From 982bf987909585ac7d1ae538f1f4b8c526cfeacb Mon Sep 17 00:00:00 2001 From: Esco Date: Sat, 12 Apr 2025 00:56:41 +0200 Subject: [PATCH 099/123] chore: Update-StandardsComments --- Tools/Update-StandardsComments.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tools/Update-StandardsComments.ps1 b/Tools/Update-StandardsComments.ps1 index 47be5aee0f2e..08493bda4fbe 100644 --- a/Tools/Update-StandardsComments.ps1 +++ b/Tools/Update-StandardsComments.ps1 @@ -112,7 +112,9 @@ foreach ($Standard in $StandardsInfo) { continue } else { - $NewComment.Add(" $(EscapeMarkdown($Property.Value.ToString()))`n") + if ($null -ne $Property.Value) { + $NewComment.Add(" $(EscapeMarkdown($Property.Value.ToString()))`n") + } } } } From 3b17fb6cb0deae42ca21803af7bd7a00a28af080 Mon Sep 17 00:00:00 2001 From: Esco Date: Sat, 12 Apr 2025 00:57:09 +0200 Subject: [PATCH 100/123] chore: run Update-StandardsComments --- .../Invoke-CIPPStandardAntiPhishPolicy.ps1 | 6 +++--- .../Standards/Invoke-CIPPStandardAutoAddProxy.ps1 | 2 +- .../Invoke-CIPPStandardAutopilotProfile.ps1 | 2 +- .../Invoke-CIPPStandardAutopilotStatusPage.ps1 | 2 +- ...Invoke-CIPPStandardConditionalAccessTemplate.ps1 | 2 +- .../Standards/Invoke-CIPPStandardDisableReshare.ps1 | 2 +- .../Invoke-CIPPStandardDisableTenantCreation.ps1 | 2 +- .../Standards/Invoke-CIPPStandardDisableViva.ps1 | 4 ++-- .../Invoke-CIPPStandardEnableLitigationHold.ps1 | 1 + .../Standards/Invoke-CIPPStandardGroupTemplate.ps1 | 2 +- .../Standards/Invoke-CIPPStandardGuestInvite.ps1 | 2 +- .../Invoke-CIPPStandardIntuneComplianceSettings.ps1 | 2 +- .../Standards/Invoke-CIPPStandardIntuneTemplate.ps1 | 4 ++-- .../Invoke-CIPPStandardPhishProtection.ps1 | 2 +- .../Invoke-CIPPStandardPhishingSimulations.ps1 | 2 +- .../Standards/Invoke-CIPPStandardSPAzureB2B.ps1 | 2 +- .../Invoke-CIPPStandardSPExternalUserExpiration.ps1 | 2 +- .../Invoke-CIPPStandardSafeLinksPolicy.ps1 | 7 ++++--- .../Invoke-CIPPStandardSafeSendersDisable.ps1 | 2 +- .../Invoke-CIPPStandardSpamFilterPolicy.ps1 | 13 +++++++++++++ .../Standards/Invoke-CIPPStandardSpoofWarn.ps1 | 1 + .../Invoke-CIPPStandardStaleEntraDevices.ps1 | 4 ++-- .../Invoke-CIPPStandardTeamsEmailIntegration.ps1 | 2 +- .../Invoke-CIPPStandardTeamsExternalFileSharing.ps1 | 2 +- .../Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 | 2 +- .../Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 | 2 +- .../Invoke-CIPPStandardTransportRuleTemplate.ps1 | 2 +- .../Standards/Invoke-CIPPStandardcalDefault.ps1 | 2 +- .../Invoke-CIPPStandardintuneRequireMFA.ps1 | 2 +- 29 files changed, 49 insertions(+), 33 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 index 3e374dbe911a..a6a8e8f2e57a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 @@ -7,8 +7,8 @@ function Invoke-CIPPStandardAntiPhishPolicy { .SYNOPSIS (Label) Default Anti-Phishing Policy .DESCRIPTION - (Helptext) This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mailtips. - (DocsDescription) This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mailtips. + (Helptext) This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mail tips. + (DocsDescription) This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mail tips. .NOTES CAT Defender Standards @@ -40,7 +40,7 @@ function Invoke-CIPPStandardAntiPhishPolicy { ADDEDDATE 2024-03-25 POWERSHELLEQUIVALENT - Set-AntiphishPolicy or New-AntiphishPolicy + Set-AntiPhishPolicy or New-AntiPhishPolicy RECOMMENDEDBY "CIS" UPDATECOMMENTBLOCK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoAddProxy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoAddProxy.ps1 index 51b3d978687d..5b2e1186408a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoAddProxy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoAddProxy.ps1 @@ -23,7 +23,7 @@ function Invoke-CIPPStandardAutoAddProxy { Set-Mailbox -EmailAddresses @{add=\$EmailAddress} RECOMMENDEDBY DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 index 1449aa6936ea..7812954bc9ec 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotProfile.ps1 @@ -14,7 +14,7 @@ function Invoke-CIPPStandardAutopilotProfile { Device Management Standards TAG DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} ADDEDCOMPONENT {"type":"textField","name":"standards.AutopilotProfile.DisplayName","label":"Profile Display Name"} {"type":"textField","name":"standards.AutopilotProfile.Description","label":"Profile Description"} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotStatusPage.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotStatusPage.ps1 index d0d39040c2d1..e91b53d2fd1b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotStatusPage.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotStatusPage.ps1 @@ -14,7 +14,7 @@ function Invoke-CIPPStandardAutopilotStatusPage { Device Management Standards TAG DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} ADDEDCOMPONENT {"type":"number","name":"standards.AutopilotStatusPage.TimeOutInMinutes","label":"Timeout in minutes","defaultValue":60} {"type":"textField","name":"standards.AutopilotStatusPage.ErrorMessage","label":"Custom Error Message","required":false} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardConditionalAccessTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardConditionalAccessTemplate.ps1 index 03105df1c8b5..ca7a409b4122 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardConditionalAccessTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardConditionalAccessTemplate.ps1 @@ -15,7 +15,7 @@ function Invoke-CIPPStandardConditionalAccessTemplate { MULTIPLE True DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} IMPACT High Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 index 3e6a98fba54b..95c2ece96ddd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 @@ -5,7 +5,7 @@ function Invoke-CIPPStandardDisableReshare { .COMPONENT (APIName) DisableReshare .SYNOPSIS - (Label) Disable Resharing by External Users + (Label) Disable Re-sharing by External Users .DESCRIPTION (Helptext) Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access (DocsDescription) Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access. This is a tenant wide setting and overrules any settings set on the site level diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 index 73059a3f91bf..835cec11cd10 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 @@ -7,7 +7,7 @@ function Invoke-CIPPStandardDisableTenantCreation { .SYNOPSIS (Label) Disable M365 Tenant creation by users .DESCRIPTION - (Helptext) Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles. + (Helptext) Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles. (DocsDescription) Users by default are allowed to create M365 tenants. This disables that so only admins can create new M365 tenants. .NOTES CAT diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 index b1302a56bec3..ba8661834447 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 @@ -7,8 +7,8 @@ function Invoke-CIPPStandardDisableViva { .SYNOPSIS (Label) Disable daily Insight/Viva reports .DESCRIPTION - (Helptext) Disables the daily viva reports for all users. - (DocsDescription) Disables the daily viva reports for all users. + (Helptext) Disables the daily viva reports for all users. This standard requires the CIPP-SAM application to have the Company Administrator (Global Admin) role in the tenant. Enable this using CIPP > Advanced > Super Admin > SAM App Roles. Activate the roles with a CPV refresh. + (DocsDescription) Disables the daily viva reports for all users. This standard requires the CIPP-SAM application to have the Company Administrator (Global Admin) role in the tenant. Enable this using CIPP \> Advanced \> Super Admin \> SAM App Roles. Activate the roles with a CPV refresh. .NOTES CAT Exchange Standards diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 index 1064b89a9ecf..e80b6077345c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableLitigationHold.ps1 @@ -14,6 +14,7 @@ function Invoke-CIPPStandardEnableLitigationHold { Exchange Standards TAG ADDEDCOMPONENT + {"type":"textField","name":"standards.EnableLitigationHold.days","required":false,"label":"Days to apply for litigation hold"} IMPACT Low Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGroupTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGroupTemplate.ps1 index ca72eac437d5..f299e4762242 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGroupTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGroupTemplate.ps1 @@ -15,7 +15,7 @@ function Invoke-CIPPStandardGroupTemplate { CAT Templates DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} IMPACT Medium Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 index 5a8c6c039797..b244ebc80777 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardGuestInvite.ps1 @@ -20,7 +20,7 @@ function Invoke-CIPPStandardGuestInvite { ADDEDDATE 2024-11-12 POWERSHELLEQUIVALENT - + Graph API RECOMMENDEDBY UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 index 7ca986e7a03c..2651942d5e9e 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneComplianceSettings.ps1 @@ -21,7 +21,7 @@ function Invoke-CIPPStandardIntuneComplianceSettings { ADDEDDATE 2024-11-12 POWERSHELLEQUIVALENT - + Graph API RECOMMENDEDBY UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index b75e17b924a6..fbe2007604a4 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -15,7 +15,7 @@ function Invoke-CIPPStandardIntuneTemplate { MULTIPLE True DISABLEDFEATURES - + {"report":false,"warn":false,"remediate":false} IMPACT High Impact ADDEDDATE @@ -24,7 +24,7 @@ function Invoke-CIPPStandardIntuneTemplate { {"type":"autoComplete","multiple":false,"creatable":false,"name":"TemplateList","label":"Select Intune Template","api":{"url":"/api/ListIntuneTemplates","labelField":"Displayname","valueField":"GUID","queryKey":"languages"}} {"name":"AssignTo","label":"Who should this template be assigned to?","type":"radio","options":[{"label":"Do not assign","value":"On"},{"label":"Assign to all users","value":"allLicensedUsers"},{"label":"Assign to all devices","value":"AllDevices"},{"label":"Assign to all users and devices","value":"AllDevicesAndUsers"},{"label":"Assign to Custom Group","value":"customGroup"}]} {"type":"textField","required":false,"name":"customGroup","label":"Enter the custom group name if you selected 'Assign to Custom Group'. Wildcards are allowed."} - {"name":"ExcludeGroup","label":"Exclude Groups","type":"textField","required":false,"helpText":"Enter the group name to exclude from the assignment. Wildcards are allowed."} + {"name":"excludeGroup","label":"Exclude Groups","type":"textField","required":false,"helpText":"Enter the group name to exclude from the assignment. Wildcards are allowed."} UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 index 6c8b19799635..9cf141cd5e30 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 @@ -19,7 +19,7 @@ function Invoke-CIPPStandardPhishProtection { ADDEDDATE 2024-01-22 DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} POWERSHELLEQUIVALENT Portal only RECOMMENDEDBY diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 index 557c0d06e60f..1c5176b51f2d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 @@ -16,7 +16,7 @@ function Invoke-CIPPStandardPhishingSimulations { ADDEDCOMPONENT {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Domains","name":"standards.PhishingSimulations.Domains"} {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Sender IP Ranges","name":"standards.PhishingSimulations.SenderIpRanges"} - {"type":"autoComplete","multiple":true,"creatable":true,"required":true,"label":"Phishing Simulation Urls","name":"standards.PhishingSimulations.PhishingSimUrls"} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"label":"Phishing Simulation Urls","name":"standards.PhishingSimulations.PhishingSimUrls"} IMPACT Medium Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPAzureB2B.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPAzureB2B.ps1 index 0b445c519394..1a338e3bcdc3 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPAzureB2B.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPAzureB2B.ps1 @@ -22,7 +22,7 @@ function Invoke-CIPPStandardSPAzureB2B { POWERSHELLEQUIVALENT Set-SPOTenant -EnableAzureADB2BIntegration \$true RECOMMENDEDBY - "CIS 3.0" + "CIS" UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPExternalUserExpiration.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPExternalUserExpiration.ps1 index 1fbad860859c..aa8f99ab850b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPExternalUserExpiration.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPExternalUserExpiration.ps1 @@ -23,7 +23,7 @@ function Invoke-CIPPStandardSPExternalUserExpiration { POWERSHELLEQUIVALENT Set-SPOTenant -ExternalUserExpireInDays 30 -ExternalUserExpirationRequired \$True RECOMMENDEDBY - "CIS 3.0" + "CIS" UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 index 6227806d8895..863a0b6d36aa 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 @@ -5,10 +5,10 @@ function Invoke-CIPPStandardSafeLinksPolicy { .COMPONENT (APIName) SafeLinksPolicy .SYNOPSIS - (Label) Default SafeLinks Policy + (Label) Default Safe Links Policy .DESCRIPTION - (Helptext) This creates a safelink policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders - (DocsDescription) This creates a safelink policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders + (Helptext) This creates a Safe Links policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders + (DocsDescription) This creates a Safe Links policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders .NOTES CAT Defender Standards @@ -20,6 +20,7 @@ function Invoke-CIPPStandardSafeLinksPolicy { {"type":"switch","label":"AllowClickThrough","name":"standards.SafeLinksPolicy.AllowClickThrough"} {"type":"switch","label":"DisableUrlRewrite","name":"standards.SafeLinksPolicy.DisableUrlRewrite"} {"type":"switch","label":"EnableOrganizationBranding","name":"standards.SafeLinksPolicy.EnableOrganizationBranding"} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"name":"standards.SafeLinksPolicy.DoNotRewriteUrls","label":"Do not rewrite the following URLs in email"} IMPACT Low Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 index 11357cbd81a0..72899c27ce9b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 @@ -15,7 +15,7 @@ function Invoke-CIPPStandardSafeSendersDisable { TAG ADDEDCOMPONENT DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} IMPACT Medium Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 index 0665c50176d6..09a46d518211 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 @@ -24,6 +24,19 @@ function Invoke-CIPPStandardSpamFilterPolicy { {"type":"autoComplete","required":true,"multiple":false,"creatable":false,"label":"Phish Spam Action","name":"standards.SpamFilterPolicy.PhishSpamAction","options":[{"label":"Quarantine the message","value":"Quarantine"},{"label":"Move message to Junk Email folder","value":"MoveToJmf"}]} {"type":"autoComplete","required":true,"multiple":false,"creatable":false,"label":"Phish Quarantine Tag","name":"standards.SpamFilterPolicy.PhishQuarantineTag","options":[{"label":"AdminOnlyAccessPolicy","value":"AdminOnlyAccessPolicy"},{"label":"DefaultFullAccessPolicy","value":"DefaultFullAccessPolicy"},{"label":"DefaultFullAccessWithNotificationPolicy","value":"DefaultFullAccessWithNotificationPolicy"}]} {"type":"autoComplete","required":true,"multiple":false,"creatable":false,"label":"High Confidence Phish Quarantine Tag","name":"standards.SpamFilterPolicy.HighConfidencePhishQuarantineTag","options":[{"label":"AdminOnlyAccessPolicy","value":"AdminOnlyAccessPolicy"},{"label":"DefaultFullAccessPolicy","value":"DefaultFullAccessPolicy"},{"label":"DefaultFullAccessWithNotificationPolicy","value":"DefaultFullAccessWithNotificationPolicy"}]} + {"type":"switch","name":"standards.SpamFilterPolicy.IncreaseScoreWithImageLinks","label":"Increase score if message contains image links to remote websites","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.IncreaseScoreWithBizOrInfoUrls","label":"Increase score if message contains links to .biz or .info domains","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamFramesInHtml","label":"Mark as spam if message contains HTML or iframe tags","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamObjectTagsInHtml","label":"Mark as spam if message contains HTML object tags","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamEmbedTagsInHtml","label":"Mark as spam if message contains HTML embed tags","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamFormTagsInHtml","label":"Mark as spam if message contains HTML form tags","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamWebBugsInHtml","label":"Mark as spam if message contains web bugs (also known as web beacons)","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.MarkAsSpamSensitiveWordList","label":"Mark as spam if message contains words from the sensitive words list","defaultValue":false} + {"type":"switch","name":"standards.SpamFilterPolicy.EnableLanguageBlockList","label":"Enable language block list","defaultValue":false} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"name":"standards.SpamFilterPolicy.LanguageBlockList","label":"Languages to block (uppercase ISO 639-1 two-letter)"} + {"type":"switch","name":"standards.SpamFilterPolicy.EnableRegionBlockList","label":"Enable region block list","defaultValue":false} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"name":"standards.SpamFilterPolicy.RegionBlockList","label":"Regions to block (uppercase ISO 3166-1 two-letter)"} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"name":"standards.SpamFilterPolicy.AllowedSenderDomains","label":"Allowed sender domains"} IMPACT Medium Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 index 19b0d7626b04..8a843339b622 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 @@ -16,6 +16,7 @@ function Invoke-CIPPStandardSpoofWarn { "CIS" ADDEDCOMPONENT {"type":"autoComplete","multiple":false,"label":"Select value","name":"standards.SpoofWarn.state","options":[{"label":"Enabled","value":"enabled"},{"label":"Disabled","value":"disabled"}]} + {"type":"autoComplete","multiple":true,"creatable":true,"required":false,"label":"Enter allowed senders(domain.com, *.domain.com or test@domain.com)","name":"standards.SpoofWarn.AllowListAdd"} IMPACT Low Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 index 57946ee6bccd..f57beaad5671 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 @@ -15,9 +15,9 @@ function Invoke-CIPPStandardStaleEntraDevices { TAG "CIS" ADDEDCOMPONENT - {"type":"number","name":"standards.StaleEntraDevices.deviceAgeThreshold","label":"Days before stale(Dont set below 30)"} + {"type":"number","name":"standards.StaleEntraDevices.deviceAgeThreshold","label":"Days before stale(Do not set below 30)"} DISABLEDFEATURES - + {"report":false,"warn":false,"remediate":true} IMPACT High Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 index c6cdaa239035..bb4e98c46ba3 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 @@ -22,7 +22,7 @@ Function Invoke-CIPPStandardTeamsEmailIntegration { POWERSHELLEQUIVALENT Set-CsTeamsClientConfiguration -AllowEmailIntoChannel \$false RECOMMENDEDBY - "CIS 3.0" + "CIS" UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 index 7c0da8594146..5967daa8a443 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 @@ -26,7 +26,7 @@ function Invoke-CIPPStandardTeamsExternalFileSharing { POWERSHELLEQUIVALENT Set-CsTeamsClientConfiguration -AllowGoogleDrive \$false -AllowShareFile \$false -AllowBox \$false -AllowDropBox \$false -AllowEgnyte \$false RECOMMENDEDBY - "CIS 3.0" + "CIS" UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 index c74e89c8d606..5b37cbf775dd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsGlobalMeetingPolicy.ps1 @@ -25,7 +25,7 @@ function Invoke-CIPPStandardTeamsGlobalMeetingPolicy { POWERSHELLEQUIVALENT Set-CsTeamsMeetingPolicy -AllowAnonymousUsersToJoinMeeting \$false -AllowAnonymousUsersToStartMeeting \$false -AutoAdmittedUsers EveryoneInCompanyExcludingGuests -AllowPSTNUsersToBypassLobby \$false -MeetingChatEnabledType EnabledExceptAnonymous -DesignatedPresenterRoleMode \$DesignatedPresenterRoleMode -AllowExternalParticipantGiveRequestControl \$false RECOMMENDEDBY - "CIS 3.0" + "CIS" UPDATECOMMENTBLOCK Run the Tools\Update-StandardsComments.ps1 script to update this comment block .LINK diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 index a70ad82d78a6..59fe213f54a0 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMeetingsByDefault.ps1 @@ -14,7 +14,7 @@ function Invoke-CIPPStandardTeamsMeetingsByDefault { Exchange Standards TAG ADDEDCOMPONENT - {"type":"autoComplete","multiple":false,"label":"Select value","name":"standards.TeamsMeetingsByDefault.state","options":[{"label":"Enabled","value":"true"},{"label":"Disabled","value":"false"}]} + {"type":"autoComplete","multiple":false,"creatable":false,"label":"Select value","name":"standards.TeamsMeetingsByDefault.state","options":[{"label":"Enabled","value":"true"},{"label":"Disabled","value":"false"}]} IMPACT Low Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 index d7dd378a2562..82c2763fd5b2 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 @@ -13,7 +13,7 @@ function Invoke-CIPPStandardTransportRuleTemplate { CAT Templates DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} IMPACT Medium Impact ADDEDDATE diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 index ed84d3466ba5..09ecea1a9acd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 @@ -14,7 +14,7 @@ function Invoke-CIPPStandardcalDefault { Exchange Standards TAG DISABLEDFEATURES - + {"report":true,"warn":true,"remediate":false} ADDEDCOMPONENT {"type":"autoComplete","multiple":false,"label":"Select Sharing Level","name":"standards.calDefault.permissionLevel","options":[{"label":"Owner - The user can create, read, edit, and delete all items in the folder, and create subfolders. The user is both folder owner and folder contact.","value":"Owner"},{"label":"Publishing Editor - The user can create, read, edit, and delete all items in the folder, and create subfolders.","value":"PublishingEditor"},{"label":"Editor - The user can create items in the folder. The contents of the folder do not appear.","value":"Editor"},{"label":"Publishing Author. The user can read, create all items/subfolders. Can modify and delete only items they create.","value":"PublishingAuthor"},{"label":"Author - The user can create and read items, and modify and delete items that they create.","value":"Author"},{"label":"Non Editing Author - The user has full read access and create items. Can can delete only own items.","value":"NonEditingAuthor"},{"label":"Reviewer - The user can read all items in the folder.","value":"Reviewer"},{"label":"Contributor - The user can create items and folders.","value":"Contributor"},{"label":"Availability Only - Indicates that the user can view only free/busy time within the calendar.","value":"AvailabilityOnly"},{"label":"Limited Details - The user can view free/busy time within the calendar and the subject and location of appointments.","value":"LimitedDetails"},{"label":"None - The user has no permissions on the folder.","value":"none"}]} IMPACT diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 index 8aa0b7f75e74..302718c98931 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 @@ -5,7 +5,7 @@ function Invoke-CIPPStandardintuneRequireMFA { .COMPONENT (APIName) intuneRequireMFA .SYNOPSIS - (Label) Require Multifactor Authentication to register or join devices with Microsoft Entra + (Label) Require Multi-factor Authentication to register or join devices with Microsoft Entra .DESCRIPTION (Helptext) Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access. (DocsDescription) Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access. From 3e64ed966a671f3b05b9873951db01b2e19e4c27 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 12 Apr 2025 12:50:38 +0200 Subject: [PATCH 101/123] Sherweb code changes --- .../CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 7 +++ .../Sherweb/Test-SherwebMigrationAccounts.ps1 | 50 ++++++++++++++++--- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 34ae4f5ce9d8..63363be0b08c 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -31,6 +31,13 @@ function New-CIPPAlertTemplate { if ($InputObject -eq 'sherwebmig') { $DataHTML = ($Data | ConvertTo-Html | Out-String).Replace('', '
') $IntroText = "

The following licenses have not yet been found at Sherweb, and are expiring within 7 days:

$dataHTML" + if ($data.SherwebMig -like '*buy*') { + $introText = "

The following licenses have not yet been found at Sherweb, and are expiring within 7 days. We have started the process to automatically buy these licenses:

$dataHTML" + } + } + if ($InputObject -eq 'sherwebmigfailcancel') { + $DataHTML = ($Data | ConvertTo-Html | Out-String).Replace('
', '
') + $IntroText = "

The following licenses have not been cancelled due to an API error at the old provider:

$dataHTML" } if ($InputObject -eq 'table') { #data can be a array of strings or a string, if it is, we need to convert it to an object so it shows up nicely, that object will have one header: message. diff --git a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 index d549a6599926..6156d81cdacf 100644 --- a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 +++ b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 @@ -31,19 +31,57 @@ function Test-SherwebMigrationAccounts { switch -wildcard ($config.migrationMethods) { '*notify*' { + $Subject = "Sherweb Migration: $($TenantFilter) - $($LicencesToMigrate.Count) licenses to migrate" $HTMLContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'html' -InputObject 'sherwebmig' $JSONContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'json' -InputObject 'sherwebmig' Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' Send-CIPPAlert -Type 'psa' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $standardsTenant -APIName 'Alerts' Send-CIPPAlert -Type 'webhook' -JSONContent $JSONContent -TenantFilter $Tenant -APIName 'Alerts' } - 'buyAndNotify' { - #Buy the licenses at Sherweb using the matching CSV. + '*buy*' { + try { + $PotentialLicenses = Get-SherwebCatalog -TenantFilter $TenantFilter | Where-Object { $_.microsoftSkuId -in $LicencesToMigrate.SkuId -and $_.sku -like "*$($Config.migrateToLicense)" } + if (!$PotentialLicenses) { + throw 'cannot buy new license: no matching license found in catalog' + } else { + $PotentialLicenses | ForEach-Object { + Set-SherwebSubscription -TenantFilter $TenantFilter -SKU $PotentialLicenses.sku -Quantity $LicencesToMigrate.TotalLicensesAtUnknownCSP + } + } + } catch { + $Subject = "Sherweb Migration: $($TenantFilter) - Failed to buy licenses." + $HTMLContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'html' -InputObject 'sherwebmig' + $JSONContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'json' -InputObject 'sherwebmig' + Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' + Send-CIPPAlert -Type 'psa' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $standardsTenant -APIName 'Alerts' + Send-CIPPAlert -Type 'webhook' -JSONContent $JSONContent -TenantFilter $Tenant -APIName 'Alerts' + } + } - 'buyAndCancel' { - #Create HTML report for this tenant. Send to webhook/notifications/etc - #Buy the licenses at Sherweb using the matching CSV. - #Cancel the licenses in old vendor. + '*Cancel' { + try { + $tenantid = (Get-Tenants -TenantFilter $TenantFilter).customerId + $paxBody = @{ + client_id = $Config.paxclientId + client_secret = $Config.paxclientSecret + audience = 'https://api.pax8.com' + grant_type = 'client_credentials' + } + $Token = Invoke-RestMethod -Uri 'https://api.pax8.com/v1/token' -Method POST -Headers $headers -ContentType 'application/json' -Body $paxBody + $headers = @{ Authorization = "Bearer $($Token.access_token)" } + $cancelSubList = Invoke-RestMethod -Uri "https://api.pax8.com/v1/subscriptions?page=0&size=10&status=Active&companyId=$($tenantid)" -Method GET -Headers $headers | Where-Object -Property productId -In $LicencesToMigrate.SkuId + $cancelSubList | ForEach-Object { + $response = Invoke-RestMethod -Uri "https://api.pax8.com/v1/subscriptions/$($_.subscriptionId)" -Method DELETE -Headers $headers -ContentType 'application/json' -Body ($body | ConvertTo-Json) + } + + } catch { + $Subject = 'Sherweb Migration: Pax Migration failed' + $HTMLContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'html' -InputObject 'sherwebmigfailpax' + $JSONContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'json' -InputObject 'sherwebmigfailpax' + Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' + Send-CIPPAlert -Type 'psa' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $standardsTenant -APIName 'Alerts' + Send-CIPPAlert -Type 'webhook' -JSONContent $JSONContent -TenantFilter $Tenant -APIName 'Alerts' + } } } From 8a401a57506115044a36cf131e162f3399eb1d38 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 12 Apr 2025 13:13:33 +0200 Subject: [PATCH 102/123] sherweb updates --- Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 | 4 ++++ .../Public/Sherweb/Test-SherwebMigrationAccounts.ps1 | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 index 63363be0b08c..bf93a9098812 100644 --- a/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPAlertTemplate.ps1 @@ -39,6 +39,10 @@ function New-CIPPAlertTemplate { $DataHTML = ($Data | ConvertTo-Html | Out-String).Replace('
', '
') $IntroText = "

The following licenses have not been cancelled due to an API error at the old provider:

$dataHTML" } + if ($InputObject -eq 'sherwebmigBuyFail') { + $DataHTML = ($Data | ConvertTo-Html | Out-String).Replace('
', '
') + $IntroText = "

The following licenses have not been bought as we could not find a correctly matching license. Please login and buy the license:

$dataHTML" + } if ($InputObject -eq 'table') { #data can be a array of strings or a string, if it is, we need to convert it to an object so it shows up nicely, that object will have one header: message. diff --git a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 index 6156d81cdacf..6f05cc499f51 100644 --- a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 +++ b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 @@ -50,8 +50,8 @@ function Test-SherwebMigrationAccounts { } } catch { $Subject = "Sherweb Migration: $($TenantFilter) - Failed to buy licenses." - $HTMLContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'html' -InputObject 'sherwebmig' - $JSONContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'json' -InputObject 'sherwebmig' + $HTMLContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'html' -InputObject 'sherwebmigBuyFail' + $JSONContent = New-CIPPAlertTemplate -Data $LicencesToMigrate -Format 'json' -InputObject 'sherwebmigBuyFail' Send-CIPPAlert -Type 'email' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $tenant -APIName 'Alerts' Send-CIPPAlert -Type 'psa' -Title $Subject -HTMLContent $HTMLContent.htmlcontent -TenantFilter $standardsTenant -APIName 'Alerts' Send-CIPPAlert -Type 'webhook' -JSONContent $JSONContent -TenantFilter $Tenant -APIName 'Alerts' From 0dc03d1b59c551b4bd95e778978c64c4aea94737 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 12 Apr 2025 14:12:24 +0200 Subject: [PATCH 103/123] fixes issue with shrinking tables --- .../Public/Get-CIPPAzDatatableEntity.ps1 | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/Modules/CIPPCore/Public/Get-CIPPAzDatatableEntity.ps1 b/Modules/CIPPCore/Public/Get-CIPPAzDatatableEntity.ps1 index 27c4002fb814..cd1fbce70771 100644 --- a/Modules/CIPPCore/Public/Get-CIPPAzDatatableEntity.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPAzDatatableEntity.ps1 @@ -12,31 +12,43 @@ function Get-CIPPAzDataTableEntity { $Results = Get-AzDataTableEntity @PSBoundParameters $mergedResults = @{} + $rootEntities = @{} # Keyed by "$PartitionKey|$RowKey" - # First pass: Collect all parts and complete entities foreach ($entity in $Results) { - if ($entity.OriginalEntityId) { - $entityId = $entity.OriginalEntityId - $partitionKey = $entity.PartitionKey - if (-not $mergedResults.ContainsKey($partitionKey)) { - $mergedResults[$partitionKey] = @{} - } - if (-not $mergedResults[$partitionKey].ContainsKey($entityId)) { - $mergedResults[$partitionKey][$entityId] = @{ - Parts = [System.Collections.Generic.List[object]]::new() - } - } - $mergedResults[$partitionKey][$entityId]['Parts'].Add($entity) - } else { - $partitionKey = $entity.PartitionKey - if (-not $mergedResults.ContainsKey($partitionKey)) { - $mergedResults[$partitionKey] = @{} - } - $mergedResults[$partitionKey][$entity.RowKey] = @{ + $partitionKey = $entity.PartitionKey + $rowKey = $entity.RowKey + $hasOriginalId = $entity.PSObject.Properties.Match('OriginalEntityId') -and $entity.OriginalEntityId + + if (-not $mergedResults.ContainsKey($partitionKey)) { + $mergedResults[$partitionKey] = @{} + } + + if (-not $hasOriginalId) { + # It's a standalone root row + $rootEntities["$partitionKey|$rowKey"] = $true + $mergedResults[$partitionKey][$rowKey] = @{ Entity = $entity Parts = [System.Collections.Generic.List[object]]::new() } + continue + } + + # It's a part of something else + $entityId = $entity.OriginalEntityId + + # Check if this entity's target has a "real" base + if ($rootEntities.ContainsKey("$partitionKey|$entityId")) { + # Root row exists → skip merging this part + continue + } + + # Merge it as a part + if (-not $mergedResults[$partitionKey].ContainsKey($entityId)) { + $mergedResults[$partitionKey][$entityId] = @{ + Parts = [System.Collections.Generic.List[object]]::new() + } } + $mergedResults[$partitionKey][$entityId]['Parts'].Add($entity) } $finalResults = [System.Collections.Generic.List[object]]::new() From 65707c3089e60ef1f7caf30dd118b3684054e50e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 12 Apr 2025 14:27:52 +0200 Subject: [PATCH 104/123] final touches --- .../Public/Sherweb/Test-SherwebMigrationAccounts.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 index 6f05cc499f51..ef52c8ad4c08 100644 --- a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 +++ b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 @@ -7,13 +7,13 @@ function Test-SherwebMigrationAccounts { $Table = Get-CIPPTable -TableName Extensionsconfig $Config = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json).Sherweb #First get a list of all subscribed skus for this tenant, that are in the transfer window. - $Licenses = (Get-CIPPLicenseOverview -TenantFilter $TenantFilter) | ForEach-Object { $_.terminfo = ($_.terminfo | ConvertFrom-Json -ErrorAction SilentlyContinue) ; $_ } | Where-Object { $_.terminfo -ne $null -and $_.terminfo.TransferWindow -LE 78 } + $Licenses = (Get-CIPPLicenseOverview -TenantFilter $TenantFilter) | ForEach-Object { $_.terminfo = ($_.terminfo | ConvertFrom-Json -ErrorAction SilentlyContinue) ; $_ } | Where-Object { $_.terminfo -ne $null -and $_.terminfo.TransferWindow -LE 7 } #now check if this exact count of licenses is available at Sherweb, if not, we need to migrate them. $SherwebLicenses = Get-SherwebCurrentSubscription -TenantFilter $TenantFilter $LicencesToMigrate = foreach ($License in $Licenses) { foreach ($termInfo in $License.terminfo) { - $matchedSherweb = $SherwebLicenses | Where-Object { $_.quantity -eq 3 -and $_.commitmentTerm.termEndDate -eq $termInfo.NextLifecycle } + $matchedSherweb = $SherwebLicenses | Where-Object { $_.quantity -eq $termInfo.TotalLicenses -and $_.commitmentTerm.termEndDate -eq $termInfo.NextLifecycle } if (-not $matchedSherweb) { [PSCustomObject]@{ LicenseName = ($Licenses | Where-Object { $_.skuId -eq $License.skuId }).license From c293c0d6809cd4f0b78520759d0cee798b3b0c06 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sat, 12 Apr 2025 14:48:56 +0200 Subject: [PATCH 105/123] scheduler sherweb --- .../CIPPCore/Public/Set-CIPPSherwebLicense.ps1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Modules/CIPPCore/Public/Set-CIPPSherwebLicense.ps1 diff --git a/Modules/CIPPCore/Public/Set-CIPPSherwebLicense.ps1 b/Modules/CIPPCore/Public/Set-CIPPSherwebLicense.ps1 new file mode 100644 index 000000000000..fb71de2ea786 --- /dev/null +++ b/Modules/CIPPCore/Public/Set-CIPPSherwebLicense.ps1 @@ -0,0 +1,15 @@ +function Set-CIPPSherwebLicense { + param ( + [Parameter(Mandatory = $true)] + [string]$tenantFilter, + + [Parameter(Mandatory = $true)] + [string]$SKUid, + + [int]$Quantity, + [int]$Add, + [int]$Remove + ) + + Set-SherwebSubscription -SKU $SKUid -Quantity $Quantity -Add $Add -Remove $Remove -TenantFilter $tenantFilter +} From eb8f4fcfeb927c76ac9da19c84defd40abc1b86e Mon Sep 17 00:00:00 2001 From: Esco Date: Sat, 12 Apr 2025 17:02:08 +0200 Subject: [PATCH 106/123] chore: update cSpell with CIPP-API standard words --- cspell.json | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cspell.json b/cspell.json index 9aa3bf30dfc3..376f61639b3f 100644 --- a/cspell.json +++ b/cspell.json @@ -9,18 +9,29 @@ "GDAP", "CIPP", "CIPP-API", + "OBEE", + "TNEF", + "winmail", + "AITM", + "Yubikey", "Sherweb", "Autotask", "Connectwise", "Datto", "Bluetrait", + "ADMS", + "SSPR", + "PSTN", + "Passwordless", ], "ignoreWords": [ "tenantid", "APINAME", "CIPPBPA", + "CIPPCA", "CIPPSPO", "CIPPAPI", + "Addins", "Helptext", "ADDEDCOMPONENT", "ADDEDDATE", @@ -28,6 +39,31 @@ "RECOMMENDEDBY", "UPDATECOMMENTBLOCK", "DISABLEDFEATURES", + "pscustomobject", + "microsoftonline", + "mdo_safeattachments", + "mdo_highconfidencespamaction", + "mdo_highconfidencephishaction", + "mdo_phisspamacation", + "mdo_spam_notifications_only_for_admins", + "mdo_antiphishingpolicies", + "mdo_phishthresholdlevel", + "mdo_autoforwardingmode", + "mdo_blockmailforward", + "mdo_zapspam", + "mdo_zapphish", + "mdo_zapmalware", + "mdo_safedocuments", + "mdo_commonattachmentsfilter", + "mdo_safeattachmentpolicy", + "mdo_safelinksforemail", + "mdo_safelinksforOfficeApps", + "exo_storageproviderrestricted", + "exo_individualsharing", + "exo_outlookaddins", + "exo_mailboxaudit", + "exo_mailtipsenabled", + "mip_search_auditlog", ], "import": [] } From 6156f83b66797c044f8921325bb492e0034b4ff4 Mon Sep 17 00:00:00 2001 From: Esco Date: Sat, 12 Apr 2025 17:03:18 +0200 Subject: [PATCH 107/123] chore: update Standards capitalization and spelling --- .../Invoke-CIPPStandardAnonReportDisable.ps1 | 4 ++-- .../Invoke-CIPPStandardAntiPhishPolicy.ps1 | 24 +++++++++---------- .../Invoke-CIPPStandardAtpPolicyForO365.ps1 | 4 ++-- ...nvoke-CIPPStandardDisableOutlookAddins.ps1 | 4 ++-- .../Invoke-CIPPStandardDisableTNEF.ps1 | 2 +- ...e-CIPPStandardEXODisableAutoForwarding.ps1 | 4 ++-- .../Invoke-CIPPStandardEnableMailTips.ps1 | 2 +- ...voke-CIPPStandardEnableOnlineArchiving.ps1 | 2 +- .../Invoke-CIPPStandardIntuneTemplate.ps1 | 2 +- ...Invoke-CIPPStandardMalwareFilterPolicy.ps1 | 22 ++++++++--------- .../Invoke-CIPPStandardOauthConsent.ps1 | 2 +- .../Invoke-CIPPStandardOutBoundSpamAlert.ps1 | 2 +- ...oke-CIPPStandardPasswordExpireDisabled.ps1 | 18 +++++++------- .../Invoke-CIPPStandardPhishProtection.ps1 | 8 +++---- ...Invoke-CIPPStandardPhishingSimulations.ps1 | 6 ++--- ...oke-CIPPStandardQuarantineRequestAlert.ps1 | 12 +++++----- .../Invoke-CIPPStandardRotateDKIM.ps1 | 2 +- .../Invoke-CIPPStandardSPEmailAttestation.ps1 | 12 +++++----- ...nvoke-CIPPStandardSafeAttachmentPolicy.ps1 | 22 ++++++++--------- .../Invoke-CIPPStandardSafeLinksPolicy.ps1 | 22 ++++++++--------- .../Invoke-CIPPStandardSpamFilterPolicy.ps1 | 2 +- .../Invoke-CIPPStandardStaleEntraDevices.ps1 | 2 +- ...voke-CIPPStandardTeamsEmailIntegration.ps1 | 4 ++-- ...-CIPPStandardTeamsExternalAccessPolicy.ps1 | 4 ++-- ...e-CIPPStandardTeamsExternalFileSharing.ps1 | 4 ++-- ...PPStandardTeamsFederationConfiguration.ps1 | 8 +++---- ...nvoke-CIPPStandardTeamsMessagingPolicy.ps1 | 4 ++-- ...voke-CIPPStandardTransportRuleTemplate.ps1 | 4 ++-- ...voke-CIPPStandardUserPreferredLanguage.ps1 | 4 ++-- .../Invoke-CIPPStandardcalDefault.ps1 | 4 ++-- ...voke-CIPPStandardintuneBrandingProfile.ps1 | 4 ++-- .../Invoke-CIPPStandardintuneDeviceReg.ps1 | 2 +- .../Invoke-CIPPStandardintuneRequireMFA.ps1 | 2 +- .../Standards/Invoke-CIPPStandardlaps.ps1 | 2 +- 34 files changed, 113 insertions(+), 113 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 index 9b5af33c4306..496859c365a5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 @@ -57,8 +57,8 @@ function Invoke-CIPPStandardAnonReportDisable { } } if ($Settings.report -eq $true) { - $stateisCorrrect = $CurrentInfo.displayConcealedNames ? $false : $true - Set-CIPPStandardsCompareField -FieldName 'standards.AnonReportDisable' -FieldValue $stateisCorrrect -TenantFilter $tenant + $StateIsCorrect = $CurrentInfo.displayConcealedNames ? $false : $true + Set-CIPPStandardsCompareField -FieldName 'standards.AnonReportDisable' -FieldValue $StateIsCorrect -TenantFilter $tenant Add-CIPPBPAField -FieldName 'AnonReport' -FieldValue $CurrentInfo.displayConcealedNames -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 index a6a8e8f2e57a..deb7eddd23bc 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAntiPhishPolicy.ps1 @@ -124,7 +124,7 @@ function Invoke-CIPPStandardAntiPhishPolicy { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Anti-phishing policy already correctly configured' -sev Info } else { if ($MDOLicensed) { - $cmdparams = @{ + $cmdParams = @{ Enabled = $true PhishThresholdLevel = $Settings.PhishThresholdLevel EnableMailboxIntelligence = $true @@ -147,7 +147,7 @@ function Invoke-CIPPStandardAntiPhishPolicy { EnableOrganizationDomainsProtection = $true } } else { - $cmdparams = @{ + $cmdParams = @{ Enabled = $true EnableSpoofIntelligence = $true EnableFirstContactSafetyTips = $Settings.EnableFirstContactSafetyTips @@ -160,16 +160,16 @@ function Invoke-CIPPStandardAntiPhishPolicy { if ($CurrentState.Name -eq $PolicyName) { try { - $cmdparams.Add('Identity', $PolicyName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AntiPhishPolicy' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $PolicyName." -sev Info } catch { 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 + $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 $PolicyName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing policy $PolicyName." -sev Error -LogData $_ @@ -178,27 +178,27 @@ function Invoke-CIPPStandardAntiPhishPolicy { } if ($RuleStateIsCorrect -eq $false) { - $cmdparams = @{ + $cmdParams = @{ Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } if ($RuleState.AntiPhishPolicy -ne $PolicyName) { - $cmdparams.Add('AntiPhishPolicy', $PolicyName) + $cmdParams.Add('AntiPhishPolicy', $PolicyName) } if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AntiPhishRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Anti-phishing rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'New-AntiPhishRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Anti-phishing rule $RuleName." -sev Error -LogData $_ diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAtpPolicyForO365.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAtpPolicyForO365.ps1 index 929473191113..14b1a578b0c8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAtpPolicyForO365.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAtpPolicyForO365.ps1 @@ -48,14 +48,14 @@ function Invoke-CIPPStandardAtpPolicyForO365 { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Atp Policy For O365 already set.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ EnableATPForSPOTeamsODB = $true EnableSafeDocs = $true AllowSafeDocsOpen = $Settings.AllowSafeDocsOpen } try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AtpPolicyForO365' -cmdparams $cmdparams -UseSystemMailbox $true + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AtpPolicyForO365' -cmdParams $cmdParams -UseSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Atp Policy For O365' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 index c994e417ffcc..0f6f6829f9af 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 @@ -47,8 +47,8 @@ function Invoke-CIPPStandardDisableOutlookAddins { foreach ($Role in $RolesToRemove) { try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ManagementRoleAssignment' -cmdparams @{ RoleAssignee = $CurrentInfo.Identity; Role = $Role } | ForEach-Object { - New-ExoRequest -tenantid $Tenant -cmdlet 'Remove-ManagementRoleAssignment' -cmdparams @{ Identity = $_.Guid; Confirm = $false } -UseSystemMailbox $true + New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ManagementRoleAssignment' -cmdParams @{ RoleAssignee = $CurrentInfo.Identity; Role = $Role } | ForEach-Object { + New-ExoRequest -tenantid $Tenant -cmdlet 'Remove-ManagementRoleAssignment' -cmdParams @{ Identity = $_.Guid; Confirm = $false } -UseSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled Outlook add-in role: $Role" -sev Debug } } catch { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTNEF.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTNEF.ps1 index f7f1502a69e7..589832537c7d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTNEF.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTNEF.ps1 @@ -38,7 +38,7 @@ function Invoke-CIPPStandardDisableTNEF { if ($CurrentState.TNEFEnabled -ne $false) { try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-RemoteDomain' -cmdParams @{Identity = 'Default'; TNEFEnabled = $false } -useSystemmailbox $true + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-RemoteDomain' -cmdParams @{Identity = 'Default'; TNEFEnabled = $false } -useSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled TNEF for Default Remote Domain' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEXODisableAutoForwarding.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEXODisableAutoForwarding.ps1 index 8fe6b14885d4..2d8736b335c9 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEXODisableAutoForwarding.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEXODisableAutoForwarding.ps1 @@ -35,13 +35,13 @@ function Invoke-CIPPStandardEXODisableAutoForwarding { param($Tenant, $Settings) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'EXODisableAutoForwarding' - $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -cmdparams @{Identity = 'Default' } -useSystemMailbox $true + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -cmdParams @{Identity = 'Default' } -useSystemMailbox $true $StateIsCorrect = $CurrentInfo.AutoForwardingMode -eq 'Off' If ($Settings.remediate -eq $true) { try { - New-ExoRequest -tenantid $tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdparams @{ Identity = 'Default'; AutoForwardingMode = 'Off' } -useSystemMailbox $true + New-ExoRequest -tenantid $tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdParams @{ Identity = 'Default'; AutoForwardingMode = 'Off' } -useSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled auto forwarding' -sev Info } catch { $ErrorMessage = Get-CippException -Exception $_ diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 index 32266151d8a2..b4671d72e7ea 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 @@ -44,7 +44,7 @@ function Invoke-CIPPStandardEnableMailTips { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are already enabled.' -sev Info } else { try { - New-ExoRequest -useSystemMailbox $true -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdparams @{ MailTipsAllTipsEnabled = $true; MailTipsExternalRecipientsTipsEnabled = $true; MailTipsGroupMetricsEnabled = $true; MailTipsLargeAudienceThreshold = $Settings.MailTipsLargeAudienceThreshold } + New-ExoRequest -useSystemMailbox $true -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ MailTipsAllTipsEnabled = $true; MailTipsExternalRecipientsTipsEnabled = $true; MailTipsGroupMetricsEnabled = $true; MailTipsLargeAudienceThreshold = $Settings.MailTipsLargeAudienceThreshold } Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Enabled all MailTips' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 index e0d71e06bc25..8e7bfae1e5cf 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableOnlineArchiving.ps1 @@ -32,7 +32,7 @@ function Invoke-CIPPStandardEnableOnlineArchiving { $MailboxPlans = @( 'ExchangeOnline', 'ExchangeOnlineEnterprise' ) $MailboxesNoArchive = $MailboxPlans | ForEach-Object { - New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdparams @{ MailboxPlan = $_; Filter = 'ArchiveGuid -Eq "00000000-0000-0000-0000-000000000000" -AND RecipientTypeDetails -Eq "UserMailbox"' } + New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdParams @{ MailboxPlan = $_; Filter = 'ArchiveGuid -Eq "00000000-0000-0000-0000-000000000000" -AND RecipientTypeDetails -Eq "UserMailbox"' } Write-Host "Getting mailboxes without Online Archiving for plan $_" } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 index fbe2007604a4..ed04a79091bd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardIntuneTemplate.ps1 @@ -39,7 +39,7 @@ function Invoke-CIPPStandardIntuneTemplate { $CompareList = foreach ($Template in $Settings) { Write-Host "IntuneTemplate: $($Template.TemplateList.value) - Trying to find template" $Request.body = (Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object -Property RowKey -Like "$($Template.TemplateList.value)*").JSON | ConvertFrom-Json -ErrorAction SilentlyContinue - if ($Request.body -eq $null) { + if ($null -eq $Request.body) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to find template $($Template.TemplateList.value). Has this Intune Template been deleted?" -sev 'Error' continue } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 index ad447c2a6288..d5044ec3e36a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMalwareFilterPolicy.ps1 @@ -96,7 +96,7 @@ function Invoke-CIPPStandardMalwareFilterPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Malware Filter Policy already correctly configured' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ EnableFileFilter = $true FileTypes = $ExpectedFileTypes FileTypeAction = $Settings.FileTypeAction @@ -110,16 +110,16 @@ function Invoke-CIPPStandardMalwareFilterPolicy { if ($CurrentState.Name -eq $PolicyName) { try { - $cmdparams.Add('Identity', $PolicyName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-MalwareFilterPolicy' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $PolicyName." -sev Info } catch { 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 + $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 $PolicyName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Malware Filter policy $PolicyName." -sev Error -LogData $_ @@ -128,27 +128,27 @@ function Invoke-CIPPStandardMalwareFilterPolicy { } if ($RuleStateIsCorrect -eq $false) { - $cmdparams = @{ + $cmdParams = @{ Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } if ($RuleState.MalwareFilterPolicy -ne $PolicyName) { - $cmdparams.Add('MalwareFilterPolicy', $PolicyName) + $cmdParams.Add('MalwareFilterPolicy', $PolicyName) } if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-MalwareFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Malware Filter Rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'New-MalwareFilterRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { 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-CIPPStandardOauthConsent.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOauthConsent.ps1 index e9fde585ffe1..f53d2a3b0762 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOauthConsent.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOauthConsent.ps1 @@ -43,7 +43,7 @@ function Invoke-CIPPStandardOauthConsent { $Existing = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/permissionGrantPolicies/' -tenantid $tenant) | Where-Object -Property id -EQ 'cipp-consent-policy' if (!$Existing) { New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/permissionGrantPolicies' -Type POST -Body '{ "id":"cipp-consent-policy", "displayName":"Application Consent Policy", "description":"This policy controls the current application consent policies."}' -ContentType 'application/json' - #Replaced static web app appid with Office 365 Management by Microsofts recommendation; this application is always consented, cannot be removed nor elevated as the portals run on this app id. + #Replaced static web app appid with Office 365 Management by Microsoft's recommendation; this application is always consented, cannot be removed nor elevated as the portals run on this app id. New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/permissionGrantPolicies/cipp-consent-policy/includes' -Type POST -Body '{"permissionClassification":"all","permissionType":"delegated","clientApplicationIds":["00b41c95-dab0-4487-9791-b9d2c32c80f2"]}' -ContentType 'application/json' } try { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 index 9c28667cd0f1..ee8cbd3db58a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 @@ -39,7 +39,7 @@ function Invoke-CIPPStandardOutBoundSpamAlert { if ($CurrentInfo.NotifyOutboundSpam -ne $true -or $CurrentInfo.NotifyOutboundSpamRecipients -ne $settings.OutboundSpamContact) { $Contacts = $settings.OutboundSpamContact try { - New-ExoRequest -tenantid $tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdparams @{ Identity = 'Default'; NotifyOutboundSpam = $true; NotifyOutboundSpamRecipients = $Contacts } -useSystemMailbox $true + New-ExoRequest -tenantid $tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdParams @{ Identity = 'Default'; NotifyOutboundSpam = $true; NotifyOutboundSpamRecipients = $Contacts } -useSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $tenant -message "Set outbound spam filter alert to $($Contacts)" -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 index 17ce2b2835f4..c2db0ebf36e1 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 @@ -34,12 +34,12 @@ function Invoke-CIPPStandardPasswordExpireDisabled { param($Tenant, $Settings) $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/domains' -tenantid $Tenant - $DomainswithoutPassExpire = $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' + $DomainsWithoutPassExpire = $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' if ($Settings.remediate -eq $true) { - if ($DomainswithoutPassExpire) { - $DomainswithoutPassExpire | ForEach-Object { + if ($DomainsWithoutPassExpire) { + $DomainsWithoutPassExpire | ForEach-Object { try { if ( $null -eq $_.passwordNotificationWindowInDays ) { $Body = '{"passwordValidityPeriodInDays": 2147483647, "passwordNotificationWindowInDays": 14 }' @@ -61,18 +61,18 @@ function Invoke-CIPPStandardPasswordExpireDisabled { } if ($Settings.alert -eq $true) { - if ($DomainswithoutPassExpire) { - Write-StandardsAlert -message "Password Expiration is not disabled for the following $($DomainswithoutPassExpire.Count) domains: $($DomainswithoutPassExpire.id -join ', ')" -object $DomainswithoutPassExpire -tenant $tenant -standardName 'PasswordExpireDisabled' -standardId $Settings.standardId - Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for the following $($DomainswithoutPassExpire.Count) domains: $($DomainswithoutPassExpire.id -join ', ')" -sev Info + if ($DomainsWithoutPassExpire) { + Write-StandardsAlert -message "Password Expiration is not disabled for the following $($DomainsWithoutPassExpire.Count) domains: $($DomainsWithoutPassExpire.id -join ', ')" -object $DomainsWithoutPassExpire -tenant $tenant -standardName 'PasswordExpireDisabled' -standardId $Settings.standardId + Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for the following $($DomainsWithoutPassExpire.Count) domains: $($DomainsWithoutPassExpire.id -join ', ')" -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is disabled for all $($GraphRequest.Count) domains." -sev Info } } if ($Settings.report -eq $true) { - Add-CIPPBPAField -FieldName 'PasswordExpireDisabled' -FieldValue $DomainswithoutPassExpire -StoreAs json -Tenant $tenant - if ($DomainswithoutPassExpire) { - $FieldValue = $DomainswithoutPassExpire + Add-CIPPBPAField -FieldName 'PasswordExpireDisabled' -FieldValue $DomainsWithoutPassExpire -StoreAs json -Tenant $tenant + if ($DomainsWithoutPassExpire) { + $FieldValue = $DomainsWithoutPassExpire } else { $FieldValue = $true } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 index 9cf141cd5e30..6701703620a2 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 @@ -62,7 +62,7 @@ function Invoke-CIPPStandardPhishProtection { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Logon Screen Phishing Protection system already active' -sev Info } else { $currentBody = $currentBody + $CSS - Write-Host 'Creating Logon Screen Phising Protection System' + Write-Host 'Creating Logon Screen Phishing Protection System' New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/organization/$($TenantId.customerId)/branding/localizations/0/customCSS" -ContentType 'text/css' -asApp $true -Type PUT -Body $currentBody Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled Logon Screen Phishing Protection system' -sev Info @@ -82,8 +82,8 @@ function Invoke-CIPPStandardPhishProtection { } } if ($Settings.report -eq $true) { - if ($currentBody -like "*$CSS*") { $authstate = $true } else { $authstate = $false } - Add-CIPPBPAField -FieldName 'PhishProtection' -FieldValue $authstate -StoreAs bool -Tenant $tenant - Set-CIPPStandardsCompareField -FieldName 'standards.PhishProtection' -FieldValue $authstate -Tenant $tenant + if ($currentBody -like "*$CSS*") { $authState = $true } else { $authState = $false } + Add-CIPPBPAField -FieldName 'PhishProtection' -FieldValue $authState -StoreAs bool -Tenant $tenant + Set-CIPPStandardsCompareField -FieldName 'standards.PhishProtection' -FieldValue $authState -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 index 1c5176b51f2d..ee792a946796 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishingSimulations.ps1 @@ -70,7 +70,7 @@ function Invoke-CIPPStandardPhishingSimulations { If ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Advanced Phishing Simulations already correctly configured' -sev Info } Else { - # Remedidate incorrect Phishing Simulations Policy + # Remediate incorrect Phishing Simulations Policy If ($PolicyIsCorrect -eq $false) { If ($PolicyState.Name -eq 'PhishSimOverridePolicy') { Try { @@ -89,7 +89,7 @@ function Invoke-CIPPStandardPhishingSimulations { } } - # Remedidate incorrect Phishing Simulations Policy Rule + # Remediate incorrect Phishing Simulations Policy Rule If ($RuleIsCorrect -eq $false) { If ($RuleState.Name -like "*PhishSimOverr*") { $cmdParams = @{ @@ -121,7 +121,7 @@ function Invoke-CIPPStandardPhishingSimulations { } } - # Remedidate incorrect Phishing Simulations URLs + # Remediate incorrect Phishing Simulations URLs If ($PhishingSimUrlsIsCorrect -eq $false) { $cmdParams = @{ ListType = 'Url' diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardQuarantineRequestAlert.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardQuarantineRequestAlert.ps1 index 8ba28e6582f0..79f52025b76b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardQuarantineRequestAlert.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardQuarantineRequestAlert.ps1 @@ -42,7 +42,7 @@ function Invoke-CIPPStandardQuarantineRequestAlert { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Quarantine Request Alert is configured correctly' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ 'NotifyUser' = $Settings.NotifyUser 'Category' = 'ThreatManagement' 'Operation' = 'QuarantineRequestReleaseMessage' @@ -52,8 +52,8 @@ function Invoke-CIPPStandardQuarantineRequestAlert { if ($CurrentState.Name -eq $PolicyName) { try { - $cmdparams['Identity'] = $PolicyName - New-ExoRequest -TenantId $Tenant -cmdlet 'Set-ProtectionAlert' -Compliance -cmdparams $cmdparams -UseSystemMailbox $true + $cmdParams['Identity'] = $PolicyName + New-ExoRequest -TenantId $Tenant -cmdlet 'Set-ProtectionAlert' -Compliance -cmdParams $cmdParams -UseSystemMailbox $true Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully configured Quarantine Request Alert' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message @@ -61,10 +61,10 @@ function Invoke-CIPPStandardQuarantineRequestAlert { } } else { try { - $cmdparams['name'] = $PolicyName - $cmdparams['ThreatType'] = 'Activity' + $cmdParams['name'] = $PolicyName + $cmdParams['ThreatType'] = 'Activity' - New-ExoRequest -TenantId $Tenant -cmdlet 'New-ProtectionAlert' -Compliance -cmdparams $cmdparams -UseSystemMailbox $true + New-ExoRequest -TenantId $Tenant -cmdlet 'New-ProtectionAlert' -Compliance -cmdParams $cmdParams -UseSystemMailbox $true Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully created Quarantine Request Alert' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 index 6cb255e67378..52d311bbb236 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 @@ -39,7 +39,7 @@ function Invoke-CIPPStandardRotateDKIM { if ($DKIM) { $DKIM | ForEach-Object { try { - (New-ExoRequest -tenantid $tenant -cmdlet 'Rotate-DkimSigningConfig' -cmdparams @{ KeySize = 2048; Identity = $_.Identity } -useSystemMailbox $true) + (New-ExoRequest -tenantid $tenant -cmdlet 'Rotate-DkimSigningConfig' -cmdParams @{ KeySize = 2048; Identity = $_.Identity } -useSystemMailbox $true) Write-LogMessage -API 'Standards' -tenant $tenant -message "Rotated DKIM for $($_.Identity)" -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPEmailAttestation.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPEmailAttestation.ps1 index 30cf54129538..25a644856841 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPEmailAttestation.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSPEmailAttestation.ps1 @@ -40,7 +40,7 @@ function Invoke-CIPPStandardSPEmailAttestation { if ($Settings.remediate -eq $true) { if ($StateIsCorrect -eq $true) { - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'SharePoint reauthentication with verification code is already restricted.' -Sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'SharePoint re-authentication with verification code is already restricted.' -Sev Info } else { $Properties = @{ EmailAttestationReAuthDays = [int]$Settings.Days @@ -51,22 +51,22 @@ function Invoke-CIPPStandardSPEmailAttestation { $Response = Get-CIPPSPOTenant -TenantFilter $Tenant | Set-CIPPSPOTenant -Properties $Properties if ($Response.ErrorInfo.ErrorMessage) { $ErrorMessage = Get-NormalizedError -Message $Response.ErrorInfo.ErrorMessage - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to set reauthentication with verification code restriction. Error: $ErrorMessage" -Sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to set re-authentication with verification code restriction. Error: $ErrorMessage" -Sev Error } else { - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully set reauthentication with verification code restriction.' -Sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Successfully set re-authentication with verification code restriction.' -Sev Info } } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to set reauthentication with verification code restriction. Error: $ErrorMessage" -Sev Error + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message "Failed to set re-authentication with verification code restriction. Error: $ErrorMessage" -Sev Error } } } if ($Settings.alert -eq $true) { if ($StateIsCorrect -eq $true) { - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Reauthentication with verification code is restricted.' -Sev Info + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Re-authentication with verification code is restricted.' -Sev Info } else { - Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Reauthentication with verification code is not restricted.' -Sev Alert + Write-LogMessage -API 'Standards' -Tenant $Tenant -Message 'Re-authentication with verification code is not restricted.' -Sev Alert } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 index cf2a092f3b9e..7c37a8cc98da 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeAttachmentPolicy.ps1 @@ -85,7 +85,7 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Safe Attachment Policy already correctly configured' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ Enable = $true Action = $Settings.SafeAttachmentAction QuarantineTag = $Settings.QuarantineTag @@ -95,16 +95,16 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { if ($CurrentState.Name -eq $PolicyName) { try { - $cmdparams.Add('Identity', $PolicyName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeAttachmentPolicy' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $PolicyName." -sev Info } catch { 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 + $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 $PolicyName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create Safe Attachment policy $PolicyName." -sev Error -LogData $_ @@ -113,27 +113,27 @@ function Invoke-CIPPStandardSafeAttachmentPolicy { } if ($RuleStateIsCorrect -eq $false) { - $cmdparams = @{ + $cmdParams = @{ Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } if ($RuleState.SafeAttachmentPolicy -ne $PolicyName) { - $cmdparams.Add('SafeAttachmentPolicy', $PolicyName) + $cmdParams.Add('SafeAttachmentPolicy', $PolicyName) } if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeAttachmentRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Safe Attachment rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeAttachmentRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { 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 863a0b6d36aa..199d74e38e1c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeLinksPolicy.ps1 @@ -90,7 +90,7 @@ function Invoke-CIPPStandardSafeLinksPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'SafeLink Policy already correctly configured' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ EnableSafeLinksForEmail = $true EnableSafeLinksForTeams = $true EnableSafeLinksForOffice = $true @@ -106,16 +106,16 @@ function Invoke-CIPPStandardSafeLinksPolicy { if ($CurrentState.Name -eq $Policyname) { try { - $cmdparams.Add('Identity', $PolicyName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeLinksPolicy' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $PolicyName." -sev Info } catch { 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 + $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 $PolicyName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to create SafeLink policy $PolicyName." -sev Error -LogData $_ @@ -124,27 +124,27 @@ function Invoke-CIPPStandardSafeLinksPolicy { } if ($RuleStateIsCorrect -eq $false) { - $cmdparams = @{ + $cmdParams = @{ Priority = 0 RecipientDomainIs = $AcceptedDomains.Name } if ($RuleState.SafeLinksPolicy -ne $PolicyName) { - $cmdparams.Add('SafeLinksPolicy', $PolicyName) + $cmdParams.Add('SafeLinksPolicy', $PolicyName) } if ($RuleState.Name -eq $RuleName) { try { - $cmdparams.Add('Identity', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SafeLinksRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update SafeLink rule $RuleName." -sev Error -LogData $_ } } else { try { - $cmdparams.Add('Name', $RuleName) - New-ExoRequest -tenantid $Tenant -cmdlet 'New-SafeLinksRule' -cmdparams $cmdparams -UseSystemMailbox $true + $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 $RuleName." -sev Info } catch { 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 09a46d518211..c21bf3472820 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpamFilterPolicy.ps1 @@ -128,7 +128,7 @@ function Invoke-CIPPStandardSpamFilterPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -Tenant $Tenant -message 'Spam Filter Policy already correctly configured' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ SpamAction = $SpamAction SpamQuarantineTag = $SpamQuarantineTag HighConfidenceSpamAction = $HighConfidenceSpamAction diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 index f57beaad5671..148144a0da29 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardStaleEntraDevices.ps1 @@ -47,7 +47,7 @@ function Invoke-CIPPStandardStaleEntraDevices { # Properties to look at: # approximateLastSignInDateTime: For knowing when the device last signed in # enrollmentProfileName and operatingSystem: For knowing if it's an AutoPilot device - # managementType or isManaged: For knowing if it's an Intune managed device. If it is, should be removed from Intune also. Stale intune standard could prossibly be used for this. + # managementType or isManaged: For knowing if it's an Intune managed device. If it is, should be removed from Intune also. Stale intune standard could possibly be used for this. # profileType: For knowing if it's only registered or also managed # accountEnabled: For knowing if the device is disabled or not diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 index bb4e98c46ba3..7e33ceca0f9c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsEmailIntegration.ps1 @@ -42,13 +42,13 @@ Function Invoke-CIPPStandardTeamsEmailIntegration { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Email Integration settings already set.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ Identity = 'Global' AllowEmailIntoChannel = $Settings.AllowEmailIntoChannel } try { - New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsClientConfiguration' -CmdParams $cmdparams + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsClientConfiguration' -CmdParams $cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Teams Email Integration settings' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalAccessPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalAccessPolicy.ps1 index 544f7ca8e921..6fccb1a51fa1 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalAccessPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalAccessPolicy.ps1 @@ -47,7 +47,7 @@ function Invoke-CIPPStandardTeamsExternalAccessPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'External Access Policy already set.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ Identity = 'Global' EnableFederationAccess = $Settings.EnableFederationAccess EnablePublicCloudAccess = $Settings.EnablePublicCloudAccess @@ -55,7 +55,7 @@ function Invoke-CIPPStandardTeamsExternalAccessPolicy { } try { - New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsExternalAccessPolicy' -CmdParams $cmdparams + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsExternalAccessPolicy' -CmdParams $cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated External Access Policy' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 index 5967daa8a443..0923d4e6206b 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsExternalFileSharing.ps1 @@ -54,7 +54,7 @@ function Invoke-CIPPStandardTeamsExternalFileSharing { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams External File Sharing already set.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ AllowGoogleDrive = $Settings.AllowGoogleDrive AllowShareFile = $Settings.AllowShareFile AllowBox = $Settings.AllowBox @@ -63,7 +63,7 @@ function Invoke-CIPPStandardTeamsExternalFileSharing { } try { - New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsClientConfiguration' -CmdParams $cmdparams + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsClientConfiguration' -CmdParams $cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Teams External File Sharing' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsFederationConfiguration.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsFederationConfiguration.ps1 index 252758450c57..e339a02fd911 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsFederationConfiguration.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsFederationConfiguration.ps1 @@ -96,7 +96,7 @@ function Invoke-CIPPStandardTeamsFederationConfiguration { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Federation Configuration already set.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ Identity = 'Global' AllowTeamsConsumer = $Settings.AllowTeamsConsumer AllowPublicUsers = $Settings.AllowPublicUsers @@ -105,13 +105,13 @@ function Invoke-CIPPStandardTeamsFederationConfiguration { } if (!$AllowedDomainsAsAList) { - $cmdparams.AllowedDomains = $AllowedDomains + $cmdParams.AllowedDomains = $AllowedDomains } else { - $cmdparams.AllowedDomainsAsAList = $AllowedDomainsAsAList + $cmdParams.AllowedDomainsAsAList = $AllowedDomainsAsAList } try { - New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTenantFederationConfiguration' -CmdParams $cmdparams + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTenantFederationConfiguration' -CmdParams $cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Federation Configuration Policy' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMessagingPolicy.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMessagingPolicy.ps1 index 501dbaba13a0..6de85ba0ad64 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMessagingPolicy.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTeamsMessagingPolicy.ps1 @@ -65,7 +65,7 @@ Function Invoke-CIPPStandardTeamsMessagingPolicy { if ($StateIsCorrect -eq $true) { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Global Teams Messaging policy already configured.' -sev Info } else { - $cmdparams = @{ + $cmdParams = @{ Identity = 'Global' AllowOwnerDeleteMessage = $Settings.AllowOwnerDeleteMessage AllowUserDeleteMessage = $Settings.AllowUserDeleteMessage @@ -79,7 +79,7 @@ Function Invoke-CIPPStandardTeamsMessagingPolicy { } try { - New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsMessagingPolicy' -CmdParams $cmdparams + New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsMessagingPolicy' -CmdParams $cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated global Teams messaging policy' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 index 82c2763fd5b2..1289d1682296 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTransportRuleTemplate.ps1 @@ -51,10 +51,10 @@ function Invoke-CIPPStandardTransportRuleTemplate { Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully created transport rule for $tenant" -sev 'Info' } - Write-LogMessage -API $APINAME -tenant $Tenant -message "Created transport rule for $($tenantfilter)" -sev 'Debug' + Write-LogMessage -API $APINAME -tenant $Tenant -message "Created transport rule for $($tenantFilter)" -sev 'Debug' } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not create transport rule for $($tenantfilter): $ErrorMessage" -sev 'Error' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not create transport rule for $($tenantFilter): $ErrorMessage" -sev 'Error' } } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserPreferredLanguage.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserPreferredLanguage.ps1 index 0907d6c5f485..0bbc6e4372b7 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserPreferredLanguage.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserPreferredLanguage.ps1 @@ -37,7 +37,7 @@ function Invoke-CIPPStandardUserPreferredLanguage { if (($IncorrectUsers | Measure-Object).Count -gt 0) { try { foreach ($user in $IncorrectUsers) { - $cmdparams = @{ + $cmdParams = @{ tenantid = $Tenant uri = "https://graph.microsoft.com/beta/users/$($user.userPrincipalName)" AsApp = $true @@ -47,7 +47,7 @@ function Invoke-CIPPStandardUserPreferredLanguage { } | ConvertTo-Json ContentType = 'application/json; charset=utf-8' } - $null = New-GraphPOSTRequest @cmdparams + $null = New-GraphPOSTRequest @cmdParams Write-LogMessage -API 'Standards' -tenant $Tenant -message "Preferred language for $($user.userPrincipalName) has been set to $preferredLanguage" -sev Info } } catch { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 index 09ecea1a9acd..97534b7ac800 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardcalDefault.ps1 @@ -33,12 +33,12 @@ function Invoke-CIPPStandardcalDefault { param($Tenant, $Settings, $QueueItem) ##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'calDefault' - # Get permissionlevel value using null-coalescing operator + # Get permissionLevel value using null-coalescing operator $permissionLevel = $Settings.permissionLevel.value ?? $Settings.permissionLevel # Input validation if ([string]::IsNullOrWhiteSpace($permissionLevel) -or $permissionLevel -eq 'Select a value') { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'calDefault: Invalid permissionlevel parameter set' -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message 'calDefault: Invalid permissionLevel parameter set' -sev Error Return } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneBrandingProfile.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneBrandingProfile.ps1 index ce778dcefd70..b7aaa6277e06 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneBrandingProfile.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneBrandingProfile.ps1 @@ -69,7 +69,7 @@ function Invoke-CIPPStandardintuneBrandingProfile { if ($Settings.onlineSupportSiteUrl) { $Body.onlineSupportSiteUrl = $Settings.onlineSupportSiteUrl } if ($Settings.privacyUrl) { $Body.privacyUrl = $Settings.privacyUrl } - $cmdparams = @{ + $cmdParams = @{ tenantid = $tenant uri = 'https://graph.microsoft.com/beta/deviceManagement/intuneBrandingProfiles/c3a59481-1bf2-46ce-94b3-66eec07a8d60' AsApp = $true @@ -79,7 +79,7 @@ function Invoke-CIPPStandardintuneBrandingProfile { } try { - New-GraphPostRequest @cmdparams + New-GraphPostRequest @cmdParams Write-LogMessage -API 'Standards' -tenant $tenant -message 'Successfully updated Intune Branding Profile' -sev Info } catch { $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 index fa622a54961d..cbe8ef576aa1 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 @@ -41,7 +41,7 @@ function Invoke-CIPPStandardintuneDeviceReg { } else { try { $PreviousSetting.userDeviceQuota = $Settings.max - $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting -Depth 5 + $NewBody = ConvertTo-Json -Compress -InputObject $PreviousSetting -Depth 5 $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -Type PUT -Body $NewBody -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $tenant -message "Set user device quota to $($Settings.max)" -sev Info } catch { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 index 302718c98931..e6a7f929a4c8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 @@ -38,7 +38,7 @@ function Invoke-CIPPStandardintuneRequireMFA { try { $NewSetting = $PreviousSetting $NewSetting.multiFactorAuthConfiguration = 'required' - $Newbody = ConvertTo-Json -Compress -InputObject $NewSetting -Depth 10 + $NewBody = ConvertTo-Json -Compress -InputObject $NewSetting -Depth 10 New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -Type PUT -Body $NewBody -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $tenant -message 'Set required to use MFA when joining/registering Entra Devices' -sev Info } catch { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 index 54ba250fe97a..dde78c661881 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 @@ -36,7 +36,7 @@ function Invoke-CIPPStandardlaps { If ($Settings.remediate -eq $true) { try { $PreviousSetting.localAdminPassword.isEnabled = $true - $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting -Depth 10 + $NewBody = ConvertTo-Json -Compress -InputObject $PreviousSetting -Depth 10 New-GraphPostRequest -tenantid $Tenant -Uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -Type PUT -Body $NewBody -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $Tenant -message 'LAPS has been enabled.' -sev Info } catch { From 2765cc0d9cc60932bbbaae6955f81ab490088134 Mon Sep 17 00:00:00 2001 From: Esco Date: Sat, 12 Apr 2025 17:03:47 +0200 Subject: [PATCH 108/123] chore: update standards.json from frontend --- Config/standards.json | 84 +++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/Config/standards.json b/Config/standards.json index c4d741e08e7b..92ef2e2806f5 100644 --- a/Config/standards.json +++ b/Config/standards.json @@ -217,7 +217,7 @@ "name": "standards.DisableBasicAuthSMTP", "cat": "Global Standards", "tag": [], - "helpText": "Disables SMTP AUTH for the organization and all users. This is the default for new tenants. ", + "helpText": "Disables SMTP AUTH for the organization and all users. This is the default for new tenants.", "docsDescription": "Disables SMTP basic authentication for the tenant and all users with it explicitly enabled.", "addedComponent": [], "label": "Disable SMTP Basic Authentication", @@ -546,7 +546,7 @@ "name": "standards.DisableTenantCreation", "cat": "Entra (AAD) Standards", "tag": ["CIS"], - "helpText": "Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles. ", + "helpText": "Restricts creation of M365 tenants to the Global Administrator or Tenant Creator roles.", "docsDescription": "Users by default are allowed to create M365 tenants. This disables that so only admins can create new M365 tenants.", "addedComponent": [], "label": "Disable M365 Tenant creation by users", @@ -772,7 +772,7 @@ "impact": "Medium Impact", "impactColour": "warning", "addedDate": "2024-11-12", - "powershellEquivalent": "", + "powershellEquivalent": "Graph API", "recommendedBy": [] }, { @@ -785,7 +785,7 @@ { "type": "number", "name": "standards.StaleEntraDevices.deviceAgeThreshold", - "label": "Days before stale(Dont set below 30)" + "label": "Days before stale(Do not set below 30)" } ], "disabledFeatures": { @@ -1687,11 +1687,46 @@ "powershellEquivalent": "New-ProtectionAlert and Set-ProtectionAlert", "recommendedBy": [] }, + { + "name": "standards.SharePointMassDeletionAlert", + "cat": "Defender Standards", + "tag": [], + "helpText": "Sets a e-mail address to alert when a User deletes more than 20 SharePoint files within 60 minutes. NB: Requires a Office 365 E5 subscription, Office 365 E3 with Threat Intelligence or Office 365 EquivioAnalytics add-on.", + "docsDescription": "Sets a e-mail address to alert when a User deletes more than 20 SharePoint files within 60 minutes. This is useful for monitoring and ensuring that the correct SharePoint files are deleted. NB: Requires a Office 365 E5 subscription, Office 365 E3 with Threat Intelligence or Office 365 EquivioAnalytics add-on.", + "addedComponent": [ + { + "type": "number", + "name": "standards.SharePointMassDeletionAlert.Threshold", + "label": "Max files to delete within the time frame", + "defaultValue": 20 + }, + { + "type": "number", + "name": "standards.SharePointMassDeletionAlert.TimeWindow", + "label": "Time frame in minutes", + "defaultValue": 60 + }, + { + "type": "autoComplete", + "multiple": true, + "creatable": true, + "required": true, + "name": "standards.SharePointMassDeletionAlert.NotifyUser", + "label": "E-mail to receive the alert" + } + ], + "label": "SharePoint Mass Deletion Alert", + "impact": "Low Impact", + "impactColour": "info", + "addedDate": "2025-04-07", + "powershellEquivalent": "New-ProtectionAlert and Set-ProtectionAlert", + "recommendedBy": [] + }, { "name": "standards.SafeLinksPolicy", "cat": "Defender Standards", "tag": ["CIS", "mdo_safelinksforemail", "mdo_safelinksforOfficeApps"], - "helpText": "This creates a safelink policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders", + "helpText": "This creates a Safe Links policy that automatically scans, tracks, and and enables safe links for Email, Office, and Teams for both external and internal senders", "addedComponent": [ { "type": "switch", @@ -1717,7 +1752,7 @@ "label": "Do not rewrite the following URLs in email" } ], - "label": "Default SafeLinks Policy", + "label": "Default Safe Links Policy", "impact": "Low Impact", "impactColour": "info", "addedDate": "2024-03-25", @@ -1737,7 +1772,7 @@ "mdo_antiphishingpolicies", "mdo_phishthresholdlevel" ], - "helpText": "This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mailtips.", + "helpText": "This creates a Anti-Phishing policy that automatically enables Mailbox Intelligence and spoofing, optional switches for Mail tips.", "addedComponent": [ { "type": "number", @@ -1930,18 +1965,13 @@ "impact": "Low Impact", "impactColour": "info", "addedDate": "2024-03-25", - "powershellEquivalent": "Set-AntiphishPolicy or New-AntiphishPolicy", + "powershellEquivalent": "Set-AntiPhishPolicy or New-AntiPhishPolicy", "recommendedBy": ["CIS"] }, { "name": "standards.SafeAttachmentPolicy", "cat": "Defender Standards", - "tag": [ - "CIS", - "mdo_safedocuments", - "mdo_commonattachmentsfilter", - "mdo_safeattachmentpolicy" - ], + "tag": ["CIS", "mdo_safedocuments", "mdo_commonattachmentsfilter", "mdo_safeattachmentpolicy"], "helpText": "This creates a Safe Attachment policy", "addedComponent": [ { @@ -2576,7 +2606,7 @@ "impact": "Low Impact", "impactColour": "info", "addedDate": "2024-11-12", - "powershellEquivalent": "", + "powershellEquivalent": "Graph API", "recommendedBy": [] }, { @@ -2709,7 +2739,7 @@ "cat": "Intune Standards", "tag": [], "helpText": "Requires MFA for all users to register devices with Intune. This is useful when not using Conditional Access.", - "label": "Require Multifactor Authentication to register or join devices with Microsoft Entra", + "label": "Require Multi-factor Authentication to register or join devices with Microsoft Entra", "impact": "Medium Impact", "impactColour": "warning", "addedDate": "2023-10-23", @@ -2817,7 +2847,7 @@ "impactColour": "info", "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -EnableAzureADB2BIntegration $true", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS"] }, { "name": "standards.SPDisallowInfectedFiles", @@ -2875,7 +2905,7 @@ "impactColour": "warning", "addedDate": "2024-07-09", "powershellEquivalent": "Set-SPOTenant -ExternalUserExpireInDays 30 -ExternalUserExpirationRequired $True", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS"] }, { "name": "standards.SPEmailAttestation", @@ -3017,7 +3047,7 @@ "helpText": "Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access", "docsDescription": "Disables the ability for external users to share files they don't own. Sharing links can only be made for People with existing access. This is a tenant wide setting and overrules any settings set on the site level", "addedComponent": [], - "label": "Disable Resharing by External Users", + "label": "Disable Re-sharing by External Users", "impact": "High Impact", "impactColour": "danger", "addedDate": "2022-06-15", @@ -3193,7 +3223,7 @@ "impactColour": "info", "addedDate": "2024-11-12", "powershellEquivalent": "Set-CsTeamsMeetingPolicy -AllowAnonymousUsersToJoinMeeting $false -AllowAnonymousUsersToStartMeeting $false -AutoAdmittedUsers EveryoneInCompanyExcludingGuests -AllowPSTNUsersToBypassLobby $false -MeetingChatEnabledType EnabledExceptAnonymous -DesignatedPresenterRoleMode $DesignatedPresenterRoleMode -AllowExternalParticipantGiveRequestControl $false", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS"] }, { "name": "standards.TeamsEmailIntegration", @@ -3213,7 +3243,7 @@ "impactColour": "info", "addedDate": "2024-07-30", "powershellEquivalent": "Set-CsTeamsClientConfiguration -AllowEmailIntoChannel $false", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS"] }, { "name": "standards.TeamsExternalFileSharing", @@ -3252,7 +3282,7 @@ "impactColour": "info", "addedDate": "2024-07-28", "powershellEquivalent": "Set-CsTeamsClientConfiguration -AllowGoogleDrive $false -AllowShareFile $false -AllowBox $false -AllowDropBox $false -AllowEgnyte $false", - "recommendedBy": ["CIS 3.0"] + "recommendedBy": ["CIS"] }, { "name": "standards.TeamsEnrollUser", @@ -3667,10 +3697,7 @@ { "label": "Do not assign", "value": "On" }, { "label": "Assign to all users", "value": "allLicensedUsers" }, { "label": "Assign to all devices", "value": "AllDevices" }, - { - "label": "Assign to all users and devices", - "value": "AllDevicesAndUsers" - }, + { "label": "Assign to all users and devices", "value": "AllDevicesAndUsers" }, { "label": "Assign to Custom Group", "value": "customGroup" } ] }, @@ -3749,10 +3776,7 @@ { "value": "donotchange", "label": "Do not change state" }, { "value": "Enabled", "label": "Set to enabled" }, { "value": "Disabled", "label": "Set to disabled" }, - { - "value": "enabledForReportingButNotEnforced", - "label": "Set to report only" - } + { "value": "enabledForReportingButNotEnforced", "label": "Set to report only" } ] } ] From aa1f2d6873b703e1036595023891d099e7fb79ca Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 15:20:39 -0400 Subject: [PATCH 109/123] audit log tweaks --- .../Webhooks/Test-CIPPAuditLogRules.ps1 | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 index b1be7de666a9..6824b08058ea 100644 --- a/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 +++ b/Modules/CIPPCore/Public/Webhooks/Test-CIPPAuditLogRules.ps1 @@ -41,6 +41,9 @@ function Test-CIPPAuditLogRules { } } + Write-Warning '## Audit Log Configuration ##' + Write-Information ($Configuration | ConvertTo-Json -Depth 10) + try { $LogCount = $Rows.count $RunGuid = (New-Guid).Guid @@ -186,39 +189,45 @@ function Test-CIPPAuditLogRules { #write-warning "Processed Data: $(($ProcessedData | Measure-Object).Count) - This should be higher than 0 in many cases, because the where object has not run yet." #write-warning "Creating filters - $(($ProcessedData.operation | Sort-Object -Unique) -join ',') - $($TenantFilter)" - $Where = $Configuration | ForEach-Object { - if ($TenantFilter -in $_.Excluded.value) { - return - } - $conditions = $_.Conditions | ConvertFrom-Json | Where-Object { $_.Input.value -ne '' } - $actions = $_.Actions - $conditionStrings = [System.Collections.Generic.List[string]]::new() - $CIPPClause = [System.Collections.Generic.List[string]]::new() - $AddedLocationCondition = $false - foreach ($condition in $conditions) { - if ($condition.Property.label -eq 'CIPPGeoLocation' -and !$AddedLocationCondition) { - $conditionsString.Add("`$_.HasLocationData -eq `$true") - $CIPPClause.Add('HasLocationData is true') - $AddedLocationCondition = $true + try { + $Where = foreach ($Config in $Configuration) { + if ($TenantFilter -in $Config.Excluded.value) { + continue } - $value = if ($condition.Input.value -is [array]) { - $arrayAsString = $condition.Input.value | ForEach-Object { - "'$_'" + $conditions = $Config.Conditions | ConvertFrom-Json | Where-Object { $Config.Input.value -ne '' } + $actions = $Config.Actions + $conditionStrings = [System.Collections.Generic.List[string]]::new() + $CIPPClause = [System.Collections.Generic.List[string]]::new() + $AddedLocationCondition = $false + foreach ($condition in $conditions) { + if ($condition.Property.label -eq 'CIPPGeoLocation' -and !$AddedLocationCondition) { + $conditionStrings.Add("`$_.HasLocationData -eq `$true") + $CIPPClause.Add('HasLocationData is true') + $AddedLocationCondition = $true } - "@($($arrayAsString -join ', '))" - } else { "'$($condition.Input.value)'" } + $value = if ($condition.Input.value -is [array]) { + $arrayAsString = $condition.Input.value | ForEach-Object { + "'$_'" + } + "@($($arrayAsString -join ', '))" + } else { "'$($condition.Input.value)'" } - $conditionStrings.Add("`$(`$_.$($condition.Property.label)) -$($condition.Operator.value) $value") - $CIPPClause.Add("$($condition.Property.label) is $($condition.Operator.label) $value") - } - $finalCondition = $conditionStrings -join ' -AND ' + $conditionStrings.Add("`$(`$_.$($condition.Property.label)) -$($condition.Operator.value) $value") + $CIPPClause.Add("$($condition.Property.label) is $($condition.Operator.label) $value") + } + $finalCondition = $conditionStrings -join ' -AND ' - [PSCustomObject]@{ - clause = $finalCondition - expectedAction = $actions - CIPPClause = $CIPPClause + [PSCustomObject]@{ + clause = $finalCondition + expectedAction = $actions + CIPPClause = $CIPPClause + } } - + } catch { + Write-Warning "Error creating where clause: $($_.Exception.Message)" + Write-Information $_.InvocationInfo.PositionMessage + #Write-LogMessage -API 'Webhooks' -message 'Error creating where clause' -LogData (Get-CippException -Exception $_) -sev Error -tenant $TenantFilter + throw $_ } $MatchedRules = [System.Collections.Generic.List[string]]::new() From fc4c8b5b8552b598f8ab308e486e7168867da251 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 16:44:19 -0400 Subject: [PATCH 110/123] add run now support --- .../CIPPCore/Public/Add-CIPPScheduledTask.ps1 | 183 +++++++++++------- .../Scheduler/Invoke-AddScheduledItem.ps1 | 26 ++- 2 files changed, 129 insertions(+), 80 deletions(-) diff --git a/Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1 b/Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1 index 70388e578446..4a8548e0a741 100644 --- a/Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1 +++ b/Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1 @@ -1,96 +1,129 @@ function Add-CIPPScheduledTask { - [CmdletBinding()] + [CmdletBinding(DefaultParameterSetName = 'Default')] param( + [Parameter(Mandatory = $true, ParameterSetName = 'Default')] [pscustomobject]$Task, + + [Parameter(Mandatory = $false, ParameterSetName = 'Default')] [bool]$Hidden, + + [Parameter(Mandatory = $false, ParameterSetName = 'Default')] $DisallowDuplicateName = $false, + + [Parameter(Mandatory = $false, ParameterSetName = 'Default')] [string]$SyncType = $null, + + [Parameter(Mandatory = $false, ParameterSetName = 'RunNow')] + [switch]$RunNow, + + [Parameter(Mandatory = $true, ParameterSetName = 'RunNow')] + [string]$RowKey, + + [Parameter(Mandatory = $false, ParameterSetName = 'Default')] + [Parameter(Mandatory = $false, ParameterSetName = 'RunNow')] $Headers ) $Table = Get-CIPPTable -TableName 'ScheduledTasks' - if ($DisallowDuplicateName) { - $Filter = "PartitionKey eq 'ScheduledTask' and Name eq '$($Task.Name)'" - $ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) - if ($ExistingTask) { - return "Task with name $($Task.Name) already exists" + + if ($RunNow.IsPresent -and $RowKey) { + try { + $Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($RowKey)'" + $ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) + $ExistingTask.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds + $ExistingTask.TaskState = 'Planned' + Add-CIPPAzDataTableEntity @Table -Entity $ExistingTask -Force + Write-LogMessage -headers $Headers -API 'RunNow' -message "Task $($ExistingTask.Name) scheduled to run now" -Sev 'Info' -Tenant $ExistingTask.Tenant + return "Task $($ExistingTask.Name) scheduled to run now" + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -headers $Headers -API 'RunNow' -message "Could not run task: $ErrorMessage" -Sev 'Error' + return "Could not run task: $ErrorMessage" + } + } else { + if ($DisallowDuplicateName) { + $Filter = "PartitionKey eq 'ScheduledTask' and Name eq '$($Task.Name)'" + $ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) + if ($ExistingTask) { + return "Task with name $($Task.Name) already exists" + } } - } - $propertiesToCheck = @('Webhook', 'Email', 'PSA') - $PostExecutionObject = ($propertiesToCheck | Where-Object { $task.PostExecution.$_ -eq $true }) - $PostExecution = $PostExecutionObject ? ($PostExecutionObject -join ',') : ($Task.PostExecution.value -join ',') - $Parameters = [System.Collections.Hashtable]@{} - foreach ($Key in $task.Parameters.PSObject.Properties.Name) { - $Param = $task.Parameters.$Key + $propertiesToCheck = @('Webhook', 'Email', 'PSA') + $PostExecutionObject = ($propertiesToCheck | Where-Object { $task.PostExecution.$_ -eq $true }) + $PostExecution = $PostExecutionObject ? ($PostExecutionObject -join ',') : ($Task.PostExecution.value -join ',') + $Parameters = [System.Collections.Hashtable]@{} + foreach ($Key in $task.Parameters.PSObject.Properties.Name) { + $Param = $task.Parameters.$Key - if ($null -eq $Param -or $Param -eq '' -or ($Param | Measure-Object).Count -eq 0) { - continue - } - if ($Param -is [System.Collections.IDictionary] -or $Param.Key) { - $ht = @{} - foreach ($p in $Param.GetEnumerator()) { - $ht[$p.Key] = $p.Value + if ($null -eq $Param -or $Param -eq '' -or ($Param | Measure-Object).Count -eq 0) { + continue + } + if ($Param -is [System.Collections.IDictionary] -or $Param.Key) { + $ht = @{} + foreach ($p in $Param.GetEnumerator()) { + $ht[$p.Key] = $p.Value + } + $Parameters[$Key] = [PSCustomObject]$ht + } else { + $Parameters[$Key] = $Param } - $Parameters[$Key] = [PSCustomObject]$ht - } else { - $Parameters[$Key] = $Param } - } - if ($Headers) { - $Parameters.Headers = $Headers | Select-Object -Property 'x-forwarded-for', 'x-ms-client-principal', 'x-ms-client-principal-idp', 'x-ms-client-principal-name' - } + if ($Headers) { + $Parameters.Headers = $Headers | Select-Object -Property 'x-forwarded-for', 'x-ms-client-principal', 'x-ms-client-principal-idp', 'x-ms-client-principal-name' + } - $Parameters = ($Parameters | ConvertTo-Json -Depth 10 -Compress) - $AdditionalProperties = [System.Collections.Hashtable]@{} - foreach ($Prop in $task.AdditionalProperties) { - $AdditionalProperties[$Prop.Key] = $Prop.Value - } - $AdditionalProperties = ([PSCustomObject]$AdditionalProperties | ConvertTo-Json -Compress) - if ($Parameters -eq 'null') { $Parameters = '' } - if (!$Task.RowKey) { - $RowKey = (New-Guid).Guid - } else { - $RowKey = $Task.RowKey - } + $Parameters = ($Parameters | ConvertTo-Json -Depth 10 -Compress) + $AdditionalProperties = [System.Collections.Hashtable]@{} + foreach ($Prop in $task.AdditionalProperties) { + $AdditionalProperties[$Prop.Key] = $Prop.Value + } + $AdditionalProperties = ([PSCustomObject]$AdditionalProperties | ConvertTo-Json -Compress) + if ($Parameters -eq 'null') { $Parameters = '' } + if (!$Task.RowKey) { + $RowKey = (New-Guid).Guid + } else { + $RowKey = $Task.RowKey + } - $Recurrence = if ([string]::IsNullOrEmpty($task.Recurrence.value)) { - $task.Recurrence - } else { - $task.Recurrence.value - } + $Recurrence = if ([string]::IsNullOrEmpty($task.Recurrence.value)) { + $task.Recurrence + } else { + $task.Recurrence.value + } - if ([int64]$task.ScheduledTime -eq 0 -or [string]::IsNullOrEmpty($task.ScheduledTime)) { - $task.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds - } - $excludedTenants = if ($task.excludedTenants.value) { - $task.excludedTenants.value -join ',' - } - $entity = @{ - PartitionKey = [string]'ScheduledTask' - TaskState = [string]'Planned' - RowKey = [string]$RowKey - Tenant = $task.TenantFilter.value ? "$($task.TenantFilter.value)" : "$($task.TenantFilter)" - excludedTenants = [string]$excludedTenants - Name = [string]$task.Name - Command = [string]$task.Command.value - Parameters = [string]$Parameters - ScheduledTime = [string]$task.ScheduledTime - Recurrence = [string]$Recurrence - PostExecution = [string]$PostExecution - AdditionalProperties = [string]$AdditionalProperties - Hidden = [bool]$Hidden - Results = 'Planned' - } - if ($SyncType) { - $entity.SyncType = $SyncType - } - try { - Add-CIPPAzDataTableEntity @Table -Entity $entity -Force - } catch { - $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message - return "Could not add task: $ErrorMessage" + if ([int64]$task.ScheduledTime -eq 0 -or [string]::IsNullOrEmpty($task.ScheduledTime)) { + $task.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds + } + $excludedTenants = if ($task.excludedTenants.value) { + $task.excludedTenants.value -join ',' + } + $entity = @{ + PartitionKey = [string]'ScheduledTask' + TaskState = [string]'Planned' + RowKey = [string]$RowKey + Tenant = $task.TenantFilter.value ? "$($task.TenantFilter.value)" : "$($task.TenantFilter)" + excludedTenants = [string]$excludedTenants + Name = [string]$task.Name + Command = [string]$task.Command.value + Parameters = [string]$Parameters + ScheduledTime = [string]$task.ScheduledTime + Recurrence = [string]$Recurrence + PostExecution = [string]$PostExecution + AdditionalProperties = [string]$AdditionalProperties + Hidden = [bool]$Hidden + Results = 'Planned' + } + if ($SyncType) { + $entity.SyncType = $SyncType + } + try { + Add-CIPPAzDataTableEntity @Table -Entity $entity -Force + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + return "Could not add task: $ErrorMessage" + } + return "Successfully added task: $($entity.Name)" } - return "Successfully added task: $($entity.Name)" } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 index b013d2668806..1ec5a2d2c70d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1 @@ -1,6 +1,6 @@ using namespace System.Net -Function Invoke-AddScheduledItem { +function Invoke-AddScheduledItem { <# .FUNCTIONALITY Entrypoint @@ -9,17 +9,33 @@ Function Invoke-AddScheduledItem { #> [CmdletBinding()] param($Request, $TriggerMetadata) - if ($null -eq $Request.query.hidden) { + if ($null -eq $Request.Query.hidden) { $hidden = $false } else { $hidden = $true } - $Result = Add-CIPPScheduledTask -Task $Request.body -Headers $Request.Headers -hidden $hidden -DisallowDuplicateName $Request.query.DisallowDuplicateName - Write-LogMessage -headers $Request.Headers -API $APINAME -message $Result -Sev 'Info' + if ($Request.Body.RunNow -eq $true) { + try { + $Table = Get-CIPPTable -TableName 'ScheduledTasks' + $Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($Request.Body.RowKey)'" + $ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter) + if ($ExistingTask) { + $Result = Add-CIPPScheduledTask -RowKey $Request.Body.RowKey -RunNow -Headers $Request.Headers + } else { + $Result = "Task with id $($Request.Body.RowKey) does not exist" + } + } catch { + Write-Warning "Error scheduling task: $($_.Exception.Message)" + Write-Information $_.InvocationInfo.PositionMessage + $Result = "Error scheduling task: $($_.Exception.Message)" + } + } else { + $Result = Add-CIPPScheduledTask -Task $Request.Body -Headers $Request.Headers -hidden $hidden -DisallowDuplicateName $Request.Query.DisallowDuplicateName + Write-LogMessage -headers $Request.Headers -API $APINAME -message $Result -Sev 'Info' + } Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = @{ Results = $Result } }) - } From 225350e26cdbe135066e0609fe4366f5ee3e01be Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 18:21:02 -0400 Subject: [PATCH 111/123] scheduled task details --- .../Push-ExecScheduledCommand.ps1 | 78 +++++++----- .../Invoke-ListScheduledItemDetails.ps1 | 114 ++++++++++++++++++ 2 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 index e969dd680cf2..869774a3b09d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 @@ -82,7 +82,14 @@ function Push-ExecScheduledCommand { } if ($StoredResults.Length -gt 64000 -or $task.Tenant -eq 'AllTenants') { - $StoredResults = @{ Results = 'The results for this query are too long to store in this table, or the query was meant for All Tenants. Please use the options to send the results to another target to be able to view the results. ' } | ConvertTo-Json -Compress + $TaskResultsTable = Get-CippTable -tablename 'ScheduledTaskResults' + $TaskResults = @{ + PartitionKey = $task.RowKey + RowKey = $Tenant + Results = [string](ConvertTo-Json -Compress -Depth 20 $results) + } + $null = Add-AzDataTableEntity @TaskResultsTable -Entity $TaskResults -Force + $StoredResults = @{ Results = 'Completed, click see details for more information' } | ConvertTo-Json -Compress } } catch { $errorMessage = $_.Exception.Message @@ -119,42 +126,47 @@ function Push-ExecScheduledCommand { } Write-Host 'Sent the results to the target. Updating the task state.' - if ($task.Recurrence -eq '0' -or [string]::IsNullOrEmpty($task.Recurrence)) { - Write-Host 'Recurrence empty or 0. Task is not recurring. Setting task state to completed.' - Update-AzDataTableEntity -Force @Table -Entity @{ - PartitionKey = $task.PartitionKey - RowKey = $task.RowKey - Results = "$StoredResults" - TaskState = 'Completed' - } - } else { - #if recurrence is just a number, add it in days. - if ($task.Recurrence -match '^\d+$') { - $task.Recurrence = $task.Recurrence + 'd' - } - $secondsToAdd = switch -Regex ($task.Recurrence) { - '(\d+)m$' { [int64]$matches[1] * 60 } - '(\d+)h$' { [int64]$matches[1] * 3600 } - '(\d+)d$' { [int64]$matches[1] * 86400 } - default { throw "Unsupported recurrence format: $($task.Recurrence)" } - } + try { + if ($task.Recurrence -eq '0' -or [string]::IsNullOrEmpty($task.Recurrence)) { + Write-Host 'Recurrence empty or 0. Task is not recurring. Setting task state to completed.' + Update-AzDataTableEntity -Force @Table -Entity @{ + PartitionKey = $task.PartitionKey + RowKey = $task.RowKey + Results = "$StoredResults" + TaskState = 'Completed' + } + } else { + #if recurrence is just a number, add it in days. + if ($task.Recurrence -match '^\d+$') { + $task.Recurrence = $task.Recurrence + 'd' + } + $secondsToAdd = switch -Regex ($task.Recurrence) { + '(\d+)m$' { [int64]$matches[1] * 60 } + '(\d+)h$' { [int64]$matches[1] * 3600 } + '(\d+)d$' { [int64]$matches[1] * 86400 } + default { 0 } + } - if ($secondsToAdd -gt 0) { - $unixtimeNow = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds - if ([int64]$task.ScheduledTime -lt ($unixtimeNow - $secondsToAdd)) { - $task.ScheduledTime = $unixtimeNow + if ($secondsToAdd -gt 0) { + $unixtimeNow = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds + if ([int64]$task.ScheduledTime -lt ($unixtimeNow - $secondsToAdd)) { + $task.ScheduledTime = $unixtimeNow + } } - } - $nextRunUnixTime = [int64]$task.ScheduledTime + [int64]$secondsToAdd - Write-Host "The job is recurring. It was scheduled for $($task.ScheduledTime). The next runtime should be $nextRunUnixTime" - Update-AzDataTableEntity -Force @Table -Entity @{ - PartitionKey = $task.PartitionKey - RowKey = $task.RowKey - Results = "$StoredResults" - TaskState = 'Planned' - ScheduledTime = "$nextRunUnixTime" + $nextRunUnixTime = [int64]$task.ScheduledTime + [int64]$secondsToAdd + Write-Host "The job is recurring. It was scheduled for $($task.ScheduledTime). The next runtime should be $nextRunUnixTime" + Update-AzDataTableEntity -Force @Table -Entity @{ + PartitionKey = $task.PartitionKey + RowKey = $task.RowKey + Results = "$StoredResults" + TaskState = 'Planned' + ScheduledTime = "$nextRunUnixTime" + } } + } catch { + Write-Warning "Failed to update task state: $($_.Exception.Message)" + Write-Information $_.InvocationInfo.PositionMessage } if ($TaskType -ne 'Alert') { Write-LogMessage -API 'Scheduler_UserTasks' -tenant $Tenant -tenantid $TenantInfo.customerId -message "Successfully executed task: $($task.Name)" -sev Info diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 new file mode 100644 index 000000000000..8e3fb6093972 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 @@ -0,0 +1,114 @@ +using namespace System.Net + +function Invoke-ListScheduledItemDetails { + <# + .FUNCTIONALITY + Entrypoint,AnyTenant + .ROLE + CIPP.Scheduler.Read + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $Request.Params.CIPPEndpoint + $Headers = $Request.Headers + Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + + # Get parameters from the request + $RowKey = $Request.Query.RowKey ?? $Request.Body.RowKey + + # Validate required parameters + if (-not $RowKey) { + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::BadRequest + Body = "Required parameter 'RowKey' is missing" + }) + return + } + + # Retrieve the task information + $TaskTable = Get-CIPPTable -TableName 'ScheduledTasks' + $Task = Get-CIPPAzDataTableEntity @TaskTable -Filter "RowKey eq '$RowKey' and PartitionKey eq 'ScheduledTask'" | Select-Object Name, TaskState, Command, Parameters, Recurrence, ExecutedTime, ScheduledTime, PostExecution, Tenant, Hidden, Results, Timestamp + + if (-not $Task) { + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::NotFound + Body = "Task with RowKey '$RowKey' not found" + }) + return + } + + # Process the task (similar to the way it's done in Invoke-ListScheduledItems) + if ($Task.Parameters) { + $Task.Parameters = $Task.Parameters | ConvertFrom-Json -ErrorAction SilentlyContinue + } else { + $Task | Add-Member -NotePropertyName Parameters -NotePropertyValue @{} + } + + if ($Task.Recurrence -eq 0 -or [string]::IsNullOrEmpty($Task.Recurrence)) { + $Task.Recurrence = 'Once' + } + + try { + $Task.ExecutedTime = [DateTimeOffset]::FromUnixTimeSeconds($Task.ExecutedTime).UtcDateTime + } catch {} + + try { + $Task.ScheduledTime = [DateTimeOffset]::FromUnixTimeSeconds($Task.ScheduledTime).UtcDateTime + } catch {} + + # Get the results if available + $ResultsTable = Get-CIPPTable -TableName 'ScheduledTaskResults' + $ResultsFilter = "PartitionKey eq '$RowKey'" + + $Results = Get-CIPPAzDataTableEntity @ResultsTable -Filter $ResultsFilter + + if (!$Results) { + $ResultData = ($Task.Results | ConvertFrom-Json -ErrorAction SilentlyContinue) ?? $Task.Results + $Results = @( + [PSCustomObject]@{ + RowKey = $Task.Tenant + Results = $ResultData + Timestamp = $Task.Timestamp + } + ) + } + # Process the results if they exist + $ProcessedResults = [System.Collections.Generic.List[object]]::new() + foreach ($Result in $Results) { + try { + if ($Result.Results) { + $ParsedResults = ($Result.Results | ConvertFrom-Json -ErrorAction SilentlyContinue) ?? $Result.Results + if (!$ParsedResults -or 'null' -eq $ParsedResults) { + $Result.Results = @() + } else { + $Result.Results = @($ParsedResults) + } + # Store tenant information with the result + $TenantId = $Result.RowKey + $TenantInfo = Get-Tenants -TenantFilter $TenantId -ErrorAction SilentlyContinue + if ($TenantInfo) { + $Result | Add-Member -NotePropertyName TenantName -NotePropertyValue $TenantInfo.displayName -Force + $Result | Add-Member -NotePropertyName TenantDefaultDomain -NotePropertyValue $TenantInfo.defaultDomainName -Force + $Result | Add-Member -NotePropertyName TenantId -NotePropertyValue $TenantInfo.customerId -Force + } + } + } catch { + Write-LogMessage -API $APIName -message "Error processing results for task $RowKey with tenant $($Result.RowKey): $_" -Sev 'Error' + } + $EndResult = $Result | Select-Object Timestamp, @{n = 'Tenant'; Expression = { $_.RowKey } }, Results + $ProcessedResults.Add($EndResult) + } + + # Combine task and results into one response + $Response = ConvertTo-Json -Depth 100 -InputObject @{ + Task = $Task + Details = $ProcessedResults + } + + # Return the response + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Response + }) +} From 4827d90342b01b091ed5debccf06bb56dbf4a184 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 19:01:11 -0400 Subject: [PATCH 112/123] tweak scheduled task details and removal --- .../Activity Triggers/Push-ExecScheduledCommand.ps1 | 2 +- .../CIPP/Scheduler/Invoke-RemoveScheduledItem.ps1 | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 index 869774a3b09d..bf47a28af856 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1 @@ -89,7 +89,7 @@ function Push-ExecScheduledCommand { Results = [string](ConvertTo-Json -Compress -Depth 20 $results) } $null = Add-AzDataTableEntity @TaskResultsTable -Entity $TaskResults -Force - $StoredResults = @{ Results = 'Completed, click see details for more information' } | ConvertTo-Json -Compress + $StoredResults = @{ Results = 'Completed, details are available in the More Info pane' } | ConvertTo-Json -Compress } } catch { $errorMessage = $_.Exception.Message 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 d6e06bfd11b4..11a0a23f8716 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 @@ -1,6 +1,6 @@ using namespace System.Net -Function Invoke-RemoveScheduledItem { +function Invoke-RemoveScheduledItem { <# .FUNCTIONALITY Entrypoint,AnyTenant @@ -13,13 +13,21 @@ Function Invoke-RemoveScheduledItem { $APIName = 'RemoveScheduledItem' $User = $Request.Headers + $RowKey = $Request.Query.id ? $Request.Query.id : $Request.Body.id $task = @{ - RowKey = $Request.Query.id ? $Request.Query.id : $Request.Body.id + RowKey = $RowKey PartitionKey = 'ScheduledTask' } $Table = Get-CIPPTable -TableName 'ScheduledTasks' Remove-AzDataTableEntity -Force @Table -Entity $task + $DetailTable = Get-CIPPTable -TableName 'ScheduledTaskDetails' + $Details = Get-CIPPAzDataTableEntity @DetailTable -Filter "PartitionKey eq '$($RowKey)'" -Property RowKey, PartitionKey, ETag + + if ($Details) { + Remove-AzDataTableEntity -Force @DetailTable -Entity $Details + } + Write-LogMessage -Headers $User -API $APINAME -message "Task removed: $($task.RowKey)" -Sev 'Info' Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ From 991a7b37b7742a56c1c90d0534ef65ccd31bdf88 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 20:51:54 -0400 Subject: [PATCH 113/123] Fix API auth for pax --- .../Public/Sherweb/Test-SherwebMigrationAccounts.ps1 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 index ef52c8ad4c08..5a44c7b5cf4d 100644 --- a/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 +++ b/Modules/CippExtensions/Public/Sherweb/Test-SherwebMigrationAccounts.ps1 @@ -5,9 +5,10 @@ function Test-SherwebMigrationAccounts { ) $Table = Get-CIPPTable -TableName Extensionsconfig - $Config = ((Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json).Sherweb + $ExtensionConfig = (Get-CIPPAzDataTableEntity @Table).config | ConvertFrom-Json + $Config = $ExtensionConfig.Sherweb #First get a list of all subscribed skus for this tenant, that are in the transfer window. - $Licenses = (Get-CIPPLicenseOverview -TenantFilter $TenantFilter) | ForEach-Object { $_.terminfo = ($_.terminfo | ConvertFrom-Json -ErrorAction SilentlyContinue) ; $_ } | Where-Object { $_.terminfo -ne $null -and $_.terminfo.TransferWindow -LE 7 } + $Licenses = (Get-CIPPLicenseOverview -TenantFilter $TenantFilter) | ForEach-Object { $_.terminfo = ($_.terminfo | ConvertFrom-Json -ErrorAction SilentlyContinue) ; $_ } | Where-Object { $_.terminfo -ne $null -and $_.terminfo.TransferWindow -le 7 } #now check if this exact count of licenses is available at Sherweb, if not, we need to migrate them. $SherwebLicenses = Get-SherwebCurrentSubscription -TenantFilter $TenantFilter @@ -61,9 +62,12 @@ function Test-SherwebMigrationAccounts { '*Cancel' { try { $tenantid = (Get-Tenants -TenantFilter $TenantFilter).customerId + $Pax8Config = $ExtensionConfig.Pax8 + $Pax8ClientId = $Pax8Config.clientId + $Pax8ClientSecret = Get-ExtensionAPIKey -Extension 'Pax8' $paxBody = @{ - client_id = $Config.paxclientId - client_secret = $Config.paxclientSecret + client_id = $Pax8ClientId + client_secret = $Pax8ClientSecret audience = 'https://api.pax8.com' grant_type = 'client_credentials' } From 02fe38f5396f0d26fc7f1d8af5b3fcae6a160211 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 20:52:23 -0400 Subject: [PATCH 114/123] fix template sha comparison --- Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 index 953baa351a10..bf1e817537f8 100644 --- a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 @@ -13,6 +13,13 @@ function New-CIPPTemplateRun { $data } | Sort-Object -Property displayName + function Get-SanitizedFilename { + param ( + [string]$filename + ) + $filename = $filename -replace '\s', '_' -replace '[^\w\d_]', '' + return $filename + } $Tasks = foreach ($key in $TemplateSettings.Keys) { if ($TemplateSettings[$key] -eq $true) { @@ -30,7 +37,7 @@ function New-CIPPTemplateRun { } foreach ($File in $Files) { if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue } - $ExistingTemplate = $ExistingTemplates | Where-Object { $_.displayName -eq $File.name } | Select-Object -First 1 + $ExistingTemplate = $ExistingTemplates | Where-Object { ($_.displayName -and (Get-SanitizedFilename -filename $_.displayName) -eq $File.name) -or ($_.templateName -and (Get-SanitizedFilename -filename $_.templateName) -eq $_.templateName ) } | Select-Object -First 1 $Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json if ($ExistingTemplate) { $UpdateNeeded = $false @@ -40,6 +47,8 @@ function New-CIPPTemplateRun { if ($UpdateNeeded) { Write-Host "Template $($File.name) needs to be updated as the SHA is different" Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable + } else { + Write-Host "Template $($File.name) already exists and is up to date" } } else { Write-Host "Template $($File.name) needs to be created" From 5e1de9950d029f9d1f9a3e8294491ca7eb008672 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 21:02:56 -0400 Subject: [PATCH 115/123] add result messages --- Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 index bf1e817537f8..5c4af7d7b221 100644 --- a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 @@ -47,12 +47,15 @@ function New-CIPPTemplateRun { if ($UpdateNeeded) { Write-Host "Template $($File.name) needs to be updated as the SHA is different" Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable + "Template $($File.name) updated" } else { Write-Host "Template $($File.name) already exists and is up to date" + "Template $($File.name) already exists and is up to date" } } else { Write-Host "Template $($File.name) needs to be created" Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable + "Template $($File.name) created" } } } catch { From b4540fb5265ec7b89bfad7b45fa72d69d4e798b0 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 21:43:50 -0400 Subject: [PATCH 116/123] cleanup template run logic --- .../CIPPCore/Public/New-CIPPTemplateRun.ps1 | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 index 5c4af7d7b221..da61eb588ca9 100644 --- a/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1 @@ -27,7 +27,7 @@ function New-CIPPTemplateRun { } } if ($TemplateSettings.templateRepo) { - Write-Host 'Grabbing data from required community repo' + Write-Information 'Grabbing data from community repo' try { $Files = (Get-GitHubFileTree -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value).tree | Where-Object { $_.path -match '.json$' -and $_.path -notmatch 'NativeImport' } | Select-Object *, @{n = 'html_url'; e = { "https://github.com/$($SplatParams.FullName)/tree/$($SplatParams.Branch)/$($_.path)" } }, @{n = 'name'; e = { ($_.path -split '/')[ -1 ] -replace '\.json$', '' } } #if there is a migration table file, file the file. Store the file contents in $migrationtable @@ -37,25 +37,29 @@ function New-CIPPTemplateRun { } foreach ($File in $Files) { if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue } - $ExistingTemplate = $ExistingTemplates | Where-Object { ($_.displayName -and (Get-SanitizedFilename -filename $_.displayName) -eq $File.name) -or ($_.templateName -and (Get-SanitizedFilename -filename $_.templateName) -eq $_.templateName ) } | Select-Object -First 1 - $Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json - if ($ExistingTemplate) { - $UpdateNeeded = $false - if ($ExistingTemplate.sha -ne $File.sha -or !$ExistingTemplate.sha) { - $UpdateNeeded = $true - } + $ExistingTemplate = $ExistingTemplates | Where-Object { (![string]::IsNullOrEmpty($_.displayName) -and (Get-SanitizedFilename -filename $_.displayName) -eq $File.name) -or (![string]::IsNullOrEmpty($_.templateName) -and (Get-SanitizedFilename -filename $_.templateName) -eq $File.name ) } | Select-Object -First 1 + + $UpdateNeeded = $false + if ($ExistingTemplate -and $ExistingTemplate.SHA -ne $File.sha) { + $Name = $ExistingTemplate.displayName ?? $ExistingTemplate.templateName + Write-Information "Existing template $($Name) found, but SHA is different. Updating template." + $UpdateNeeded = $true + "Template $($Name) needs to be updated as the SHA is different" + } else { + Write-Information "Existing template $($File.name) found, but SHA is the same. No update needed." + "Template $($File.name) found, but SHA is the same. No update needed." + } + + if (!$ExistingTemplate -or $UpdateNeeded) { + $Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json + Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable if ($UpdateNeeded) { - Write-Host "Template $($File.name) needs to be updated as the SHA is different" - Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable + Write-Information "Template $($File.name) needs to be updated as the SHA is different" "Template $($File.name) updated" } else { - Write-Host "Template $($File.name) already exists and is up to date" - "Template $($File.name) already exists and is up to date" + Write-Information "Template $($File.name) needs to be created" + "Template $($File.name) created" } - } else { - Write-Host "Template $($File.name) needs to be created" - Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable - "Template $($File.name) created" } } } catch { @@ -65,12 +69,12 @@ function New-CIPPTemplateRun { } } else { foreach ($Task in $Tasks) { - Write-Host "Working on task $Task" + Write-Information "Working on task $Task" switch ($Task) { 'ca' { - Write-Host "Template Conditional Access Policies for $TenantFilter" + Write-Information "Template Conditional Access Policies for $TenantFilter" $Policies = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/conditionalAccess/policies?$top=999' -tenantid $TenantFilter - Write-Host 'Creating templates for found Conditional Access Policies' + Write-Information 'Creating templates for found Conditional Access Policies' foreach ($policy in $policies) { try { $Template = New-CIPPCATemplate -TenantFilter $TenantFilter -JSON $policy @@ -101,7 +105,7 @@ function New-CIPPTemplateRun { } } 'intuneconfig' { - Write-Host "Backup Intune Configuration Policies for $TenantFilter" + Write-Information "Backup Intune Configuration Policies for $TenantFilter" $GraphURLS = @("https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations?`$select=id,displayName,lastModifiedDateTime,roleScopeTagIds,microsoft.graph.unsupportedDeviceConfiguration/originalEntityTypeName&`$expand=assignments&top=1000" 'https://graph.microsoft.com/beta/deviceManagement/windowsDriverUpdateProfiles' "https://graph.microsoft.com/beta/deviceManagement/groupPolicyConfigurations?`$expand=assignments&top=999" @@ -158,12 +162,12 @@ function New-CIPPTemplateRun { } } } catch { - Write-Host "Failed to backup $url" + Write-Information "Failed to backup $url" } } } 'intunecompliance' { - Write-Host "Backup Intune Compliance Policies for $TenantFilter" + Write-Information "Backup Intune Compliance Policies for $TenantFilter" New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/deviceCompliancePolicies?$top=999' -tenantid $TenantFilter | ForEach-Object { $Template = New-CIPPIntuneTemplate -TenantFilter $TenantFilter -URLName 'deviceCompliancePolicies' -ID $_.ID $ExistingPolicy = $ExistingTemplates | Where-Object { $_.displayName -eq $Template.DisplayName } | Select-Object -First 1 @@ -204,7 +208,7 @@ function New-CIPPTemplateRun { } 'intuneprotection' { - Write-Host "Backup Intune Protection Policies for $TenantFilter" + Write-Information "Backup Intune Protection Policies for $TenantFilter" New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceAppManagement/managedAppPolicies?$top=999' -tenantid $TenantFilter | ForEach-Object { $Template = New-CIPPIntuneTemplate -TenantFilter $TenantFilter -URLName 'managedAppPolicies' -ID $_.ID $ExistingPolicy = $ExistingTemplates | Where-Object { $_.displayName -eq $Template.DisplayName } | Select-Object -First 1 From b33205b7b853247aacb76e9903606a31da4d48c1 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 22:37:55 -0400 Subject: [PATCH 117/123] fix parsing of scheduled task details --- .../Invoke-ListScheduledItemDetails.ps1 | 65 +++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 index 8e3fb6093972..b9dd162b974e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItemDetails.ps1 @@ -64,7 +64,36 @@ function Invoke-ListScheduledItemDetails { $Results = Get-CIPPAzDataTableEntity @ResultsTable -Filter $ResultsFilter if (!$Results) { - $ResultData = ($Task.Results | ConvertFrom-Json -ErrorAction SilentlyContinue) ?? $Task.Results + try { + # Handle the case when we need to use Task.Results + if ($Task.Results) { + # Try to safely parse JSON or use the raw value if parsing fails + try { + if ($Task.Results -is [string]) { + $ResultString = $Task.Results.ToString().Trim() + if (($ResultString -match '^\[.*\]$') -or ($ResultString -match '^\{.*\}$')) { + $ResultData = $Task.Results | ConvertFrom-Json -ErrorAction Stop + } else { + # Not valid JSON format, use as is + $ResultData = $Task.Results + } + } else { + # Already an object, use as is + $ResultData = $Task.Results + } + } catch { + # If JSON parsing fails, use raw value + Write-LogMessage -API $APIName -message "Error parsing Task.Results as JSON: $_" -Sev 'Warning' + $ResultData = $Task.Results + } + } else { + $ResultData = $null + } + } catch { + Write-LogMessage -API $APIName -message "Error processing Task.Results: $_" -Sev 'Error' + $ResultData = $null + } + $Results = @( [PSCustomObject]@{ RowKey = $Task.Tenant @@ -73,17 +102,43 @@ function Invoke-ListScheduledItemDetails { } ) } + # Process the results if they exist $ProcessedResults = [System.Collections.Generic.List[object]]::new() foreach ($Result in $Results) { try { - if ($Result.Results) { - $ParsedResults = ($Result.Results | ConvertFrom-Json -ErrorAction SilentlyContinue) ?? $Result.Results - if (!$ParsedResults -or 'null' -eq $ParsedResults) { + if ($null -ne $Result.Results) { + # Safe handling based on result type + if ($Result.Results -is [array] -or $Result.Results -is [System.Collections.ICollection]) { + # Already a collection, use as is + $ParsedResults = $Result.Results + } elseif ($Result.Results -is [string]) { + $ResultString = $Result.Results.ToString().Trim() + # Only try to parse as JSON if it looks like JSON + if (($ResultString -match '^\[.*\]$') -or ($ResultString -match '^\{.*\}$')) { + try { + $ParsedResults = $Result.Results | ConvertFrom-Json -ErrorAction Stop + } catch { + Write-LogMessage -API $APIName -message "Failed to parse result as JSON: $_" -Sev 'Warning' + # On failure, keep as string + $ParsedResults = $Result.Results + } + } else { + # Not valid JSON format + $ParsedResults = $Result.Results + } + } else { + # Any other object type + $ParsedResults = $Result.Results + } + + # Ensure results is always an array + if ($null -eq $ParsedResults -or 'null' -eq $ParsedResults) { $Result.Results = @() } else { $Result.Results = @($ParsedResults) } + # Store tenant information with the result $TenantId = $Result.RowKey $TenantInfo = Get-Tenants -TenantFilter $TenantId -ErrorAction SilentlyContinue @@ -95,6 +150,8 @@ function Invoke-ListScheduledItemDetails { } } catch { Write-LogMessage -API $APIName -message "Error processing results for task $RowKey with tenant $($Result.RowKey): $_" -Sev 'Error' + # Set Results to an empty array to prevent further errors + $Result.Results = @() } $EndResult = $Result | Select-Object Timestamp, @{n = 'Tenant'; Expression = { $_.RowKey } }, Results $ProcessedResults.Add($EndResult) From 6cbaf450179a832c1437095188fd21a3298571cc Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sat, 12 Apr 2025 22:38:13 -0400 Subject: [PATCH 118/123] feat - offboarding user group license removal --- Modules/CIPPCore/Public/Remove-CIPPGroups.ps1 | 27 ++++++++++------- .../CIPPCore/Public/Remove-CIPPLicense.ps1 | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Modules/CIPPCore/Public/Remove-CIPPGroups.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGroups.ps1 index b7fcec73a316..933f6fbdb99e 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGroups.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGroups.ps1 @@ -11,7 +11,7 @@ function Remove-CIPPGroups { if (-not $userid) { $userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($Username)" -tenantid $Tenantfilter).id } - $AllGroups = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/groups/?`$select=displayName,mailEnabled,id,groupTypes" -tenantid $tenantFilter) + $AllGroups = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/groups/?`$select=displayName,mailEnabled,id,groupTypes,assignedLicenses&`$top=999" -tenantid $tenantFilter) $Returnval = (New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userid)/GetMemberGroups" -tenantid $tenantFilter -type POST -body '{"securityEnabledOnly": false}').value | ForEach-Object -Parallel { Import-Module '.\Modules\AzBobbyTables' @@ -22,18 +22,23 @@ function Remove-CIPPGroups { $Groupname = ($using:AllGroups | Where-Object -Property id -EQ $group).displayName $IsMailEnabled = ($using:AllGroups | Where-Object -Property id -EQ $group).mailEnabled $IsM365Group = $null -ne ($using:AllGroups | Where-Object { $_.id -eq $group -and $_.groupTypes -contains 'Unified' }) + $IsLicensed = ($using:AllGroups | Where-Object -Property id -EQ $group).assignedLicenses.Count -gt 0 - if ($IsM365Group) { - $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$_/members/$($using:userid)/`$ref" -tenantid $using:tenantFilter -type DELETE -body '' -Verbose - } elseif (-not $IsMailEnabled) { - $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$_/members/$($using:userid)/`$ref" -tenantid $using:tenantFilter -type DELETE -body '' -Verbose - } elseif ($IsMailEnabled) { - $Params = @{ Identity = $Groupname; Member = $using:userid ; BypassSecurityGroupManagerCheck = $true } - New-ExoRequest -tenantid $using:tenantFilter -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true - } + if ($IsLicensed) { + "Could not remove $($using:Username) from $Groupname. This is because the group has licenses assigned to it." + } else { + if ($IsM365Group) { + $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$_/members/$($using:userid)/`$ref" -tenantid $using:tenantFilter -type DELETE -body '' -Verbose + } elseif (-not $IsMailEnabled) { + $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$_/members/$($using:userid)/`$ref" -tenantid $using:tenantFilter -type DELETE -body '' -Verbose + } elseif ($IsMailEnabled) { + $Params = @{ Identity = $Groupname; Member = $using:userid ; BypassSecurityGroupManagerCheck = $true } + New-ExoRequest -tenantid $using:tenantFilter -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true + } - Write-LogMessage -headers $using:Headers -API $($using:APIName) -message "Removed $($using:Username) from $groupname" -Sev 'Info' -tenant $using:TenantFilter - "Successfully removed $($using:Username) from group $Groupname" + Write-LogMessage -headers $using:Headers -API $($using:APIName) -message "Removed $($using:Username) from $groupname" -Sev 'Info' -tenant $using:TenantFilter + "Successfully removed $($using:Username) from group $Groupname" + } } catch { $ErrorMessage = Get-CippException -Exception $_ Write-LogMessage -headers $using:Headers -API $($using:APIName) -message "Could not remove $($using:Username) from group $groupname : $($ErrorMessage.NormalizedError)" -Sev 'Error' -tenant $using:TenantFilter -LogData $ErrorMessage diff --git a/Modules/CIPPCore/Public/Remove-CIPPLicense.ps1 b/Modules/CIPPCore/Public/Remove-CIPPLicense.ps1 index 30c8e6c10abc..b2d8d447e9d1 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPLicense.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPLicense.ps1 @@ -35,6 +35,36 @@ function Remove-CIPPLicense { try { $ConvertTable = Import-Csv ConversionTable.csv $User = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($userid)" -tenantid $tenantFilter + $GroupMemberships = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($userid)/memberOf/microsoft.graph.group?`$select=id,displayName,assignedLicenses" -tenantid $tenantFilter + $LicenseGroups = $GroupMemberships | Where-Object { ($_.assignedLicenses | Measure-Object).Count -gt 0 } + + if ($LicenseGroups) { + # remove user from groups with licenses, these can only be graph groups + $RemoveRequests = foreach ($LicenseGroup in $LicenseGroups) { + @{ + id = $LicenseGroup.id + method = 'DELETE' + url = "groups/$($LicenseGroup.id)/members/$($User.id)/`$ref" + } + } + + Write-Information 'Removing user from groups with licenses' + $RemoveResults = New-GraphBulkRequest -tenantid $tenantFilter -requests @($RemoveRequests) + Write-Information ($RemoveResults | ConvertTo-Json -Depth 5) + $RemoveResults | ForEach-Object { + $Group = $GroupMemberships | Where-Object { $_.id -eq $_.id } + $GroupName = $Group | Select-Object -ExpandProperty displayName + + if ($_.status -eq 204) { + Write-LogMessage -headers $Headers -API $APIName -message "Removed $($User.displayName) from license group $GroupName" -Sev 'Info' -tenant $TenantFilter + "Removed $($User.displayName) from license group $GroupName" + } else { + Write-LogMessage -headers $Headers -API $APIName -message "Failed to remove $($User.displayName) from license group $GroupName. This is likely because its a Dynamic Group or synced with active directory." -Sev 'Error' -tenant $TenantFilter + "Failed to remove $($User.displayName) from license group $GroupName. This is likely because its a Dynamic Group or synced with active directory." + } + } + } + if (!$username) { $username = $User.userPrincipalName } $CurrentLicenses = $User.assignedlicenses.skuid $ConvertedLicense = $(($ConvertTable | Where-Object { $_.guid -in $CurrentLicenses }).'Product_Display_Name' | Sort-Object -Unique) -join ', ' From 6d53fcda274acac5d536a9c99dd13e19181d3241 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 13 Apr 2025 12:39:30 +0200 Subject: [PATCH 119/123] fix --- Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 index b57859c9b197..75c4fb04cfa4 100644 --- a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 @@ -235,6 +235,10 @@ function New-CIPPCAPolicy { } } else { Write-Information 'Creating' + if ($JSONobj.GrantControls.authenticationStrength.policyType -or $JSONObj.$jsonobj.LocationInfo) { + #quick fix for if the policy isn't available + Start-Sleep 1 + } $null = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/policies' -tenantid $tenantfilter -type POST -body $RawJSON -asApp $true Write-LogMessage -Headers $User -API $APINAME -tenant $($Tenant) -message "Added Conditional Access Policy $($JSONObj.Displayname)" -Sev 'Info' return "Created policy $displayname for $tenantfilter" From f772db180792b4d31ed04fd304512d4eccf22bc0 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Sun, 13 Apr 2025 13:40:09 +0200 Subject: [PATCH 120/123] Create Get-TenantIdFromSubscriptionId.ps1 For future use --- .../Public/Get-TenantIdFromSubscriptionId.ps1 | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Modules/CIPPCore/Public/Get-TenantIdFromSubscriptionId.ps1 diff --git a/Modules/CIPPCore/Public/Get-TenantIdFromSubscriptionId.ps1 b/Modules/CIPPCore/Public/Get-TenantIdFromSubscriptionId.ps1 new file mode 100644 index 000000000000..5c7547fc8b2e --- /dev/null +++ b/Modules/CIPPCore/Public/Get-TenantIdFromSubscriptionId.ps1 @@ -0,0 +1,26 @@ +function Get-TenantIdFromSubscriptionId { + param ( + [Parameter(Mandatory = $true)] + [string]$SubscriptionId + ) + + # Full credit goes to Jos Lieben + # https://www.lieben.nu/liebensraum/2020/08/get-tenant-id-using-azure-subscription-id/ + + try { + Invoke-WebRequest -UseBasicParsing -Uri "https://management.azure.com/subscriptions/$($SubscriptionId)`?api-version=2015-01-01" -ErrorAction Stop + } catch { + # The error response contains the WWW-Authenticate header with the tenant ID + $response = $_.Exception.Response + } + + # Extract tenant ID from WWW-Authenticate header + $authHeader = $response.Headers.GetValues("WWW-Authenticate")[0] + + # Use regex to extract the tenant ID + if ($authHeader -match "login\.windows\.net\/([0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12})") { + return $matches[1] + } + + return $null +} From bd01e286037b2b93fa646383d8bcdcdf38d84af9 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 13 Apr 2025 13:43:56 +0200 Subject: [PATCH 121/123] adds originalDisplayName in package --- .../Tenant/Administration/Tenant/Invoke-EditTenant.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 index 3bc8d89e92cd..e100c89b8e2d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1 @@ -40,6 +40,7 @@ Function Invoke-EditTenant { } $null = Add-CIPPAzDataTableEntity @PropertiesTable -Entity $aliasEntity -Force Write-Host "Setting alias to $tenantAlias" + $Tenant | Add-Member -NotePropertyName 'originalDisplayName' -NotePropertyValue $tenant.displayName -Force $Tenant.displayName = $tenantAlias $null = Add-CIPPAzDataTableEntity @TenantTable -Entity $Tenant -Force } From 30598483b1a03e8cb9e694196f2390484ba1dc93 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 13 Apr 2025 15:27:46 +0200 Subject: [PATCH 122/123] prettier error for tap --- .../Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 index c4e205aaa480..8aed811cfd84 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1 @@ -22,7 +22,7 @@ Function Invoke-ExecCreateTAP { $Result = New-CIPPTAP -userid $UserID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers $StatusCode = [HttpStatusCode]::OK } catch { - $Result = "$($_.Exception.Message)" + $Result = Get-NormalizedError -message $($_.Exception.Message) $StatusCode = [HttpStatusCode]::InternalServerError } From 9ce28eba5617b1efe30f65d31a4e52b5a5669a7e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar <49186168+KelvinTegelaar@users.noreply.github.com> Date: Sun, 13 Apr 2025 19:49:57 +0200 Subject: [PATCH 123/123] version up --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index f8cb1fa110da..18bb4182dd01 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -7.4.2 +7.5.0