From cc3135c3769969c34692444dd5f98a0fdc7809fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 7 Feb 2024 22:14:58 +0100 Subject: [PATCH 01/55] Better logging --- ...nvoke-CIPPStandardDisableBasicAuthSMTP.ps1 | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 index 470e5498a1dd..c30afebc1318 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 @@ -4,43 +4,55 @@ function Invoke-CIPPStandardDisableBasicAuthSMTP { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-TransportConfig' + $SMTPusers = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-CASMailbox' -cmdParams @{ ResultSize = 'Unlimited' } | Where-Object { ($_.SmtpClientAuthenticationDisabled -eq $false) } + If ($Settings.remediate) { - # Disable SMTP Basic Authentication for the tenant - try { - $Request = New-ExoRequest -tenantid $Tenant -cmdlet 'Set-TransportConfig' -cmdParams @{ SmtpClientAuthenticationDisabled = $true } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled SMTP Basic Authentication' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SMTP Basic Authentication: $($_.exception.message)" -sev Error - } - - # Disable SMTP Basic Authentication for all users - $SMTPusers = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-CASMailbox' -cmdParams @{ ResultSize = 'Unlimited' } | Where-Object { ($null -ne $_.SmtpClientAuthenticationDisabled) } - $SMTPusers | ForEach-Object { + if ($CurrentInfo.SmtpClientAuthenticationDisabled -and $SMTPusers.Count -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMTP Basic Authentication for tenant and all users is already disabled' -sev Info + } else { + # Disable SMTP Basic Authentication for the tenant try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-CASMailbox' -cmdParams @{ Identity = $_.Identity; SmtpClientAuthenticationDisabled = $null } -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress)" -sev Info + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-TransportConfig' -cmdParams @{ SmtpClientAuthenticationDisabled = $true } + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled SMTP Basic Authentication' -sev Info } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress). Error: $($_.exception.message)" -sev Error - + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SMTP Basic Authentication: $($_.exception.message)" -sev Error + } + + # Disable SMTP Basic Authentication for all users + $SMTPusers | ForEach-Object { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-CASMailbox' -cmdParams @{ Identity = $_.Identity; SmtpClientAuthenticationDisabled = $null } -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress)" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress). Error: $($_.exception.message)" -sev Error + + } } } } - - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-TransportConfig' - - if ($Settings.alert) { - if ($CurrentInfo.SmtpClientAuthenticationDisabled) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMTP Basic Authentication is disabled' -sev Info + if ($Settings.alert) { + if ($CurrentInfo.SmtpClientAuthenticationDisabled -and $SMTPusers.Count -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMTP Basic Authentication for tenant and all users is disabled' -sev Info + } else { + + if ($CurrentInfo.SmtpClientAuthenticationDisabled -eq $false) { + $LogMessage = 'SMTP Basic Authentication for tenant is not disabled. ' } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMTP Basic Authentication is not disabled' -sev Alert + $LogMessage = 'SMTP Basic Authentication for tenant is disabled. ' } + if ($SMTPusers.Count -ne 0) { + $LogMessage += "SMTP Basic Authentication for $($SMTPusers.Count) users is not disabled" + } else { + $LogMessage += 'SMTP Basic Authentication for all users is disabled' + } + Write-LogMessage -API 'Standards' -tenant $tenant -message $LogMessage -sev Alert } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableBasicAuthSMTP' -FieldValue [bool]$CurrentInfo.SmtpClientAuthenticationDisabled -StoreAs bool -Tenant $tenant - } + } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'DisableBasicAuthSMTP' -FieldValue [bool]$CurrentInfo.SmtpClientAuthenticationDisabled -StoreAs bool -Tenant $tenant } } From 84d9c84ecdfa2462ae8eff9ca999d816188300ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 7 Feb 2024 22:35:50 +0100 Subject: [PATCH 02/55] Change all global standards to report if they were already in the correct state --- ...nvoke-CIPPStandardActivityBasedTimeout.ps1 | 7 +++- .../Invoke-CIPPStandardAnonReportDisable.ps1 | 16 +++++--- .../Standards/Invoke-CIPPStandardAuditLog.ps1 | 16 +++++--- ...nvoke-CIPPStandardDisableBasicAuthSMTP.ps1 | 13 +++---- ...voke-CIPPStandardDisableGuestDirectory.ps1 | 25 ++++++------ .../Invoke-CIPPStandardMailContacts.ps1 | 38 ++++++++++++------- 6 files changed, 68 insertions(+), 47 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 index e61c9bd9e75e..ae2d6a6c094a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardActivityBasedTimeout.ps1 @@ -16,9 +16,12 @@ function Invoke-CIPPStandardActivityBasedTimeout { "definition":["{\"ActivityBasedTimeoutPolicy\":{\"Version\":1,\"ApplicationPolicies\":[{\"ApplicationId\":\"default\",\"WebSessionIdleTimeout\":\"01:00:00\"}]}}"] } '@ - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -Type POST -Body $body -ContentType 'application/json') + + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/activityBasedTimeoutPolicies' -Type POST -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled Activity Based Timeout of one hour' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Activity Based Timeout is already enabled' -sev Info } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled Activity Based Timeout of one hour' -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Activity Based Timeout $($_.exception.message)" -sev Error } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 index b17bccf7290c..93f0183adf14 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAnonReportDisable.ps1 @@ -5,12 +5,18 @@ function Invoke-CIPPStandardAnonReportDisable { #> param($Tenant, $Settings) $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -tenantid $Tenant -AsApp $true + If ($Settings.remediate) { - try { - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -Type patch -Body '{"displayConcealedNames": false}' -ContentType 'application/json' -AsApp $true - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Anonymous Reports Disabled.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable anonymous reports. Error: $($_.exception.message)" -sev Error + + if ($CurrentInfo.displayConcealedNames -eq $false) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Anonymous Reports is already disabled.' -sev Info + } else { + try { + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -Type patch -Body '{"displayConcealedNames": false}' -ContentType 'application/json' -AsApp $true + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Anonymous Reports Disabled.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable anonymous reports. Error: $($_.exception.message)" -sev Error + } } } if ($Settings.alert) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 index 63bbdafe4269..1dcd16e89cdb 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAuditLog.ps1 @@ -9,19 +9,23 @@ function Invoke-CIPPStandardAuditLog { If ($Settings.remediate) { Write-Host 'Time to remediate' + $DehydratedTenant = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').IsDehydrated if ($DehydratedTenant) { - New-ExoRequest -tenantid $Tenant -cmdlet 'Enable-OrganizationCustomization' + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Enable-OrganizationCustomization' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Organization customization enabled.' -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable organization customization. Error: $ErrorMessage" -sev Debug + } } - + try { if ($AuditLogEnabled) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Unified Audit Log already enabled.' -sev Info } else { - $AdminAuditLogParams = @{ - UnifiedAuditLogIngestionEnabled = $true - } - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AdminAuditLogConfig' -cmdParams $AdminAuditLogParams + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-AdminAuditLogConfig' -cmdParams @{UnifiedAuditLogIngestionEnabled = $true } Write-LogMessage -API 'Standards' -tenant $tenant -message 'Unified Audit Log Enabled.' -sev Info } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 index c30afebc1318..ea9158643d86 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableBasicAuthSMTP.ps1 @@ -27,7 +27,6 @@ function Invoke-CIPPStandardDisableBasicAuthSMTP { Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress)" -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SMTP Basic Authentication for $($_.DisplayName), $($_.PrimarySmtpAddress). Error: $($_.exception.message)" -sev Error - } } } @@ -38,15 +37,15 @@ function Invoke-CIPPStandardDisableBasicAuthSMTP { Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMTP Basic Authentication for tenant and all users is disabled' -sev Info } else { - if ($CurrentInfo.SmtpClientAuthenticationDisabled -eq $false) { - $LogMessage = 'SMTP Basic Authentication for tenant is not disabled. ' - } else { + if ($CurrentInfo.SmtpClientAuthenticationDisabled) { $LogMessage = 'SMTP Basic Authentication for tenant is disabled. ' - } - if ($SMTPusers.Count -ne 0) { - $LogMessage += "SMTP Basic Authentication for $($SMTPusers.Count) users is not disabled" } else { + $LogMessage = 'SMTP Basic Authentication for tenant is not disabled. ' + } + if ($SMTPusers.Count -eq 0) { $LogMessage += 'SMTP Basic Authentication for all users is disabled' + } else { + $LogMessage += "SMTP Basic Authentication for $($SMTPusers.Count) users is not disabled" } Write-LogMessage -API 'Standards' -tenant $tenant -message $LogMessage -sev Alert } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuestDirectory.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuestDirectory.ps1 index 9729b4b163a7..44d92753db8f 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuestDirectory.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuestDirectory.ps1 @@ -8,14 +8,16 @@ function Invoke-CIPPStandardDisableGuestDirectory { If ($Settings.remediate) { - - try { - $body = '{guestUserRoleId: "2af84b1e-32c8-42b7-82bc-daa82404023b"}' - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json') - - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Guest access to directory information.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Guest access to directory information.: $($_.exception.message)" -sev 'Error' + if ($CurrentInfo.guestUserRoleId -eq '2af84b1e-32c8-42b7-82bc-daa82404023b') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guest access to directory information is already disabled.' -sev Info + } else { + try { + $body = '{guestUserRoleId: "2af84b1e-32c8-42b7-82bc-daa82404023b"}' + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Guest access to directory information.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Guest access to directory information.: $($_.exception.message)" -sev 'Error' + } } } @@ -27,12 +29,9 @@ function Invoke-CIPPStandardDisableGuestDirectory { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guest access to directory information is not disabled.' -sev Alert } } + if ($Settings.report) { - if ($CurrentInfo.guestUserRoleId -eq '2af84b1e-32c8-42b7-82bc-daa82404023b') { - $CurrentInfo.guestUserRoleId = $true - } else { - $CurrentInfo.guestUserRoleId = $false - } + if ($CurrentInfo.guestUserRoleId -eq '2af84b1e-32c8-42b7-82bc-daa82404023b') { $CurrentInfo.guestUserRoleId = $true } else { $CurrentInfo.guestUserRoleId = $false } Add-CIPPBPAField -FieldName 'DisableGuestDirectory' -FieldValue [bool]$CurrentInfo.guestUserRoleId -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1 index fc2b34dda7b1..09b58fe0671a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1 @@ -5,28 +5,37 @@ function Invoke-CIPPStandardMailContacts { #> param($Tenant, $Settings) $TenantID = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/organization' -tenantid $tenant) + $CurrentInfo = New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/organization/$($TenantID.id)" -tenantid $Tenant + $contacts = $settings + $TechAndSecurityContacts = @($Contacts.SecurityContact, $Contacts.TechContact) If ($Settings.remediate) { - $contacts = $settings - try { - $Body = [pscustomobject]@{} - switch ($Contacts) { - { $Contacts.MarketingContact } { $body | Add-Member -NotePropertyName marketingNotificationEmails -NotePropertyValue @($Contacts.MarketingContact) } - { $Contacts.SecurityContact } { $body | Add-Member -NotePropertyName technicalNotificationMails -NotePropertyValue @($Contacts.SecurityContact) } - { $Contacts.TechContact } { $body | Add-Member -NotePropertyName technicalNotificationMails -NotePropertyValue @($Contacts.TechContact) } - { $Contacts.GeneralContact } { $body | Add-Member -NotePropertyName privacyProfile -NotePropertyValue @{contactEmail = $Contacts.GeneralContact } } + # TODO: Make this smaller if possible + if ($CurrentInfo.marketingNotificationEmails -eq $Contacts.MarketingContact -and ` + ($CurrentInfo.securityComplianceNotificationMails -in $TechAndSecurityContacts -or + $CurrentInfo.technicalNotificationMails -in $TechAndSecurityContacts) -and ` + $CurrentInfo.privacyProfile.contactEmail -eq $Contacts.GeneralContact) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Contact emails are already set.' -sev Info + } else { + try { + $Body = [pscustomobject]@{} + switch ($Contacts) { + { $Contacts.MarketingContact } { $body | Add-Member -NotePropertyName marketingNotificationEmails -NotePropertyValue @($Contacts.MarketingContact) } + { $Contacts.SecurityContact } { $body | Add-Member -NotePropertyName technicalNotificationMails -NotePropertyValue @($Contacts.SecurityContact) } + { $Contacts.TechContact } { $body | Add-Member -NotePropertyName technicalNotificationMails -NotePropertyValue @($Contacts.TechContact) -ErrorAction SilentlyContinue } + { $Contacts.GeneralContact } { $body | Add-Member -NotePropertyName privacyProfile -NotePropertyValue @{contactEmail = $Contacts.GeneralContact } } + } + Write-Host (ConvertTo-Json -InputObject $body) + New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/v1.0/organization/$($TenantID.id)" -asApp $true -Type patch -Body (ConvertTo-Json -InputObject $body) -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Contact emails set.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set contact emails: $($_.exception.message)" -sev Error } - Write-Host (ConvertTo-Json -InputObject $body) - New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/v1.0/organization/$($TenantID.id)" -asApp $true -Type patch -Body (ConvertTo-Json -InputObject $body) -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Contact emails set.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set contact emails: $($_.exception.message)" -sev Error } } if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/organization/$($TenantID.id)" -tenantid $Tenant if ($CurrentInfo.marketingNotificationEmails -eq $Contacts.MarketingContact) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Marketing contact email is set to $($Contacts.MarketingContact)" -sev Info } else { @@ -47,6 +56,7 @@ function Invoke-CIPPStandardMailContacts { } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "General contact email is not set to $($Contacts.GeneralContact)" -sev Alert } + } if ($Settings.report) { Add-CIPPBPAField -FieldName 'MailContacts' -FieldValue $CurrentInfo -StoreAs json -Tenant $tenant From 4be77ed4ba0d7e51f367e58c4e63971d7dff0238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 8 Feb 2024 18:52:53 +0100 Subject: [PATCH 03/55] Logging change in Invoke-CIPPStandardRotateDKIM.ps1 --- .../Invoke-CIPPStandardRotateDKIM.ps1 | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 index 5246d658f5de..0823e515d6c8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 @@ -8,22 +8,26 @@ function Invoke-CIPPStandardRotateDKIM { If ($Settings.remediate) { - $DKIM | ForEach-Object { - try { - (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 { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to rotate DKIM Error: $($_.exception.message)" -sev Error + if ($DKIM) { + $DKIM | ForEach-Object { + try { + (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 { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to rotate DKIM Error: $($_.exception.message)" -sev Error + } } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is rotated for all domains' -sev Info } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Rotated DKIM' -sev Info + } if ($Settings.alert) { - if ($null -eq $DKIM) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is rotated for all domains' -sev Info - } else { + if ($DKIM) { Write-LogMessage -API 'Standards' -tenant $tenant -message "DKIM is not rotated for $($DKIM.Identity -join ';')" -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is rotated for all domains' -sev Info } } From ae7ddb4645d1bd0cdb2a466526a5f118dcdbb149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 8 Feb 2024 18:59:24 +0100 Subject: [PATCH 04/55] I FORGOT THE ALREADY PART --- .../CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 index 0823e515d6c8..17236da05fdf 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 @@ -18,7 +18,7 @@ function Invoke-CIPPStandardRotateDKIM { } } } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is rotated for all domains' -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is already rotated for all domains' -sev Info } } From e2fd37d8ccb24ace5f06a896405a68af1947c623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 8 Feb 2024 22:01:25 +0100 Subject: [PATCH 05/55] Resharing standard loggign --- .../Invoke-CIPPStandardDisableReshare.ps1 | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 index 2f438e417605..30898dde2ddd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 @@ -4,27 +4,32 @@ function Invoke-CIPPStandardDisableReshare { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + If ($Settings.remediate) { - - try { - $body = '{"isResharingByExternalUsersEnabled": "False"}' - $Request = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' - Write-Host ($Request | ConvertTo-Json) - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled guests from resharing files' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable guests from resharing files: $($_.exception.message)" -sev Error + + if ($CurrentInfo.isResharingByExternalUsersEnabled) { + try { + $body = '{"isResharingByExternalUsersEnabled": "False"}' + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled guests from resharing files' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable guests from resharing files: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are already disabled from resharing files' -sev Info } } if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true if ($CurrentInfo.isResharingByExternalUsersEnabled -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are not allowed to reshare files' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are allowed to reshare files' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'DisableReshare' -FieldValue [bool]$CurrentInfo.isResharingByExternalUsersEnabled -StoreAs bool -Tenant $tenant } From 775940c26b25a44a0531ca8ba700cb8e65827464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 8 Feb 2024 22:22:08 +0100 Subject: [PATCH 06/55] LAPS standard logging --- .../Invoke-CIPPStandardDisableReshare.ps1 | 9 +++---- .../Standards/Invoke-CIPPStandardlaps.ps1 | 27 +++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 index 30898dde2ddd..6f6c0b9f7f7a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableReshare.ps1 @@ -8,7 +8,6 @@ function Invoke-CIPPStandardDisableReshare { If ($Settings.remediate) { - if ($CurrentInfo.isResharingByExternalUsersEnabled) { try { $body = '{"isResharingByExternalUsersEnabled": "False"}' @@ -23,13 +22,13 @@ function Invoke-CIPPStandardDisableReshare { } if ($Settings.alert) { - if ($CurrentInfo.isResharingByExternalUsersEnabled -eq $false) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are not allowed to reshare files' -sev Info - } else { + if ($CurrentInfo.isResharingByExternalUsersEnabled) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are allowed to reshare files' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Guests are not allowed to reshare files' -sev Info } } - + if ($Settings.report) { Add-CIPPBPAField -FieldName 'DisableReshare' -FieldValue [bool]$CurrentInfo.isResharingByExternalUsersEnabled -StoreAs bool -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 index 7ae60c772a41..5732995e01ca 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardlaps.ps1 @@ -7,24 +7,29 @@ function Invoke-CIPPStandardlaps { $PreviousSetting = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -tenantid $Tenant If ($Settings.remediate) { - - try { - $previoussetting.localadminpassword.isEnabled = $true - $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting - 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 { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set LAPS: $($_.exception.message)" -sev Error + if ($PreviousSetting.localadminpassword.isEnabled) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'LAPS is already enabled.' -sev Info + } else { + try { + $previoussetting.localadminpassword.isEnabled = $true + $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting + 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 { + $previoussetting.localadminpassword.isEnabled = $false + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to set LAPS: $($_.exception.message)" -sev Error + } } } if ($Settings.alert) { - if ($PreviousSetting.localadminpassword.isEnabled -eq $true) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'LAPS is enabled.' -sev Info + if ($PreviousSetting.localadminpassword.isEnabled) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'LAPS is enabled.' -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'LAPS is not enabled.' -sev Alert + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'LAPS is not enabled.' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'laps' -FieldValue [bool]$PreviousSetting.localadminpassword.isEnabled -StoreAs bool -Tenant $tenant } From f393e4eecb74706d0ef82681db4eaf037a60f954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 9 Feb 2024 00:29:59 +0100 Subject: [PATCH 07/55] Logging and bug fix --- ...rdPWdisplayAppInformationRequiredState.ps1 | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 index 4bf9ebcd3426..78d183b10e27 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWdisplayAppInformationRequiredState.ps1 @@ -4,24 +4,26 @@ function Invoke-CIPPStandardPWdisplayAppInformationRequiredState { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'MicrosoftAuthenticator' -Enabled $true - } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant - $State = if ($CurrentInfo.featureSettings.displayAppInformationRequiredState.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is enabled.' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is not enabled.' -sev Alert - } + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'MicrosoftAuthenticator' -Enabled $true } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'PWdisplayAppInformationRequiredState' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } + + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is enabled.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Passwordless with Information and Number Matching is not enabled.' -sev Alert } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'PWdisplayAppInformationRequiredState' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } \ No newline at end of file From ee1bda04ff4402f6c17a5b3f3fb0c486e75fcd1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 9 Feb 2024 01:18:46 +0100 Subject: [PATCH 08/55] More logging changes and a few bug fixes --- ...voke-CIPPStandardDisableTenantCreation.ps1 | 30 +++++++---- .../Invoke-CIPPStandardEnableFIDO2.ps1 | 34 +++++++----- ...Invoke-CIPPStandardEnableHardwareOAuth.ps1 | 35 +++++++------ ...CIPPStandardPWcompanionAppAllowedState.ps1 | 52 +++++++++++-------- ...oke-CIPPStandardPasswordExpireDisabled.ps1 | 33 +++++++----- .../Standards/Invoke-CIPPStandardTAP.ps1 | 33 ++++++------ .../Invoke-CIPPStandardallowOAuthTokens.ps1 | 33 ++++++------ .../Invoke-CIPPStandardallowOTPTokens.ps1 | 29 ++++++----- 8 files changed, 158 insertions(+), 121 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 index 55cde0260efc..d7a57014edcd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableTenantCreation.ps1 @@ -4,25 +4,33 @@ function Invoke-CIPPStandardDisableTenantCreation { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant + $State = $CurrentInfo.defaultUserRolePermissions.allowedToCreateTenants + If ($Settings.remediate) { - try { - $body = '{"defaultUserRolePermissions":{"allowedToCreateTenants":false}}' - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json') - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standards API: Disabled users from creating tenants.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating tenants: $($_.exception.message)" -sev 'Error' + + if ($State) { + try { + $body = '{"defaultUserRolePermissions":{"allowedToCreateTenants":false}}' + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating tenants.' -sev Info + $State = $false + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating tenants: $($_.exception.message)" -sev 'Error' + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already disabled from creating tenants.' -sev Info } } if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant - if ($CurrentInfo.defaultUserRolePermissions.allowedToCreateTenants -eq $false) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not allowed to create tenants.' -sev Info - } else { + if ($State) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are allowed to create tenants.' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not allowed to create tenants.' -sev Info } } if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableTenantCreation' -FieldValue [bool]$CurrentInfo.defaultUserRolePermissions.allowedToCreateTenants -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableTenantCreation' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 index ff80b7f264f8..8fb8ff1a0544 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableFIDO2.ps1 @@ -4,24 +4,30 @@ function Invoke-CIPPStandardEnableFIDO2 { Internal #> param($Tenant, $Settings) - + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Fido2' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Fido2' -Enabled $true + + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Fido2' -Enabled $true + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Fido2' -tenantid $Tenant - if ($Settings.alert) { - if ($CurrentInfo.state -eq 'enabled') { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is enabled' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is not enabled' -sev Alert - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'EnableFIDO2' -FieldValue [bool]$CurrentInfo.state -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'FIDO2 Support is not enabled' -sev Alert } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'EnableFIDO2' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } + } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 index 605a5188a47d..53dc0eef1798 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableHardwareOAuth.ps1 @@ -4,24 +4,29 @@ function Invoke-CIPPStandardEnableHardwareOAuth { Internal #> param($Tenant, $Settings) - + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/HardwareOath' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } + If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'HardwareOath' -Enabled $true - } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/HardwareOath' -tenantid $Tenant - - if ($Settings.alert) { - if ($CurrentInfo.state -eq 'enabled') { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is enabled' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is not enabled' -sev Alert - } + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'HardwareOath' -Enabled $true } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'EnableHardwareOAuth' -FieldValue [bool]$CurrentInfo.state -StoreAs bool -Tenant $tenant + } + + if ($Settings.alert) { + + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'HardwareOAuth Support is not enabled' -sev Alert } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'EnableHardwareOAuth' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } + diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 index 2cd6cb851ba7..ae8dad7d31ea 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPWcompanionAppAllowedState.ps1 @@ -5,42 +5,48 @@ function Invoke-CIPPStandardPWcompanionAppAllowedState { #> param($Tenant, $Settings) $authenticatorFeaturesState = (New-GraphGetRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -Type GET) + $authstate = if ($authenticatorFeaturesState.featureSettings.companionAppAllowedState.state -eq 'enabled') { $true } else { $false } + If ($Settings.remediate) { - $Setting = $Settings - try { - # Get current state of microsoftAuthenticator policy - # Remove number matching from featureSettings because this is now Microsoft enforced and shipping it returns an error - $authenticatorFeaturesState.featureSettings.PSObject.Properties.Remove('numberMatchingRequiredState') - # Define feature body - $featureBody = @{ - state = $Setting.state - includeTarget = [PSCustomObject]@{ - targetType = 'group' - id = 'all_users' - } - excludeTarget = [PSCustomObject]@{ - targetType = 'group' - id = '00000000-0000-0000-0000-000000000000' + + if ($authenticatorFeaturesState.featureSettings.companionAppAllowedState.state -eq $Settings.state) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "companionAppAllowedState is already set to the desired state of $($Settings.state)." -sev Info + } else { + try { + # Remove number matching from featureSettings because this is now Microsoft enforced and shipping it returns an error + $authenticatorFeaturesState.featureSettings.PSObject.Properties.Remove('numberMatchingRequiredState') + # Define feature body + $featureBody = @{ + state = $Settings.state + includeTarget = [PSCustomObject]@{ + targetType = 'group' + id = 'all_users' + } + excludeTarget = [PSCustomObject]@{ + targetType = 'group' + id = '00000000-0000-0000-0000-000000000000' + } } + $authenticatorFeaturesState.featureSettings.companionAppAllowedState = $featureBody + $body = ConvertTo-Json -Depth 3 -Compress -InputObject $authenticatorFeaturesState + (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -Type patch -Body $body -ContentType 'application/json') + Write-LogMessage -API 'Standards' -tenant $tenant -message "Set companionAppAllowedState to $($Settings.state)." -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set companionAppAllowedState to $($Settings.state). Error: $($_.exception.message)" -sev Error } - $authenticatorFeaturesState.featureSettings.companionAppAllowedState = $featureBody - $body = $authenticatorFeaturesState | ConvertTo-Json -Depth 3 - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -Type patch -Body $body -ContentType 'application/json') - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled companionAppAllowedState.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable companionAppAllowedState. Error: $($_.exception.message)" -sev Error } } + if ($Settings.alert) { - if ($authenticatorFeaturesState.featureSettings.companionAppAllowedState.state -eq 'enabled') { + if ($authstate) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'companionAppAllowedState is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'companionAppAllowedState is not enabled.' -sev Alert } } + if ($Settings.report) { - if ($authenticatorFeaturesState.featureSettings.companionAppAllowedState.state -eq 'enabled') { $authstate = $true } else { $authstate = $false } Add-CIPPBPAField -FieldName 'companionAppAllowedState' -FieldValue [bool]$authstate -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 index 3788a12d72b9..7d5bb92bfad5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 @@ -5,25 +5,34 @@ function Invoke-CIPPStandardPasswordExpireDisabled { #> param($Tenant, $Settings) $GraphRequest = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $Tenant + $DomainswithoutPassExpire = $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' + If ($Settings.remediate) { - try { - $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' | ForEach-Object { - New-GraphPostRequest -type Patch -tenantid $Tenant -uri "https://graph.microsoft.com/beta/domains/$($_.id)" -body '{"passwordValidityPeriodInDays": 2147483647 }' + + if ($DomainswithoutPassExpire) { + $DomainswithoutPassExpire | ForEach-Object { + try { + New-GraphPostRequest -type Patch -tenantid $Tenant -uri "https://graph.microsoft.com/beta/domains/$($_.id)" -body '{"passwordValidityPeriodInDays": 2147483647 }' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled Password Expiration for $($_.name)." -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Password Expiration for $($_.name). Error: $($_.exception.message)" -sev Error + } } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Password Expiration' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Password Expiration. Error: $($_.exception.message)" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is already disabled for all $($GraphRequest.Count) domains." -sev Info } + } - if ($Settings.alert) { - $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' | ForEach-Object { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for $($_.name)" -sev Alert + if ($Settings.alert) { + if ($DomainswithoutPassExpire) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for the following $($DomainswithoutPassExpire.Count) domains: $($DomainswithoutPassExpire -join ', ')" -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is disabled for all $($GraphRequest.Count) domains." -sev Info } } + if ($Settings.report) { - $DomainswithoutPassExpire = $GraphRequest | Where-Object -Property passwordValidityPeriodInDays -NE '2147483647' Add-CIPPBPAField -FieldName 'PasswordExpireDisabled' -FieldValue $DomainswithoutPassExpire -StoreAs json -Tenant $tenant - } -} +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 index e98e7faddd01..178274286074 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardTAP.ps1 @@ -4,25 +4,26 @@ function Invoke-CIPPStandardTAP { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'TemporaryAccessPass' -Enabled $true -TAPisUsableOnce $Settings.config + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'TemporaryAccessPass' -Enabled $true -TAPisUsableOnce $Settings.config + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/TemporaryAccessPass' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is enabled.' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is not enabled.' -sev Alert - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'TemporaryAccessPass' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is enabled.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Temporary Access Passwords is not enabled.' -sev Alert } } -} \ No newline at end of file + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'TemporaryAccessPass' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 index 8455c93208f5..883c23c3ca5a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOAuthTokens.ps1 @@ -4,26 +4,27 @@ function Invoke-CIPPStandardallowOAuthTokens { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/softwareOath' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'softwareOath' -Enabled $true + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'softwareOath' -Enabled $true + } } + + if ($Settings.alert) { - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/softwareOath' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is enabled' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is not enabled' -sev Alert - } + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Software OTP/oAuth tokens is not enabled' -sev Alert } + } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'softwareOath' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant - } + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'softwareOath' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant } -} \ No newline at end of file +} diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOTPTokens.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOTPTokens.ps1 index cca5dc8ae8e2..8f3f6b456010 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOTPTokens.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardallowOTPTokens.ps1 @@ -4,25 +4,26 @@ function Invoke-CIPPStandardallowOTPTokens { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'MicrosoftAuthenticator' -Enabled $true -MicrosoftAuthenticatorSoftwareOathEnabled $true + if ($CurrentInfo.isSoftwareOathEnabled) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'MS authenticator OTP/oAuth tokens is already enabled.' -sev Info + } else { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'MicrosoftAuthenticator' -Enabled $true -MicrosoftAuthenticatorSoftwareOathEnabled $true + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = new-graphgetRequest -uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/microsoftAuthenticator' -tenantid $Tenant - if ($Settings.alert) { - - if ($CurrentInfo.isSoftwareOathEnabled) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'MS authenticator OTP/oAuth tokens is enabled' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'MS authenticator OTP/oAuth tokens is not enabled' -sev Alert - } + if ($Settings.alert) { + if ($CurrentInfo.isSoftwareOathEnabled) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'MS authenticator OTP/oAuth tokens is enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'MS authenticator OTP/oAuth tokens is not enabled' -sev Alert } + } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'MSAuthenticator' -FieldValue [bool]$CurrentInfo.isSoftwareOathEnabled -StoreAs bool -Tenant $tenant - } + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'MSAuthenticator' -FieldValue [bool]$CurrentInfo.isSoftwareOathEnabled -StoreAs bool -Tenant $tenant } + } \ No newline at end of file From 0a86c63065c66796141ece3d3a8df266709e7ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 9 Feb 2024 12:36:59 +0100 Subject: [PATCH 09/55] Rewrite, logging and bugfixing --- .../Standards/Invoke-CIPPStandardNudgeMFA.ps1 | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 index f9a6a0710d44..a022bea6f0f6 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardNudgeMFA.ps1 @@ -5,33 +5,39 @@ function Invoke-CIPPStandardNudgeMFA { #> param($Tenant, $Settings) $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -tenantid $Tenant + $State = if ($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - $status = if ($Settings.enable -and $Settings.disable) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'You cannot both enable and disable the Nudge MFA setting' -sev Error - Exit - } elseif ($Settings.enable) { 'enabled' } else { 'disabled' } - Write-Output $status - try { - $Body = $CurrentInfo - $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $status - $body = ConvertTo-Json -Depth 10 -InputObject ($body | Select-Object registrationEnforcement) - New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy" -Type patch -Body $body -ContentType "application/json" - Write-LogMessage -API "Standards" -tenant $tenant -message "$status Authenticator App Nudge" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to $status Authenticator App Nudge: $($_.exception.message)" -sev Error + + if ($Settings.state -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -or $Settings.snoozeDurationInDays -ne $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays) { + try { + $Body = $CurrentInfo + $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $Settings.state + $body.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays = $Settings.snoozeDurationInDays + + $body = ConvertTo-Json -Depth 10 -InputObject ($body | Select-Object registrationEnforcement) + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy' -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message "$($Settings.state) Authenticator App Nudge with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info + $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state = $Settings.state + $CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays = $Settings.snoozeDurationInDays + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to $($Settings.state) Authenticator App Nudge: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is already set to $($Settings.state) with a snooze duration of $($Settings.snoozeDurationInDays)" -sev Info } } + if ($Settings.alert) { - if ($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'enabled') { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Authenticator App Nudge is enabled' -sev Info + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is enabled with a snooze duration of $($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Authenticator App Nudge is not enabled' -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Authenticator App Nudge is not enabled with a snooze duration of $($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.snoozeDurationInDays)" -sev Alert } } + if ($Settings.report) { - if ($CurrentInfo.registrationEnforcement.authenticationMethodsRegistrationCampaign.state -eq 'enabled') { $actualstate = $true } else { $actualstate = $false } - Add-CIPPBPAField -FieldName 'NudgeMFA' -FieldValue [bool]$actualstate -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'NudgeMFA' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant } } From 16f8275859e46df11cdf5359a81f59e86721d7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 9 Feb 2024 14:33:53 +0100 Subject: [PATCH 10/55] Logging changes for rest of the standards except for the enable oauth --- .../Invoke-CIPPStandardDisableEmail.ps1 | 31 ++++++++--------- .../Invoke-CIPPStandardDisableGuests.ps1 | 21 +++++++----- ...voke-CIPPStandardDisableM365GroupUsers.ps1 | 28 +++++++++------- .../Invoke-CIPPStandardDisableSMS.ps1 | 33 ++++++++++--------- ...-CIPPStandardDisableSecurityGroupUsers.ps1 | 24 ++++++++------ .../Invoke-CIPPStandardDisableVoice.ps1 | 31 ++++++++--------- ...oke-CIPPStandardDisablex509Certificate.ps1 | 32 +++++++++--------- .../Invoke-CIPPStandardSecurityDefaults.ps1 | 19 +++++++---- .../Invoke-CIPPStandardUndoOauth.ps1 | 31 ++++++++++++++--- 9 files changed, 147 insertions(+), 103 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 index dcd995600259..1bc4d0161cb0 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableEmail.ps1 @@ -4,25 +4,26 @@ function Invoke-CIPPStandardDisableEmail { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Email' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Email' -Enabled $false + if ($State) { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Email' -Enabled $false + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is already disabled.' -sev Info + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Email' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email Support is enabled' -sev Alert - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email Support is not enabled' -sev Info - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableEmail' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Email authentication method is not enabled' -sev Info } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'DisableEmail' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuests.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuests.ps1 index e328f3d99afc..6ccac9c5f3c8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuests.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuests.ps1 @@ -4,19 +4,24 @@ function Invoke-CIPPStandardDisableGuests { Internal #> param($Tenant, $Settings) - $lookup = (Get-Date).AddDays(-90).ToUniversalTime().ToString('o') - $GraphRequest = New-GraphgetRequest -uri "https://graph.microsoft.com/beta/users?`$filter=(signInActivity/lastSignInDateTime le $lookup)&`$select=id,UserPrincipalName,signInActivity,mail,userType,accountEnabled" -scope 'https://graph.microsoft.com/.default' -tenantid $Tenant | Where-Object { $_.userType -EQ 'Guest' -and $_.AccountEnabled -EQ $true } + $Lookup = (Get-Date).AddDays(-90).ToUniversalTime().ToString('o') + $GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$filter=(signInActivity/lastSignInDateTime le $Lookup)&`$select=id,UserPrincipalName,signInActivity,mail,userType,accountEnabled" -scope 'https://graph.microsoft.com/.default' -tenantid $Tenant | Where-Object { $_.userType -EQ 'Guest' -and $_.AccountEnabled -EQ $true } If ($Settings.remediate) { - try { + + if ($GraphRequest) { foreach ($guest in $GraphRequest) { - New-GraphPostRequest -type Patch -tenantid $tenant -uri "https://graph.microsoft.com/beta/users/$($guest.id)" -body '{"accountEnabled":"false"}' - Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabling guest $($guest.UserPrincipalName) ($($guest.id))" -sev Info + try { + New-GraphPostRequest -type Patch -tenantid $tenant -uri "https://graph.microsoft.com/beta/users/$($guest.id)" -body '{"accountEnabled":"false"}' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabling guest $($guest.UserPrincipalName) ($($guest.id))" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable guest $($guest.UserPrincipalName) ($($guest.id)): $($_.exception.message)" -sev Error + } } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled guests accounts with a login longer than 90 days ago.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable guests older than 90 days: $($_.exception.message)" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'No guests accounts with a login longer than 90 days ago.' -sev Info } + } if ($Settings.alert) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1 index bbb62f9b0b92..de0c916d64b7 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1 @@ -7,19 +7,23 @@ function Invoke-CIPPStandardDisableM365GroupUsers { $CurrentState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/settings' -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified' If ($Settings.remediate) { - try { - if (!$CurrentState) { - #if no current configuration is found, we set it to the default template supplied by MS. - $CurrentState = '{"id":"","displayName":"Group.Unified","templateId":"62375ab9-6b52-47ed-826b-58e47e0e304b","values":[{"name":"NewUnifiedGroupWritebackDefault","value":"true"},{"name":"EnableMIPLabels","value":"false"},{"name":"CustomBlockedWordsList","value":""},{"name":"EnableMSStandardBlockedWords","value":"false"},{"name":"ClassificationDescriptions","value":""},{"name":"DefaultClassification","value":""},{"name":"PrefixSuffixNamingRequirement","value":""},{"name":"AllowGuestsToBeGroupOwner","value":"false"},{"name":"AllowGuestsToAccessGroups","value":"true"},{"name":"GuestUsageGuidelinesUrl","value":""},{"name":"GroupCreationAllowedGroupId","value":""},{"name":"AllowToAddGuests","value":"true"},{"name":"UsageGuidelinesUrl","value":""},{"name":"ClassificationList","value":""},{"name":"EnableGroupCreation","value":"true"}]}' - New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -AsApp $true -Type POST -Body $CurrentState -ContentType 'application/json' - $CurrentState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/settings' -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified' + if (($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value -eq 'false') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already disabled from creating M365 Groups.' -sev Info + } else { + try { + if (!$CurrentState) { + # If no current configuration is found, we set it to the default template supplied by MS. + $CurrentState = '{"id":"","displayName":"Group.Unified","templateId":"62375ab9-6b52-47ed-826b-58e47e0e304b","values":[{"name":"NewUnifiedGroupWritebackDefault","value":"true"},{"name":"EnableMIPLabels","value":"false"},{"name":"CustomBlockedWordsList","value":""},{"name":"EnableMSStandardBlockedWords","value":"false"},{"name":"ClassificationDescriptions","value":""},{"name":"DefaultClassification","value":""},{"name":"PrefixSuffixNamingRequirement","value":""},{"name":"AllowGuestsToBeGroupOwner","value":"false"},{"name":"AllowGuestsToAccessGroups","value":"true"},{"name":"GuestUsageGuidelinesUrl","value":""},{"name":"GroupCreationAllowedGroupId","value":""},{"name":"AllowToAddGuests","value":"true"},{"name":"UsageGuidelinesUrl","value":""},{"name":"ClassificationList","value":""},{"name":"EnableGroupCreation","value":"true"}]}' + New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -AsApp $true -Type POST -Body $CurrentState -ContentType 'application/json' + $CurrentState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/settings' -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified' + } + ($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value = 'false' + $body = "{values : $($CurrentState.values | ConvertTo-Json -Compress)}" + $null = New-GraphPostRequest -tenantid $tenant -asApp $true -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating M365 Groups.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating M365 Groups: $($_.exception.message)" -sev 'Error' } - ($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value = 'false' - $body = "{values : $($CurrentState.values | ConvertTo-Json -Compress)}" - New-GraphPostRequest -tenantid $tenant -asApp $true -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standards API: Disabled users from creating M365 Groups.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating M365 Groups: $($_.exception.message)" -sev 'Error' } } if ($Settings.alert) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 index d133c34deef5..337dffde4b20 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSMS.ps1 @@ -4,25 +4,26 @@ function Invoke-CIPPStandardDisableSMS { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/SMS' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'SMS' -Enabled $false - } - - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/SMS' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS Support is enabled' -sev Alert - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS Support is not enabled' -sev Info - } + if ($State) { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'SMS' -Enabled $false + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is already disabled.' -sev Info } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableSMS' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } + + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SMS authentication method is not enabled' -sev Info } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'DisableSMS' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSecurityGroupUsers.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSecurityGroupUsers.ps1 index 75facbab7757..56510a1eb758 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSecurityGroupUsers.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSecurityGroupUsers.ps1 @@ -4,28 +4,32 @@ function Invoke-CIPPStandardDisableSecurityGroupUsers { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant + If ($Settings.remediate) { - - - try { - $body = '{"defaultUserRolePermissions":{"allowedToCreateSecurityGroups":false}}' - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json') - - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standards API: Disabled users from creating Security Groups.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating Security Groups: $($_.exception.message)" -sev 'Error' + if ($CurrentInfo.defaultUserRolePermissions.allowedToCreateSecurityGroups -eq $false) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already not allowed to create Security Groups.' -sev Info + } else { + try { + $body = '{"defaultUserRolePermissions":{"allowedToCreateSecurityGroups":false}}' + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating Security Groups.' -sev Info + $CurrentInfo.defaultUserRolePermissions.allowedToCreateSecurityGroups = $false + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating Security Groups: $($_.exception.message)" -sev 'Error' + } } } if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -tenantid $Tenant if ($CurrentInfo.defaultUserRolePermissions.allowedToCreateSecurityGroups -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not allowed to create Security Groups.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are allowed to create Security Groups.' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'DisableSecurityGroupUsers' -FieldValue [bool]$CurrentInfo.defaultUserRolePermissions.allowedToCreateSecurityGroups -StoreAs bool -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 index 50d18e51c43f..96c52b33e37c 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableVoice.ps1 @@ -4,25 +4,26 @@ function Invoke-CIPPStandardDisableVoice { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Voice' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Voice' -Enabled $false + if ($State) { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'Voice' -Enabled $false + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is already disabled.' -sev Info + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/Voice' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice Support is enabled' -sev Alert - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice Support is not enabled' -sev Info - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableVoice' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Voice authentication method is not enabled' -sev Info } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'DisableVoice' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 index 94a36d9b9125..c2da2547c1a5 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisablex509Certificate.ps1 @@ -4,25 +4,27 @@ function Invoke-CIPPStandardDisablex509Certificate { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/x509Certificate' -tenantid $Tenant + $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } If ($Settings.remediate) { - Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'x509Certificate' -Enabled $false + if ($State) { + Set-CIPPAuthenticationPolicy -Tenant $tenant -APIName 'Standards' -AuthenticationMethodId 'x509Certificate' -Enabled $false + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is already disabled.' -sev Info + } } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/x509Certificate' -tenantid $Tenant - $State = if ($CurrentInfo.state -eq 'enabled') { $true } else { $false } - - if ($Settings.alert) { - if ($State) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate Support is enabled' -sev Alert - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate Support is not enabled' -sev Info - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'Disablex509Certificate' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'x509Certificate authentication method is not enabled' -sev Info } } + + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'Disablex509Certificate' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } + } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSecurityDefaults.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSecurityDefaults.ps1 index 5d2c0c9c26f7..0c92a0829b60 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSecurityDefaults.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSecurityDefaults.ps1 @@ -5,26 +5,31 @@ function Invoke-CIPPStandardSecurityDefaults { #> param($Tenant, $Settings) $SecureDefaultsState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy' -tenantid $tenant) + If ($Settings.remediate) { - try { - if ($SecureDefaultsState.IsEnabled -ne $true) { + if ($SecureDefaultsState.IsEnabled -ne $true) { + try { Write-Host "Secure Defaults is disabled. Enabling for $tenant" -ForegroundColor Yellow $body = '{ "isEnabled": true }' - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy' -Type patch -Body $body -ContentType 'application/json') + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/identitySecurityDefaultsEnforcementPolicy' -Type patch -Body $body -ContentType 'application/json' + + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled Security Defaults.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Security Defaults. Error: $($_.exception.message)" -sev Error } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standards API: Security Defaults Enabled.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable Security Defaults Error: $($_.exception.message)" -sev 'Error' + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Security Defaults is already enabled.' -sev Info } } - if ($Settings.alert) { + if ($Settings.alert) { if ($SecureDefaultsState.IsEnabled -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Security Defaults is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Security Defaults is not enabled.' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'SecurityDefaults' -FieldValue [bool]$SecureDefaultsState.IsEnabled -StoreAs bool -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 index 1098903a7c74..5eae5226cd93 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUndoOauth.ps1 @@ -4,14 +4,35 @@ function Invoke-CIPPStandardUndoOauth { Internal #> param($Tenant, $Settings) + $CurrentState = New-GraphGetRequest -tenantid $Tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy?$select=permissionGrantPolicyIdsAssignedToDefaultUserRole' + $State = if ($CurrentState.permissionGrantPolicyIdsAssignedToDefaultUserRole -eq 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy') { $true } else { $false } + $State + If ($Settings.remediate) { - try { - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type PATCH -Body '{"permissionGrantPolicyIdsAssignedToDefaultUserRole":["ManagePermissionGrantsForSelf.microsoft-user-default-legacy"]}' -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Application Consent Mode has been disabled.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Application Consent Mode to disabled Error: $($_.exception.message)" -sev Error + if ($State) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is already disabled.' -sev Info + } else { + try { + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/policies/authorizationPolicy/authorizationPolicy' -Type PATCH -Body '{"permissionGrantPolicyIdsAssignedToDefaultUserRole":["ManagePermissionGrantsForSelf.microsoft-user-default-legacy"]}' -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Application Consent Mode has been disabled.' -sev Info + $CurrentState.permissionGrantPolicyIdsAssignedToDefaultUserRole = 'ManagePermissionGrantsForSelf.microsoft-user-default-legacy' + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set Application Consent Mode to disabled. Error: $($_.exception.message)" -sev Error + } + } + + } + + if ($Settings.alert) { + if ($State) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is disabled.' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Application Consent Mode is not disabled.' -sev Alert } } + if ($Settings.report) { + Add-CIPPBPAField -FieldName 'UndoOauth' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } } From 155711c5051949c7f156a9ea059e9e18641e7997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Fri, 9 Feb 2024 14:53:45 +0100 Subject: [PATCH 11/55] Add logic to check current outbound spam filter settings and update if necessary --- .../Invoke-CIPPStandardOutBoundSpamAlert.ps1 | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 index 1816a15ca998..9758a8c40b76 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 @@ -4,24 +4,32 @@ function Invoke-CIPPStandardOutBoundSpamAlert { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -useSystemMailbox $true + If ($Settings.remediate) { - $Contacts = $settings.OutboundSpamContact - try { - 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 { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set outbound spam contact to $($Contacts). $($_.exception.message)" -sev Error + + 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 + Write-LogMessage -API 'Standards' -tenant $tenant -message "Set outbound spam filter alert to $($Contacts)" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set outbound spam contact to $($Contacts). $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Outbound spam filter alert is already set to $($CurrentInfo.NotifyOutboundSpamRecipients)" -sev Info } } + if ($Settings.alert) { - $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -useSystemMailbox $true if ($CurrentInfo.NotifyOutboundSpam -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Outbound spam filter alert is set to $($CurrentInfo.NotifyOutboundSpamRecipients)" -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Outbound spam filter alert is not set' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'OutboundSpamAlert' -FieldValue [bool]$CurrentInfo.NotifyOutboundSpam -StoreAs bool -Tenant $tenant } From fc575ae1839e014851f91e5dc0f1b10e8006b697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 10 Feb 2024 12:04:09 +0100 Subject: [PATCH 12/55] fix reporting and alert bug --- .../Invoke-CIPPStandardDisableViva.ps1 | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 index 3c7332d68d7c..462c49f3cb24 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 @@ -4,26 +4,34 @@ function Invoke-CIPPStandardDisableViva { Internal #> param($Tenant, $Settings) - $currentsetting = New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/organization/$tenant/settings/peopleInsights" -tenantid $Tenant -AsApp $true + $CurrentSetting = New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/organization/$tenant/settings/peopleInsights" -tenantid $Tenant -AsApp $true + If ($Settings.remediate) { - try { - New-GraphPOSTRequest -Uri "https://graph.microsoft.com/beta/organization/$tenant/settings/peopleInsights" -tenantid $Tenant -AsApp $true -Type PATCH -Body '{"isEnabledInOrganization": false}' -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Viva insights' -sev Info - - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Viva for all users Error: $($_.exception.message)" -sev Error + + if ($CurrentSetting.isEnabledInOrganization -eq $false) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Viva is already disabled.' -sev Info + } else { + try { + New-GraphPOSTRequest -Uri "https://graph.microsoft.com/beta/organization/$tenant/settings/peopleInsights" -tenantid $Tenant -AsApp $true -Type PATCH -Body '{"isEnabledInOrganization": false}' -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Viva insights' -sev Info + + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Viva for all users. Error: $($_.exception.message)" -sev Error + } } } + if ($Settings.alert) { - if ($currentsetting.isEnabled -eq $false) { + if ($CurrentSetting.isEnabledInOrganization -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Viva is disabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Viva is not disabled' -sev Alert } } + if ($Settings.report) { - Add-CIPPBPAField -FieldName 'DisableViva' -FieldValue [bool]$currentsetting.isEnabled -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'DisableViva' -FieldValue [bool]$CurrentSetting.isEnabledInOrganization -StoreAs bool -Tenant $tenant } } From 3dbac5e3a69ceba0942491391c47e404ebf31f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 10 Feb 2024 12:28:01 +0100 Subject: [PATCH 13/55] More logging changes to standards --- .../Standards/Invoke-CIPPStandardAddDKIM.ps1 | 54 ++++++++++--------- .../Invoke-CIPPStandardAutoExpandArchive.ps1 | 17 +++--- .../Invoke-CIPPStandardDisableViva.ps1 | 2 +- .../Invoke-CIPPStandardEnableMailTips.ps1 | 43 +++++++-------- ...voke-CIPPStandardEnableMailboxAuditing.ps1 | 6 ++- ...oke-CIPPStandardSendReceiveLimitTenant.ps1 | 1 + .../Invoke-CIPPStandardSpoofWarn.ps1 | 26 +++++---- 7 files changed, 83 insertions(+), 66 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 index 9b6eb9012710..4a980913b0f6 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 @@ -13,32 +13,37 @@ function Invoke-CIPPStandardAddDKIM { $SetDomains = $DKIM | Where-Object { $AllDomains -contains $_.Domain -and $_.Enabled -eq $false } If ($Settings.remediate) { - $ErrorCounter = 0 - # New-domains - foreach ($Domain in $NewDomains) { - try { - (New-ExoRequest -tenantid $tenant -cmdlet 'New-DkimSigningConfig' -cmdparams @{ KeySize = 2048; DomainName = $Domain; Enabled = $true } -useSystemMailbox $true) - Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled DKIM for $Domain" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $($_.Exception.Message)" -sev Error - $ErrorCounter++ + + if ($null -eq $NewDomains -and $null -eq $SetDomains) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is already enabled for all available domains.' -sev Info + } else { + $ErrorCounter = 0 + # New-domains + foreach ($Domain in $NewDomains) { + try { + (New-ExoRequest -tenantid $tenant -cmdlet 'New-DkimSigningConfig' -cmdparams @{ KeySize = 2048; DomainName = $Domain; Enabled = $true } -useSystemMailbox $true) + Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled DKIM for $Domain" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $($_.Exception.Message)" -sev Error + $ErrorCounter++ + } } - } - - # Set-domains - foreach ($Domain in $SetDomains) { - try { - (New-ExoRequest -tenantid $tenant -cmdlet 'Set-DkimSigningConfig' -cmdparams @{ Identity = $Domain.Domain; Enabled = $true } -useSystemMailbox $true) - Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled DKIM for $($Domain.Domain)" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $($_.Exception.Message)" -sev Error - $ErrorCounter++ + + # Set-domains + foreach ($Domain in $SetDomains) { + try { + (New-ExoRequest -tenantid $tenant -cmdlet 'Set-DkimSigningConfig' -cmdparams @{ Identity = $Domain.Domain; Enabled = $true } -useSystemMailbox $true) + Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled DKIM for $($Domain.Domain)" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $($_.Exception.Message)" -sev Error + $ErrorCounter++ + } + } + if ($ErrorCounter -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DKIM for all domains in tenant' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Failed to enable DKIM for all domains in tenant' -sev Error } - } - if ($ErrorCounter -eq 0) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DKIM for all domains in tenant' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Failed to enable DKIM for all domains in tenant' -sev Error } } @@ -51,6 +56,7 @@ function Invoke-CIPPStandardAddDKIM { Write-LogMessage -API 'Standards' -tenant $tenant -message "DKIM is not enabled for: $NoDKIM" -sev Alert } } + if ($Settings.report) { if ($null -eq $NewDomains -and $null -eq $SetDomains) { $DKIMState = $true } else { $DKIMState = $false } Add-CIPPBPAField -FieldName 'DKIM' -FieldValue [bool]$DKIMState -StoreAs bool -Tenant $tenant diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoExpandArchive.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoExpandArchive.ps1 index 429466241b5c..0a12b3e92524 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoExpandArchive.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutoExpandArchive.ps1 @@ -5,25 +5,30 @@ function Invoke-CIPPStandardAutoExpandArchive { #> param($Tenant, $Settings) $CurrentState = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').AutoExpandingArchiveEnabled + If ($Settings.remediate) { - try { - if (!$currentstate) { + if ($CurrentState) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Auto Expanding Archive is already enabled.' -sev Info + } else { + try { New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{AutoExpandingArchive = $true } Write-LogMessage -API 'Standards' -tenant $tenant -message 'Added Auto Expanding Archive.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Auto Expanding Archives. Error: $($_.exception.message)" -sev Error } - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Auto Expanding Archives Error: $($_.exception.message)" -sev Error } } + if ($Settings.alert) { - if ($AuditLogEnabled) { + if ($CurrentState) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Auto Expanding Archives is enabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Auto Expanding Archives is not enabled' -sev Alert } } + if ($Settings.report) { - Add-CIPPBPAField -FieldName 'AutoExpandingArchive' -FieldValue [bool]$CurrentState.AutoExpandingArchiveEnabled -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'AutoExpandingArchive' -FieldValue [bool]$CurrentState -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 index 462c49f3cb24..788e9204328f 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableViva.ps1 @@ -12,9 +12,9 @@ function Invoke-CIPPStandardDisableViva { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Viva is already disabled.' -sev Info } else { try { + # TODO This does not work. Throws an "EXCEPTION: Tenant admin role is required" error. Cant figure out how to fix -Bobby New-GraphPOSTRequest -Uri "https://graph.microsoft.com/beta/organization/$tenant/settings/peopleInsights" -tenantid $Tenant -AsApp $true -Type PATCH -Body '{"isEnabledInOrganization": false}' -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Viva insights' -sev Info - } catch { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Viva for all users. Error: $($_.exception.message)" -sev Error } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 index 51991bf57f9e..47eb5a54118f 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1 @@ -5,38 +5,35 @@ function Invoke-CIPPStandardEnableMailTips { #> param($Tenant, $Settings) + $MailTipsState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig' | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold + $StateIsCorrect = if ($MailTipsState.MailTipsAllTipsEnabled -and $MailTipsState.MailTipsExternalRecipientsTipsEnabled -and $MailTipsState.MailTipsGroupMetricsEnabled -and $MailTipsState.MailTipsLargeAudienceThreshold -eq $Settings.MailTipsLargeAudienceThreshold) { $true } else { $false } if ($Settings.remediate) { - - try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdparams @{ MailTipsAllTipsEnabled = $true; MailTipsExternalRecipientsTipsEnabled = $true; MailTipsGroupMetricsEnabled = $true; MailTipsLargeAudienceThreshold = $Settings.MailTipsLargeAudienceThreshold } - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Enabled all MailTips' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to enable all MailTips: $($_.exception.message)" -sev Error + if ($StateIsCorrect) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are already enabled.' -sev Info + } else { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdparams @{ MailTipsAllTipsEnabled = $true; MailTipsExternalRecipientsTipsEnabled = $true; MailTipsGroupMetricsEnabled = $true; MailTipsLargeAudienceThreshold = $Settings.MailTipsLargeAudienceThreshold } + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Enabled all MailTips' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to enable all MailTips. Error: $($_.exception.message)" -sev Error + } } } + if ($Settings.alert) { - if ($Settings.alert -or $Settings.report) { - $MailTipsState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig' | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold - - if ($Settings.alert) { - if ($MailTipsState.MailTipsAllTipsEnabled -and $MailTipsState.MailTipsExternalRecipientsTipsEnabled -and $MailTipsState.MailTipsGroupMetricsEnabled -and $MailTipsState.MailTipsLargeAudienceThreshold -eq $Settings.MailTipsLargeAudienceThreshold) { - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are enabled' -sev Info - } else { - Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Not all MailTips are enabled' -sev Alert - } + if ($StateIsCorrect) { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are enabled' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Not all MailTips are enabled' -sev Alert } + } - if ($Settings.report) { + if ($Settings.report) { - if ($MailTipsState.MailTipsAllTipsEnabled -and $MailTipsState.MailTipsExternalRecipientsTipsEnabled -and $MailTipsState.MailTipsGroupMetricsEnabled -and $MailTipsState.MailTipsLargeAudienceThreshold -eq $Settings.MailTipsLargeAudienceThreshold) { - $MailTipsState = $true - } else { - $MailTipsState = $false - } - Add-CIPPBPAField -FieldName 'MailTipsEnabled' -FieldValue [bool]$MailTipsState -StoreAs bool -Tenant $tenant - } + Add-CIPPBPAField -FieldName 'MailTipsEnabled' -FieldValue [bool]$StateIsCorrect -StoreAs bool -Tenant $tenant } + } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 index 3bde7b01121f..c94a51555107 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 @@ -4,14 +4,15 @@ function Invoke-CIPPStandardEnableMailboxAuditing { Internal #> param($Tenant, $Settings) - $AuditState = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').AuditDisabled - if ( $Settings.remediate) { + + if ($Settings.remediate) { if ($AuditState) { # Enable tenant level mailbox audit try { New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{AuditDisabled = $false } -useSystemMailbox $true Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Tenant level mailbox audit enabled' -sev Info + $LogMessage = 'Tenant level mailbox audit enabled. ' } catch { Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to enable tenant level mailbox audit. Error: $($_.exception.message)" -sev Error } @@ -63,6 +64,7 @@ function Invoke-CIPPStandardEnableMailboxAuditing { Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Tenant level mailbox audit is enabled' -sev Info } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'MailboxAuditingEnabled' -FieldValue [bool]$AuditState -StoreAs bool -Tenant $Tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 index 640cea2d18f0..efd1df2a6c02 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 @@ -5,6 +5,7 @@ function Invoke-CIPPStandardSendReceiveLimitTenant { #> param($Tenant, $Settings) $AllMailBoxPlans = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MailboxPlan' | Select-Object DisplayName, MaxSendSize, MaxReceiveSize, GUID + If ($Settings.remediate) { Write-Host "Time to remediate. Our Settings are $($Settings.SendLimit)MB and $($Settings.ReceiveLimit)MB" $MaxReceiveSize = [int64]"$($Settings.SendLimit)MB" diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 index 4b8d790f7dcf..a2613c4d0f3d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSpoofWarn.ps1 @@ -4,28 +4,34 @@ function Invoke-CIPPStandardSpoofWarn { Internal #> param($Tenant, $Settings) + $CurrentInfo = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ExternalInOutlook') + If ($Settings.remediate) { $status = if ($Settings.enable -and $Settings.disable) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'You cannot both enable and disable the Spoof Warnings setting' -sev Error Exit - } elseif ($Settings.state -eq 'Enabled' -or $Settings.enable) { $true } else { $false } - try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ExternalInOutlook' -cmdParams @{ Enabled = $status; } - Write-LogMessage -API 'Standards' -tenant $tenant -message "Spoofing warnings set to $status." -sev Info + } elseif ($Settings.state -eq 'enabled' -or $Settings.enable) { $true } else { $false } - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set spoofing warnings to $status. Error: $($_.exception.message)" -sev Error + if ($CurrentInfo.Enabled -eq $status) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Outlook external spoof warnings are already set to $status." -sev Info + } else { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ExternalInOutlook' -cmdParams @{ Enabled = $status; } + Write-LogMessage -API 'Standards' -tenant $tenant -message "Outlook external spoof warnings set to $status." -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set Outlook external spoof warnings to $status. Error: $($_.exception.message)" -sev Error + } } } - if ($Settings.alert) { - $CurrentInfo = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ExternalInOutlook') + if ($Settings.alert) { if ($CurrentInfo.Enabled -eq $true) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Spoofing warnings are enabled.' -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Outlook external spoof warnings are enabled.' -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Spoofing warnings are not enabled.' -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Outlook external spoof warnings are not enabled.' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'SpoofingWarnings' -FieldValue [bool]$CurrentInfo.Enabled -StoreAs bool -Tenant $tenant } From 9415082ce75191a4e4095024e6c61f44738aa56a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sat, 10 Feb 2024 20:20:29 +0100 Subject: [PATCH 14/55] Fix mailbox plan send and receive size limits --- ...oke-CIPPStandardSendReceiveLimitTenant.ps1 | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 index efd1df2a6c02..e430e96a0f93 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 @@ -5,32 +5,45 @@ function Invoke-CIPPStandardSendReceiveLimitTenant { #> param($Tenant, $Settings) $AllMailBoxPlans = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MailboxPlan' | Select-Object DisplayName, MaxSendSize, MaxReceiveSize, GUID + $MaxSendSize = [int64]"$($Settings.SendLimit)MB" + $MaxReceiveSize = [int64]"$($Settings.ReceiveLimit)MB" + $NotSetCorrectly = foreach ($MailboxPlan in $AllMailBoxPlans) { + $PlanMaxSendSize = [int64]($MailboxPlan.MaxSendSize -replace '.*\(([\d,]+).*', '$1' -replace ',', '') + $PlanMaxReceiveSize = [int64]($MailboxPlan.MaxReceiveSize -replace '.*\(([\d,]+).*', '$1' -replace ',', '') + if ($PlanMaxSendSize -ne $MaxSendSize -or $PlanMaxReceiveSize -ne $MaxReceiveSize) { + $MailboxPlan + } + } + If ($Settings.remediate) { Write-Host "Time to remediate. Our Settings are $($Settings.SendLimit)MB and $($Settings.ReceiveLimit)MB" - $MaxReceiveSize = [int64]"$($Settings.SendLimit)MB" - $MaxSendSize = [int64]"$($Settings.ReceiveLimit)MB" - try { - foreach ($MailboxPlan in $AllMailBoxPlans) { - if ($MailboxPlan.MaxSendSize -ne $MaxSendSize -and $MailboxPlan.MaxReceiveSize -ne $MaxReceiveSize) { + if ($NotSetCorrectly.Count -gt 0) { + Write-Host "Found $($NotSetCorrectly.Count) Mailbox Plans that are not set correctly. Setting them to $($Settings.SendLimit)MB and $($Settings.ReceiveLimit)MB" + try { + foreach ($MailboxPlan in $NotSetCorrectly) { New-ExoRequest -tenantid $Tenant -cmdlet 'Set-MailboxPlan' -cmdParams @{Identity = $MailboxPlan.GUID; MaxSendSize = $MaxSendSize; MaxReceiveSize = $MaxReceiveSize } -useSystemMailbox $true } + Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully set the tenant send($($Settings.SendLimit)MB) and receive($($Settings.ReceiveLimit)MB) limits" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set the tenant send and receive limits. Error: $($_.exception.message)" -sev Error } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Successfully set the tenant send and receive limits ' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set the tenant send and receive limits. Error: $($_.exception.message)" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant send($($Settings.SendLimit)MB) and receive($($Settings.ReceiveLimit)MB) limits are already set correctly" -sev Info } } + if ($Settings.alert) { - foreach ($MailboxPlan in $AllMailBoxPlans) { - if ($MailboxPlan.MaxSendSize -ne $MaxSendSize -and $MailboxPlan.MaxReceiveSize -ne $MaxReceiveSize) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant send and receive limits are not set correctly for $($MailboxPlan.DisplayName)" -sev Alert - } + if ($NotSetCorrectly.Count -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant send($($Settings.SendLimit)MB) and receive($($Settings.ReceiveLimit)MB) limits are set correctly" -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "The tenant send($($Settings.SendLimit)MB) and receive($($Settings.ReceiveLimit)MB) limits are not set correctly" -sev Alert } } + if ($Settings.report) { - Add-CIPPBPAField -FieldName 'SendReceiveLimit' -FieldValue $AllMailBoxPlans -StoreAs json -Tenant $tenant + Add-CIPPBPAField -FieldName 'SendReceiveLimit' -FieldValue $NotSetCorrectly -StoreAs json -Tenant $tenant } } From f4a1f208df51e99a012793b81df135bc70cce55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 11 Feb 2024 01:22:42 +0100 Subject: [PATCH 15/55] Logging and bug fixing in the rest of the exchange standards --- .../Invoke-CIPPStandardDelegateSentItems.ps1 | 34 ++++++----- ...ndardDisableAdditionalStorageProviders.ps1 | 5 +- ...StandardDisableExternalCalendarSharing.ps1 | 42 +++++++------ ...nvoke-CIPPStandardDisableSharedMailbox.ps1 | 21 ++++--- ...voke-CIPPStandardEnableMailboxAuditing.ps1 | 1 + .../Invoke-CIPPStandardSafeSendersDisable.ps1 | 1 + .../Invoke-CIPPStandardSendFromAlias.ps1 | 27 ++++---- .../Invoke-CIPPStandardUserSubmissions.ps1 | 61 ++++++++++--------- 8 files changed, 107 insertions(+), 85 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 index 4c219d329ba6..dfca3c7c4456 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDelegateSentItems.ps1 @@ -7,28 +7,34 @@ function Invoke-CIPPStandardDelegateSentItems { $Mailboxes = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' -cmdParams @{ RecipientTypeDetails = @('UserMailbox', 'SharedMailbox') } | Where-Object { $_.MessageCopyForSendOnBehalfEnabled -eq $false -or $_.MessageCopyForSentAsEnabled -eq $false } If ($Settings.remediate) { - try { - $Mailboxes | ForEach-Object { - try { - $username = $_.UserPrincipalName - New-ExoRequest -tenantid $Tenant -cmdlet 'set-mailbox' -cmdParams @{Identity = $_.GUID ; MessageCopyForSendOnBehalfEnabled = $True; MessageCopyForSentAsEnabled = $True } -anchor $username - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not enable delegate sent item style for $($username): $($_.Exception.message)" -sev Warn - } - } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Delegate Sent Items Style enabled.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Delegate Sent Items Style. Error: $($_.exception.message)" -sev Error + + if ($Mailboxes) { + try { + $Mailboxes | ForEach-Object { + try { + $username = $_.UserPrincipalName + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-Mailbox' -cmdParams @{Identity = $_.GUID ; MessageCopyForSendOnBehalfEnabled = $True; MessageCopyForSentAsEnabled = $True } -anchor $username + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not enable delegate sent item style for $($username): $($_.Exception.message)" -sev Warn + } + } + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Delegate Sent Items Style enabled.' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Delegate Sent Items Style. Error: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Delegate Sent Items Style already enabled.' -sev Info + } } if ($Settings.alert) { - if ($Mailboxes) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Delegate Sent Items Style is not enabled for $($mailboxes.count) users" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Delegate Sent Items Style is not enabled for $($mailboxes.count) mailboxes" -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Delegate Sent Items Style is enabled' -sev Info } } + if ($Settings.report) { $Filtered = $Mailboxes | Select-Object -Property UserPrincipalName, MessageCopyForSendOnBehalfEnabled, MessageCopyForSentAsEnabled Add-CIPPBPAField -FieldName 'DelegateSentItems' -FieldValue $Filtered -StoreAs json -Tenant $tenant diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAdditionalStorageProviders.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAdditionalStorageProviders.ps1 index c90b9cb4c4f9..c0bab8bcb749 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAdditionalStorageProviders.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableAdditionalStorageProviders.ps1 @@ -4,7 +4,6 @@ function Invoke-CIPPStandardDisableAdditionalStorageProviders { Internal #> param($Tenant, $Settings) - $AdditionalStorageProvidersState = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OwaMailboxPolicy' -cmdParams @{Identity = 'OwaMailboxPolicy-Default' } if ($Settings.remediate) { @@ -23,8 +22,7 @@ function Invoke-CIPPStandardDisableAdditionalStorageProviders { } - if ($Settings.alert) { - + if ($Settings.alert) { if ($AdditionalStorageProvidersState.AdditionalStorageProvidersAvailable) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'OWA additional storage providers are enabled' -sev Alert } else { @@ -33,7 +31,6 @@ function Invoke-CIPPStandardDisableAdditionalStorageProviders { } if ($Settings.report) { - Add-CIPPBPAField -FieldName 'AdditionalStorageProvidersEnabled' -FieldValue [bool]$AdditionalStorageProvidersState.AdditionalStorageProvidersEnabled -StoreAs bool -Tenant $tenant } } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableExternalCalendarSharing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableExternalCalendarSharing.ps1 index e5e9232ed9b4..a1c29b7724c9 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableExternalCalendarSharing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableExternalCalendarSharing.ps1 @@ -4,33 +4,35 @@ function Invoke-CIPPStandardDisableExternalCalendarSharing { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SharingPolicy' | Where-Object { $_.Default -eq $true } if ($Settings.remediate) { - New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SharingPolicy' | Where-Object { $_.Default -eq $true } | ForEach-Object { - try { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SharingPolicy' -cmdParams @{ Identity = $_.Id ; Enabled = $false } -UseSystemMailbox $true - Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully disabled external calendar sharing for the policy $($_.Name)" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable external calendar sharing for the policy $($_.Name). Error: $($_.exception.message)" -sev Error + if ($CurrentInfo.Enabled) { + $CurrentInfo | ForEach-Object { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-SharingPolicy' -cmdParams @{ Identity = $_.Id ; Enabled = $false } -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Successfully disabled external calendar sharing for the policy $($_.Name)" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable external calendar sharing for the policy $($_.Name). Error: $($_.exception.message)" -sev Error + } } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'External calendar sharing is already disabled' -sev Info + } - } - # This is ugly but done to avoid a second call to the Graph API - if ($Settings.alert -or $Settings.report) { - $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-SharingPolicy' | Where-Object { $_.Default -eq $true } + } - if ($Settings.alert) { - if ($CurrentInfo.Enabled) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'External calendar sharing is enabled' -sev Alert - } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'External calendar sharing is not enabled' -sev Info - } - } - if ($Settings.report) { - Add-CIPPBPAField -FieldName 'ExternalCalendarSharingDisabled' -FieldValue [bool]$CurrentInfo.Enabled -StoreAs bool -Tenant $tenant + if ($Settings.alert) { + if ($CurrentInfo.Enabled) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'External calendar sharing is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'External calendar sharing is not enabled' -sev Info } } - + if ($Settings.report) { + $CurrentInfo.Enabled = -not $CurrentInfo.Enabled + Add-CIPPBPAField -FieldName 'ExternalCalendarSharingDisabled' -FieldValue [bool]$CurrentInfo.Enabled -StoreAs bool -Tenant $tenant + } } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharedMailbox.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharedMailbox.ps1 index 77e7295aaca8..45b637dcc905 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharedMailbox.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharedMailbox.ps1 @@ -5,24 +5,31 @@ function Invoke-CIPPStandardDisableSharedMailbox { #> param($Tenant, $Settings) $SharedMailboxList = (New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($Tenant)/Mailbox?`$filter=ExchangeUserAccountControl ne 'accountdisabled'" -Tenantid $tenant -scope ExchangeOnline | Where-Object { $_.RecipientTypeDetails -EQ 'SharedMailbox' -or $_.RecipientTypeDetails -eq 'SchedulingMailbox' }) + If ($Settings.remediate) { - try { + if ($SharedMailboxList) { $SharedMailboxList | ForEach-Object { - New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/users/$($_.ObjectKey)" -type 'PATCH' -body '{"accountEnabled":"false"}' -tenantid $tenant + try { + New-GraphPOSTRequest -uri "https://graph.microsoft.com/v1.0/users/$($_.ObjectKey)" -type PATCH -body '{"accountEnabled":"false"}' -tenantid $tenant + Write-LogMessage -API 'Standards' -tenant $tenant -message "AAD account for shared mailbox $($_.DisplayName) disabled." -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable AAD account for shared mailbox. Error: $($_.exception.message)" -sev Error + } } - Write-LogMessage -API 'Standards' -tenant $tenant -message 'AAD Accounts for shared mailboxes disabled.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable AAD accounts for shared mailboxes. Error: $($_.exception.message)" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'All AAD accounts for shared mailboxes are already disabled.' -sev Info } } + if ($Settings.alert) { if ($SharedMailboxList) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Shared mailboxes with enabled accounts: $($SharedMailboxList.count)" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Shared mailboxes with enabled accounts: $($SharedMailboxList.Count)" -sev Alert } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'No AAD accounts enables for shared mailboxes.' -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message 'All AAD accounts for shared mailboxes are disabled.' -sev Info } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'DisableSharedMailbox' -FieldValue $SharedMailboxList -StoreAs json -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 index c94a51555107..fcdc684d1f37 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 @@ -66,6 +66,7 @@ function Invoke-CIPPStandardEnableMailboxAuditing { } if ($Settings.report) { + $AuditState = -not $AuditState Add-CIPPBPAField -FieldName 'MailboxAuditingEnabled' -FieldValue [bool]$AuditState -StoreAs bool -Tenant $Tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 index a0cb61fa8e64..5563e3d5d4e4 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSafeSendersDisable.ps1 @@ -4,6 +4,7 @@ function Invoke-CIPPStandardSafeSendersDisable { Internal #> param($Tenant, $Settings) + If ($Settings.remediate) { try { $Mailboxes = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-Mailbox' | ForEach-Object { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendFromAlias.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendFromAlias.ps1 index cd4972866185..6d465e0b51f8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendFromAlias.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendFromAlias.ps1 @@ -4,28 +4,31 @@ function Invoke-CIPPStandardSendFromAlias { Internal #> param($Tenant, $Settings) + $CurrentInfo = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig').SendFromAliasEnabled + If ($Settings.remediate) { - try { - $AdminAuditLogParams = @{ - SendFromAliasEnabled = $true + if ($CurrentInfo -eq $false) { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams @{ SendFromAliasEnabled = $true } + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Send from alias enabled.' -sev Info + $CurrentInfo = $true + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable send from alias. Error: $($_.exception.message)" -sev Error } - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-OrganizationConfig' -cmdParams $AdminAuditLogParams - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Send from alias Enabled.' -sev Info - - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to apply Send from Alias Standard. Error: $($_.exception.message)" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Send from alias is already enabled.' -sev Info } } - if ($Settings.alert) { - $CurrentInfo = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-OrganizationConfig') - if ($CurrentInfo.SendFromAliasEnabled -eq $true) { + if ($Settings.alert) { + if ($CurrentInfo -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Send from alias is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Send from alias is not enabled.' -sev Alert } } + if ($Settings.report) { - Add-CIPPBPAField -FieldName 'SendFromAlias' -FieldValue [bool]$CurrentInfo.SendFromAliasEnabled -StoreAs bool -Tenant $tenant + Add-CIPPBPAField -FieldName 'SendFromAlias' -FieldValue [bool]$CurrentInfo -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserSubmissions.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserSubmissions.ps1 index f7a5ff7aa040..934f79995842 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserSubmissions.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardUserSubmissions.ps1 @@ -5,39 +5,43 @@ function Invoke-CIPPStandardUserSubmissions { #> param($Tenant, $Settings) $Policy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ReportSubmissionPolicy' + If ($Settings.remediate) { - if ($Settings.enable -and $Settings.disable) { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'You cannot both enable and disable the User Submission policy' -sev Error - Exit - } elseif ($Settings.enable) { - $status = $true - try { - - if ($Policy.length -eq 0) { - New-ExoRequest -tenantid $Tenant -cmdlet 'New-ReportSubmissionPolicy' - Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info - } else { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ReportSubmissionPolicy' -cmdParams @{ EnableReportToMicrosoft = $status; Identity = $($Policy.Identity); } - Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + $Status = if ($Settings.state -eq 'enable') { $true } else { $false } + + # If policy is set correctly, log and skip setting the policy + if ($Policy.EnableReportToMicrosoft -eq $status) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy is already set to $status." -sev Info + } else { + if ($Settings.state -eq 'enable') { + # Policy is not set correctly, enable the policy. Create new policy if it does not exist + try { + if ($Policy.length -eq 0) { + New-ExoRequest -tenantid $Tenant -cmdlet 'New-ReportSubmissionPolicy' -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + } else { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ReportSubmissionPolicy' -cmdParams @{ EnableReportToMicrosoft = $status; Identity = $($Policy.Identity); } -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + } + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set User Submission policy to $status. Error: $($_.exception.message)" -sev Error } - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set User Submission policy to $status. Error: $($_.exception.message)" -sev Error - } - } else { - $status = $false - try { - $Policy = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ReportSubmissionPolicy' - if ($Policy.length -eq 0) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info - } else { - New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ReportSubmissionPolicy' -cmdParams @{ EnableReportToMicrosoft = $status; Identity = $($Policy.Identity); EnableThirdPartyAddress = $status; ReportJunkToCustomizedAddress = $status; ReportNotJunkToCustomizedAddress = $status; ReportPhishToCustomizedAddress = $status; } - Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + } else { + # Policy is not set correctly, disable the policy. + try { + if ($Policy.length -eq 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + } else { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-ReportSubmissionPolicy' -cmdParams @{ EnableReportToMicrosoft = $status; Identity = $($Policy.Identity); EnableThirdPartyAddress = $status; ReportJunkToCustomizedAddress = $status; ReportNotJunkToCustomizedAddress = $status; ReportPhishToCustomizedAddress = $status; } -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "User Submission policy set to $status." -sev Info + } + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set User Submission policy to $status. Error: $($_.exception.message)" -sev Error } - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set User Submission policy to $status. Error: $($_.exception.message)" -sev Error } } } + if ($Settings.alert) { if ($Policy.length -eq 0) { @@ -50,6 +54,7 @@ function Invoke-CIPPStandardUserSubmissions { } } } + if ($Settings.report) { if ($Policy.length -eq 0) { Add-CIPPBPAField -FieldName 'UserSubmissionPolicy' -FieldValue $false -StoreAs bool -Tenant $tenant @@ -57,4 +62,4 @@ function Invoke-CIPPStandardUserSubmissions { Add-CIPPBPAField -FieldName 'UserSubmissionPolicy' -FieldValue [bool]$Policy.EnableReportToMicrosoft -StoreAs bool -Tenant $tenant } } -} +} \ No newline at end of file From cc942f769ca282e0888d162d2e3081925f7f844a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 11 Feb 2024 01:59:04 +0100 Subject: [PATCH 16/55] logging changes for intune standards --- .../Invoke-CIPPStandardintuneDeviceReg.ps1 | 18 ++++++----- ...CIPPStandardintuneDeviceRetirementDays.ps1 | 23 +++++++++----- .../Invoke-CIPPStandardintuneRequireMFA.ps1 | 30 +++++++++++-------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 index 6d2ece082f77..713fe5e8ff41 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceReg.ps1 @@ -7,13 +7,17 @@ function Invoke-CIPPStandardintuneDeviceReg { $PreviousSetting = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -tenantid $Tenant If ($Settings.remediate) { - try { - $PreviousSetting.userDeviceQuota = $Settings.max - $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting - 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 { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set user device quota to $($Settings.max) : $($_.exception.message)" -sev Error + if ($PreviousSetting.userDeviceQuota -eq $Settings.max) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "User device quota is already set to $($Settings.max)" -sev Info + } else { + try { + $PreviousSetting.userDeviceQuota = $Settings.max + $Newbody = ConvertTo-Json -Compress -InputObject $PreviousSetting + $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 { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set user device quota to $($Settings.max) : $($_.exception.message)" -sev Error + } } } if ($Settings.alert) { diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceRetirementDays.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceRetirementDays.ps1 index 502be8862b12..8ab48cf6efb9 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceRetirementDays.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneDeviceRetirementDays.ps1 @@ -4,27 +4,34 @@ function Invoke-CIPPStandardintuneDeviceRetirementDays { Internal #> param($Tenant, $Settings) + $CurrentInfo = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/deviceManagement/managedDeviceCleanupSettings' -tenantid $Tenant) + If ($Settings.remediate) { - try { - $body = @{ DeviceInactivityBeforeRetirementInDays = $Settings.days } | ConvertTo-Json - (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/deviceManagement/managedDeviceCleanupSettings' -Type PATCH -Body $body -ContentType 'application/json') - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DeviceInactivityBeforeRetirementInDays.' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DeviceInactivityBeforeRetirementInDays. Error: $($_.exception.message)" -sev Error + if ($CurrentInfo.DeviceInactivityBeforeRetirementInDays -eq $Settings.days) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "DeviceInactivityBeforeRetirementInDays for $($Settings.days) days is already enabled." -sev Info + } else { + try { + $body = @{ DeviceInactivityBeforeRetirementInDays = $Settings.days } | ConvertTo-Json + (New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/deviceManagement/managedDeviceCleanupSettings' -Type PATCH -Body $body -ContentType 'application/json') + Write-LogMessage -API 'Standards' -tenant $tenant -message "Enabled DeviceInactivityBeforeRetirementInDays for $($Settings.days) days." -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DeviceInactivityBeforeRetirementInDays. Error: $($_.exception.message)" -sev Error + } } } + if ($Settings.alert) { - $CurrentInfo = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/deviceManagement/managedDeviceCleanupSettings' -tenantid $Tenant) if ($CurrentInfo.DeviceInactivityBeforeRetirementInDays -eq $Settings.days) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'DeviceInactivityBeforeRetirementInDays is enabled.' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'DeviceInactivityBeforeRetirementInDays is not enabled.' -sev Alert } } + if ($Settings.report) { - if ($PreviousSetting.DeviceInactivityBeforeRetirementInDays -eq $Settings.days) { $UserQuota = $true } else { $UserQuota = $false } + $UserQuota = if ($PreviousSetting.DeviceInactivityBeforeRetirementInDays -eq $Settings.days) { $true } else { $false } Add-CIPPBPAField -FieldName 'intuneDeviceRetirementDays' -FieldValue [bool]$UserQuota -StoreAs bool -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 index 30a25866768e..f2cc643746e9 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardintuneRequireMFA.ps1 @@ -7,26 +7,32 @@ function Invoke-CIPPStandardintuneRequireMFA { $PreviousSetting = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy' -tenantid $Tenant If ($Settings.remediate) { - try { - $NewSetting = $PreviousSetting - $NewSetting.multiFactorAuthConfiguration = '1' - $Newbody = ConvertTo-Json -Compress -InputObject $NewSetting - 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 Intune Devices' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set require to use MFA when joining Intune Devices: $($_.exception.message)" -sev Error + if ($PreviousSetting.multiFactorAuthConfiguration -eq 'required') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Require to use MFA when joining/registering Entra Devices is already enabled.' -sev Info + } else { + try { + $NewSetting = $PreviousSetting + $NewSetting.multiFactorAuthConfiguration = '1' + $Newbody = ConvertTo-Json -Compress -InputObject $NewSetting + 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 { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set require to use MFA when joining/registering Entra Devices: $($_.exception.message)" -sev Error + } } } + if ($Settings.alert) { if ($PreviousSetting.multiFactorAuthConfiguration -eq 'required') { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Require to use MFA when joining Intune Devices is enabled.' -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Require to use MFA when joining/registering Entra Devices is enabled.' -sev Info } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Require to use MFA when joining Intune Devices is not enabled.' -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Require to use MFA when joining/registering Entra Devices is not enabled.' -sev Alert } } + if ($Settings.report) { - if ($PreviousSetting.multiFactorAuthConfiguration -eq 'required') { $UserQuota = $true } else { $UserQuota = $false } - Add-CIPPBPAField -FieldName 'intuneRequireMFA' -FieldValue [bool]$UserQuota -StoreAs bool -Tenant $tenant + $RequireMFA = if ($PreviousSetting.multiFactorAuthConfiguration -eq 'required') { $true } else { $false } + Add-CIPPBPAField -FieldName 'intuneRequireMFA' -FieldValue [bool]$RequireMFA -StoreAs bool -Tenant $tenant } } From 027d6c2b794a7db99c634f845bcafe11948c8f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 11 Feb 2024 17:23:02 +0100 Subject: [PATCH 17/55] logging for almost all of the rest of SP standards --- ...voke-CIPPStandardDeletedUserRentention.ps1 | 32 ++++++++------- ...voke-CIPPStandardDisableUserSiteCreate.ps1 | 23 +++++++---- .../Invoke-CIPPStandardExcludedfileExt.ps1 | 40 +++++++++++++------ .../Invoke-CIPPStandarddisableMacSync.ps1 | 25 +++++++----- .../Invoke-CIPPStandardsharingCapability.ps1 | 24 ++++++++--- .../Invoke-CIPPStandardunmanagedSync.ps1 | 26 ++++++------ 6 files changed, 110 insertions(+), 60 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDeletedUserRentention.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDeletedUserRentention.ps1 index 975368668560..ffda26966410 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDeletedUserRentention.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDeletedUserRentention.ps1 @@ -5,30 +5,34 @@ function Invoke-CIPPStandardDeletedUserRentention { #> param($Tenant, $Settings) $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + $StateSetCorrectly = if ($CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays -eq 365) { $true } else { $false } If ($Settings.remediate) { - try { - $body = '{"deletedUserPersonalSiteRetentionPeriodInDays": 365}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type PATCH -Body $body -ContentType 'application/json' - - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Set deleted user rentention of OneDrive to 1 year' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set deleted user rentention of OneDrive to 1 year: $($_.exception.message)" -sev Error + if ($StateSetCorrectly -eq $false) { + try { + $body = '{"deletedUserPersonalSiteRetentionPeriodInDays": 365}' + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type PATCH -Body $body -ContentType 'application/json' + + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Set deleted user rentention of OneDrive to 1 year' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set deleted user rentention of OneDrive to 1 year: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Deleted user rentention of OneDrive is already set to 1 year' -sev Info + } } + if ($Settings.alert) { - if ($CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays -eq 365) { + if ($StateSetCorrectly) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Deleted user rentention of OneDrive is set to 1 year' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Deleted user rentention of OneDrive is not set to 1 year' -sev Alert } } + if ($Settings.report) { - if ($CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays -eq 365) { - $CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays = $true - } else { - $CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays = $false - } - Add-CIPPBPAField -FieldName 'DeletedUserRentention' -FieldValue [bool]$CurrentInfo.deletedUserPersonalSiteRetentionPeriodInDays -StoreAs bool -Tenant $tenant + + Add-CIPPBPAField -FieldName 'DeletedUserRentention' -FieldValue [bool]$StateSetCorrectly -StoreAs bool -Tenant $tenant } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableUserSiteCreate.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableUserSiteCreate.ps1 index 3943cbc38d43..da501dac7956 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableUserSiteCreate.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableUserSiteCreate.ps1 @@ -4,24 +4,33 @@ function Invoke-CIPPStandardDisableUserSiteCreate { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + If ($Settings.remediate) { - try { - $body = '{"isSiteCreationEnabled": false}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled standard users from creating sites' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable standard users from creating sites: $($_.exception.message)" -sev Error + + if ($CurrentInfo.isSiteCreationEnabled) { + try { + $body = '{"isSiteCreationEnabled": false}' + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled standard users from creating sites' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable standard users from creating sites: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standard users are already disabled from creating sites' -sev Info } + } + if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true if ($CurrentInfo.isSiteCreationEnabled -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standard users are not allowed to create sites' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Standard users are allowed to create sites' -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'DisableUserSiteCreate' -FieldValue [bool]$CurrentInfo.isSiteCreationEnabled -StoreAs bool -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 index 7d52d6c4eb74..b5f8ab8c006a 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 @@ -4,27 +4,43 @@ function Invoke-CIPPStandardExcludedfileExt { Internal #> param($Tenant, $Settings) - $Exts = $Settings.ext -split ',' + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + $Exts = ($Settings.ext -replace ' ', '') -split ',' + + $MissingExclutions = foreach ($Exclusion in $Exts) { + if ($Exclusion -notin $CurrentInfo.excludedFileExtensionsForSyncApp) { + $Exclusion + } + } + Write-Host "MissingExclutions: $($MissingExclutions)" + + If ($Settings.remediate) { - - try { - $body = ConvertTo-Json -InputObject @{ excludedFileExtensionsForSyncApp = @($Exts) } - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message "Added $($Settings.ext) to excluded synced files" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to add $($Settings.ext) to excluded synced files: $($_.exception.message)" -sev Error + if ($MissingExclutions) { + Write-Host "CurrentInfo.excludedFileExtensionsForSyncApp: $($CurrentInfo.excludedFileExtensionsForSyncApp)" + Write-Host "Exts: $($Exts)" + try { + $body = ConvertTo-Json -InputObject @{ excludedFileExtensionsForSyncApp = @($Exts) } + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Added $($Settings.ext) to excluded synced files" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to add $($Settings.ext) to excluded synced files: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Excluded synced files already contains $($Settings.ext)" -sev Info } } + if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true - if ($CurrentInfo.excludedFileExtensionsForSyncApp -contains $Exts) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Excluded synced files contains $($Settings.ext)" -sev Info + if ($MissingExclutions) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Excluded synced files does not contain $($MissingExclutions -join ',')" -sev Alert } else { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Excluded synced files does not contain $($Settings.ext)" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Excluded synced files contains $($Settings.ext)" -sev Info } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'ExcludedfileExt' -FieldValue $CurrentInfo.excludedFileExtensionsForSyncApp -StoreAs json -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandarddisableMacSync.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandarddisableMacSync.ps1 index 41cd85e43c53..b273dbcb9fdd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandarddisableMacSync.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandarddisableMacSync.ps1 @@ -4,27 +4,34 @@ function Invoke-CIPPStandarddisableMacSync { Internal #> param($Tenant, $Settings) - If ($Settings.remediate) { - + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true - try { - $body = '{"isMacSyncAppEnabled": false}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Mac OneDrive Sync' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Mac OneDrive Sync: $($_.exception.message)" -sev Error + If ($Settings.remediate) { + + if ($CurrentInfo.isMacSyncAppEnabled -eq $true) { + try { + $body = '{"isMacSyncAppEnabled": false}' + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Mac OneDrive Sync' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Mac OneDrive Sync: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Mac OneDrive Sync is already disabled' -sev Info } } + if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true if ($CurrentInfo.isMacSyncAppEnabled -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Mac OneDrive Sync is disabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Mac OneDrive Sync is not disabled' -sev Alert } } + if ($Settings.report) { + $CurrentInfo.isMacSyncAppEnabled = -not $CurrentInfo.isMacSyncAppEnabled Add-CIPPBPAField -FieldName 'MacSync' -FieldValue [bool]$CurrentInfo.isMacSyncAppEnabled -StoreAs bool -Tenant $tenant } } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 index 0003bddc0be4..ee36e115f5b0 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 @@ -5,23 +5,35 @@ function Invoke-CIPPStandardsharingCapability { #> param($Tenant, $Settings) $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + # $CurrentInfo.sharingCapability.GetType() + $Settings.Level + $CurrentInfo.sharingCapability If ($Settings.remediate) { - try { - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body "{`"sharingCapability`":`"$($Settings.Level)`"}" -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message "Set sharing level to $($Settings.Level)" -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set sharing level to $($Settings.Level): $($_.exception.message)" -sev Error + + if ($CurrentInfo.sharingCapability -eq $Settings.Level) { + Write-Host "Sharing level is already set to $($Settings.Level)" + Write-LogMessage -API 'Standards' -tenant $tenant -message "Sharing level is already set to $($Settings.Level)" -sev Info + } else { + Write-Host "Setting sharing level to $($Settings.Level) from $($CurrentInfo.sharingCapability)" + try { + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body "{`"sharingCapability`":`"$($Settings.Level)`"}" -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message "Set sharing level to $($Settings.Level) from $($CurrentInfo.sharingCapability)" -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set sharing level to $($Settings.Level): $($_.exception.message)" -sev Error + } } } + if ($Settings.alert) { - if ($CurrentInfo.sharingCapability -eq $Settings.level) { + if ($CurrentInfo.sharingCapability -eq $Settings.Level) { Write-LogMessage -API 'Standards' -tenant $tenant -message "Sharing level is set to $($Settings.Level)" -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Sharing level is not set to $($Settings.Level)" -sev Alert } } + if ($Settings.report) { Add-CIPPBPAField -FieldName 'sharingCapability' -FieldValue $CurrentInfo.sharingCapability -StoreAs string -Tenant $tenant } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 index 42261e2b2d86..d7595fb0416e 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 @@ -4,18 +4,24 @@ function Invoke-CIPPStandardunmanagedSync { Internal #> param($Tenant, $Settings) + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true + If ($Settings.remediate) { - try { - $body = '{"isUnmanagedSyncAppForTenantRestricted": false}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' - Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Sync for unmanaged devices' -sev Info - } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Sync for unmanaged devices: $($_.exception.message)" -sev Error + + if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $false) { + try { + $body = '{"isUnmanagedSyncAppForTenantRestricted": false}' + New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Sync for unmanaged devices' -sev Info + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Sync for unmanaged devices: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Sync for unmanaged devices is already disabled' -sev Info } } if ($Settings.alert) { - $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $false) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Sync for unmanaged devices is disabled' -sev Info } else { @@ -23,11 +29,7 @@ function Invoke-CIPPStandardunmanagedSync { } } if ($Settings.report) { - if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $false) { - $CurrentInfo.isUnmanagedSyncAppForTenantRestricted = $true - } else { - $CurrentInfo.isUnmanagedSyncAppForTenantRestricted = $false - } + $CurrentInfo.isUnmanagedSyncAppForTenantRestricted = -not $CurrentInfo.isUnmanagedSyncAppForTenantRestricted Add-CIPPBPAField -FieldName 'unmanagedSync' -FieldValue [bool]$CurrentInfo.isUnmanagedSyncAppForTenantRestricted -StoreAs bool -Tenant $tenant } } From e744e91b5a7357be31bd4fbd1073af98c8268ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 11 Feb 2024 17:59:00 +0100 Subject: [PATCH 18/55] auto handling of extensions to be in correct format and replace all exts if there is too few or too many exts --- .../Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 index b5f8ab8c006a..902fe7301a6f 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardExcludedfileExt.ps1 @@ -6,17 +6,23 @@ function Invoke-CIPPStandardExcludedfileExt { param($Tenant, $Settings) $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -tenantid $Tenant -AsApp $true $Exts = ($Settings.ext -replace ' ', '') -split ',' + # Add a wildcard to the extensions since thats what the SP admin center does + $Exts = $Exts | ForEach-Object { if ($_ -notlike '*.*') { "*.$_" } else { $_ } } + $MissingExclutions = foreach ($Exclusion in $Exts) { if ($Exclusion -notin $CurrentInfo.excludedFileExtensionsForSyncApp) { $Exclusion } } + Write-Host "MissingExclutions: $($MissingExclutions)" If ($Settings.remediate) { + # If the number of extensions in the settings does not match the number of extensions in the current settings, we need to update the settings + $MissingExclutions = if ($Exts.Count -ne $CurrentInfo.excludedFileExtensionsForSyncApp.Count) { $true } else { $MissingExclutions } if ($MissingExclutions) { Write-Host "CurrentInfo.excludedFileExtensionsForSyncApp: $($CurrentInfo.excludedFileExtensionsForSyncApp)" Write-Host "Exts: $($Exts)" From 91b9efd067a5464a1aecb85003d292046fdb4402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Sun, 11 Feb 2024 18:00:33 +0100 Subject: [PATCH 19/55] Invert standard since it was doing the opposite of what it said --- .../Standards/Invoke-CIPPStandardunmanagedSync.ps1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 index d7595fb0416e..2d6f3b81bd34 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardunmanagedSync.ps1 @@ -10,8 +10,8 @@ function Invoke-CIPPStandardunmanagedSync { if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $false) { try { - $body = '{"isUnmanagedSyncAppForTenantRestricted": false}' - New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' + $body = '{"isUnmanagedSyncAppForTenantRestricted": true}' + $null = New-GraphPostRequest -tenantid $tenant -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings' -AsApp $true -Type patch -Body $body -ContentType 'application/json' Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled Sync for unmanaged devices' -sev Info } catch { Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Sync for unmanaged devices: $($_.exception.message)" -sev Error @@ -20,16 +20,17 @@ function Invoke-CIPPStandardunmanagedSync { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Sync for unmanaged devices is already disabled' -sev Info } } + if ($Settings.alert) { - if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $false) { + if ($CurrentInfo.isUnmanagedSyncAppForTenantRestricted -eq $true) { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Sync for unmanaged devices is disabled' -sev Info } else { Write-LogMessage -API 'Standards' -tenant $tenant -message 'Sync for unmanaged devices is not disabled' -sev Alert } } + if ($Settings.report) { - $CurrentInfo.isUnmanagedSyncAppForTenantRestricted = -not $CurrentInfo.isUnmanagedSyncAppForTenantRestricted Add-CIPPBPAField -FieldName 'unmanagedSync' -FieldValue [bool]$CurrentInfo.isUnmanagedSyncAppForTenantRestricted -StoreAs bool -Tenant $tenant } } From c691becc6d4355a2c44b26c42bac332fe667408c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 13 Feb 2024 16:02:19 -0500 Subject: [PATCH 20/55] Remove excluded tenants from CPV refresh --- UpdatePermissions/run.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UpdatePermissions/run.ps1 b/UpdatePermissions/run.ps1 index e4e73f4be9ed..5707bb45734a 100644 --- a/UpdatePermissions/run.ps1 +++ b/UpdatePermissions/run.ps1 @@ -1,7 +1,7 @@ # Input bindings are passed in via param block. param($Timer) -$Tenants = get-tenants -IncludeAll | Where-Object { $_.customerId -ne $env:TenantId } +$Tenants = get-tenants -IncludeErrors | Where-Object { $_.customerId -ne $env:TenantId } foreach ($Row in $Tenants) { Push-OutputBinding -Name Msg -Value $row } \ No newline at end of file From 98a2b7682f0a1d9d473b3b22bd1e8f2db8263152 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 14 Feb 2024 21:54:15 +0100 Subject: [PATCH 21/55] bug fix for CA policy. --- Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 | 2 +- PublicWebhooks/run.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 index 5fd635238470..0ecfd722c6cf 100644 --- a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 @@ -46,7 +46,7 @@ function New-CIPPCAPolicy { } #If Grant Controls contains authenticationstrength, create these and then replace the id - if ($JSONobj.GrantControls.authenticationStrength.policyType -eq 'custom') { + if ($JSONobj.GrantControls.authenticationStrength.policyType -eq 'custom' -or $JSONobj.GrantControls.authenticationStrength.policyType -eq 'BuiltIn') { $ExistingStrength = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/authenticationStrength/policies/' -tenantid $TenantFilter | Where-Object -Property displayName -EQ $JSONobj.GrantControls.authenticationStrength.displayName if ($ExistingStrength) { $JSONObj.GrantControls.authenticationStrength = @{ id = $ExistingStrength.id } diff --git a/PublicWebhooks/run.ps1 b/PublicWebhooks/run.ps1 index fc7ca248ea4c..2faa35804e05 100644 --- a/PublicWebhooks/run.ps1 +++ b/PublicWebhooks/run.ps1 @@ -14,7 +14,7 @@ if ($Request.Query.CIPPID -in $Webhooks.RowKey) { Write-Host 'Found matching CIPPID' if ($Webhooks.Resource -eq 'M365AuditLogs') { Write-Host "Found M365AuditLogs - This is an old entry, we'll deny so Microsoft stops sending it." - $body = 'This webhook is not authorized.' + $body = 'This webhook is not authorized, its an old entry.' $StatusCode = [HttpStatusCode]::Forbidden } if ($Request.query.ValidationToken -or $Request.body.validationCode) { From 76afff083010362ab32bceca99cbc064485c01bb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 15 Feb 2024 16:08:54 +0100 Subject: [PATCH 22/55] move some code around --- .../Public/Invoke-CIPPWebhookProcessing.ps1 | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 index fee8af4c24be..77139f1ddaba 100644 --- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 +++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 @@ -43,6 +43,18 @@ function Invoke-CippWebhookProcessing { $Proxy = if ($Location.Proxy -ne $null) { $Location.Proxy } else { 'Unknown' } $hosting = if ($Location.Hosting -ne $null) { $Location.Hosting } else { 'Unknown' } $ASName = if ($Location.ASName) { $Location.ASName } else { 'Unknown' } + $IP = $data.ClientIP + $LocationInfo = @{ + RowKey = [string]$data.clientip + PartitionKey = [string]$data.UserId + Tenant = [string]$TenantFilter + CountryOrRegion = "$Country" + City = "$City" + Proxy = "$Proxy" + Hosting = "$hosting" + ASName = "$ASName" + } + $null = Add-CIPPAzDataTableEntity @LocationTable -Entity $LocationInfo -Force } } $TableObj = [PSCustomObject]::new() @@ -128,15 +140,16 @@ function Invoke-CippWebhookProcessing { $dynamicIf = "`$data.$key -$operator '$value'" } if (Invoke-Expression $dynamicIf) { + Write-Host "Condition met: $dynamicIf" $ConditionMet = $true } else { + Write-Host "Condition not met: $dynamicIf" $ConditionMet = $false } } if ($ConditionMet) { #we're doing two loops, one first to collect the results of any action taken, then the second to pass those results via email etc. - $ActionResults = foreach ($action in $dos) { Write-Host "this is our action: $($action | ConvertTo-Json -Depth 15 -Compress))" switch ($action.execute) { @@ -212,6 +225,7 @@ function Invoke-CippWebhookProcessing { Send-CIPPAlert -Type 'psa' -Title $GenerateEmail.title -HTMLContent $GenerateEmail.htmlcontent -TenantFilter $TenantFilter } 'generateWebhook' { + Write-Host 'Generating the webhook content' $GenerateJSON = New-CIPPAlertTemplate -format 'json' -data $Data -ActionResults $ActionResults $JsonContent = @{ Title = $GenerateJSON.Title @@ -225,28 +239,12 @@ function Invoke-CippWebhookProcessing { PotentialASName = $ASName ActionsTaken = [string]($ActionResults | ConvertTo-Json -Depth 15 -Compress) } | ConvertTo-Json -Depth 15 -Compress + Write-Host 'Sending Webhook Content' + Send-CIPPAlert -Type 'webhook' -Title $GenerateJSON.Title -JSONContent $JsonContent -TenantFilter $TenantFilter } } } } } - - if ($data.ClientIP) { - $IP = $data.ClientIP - if ($IP -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$') { - $IP = $IP -replace ':\d+$', '' # Remove the port number if present - } - $LocationInfo = @{ - RowKey = [string]$ip - PartitionKey = [string]$data.UserId - Tenant = [string]$TenantFilter - CountryOrRegion = "$Country" - City = "$City" - Proxy = "$Proxy" - Hosting = "$hosting" - ASName = "$ASName" - } - $null = Add-CIPPAzDataTableEntity @LocationTable -Entity $LocationInfo -Force - } } From a486572742e951daf03fb1d68df6775135a9599c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 17 Feb 2024 19:17:04 +0100 Subject: [PATCH 23/55] improvements mailbox stats --- .../CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 index e6f2f4e3ff40..2e32585d341d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 @@ -47,6 +47,10 @@ function Invoke-ListGraphRequest { $Parameters.'$search' = $Request.Query.'$search' } + if ($Request.Query.'$format') { + $Parameters.'$format' = $Request.Query.'$format' + } + $GraphRequestParams = @{ Endpoint = $Request.Query.Endpoint Parameters = $Parameters From 56a4fb8e07cc78cd9f503b5450db9407bc47ed1e Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sat, 17 Feb 2024 19:18:44 +0100 Subject: [PATCH 24/55] resolve unrequired error --- Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 index 1e5f94064479..47d455057c19 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 @@ -16,6 +16,5 @@ function Push-CIPPAlertQuotaUsed { } } } catch { - Write-AlertMessage -tenant $($QueueItem.tenant) -message "Mailbox Quota Alert Error occurred: $(Get-NormalizedError -message $_.Exception.message)" } } From 05b6c79a5b2f23da15e5adf8f918acb047137428 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 18 Feb 2024 13:46:16 +0100 Subject: [PATCH 25/55] fixes displayname issue --- Modules/CIPPCore/Public/Entrypoints/Invoke-AddPolicy.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddPolicy.ps1 index 34a79bee6b7e..ca5240804f3b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddPolicy.ps1 @@ -42,7 +42,10 @@ Function Invoke-AddPolicy { if ($PolicyName -in $CheckExististing.displayName) { Throw "Policy with Display Name $($Displayname) Already exists" } - + $PolicyFile = $RawJSON | ConvertFrom-Json + $Null = $PolicyFile | Add-Member -MemberType NoteProperty -Name 'description' -Value $description -Force + $null = $PolicyFile | Add-Member -MemberType NoteProperty -Name 'displayName' -Value $displayname -Force + $RawJSON = ConvertTo-Json -InputObject $PolicyFile -Depth 20 $CreateRequest = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/$TemplateTypeURL" -tenantid $tenant -type POST -body $RawJSON } 'Catalog' { @@ -62,8 +65,7 @@ Function Invoke-AddPolicy { Set-CIPPAssignedPolicy -GroupName $AssignTo -PolicyId $CreateRequest.id -Type $TemplateTypeURL -TenantFilter $tenant } "Successfully added policy for $($Tenant)" - } - catch { + } catch { "Failed to add policy for $($Tenant): $($_.Exception.Message)" Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($Tenant) -message "Failed adding policy $($Displayname). Error: $($_.Exception.Message)" -Sev 'Error' continue From a21802df4db5b55567b19d2df9811e555819b830 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 18 Feb 2024 19:51:54 +0100 Subject: [PATCH 26/55] added sorts --- Modules/CIPPCore/Public/Entrypoints/Invoke-ListBPA.ps1 | 2 +- .../Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 | 2 +- .../Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBPA.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBPA.ps1 index e9f9f9a1fbf4..7ff48e0ca1c9 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBPA.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListBPA.ps1 @@ -13,7 +13,7 @@ Function Invoke-ListBPA { $Table = get-cipptable 'cachebpav2' $name = $Request.query.Report - if ($name -eq $null) { $name = 'CIPP Best Practices v1.0 - Table view' } + if ($name -eq $null) { $name = 'CIPP Best Practices v1.5 - Table view' } # Get all possible JSON files for reports, find the correct one, select the Columns $JSONFields = @() diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 index 28dc15275c83..897fcf53b3ed 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListExConnectorTemplates.ps1 @@ -22,7 +22,7 @@ Function Invoke-ListExConnectorTemplates { $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $GUID $data | Add-Member -NotePropertyName 'cippconnectortype' -NotePropertyValue $Direction $data - } + } | Sort-Object -Property displayName if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property RowKey -EQ $Request.query.id } diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 index e3270a1834b0..abd31c65b7cd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 @@ -35,8 +35,8 @@ Function Invoke-ListIntuneTemplates { $data | Add-Member -NotePropertyName 'Type' -NotePropertyValue $_.Type $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID $data - } - } + } | Sort-Object -Property displayName + } if ($Request.query.ID) { $Templates = $Templates | Where-Object -Property guid -EQ $Request.query.id } From 5b877e9663b3568c413a41c0c6717f28eedab9b1 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Sun, 18 Feb 2024 23:13:57 +0100 Subject: [PATCH 27/55] added manager field --- .../Public/Entrypoints/Invoke-AddUser.ps1 | 23 ++++++++++++------- .../Public/Entrypoints/Invoke-EditUser.ps1 | 9 +++++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1 index 8845a0a8987c..c1d7512b14d6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1 @@ -8,7 +8,7 @@ Function Invoke-AddUser { [CmdletBinding()] param($Request, $TriggerMetadata) - $APIName = "AddUser" + $APIName = 'AddUser' Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $Results = [System.Collections.ArrayList]@() @@ -56,8 +56,7 @@ Function Invoke-AddUser { $results.add('Created user.') $results.add("Username: $($UserprincipalName)") $results.add("Password: $password") - } - catch { + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($userobj.tenantid) -message "Failed to create user. Error:$($_.Exception.Message)" -Sev 'Error' $body = $results.add("Failed to create user. $($_.Exception.Message)" ) } @@ -70,8 +69,7 @@ Function Invoke-AddUser { $LicenseBody = if ($licenses.count -ge 2) { $liclist = foreach ($license in $Licenses) { '{"disabledPlans": [],"skuId": "' + $license + '" },' } '{"addLicenses": [' + $LicList + '], "removeLicenses": [ ] }' - } - else { + } else { '{"addLicenses": [ {"disabledPlans": [],"skuId": "' + $licenses + '" }],"removeLicenses": [ ]}' } Write-Host $LicenseBody @@ -97,8 +95,7 @@ Function Invoke-AddUser { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($userobj.tenantid) -message "Added alias $($Alias) to $($userobj.displayname)" -Sev 'Info' $body = $results.add("Added Aliases: $($Aliases -join ',')") } - } - catch { + } catch { Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($userobj.tenantid) -message "Failed to create the Aliases. Error:$($_.Exception.Message)" -Sev 'Error' $body = $results.add("Failed to create the Aliases: $($_.Exception.Message)") } @@ -107,7 +104,15 @@ Function Invoke-AddUser { $results.Add($CopyFrom.Success -join ', ') $results.Add($CopyFrom.Error -join ', ') } - + + if ($Request.body.setManager) { + $ManagerBody = [PSCustomObject]@{'@odata.id' = "https://graph.microsoft.com/beta/users/$($Request.body.setManager.value)" } + $ManagerBodyJSON = ConvertTo-Json -Compress -Depth 10 -InputObject $ManagerBody + New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($GraphRequest.id)/manager/`$ref" -tenantid $Userobj.tenantid -type PUT -body $ManagerBodyJSON -Verbose + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Set $($UserObj.DisplayName)'s manager to $($Request.body.setManager.label)" -Sev 'Info' + $results.add("Success. Set $($UserObj.DisplayName)'s manager to $($Request.body.setManager.label)") + } + $copyFromResults = @{ 'Success' = $CopyFrom.Success 'Error' = $CopyFrom.Error @@ -119,6 +124,8 @@ Function Invoke-AddUser { 'Password' = $password 'CopyFrom' = $copyFromResults } + + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1 index d5d7b4e1b961..7c4674317d06 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1 @@ -161,7 +161,14 @@ Function Invoke-EditUser { } } - + if ($Request.body.setManager) { + $ManagerBody = [PSCustomObject]@{'@odata.id' = "https://graph.microsoft.com/beta/users/$($Request.body.setManager.value)" } + $ManagerBodyJSON = ConvertTo-Json -Compress -Depth 10 -InputObject $ManagerBody + New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)/manager/`$ref" -tenantid $Userobj.tenantid -type PUT -body $ManagerBodyJSON -Verbose + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Set $($UserObj.DisplayName)'s manager to $($Request.body.setManager.label)" -Sev 'Info' + $results.add("Success. Set $($UserObj.DisplayName)'s manager to $($Request.body.setManager.label)") + } + if ($RemoveFromGroups) { $RemoveFromGroups | ForEach-Object { From 4d9a52d731da30d2b86967906fe94f781f62f54b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 20 Feb 2024 16:14:47 -0500 Subject: [PATCH 28/55] Dev environment improvements - Move dev authentication from local.settings.json to table storage - Env vars need to be removed before the new method will take effect - Limit use to only when Azurite connection string is detected - Update SAM wizard to work - Allow for UpdateTokens function to get new refresh token and avoid 90 day timeout --- .../Entrypoints/Invoke-ExecSAMSetup.ps1 | 400 ++++++++++-------- .../Public/Get-CIPPAuthentication.ps1 | 34 +- UpdateTokens/run.ps1 | 32 +- 3 files changed, 265 insertions(+), 201 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSAMSetup.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSAMSetup.ps1 index a224182bf1c9..ba829541e6dc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSAMSetup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSAMSetup.ps1 @@ -1,198 +1,242 @@ using namespace System.Net Function Invoke-ExecSAMSetup { - <# + <# .FUNCTIONALITY Entrypoint #> - [CmdletBinding()] - param($Request, $TriggerMetadata) - - $UserCreds = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json) - if ($Request.query.error) { - Add-Type -AssemblyName System.Web - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - ContentType = 'text/html' - StatusCode = [HttpStatusCode]::Forbidden - Body = Get-normalizedError -Message [System.Web.HttpUtility]::UrlDecode($Request.Query.error_description) - }) - exit - } - if ('admin' -notin $UserCreds.userRoles) { - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - ContentType = 'text/html' - StatusCode = [HttpStatusCode]::Forbidden - Body = 'Could not find an admin cookie in your browser. Make sure you do not have an adblocker active, use a Chromium browser, and allow cookies. If our automatic refresh does not work, try pressing the URL bar and hitting enter. We will try to refresh ourselves in 3 seconds.' - }) - exit - } - - $APIName = $TriggerMetadata.FunctionName - Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' - if ($env:MSI_SECRET) { + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $UserCreds = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json) + if ($Request.query.error) { + Add-Type -AssemblyName System.Web + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + ContentType = 'text/html' + StatusCode = [HttpStatusCode]::Forbidden + Body = Get-normalizedError -Message [System.Web.HttpUtility]::UrlDecode($Request.Query.error_description) + }) + exit + } + if ('admin' -notin $UserCreds.userRoles) { + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + ContentType = 'text/html' + StatusCode = [HttpStatusCode]::Forbidden + Body = 'Could not find an admin cookie in your browser. Make sure you do not have an adblocker active, use a Chromium browser, and allow cookies. If our automatic refresh does not work, try pressing the URL bar and hitting enter. We will try to refresh ourselves in 3 seconds.' + }) + exit + } + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $DevSecretsTable = Get-CIPPTable -tablename 'DevSecrets' + $Secret = Get-CIPPAzDataTableEntity @DevSecretsTable -Filter "PartitionKey eq 'Secret' and RowKey eq 'Secret'" + if (!$Secret) { + $Secret = [PSCustomObject]@{ + 'PartitionKey' = 'Secret' + 'RowKey' = 'Secret' + 'TenantId' = '' + 'RefreshToken' = '' + 'ApplicationId' = '' + 'ApplicationSecret' = '' + } + Add-CIPPAzDataTableEntity @DevSecretsTable -Entity $Secret -Force + } + } else { + if ($env:MSI_SECRET) { Disable-AzContextAutosave -Scope Process | Out-Null $AzSession = Connect-AzAccount -Identity - } - if (!$ENV:SetFromProfile) { - Write-Host "We're reloading from KV" - Get-CIPPAuthentication - } - - $KV = $ENV:WEBSITE_DEPLOYMENT_ID - $Table = Get-CIPPTable -TableName SAMWizard - $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).AddMinutes(-10) - - try { - if ($Request.query.count -lt 1 ) { $Results = 'No authentication code found. Please go back to the wizard.' } - - if ($request.body.setkeys) { - if ($request.body.tenantid) { Set-AzKeyVaultSecret -VaultName $kv -Name 'tenantid' -SecretValue (ConvertTo-SecureString -String $request.body.tenantid -AsPlainText -Force) } - if ($request.body.RefreshToken) { Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $request.body.RefreshToken -AsPlainText -Force) } - if ($request.body.applicationid) { Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationid' -SecretValue (ConvertTo-SecureString -String $request.body.applicationid -AsPlainText -Force) } - if ($request.body.applicationsecret) { Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationsecret' -SecretValue (ConvertTo-SecureString -String $request.body.applicationsecret -AsPlainText -Force) } - $Results = @{ Results = 'The keys have been replaced. Please perform a permissions check.' } + } + } + if (!$ENV:SetFromProfile) { + Write-Host "We're reloading from KV" + Get-CIPPAuthentication + } + + $KV = $ENV:WEBSITE_DEPLOYMENT_ID + $Table = Get-CIPPTable -TableName SAMWizard + $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).AddMinutes(-10) + + try { + if ($Request.query.count -lt 1 ) { $Results = 'No authentication code found. Please go back to the wizard.' } + + if ($request.body.setkeys) { + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + if ($request.body.TenantId) { $Secret.TenantId = $Request.body.tenantid } + if ($request.body.RefreshToken) { $Secret.RefreshToken = $Request.body.RefreshToken } + if ($request.body.applicationid) { $Secret.ApplicationId = $Request.body.ApplicationId } + if ($request.body.ApplicationSecret) { $Secret.ApplicationSecret = $Request.body.ApplicationSecret } + Add-CIPPAzDataTableEntity @DevSecretsTable -Entity $Secret -Force + } else { + if ($request.body.tenantid) { Set-AzKeyVaultSecret -VaultName $kv -Name 'tenantid' -SecretValue (ConvertTo-SecureString -String $request.body.tenantid -AsPlainText -Force) } + if ($request.body.RefreshToken) { Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $request.body.RefreshToken -AsPlainText -Force) } + if ($request.body.applicationid) { Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationid' -SecretValue (ConvertTo-SecureString -String $request.body.applicationid -AsPlainText -Force) } + if ($request.body.applicationsecret) { Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationsecret' -SecretValue (ConvertTo-SecureString -String $request.body.applicationsecret -AsPlainText -Force) } + } + $Results = @{ Results = 'The keys have been replaced. Please perform a permissions check.' } + } + if ($Request.query.error -eq 'invalid_client') { $Results = 'Client ID was not found in Azure. Try waiting 10 seconds to try again, if you have gotten this error after 5 minutes, please restart the process.' } + if ($request.query.code) { + try { + $TenantId = $Rows.tenantid + if (!$TenantId) { $TenantId = $ENV:TenantId } + $AppID = $Rows.appid + if (!$AppID) { $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 } + $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" + + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $Secret.RefreshToken = $RefreshToken.refresh_token + Add-CIPPAzDataTableEntity @DevSecretsTable -Entity $Secret -Force + } else { + Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $RefreshToken.refresh_token -AsPlainText -Force) + } + + $Results = 'Authentication is now complete. You may now close this window.' + try { + $SetupPhase = $rows.validated = $true + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + } catch { + #no need. + } + } catch { + $Results = "Authentication failed. $($_.Exception.message)" + } + } + if ($request.query.CreateSAM) { + $Rows = @{ + RowKey = 'setup' + PartitionKey = 'setup' + validated = $false + SamSetup = 'NotStarted' + partnersetup = $false + appid = 'NotStarted' + tenantid = 'NotStarted' } - if ($Request.query.error -eq 'invalid_client') { $Results = 'Client ID was not found in Azure. Try waiting 10 seconds to try again, if you have gotten this error after 5 minutes, please restart the process.' } - if ($request.query.code) { - try { - $TenantId = $Rows.tenantid - if (!$TenantId) { $TenantId = $ENV:TenantId } - $AppID = $Rows.appid - if (!$AppID) { $appid = $env:ApplicationId } - $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 - $clientsecret = Get-AzKeyVaultSecret -VaultName $kv -Name 'applicationsecret' -AsPlainText - if (!$clientsecret) { $clientsecret = $ENV:ApplicationSecret } - $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" - Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $RefreshToken.refresh_token -AsPlainText -Force) - $Results = 'Authentication is now complete. You may now close this window.' + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).AddMinutes(-10) + + if ($Request.query.partnersetup) { + $SetupPhase = $Rows.partnersetup = $true + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + } + $step = 1 + $DeviceLogon = New-DeviceLogin -clientid '1b730954-1685-4b74-9bfd-dac224a7b894' -Scope 'https://graph.microsoft.com/.default' -FirstLogon + $SetupPhase = $rows.SamSetup = [string]($DeviceLogon | ConvertTo-Json) + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + $Results = @{ message = "Your code is $($DeviceLogon.user_code). Enter the code" ; step = $step; url = $DeviceLogon.verification_uri } + } + if ($Request.query.CheckSetupProcess -and $request.query.step -eq 1) { + $SAMSetup = $Rows.SamSetup | ConvertFrom-Json -ErrorAction SilentlyContinue + $Token = (New-DeviceLogin -clientid '1b730954-1685-4b74-9bfd-dac224a7b894' -Scope 'https://graph.microsoft.com/.default' -device_code $SAMSetup.device_code) + if ($token.Access_Token) { + $step = 2 + $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 + $PartnerSetup = $Rows.partnersetup + $TenantId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/organization' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method GET -ContentType 'application/json').value.id + $SetupPhase = $rows.tenantid = [string]($TenantId) + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + if ($PartnerSetup) { + $app = Get-Content '.\Cache_SAMSetup\SAMManifest.json' | ConvertFrom-Json + $App.web.redirectUris = @($App.web.redirectUris + $URL) + $app = $app | ConvertTo-Json -Depth 15 + $AppId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/applications' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body $app -ContentType 'application/json') + $rows.appid = [string]($AppId.appId) + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + $attempt = 0 + do { try { - $SetupPhase = $rows.validated = $true - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + try { + $SPNDefender = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"fc780465-2017-40d4-a0c5-307022471b92`" }" -ContentType 'application/json') + } catch { + Write-Host "didn't deploy spn for defender, probably already there." + } + try { + $SPNTeams = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"48ac35b8-9aa8-4d74-927d-1f4a14a0b239`" }" -ContentType 'application/json') + } catch { + Write-Host "didn't deploy spn for Teams, probably already there." + } + $SPN = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"$($AppId.appId)`" }" -ContentType 'application/json') + Start-Sleep 3 + $GroupID = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/groups?`$filter=startswith(displayName,'AdminAgents')" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method Get -ContentType 'application/json').value.id + Write-Host "Id is $GroupID" + $AddingToAdminAgent = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/groups/$($GroupID)/members/`$ref" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"@odata.id`": `"https://graph.microsoft.com/v1.0/directoryObjects/$($SPN.id)`"}" -ContentType 'application/json') + Write-Host 'Added to adminagents' + $attempt ++ } catch { - #no need. + $attempt ++ } - } catch { - $Results = "Authentication failed. $($_.Exception.message)" - } + } until ($attempt -gt 5) + } else { + $app = Get-Content '.\Cache_SAMSetup\SAMManifestNoPartner.json' + $AppId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/applications' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body $app -ContentType 'application/json') + $rows.appid = [string]($AppId.appId) + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + } + $AppPassword = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/applications/$($AppID.id)/addPassword" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body '{"passwordCredential":{"displayName":"CIPPInstall"}}' -ContentType 'application/json').secretText + + + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $Secret.TenantId = $Request.body.tenantid + $Secret.ApplicationId = $Request.body.ApplicationId + $Secret.ApplicationSecret = $Request.body.ApplicationSecret + Add-CIPPAzDataTableEntity @DevSecretsTable -Entity $Secret -Force + } else { + Set-AzKeyVaultSecret -VaultName $kv -Name 'tenantid' -SecretValue (ConvertTo-SecureString -String $TenantId -AsPlainText -Force) + Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationid' -SecretValue (ConvertTo-SecureString -String $Appid.appid -AsPlainText -Force) + Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationsecret' -SecretValue (ConvertTo-SecureString -String $AppPassword -AsPlainText -Force) + } + $Results = @{'message' = 'Created application. Waiting 30 seconds for Azure propagation'; step = $step } + } else { + $step = 1 + $Results = @{ message = "Your code is $($SAMSetup.user_code). Enter the code " ; step = $step; url = $SAMSetup.verification_uri } } - if ($request.query.CreateSAM) { - $Rows = @{ - RowKey = 'setup' - PartitionKey = 'setup' - validated = $false - SamSetup = 'NotStarted' - partnersetup = $false - appid = 'NotStarted' - tenantid = 'NotStarted' - } - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).AddMinutes(-10) - - if ($Request.query.partnersetup) { - $SetupPhase = $Rows.partnersetup = $true - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - } - $step = 1 - $DeviceLogon = New-DeviceLogin -clientid '1b730954-1685-4b74-9bfd-dac224a7b894' -Scope 'https://graph.microsoft.com/.default' -FirstLogon - $SetupPhase = $rows.SamSetup = [string]($DeviceLogon | ConvertTo-Json) - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - $Results = @{ message = "Your code is $($DeviceLogon.user_code). Enter the code" ; step = $step; url = $DeviceLogon.verification_uri } + + } + switch ($request.query.step) { + 2 { + $step = 2 + $TenantId = $Rows.tenantid + $AppID = $rows.appid + $PartnerSetup = $Rows.partnersetup + $SetupPhase = $rows.SamSetup = [string]($FirstLogonRefreshtoken | ConvertTo-Json) + Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null + $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 + $Validated = $Rows.validated + if ($Validated) { $step = 3 } + $Results = @{ message = 'Give the next approval by clicking ' ; step = $step; url = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/authorize?scope=https://graph.microsoft.com/.default+offline_access+openid+profile&response_type=code&client_id=$($appid)&redirect_uri=$($url)" } } - if ($Request.query.CheckSetupProcess -and $request.query.step -eq 1) { - $SAMSetup = $Rows.SamSetup | ConvertFrom-Json -ErrorAction SilentlyContinue - $Token = (New-DeviceLogin -clientid '1b730954-1685-4b74-9bfd-dac224a7b894' -Scope 'https://graph.microsoft.com/.default' -device_code $SAMSetup.device_code) - if ($token.Access_Token) { - $step = 2 - $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 - $PartnerSetup = $Rows.partnersetup - $TenantId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/organization' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method GET -ContentType 'application/json').value.id - $SetupPhase = $rows.tenantid = [string]($TenantId) - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - if ($PartnerSetup) { - $app = Get-Content '.\Cache_SAMSetup\SAMManifest.json' | ConvertFrom-Json - $App.web.redirectUris = @($App.web.redirectUris + $URL) - $app = $app | ConvertTo-Json -Depth 15 - $AppId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/applications' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body $app -ContentType 'application/json') - $rows.appid = [string]($AppId.appId) - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - $attempt = 0 - do { - try { - try { - $SPNDefender = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"fc780465-2017-40d4-a0c5-307022471b92`" }" -ContentType 'application/json') - } catch { - Write-Host "didn't deploy spn for defender, probably already there." - } - try { - $SPNTeams = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"48ac35b8-9aa8-4d74-927d-1f4a14a0b239`" }" -ContentType 'application/json') - } catch { - Write-Host "didn't deploy spn for Teams, probably already there." - } - $SPN = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/servicePrincipals' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"appId`": `"$($AppId.appId)`" }" -ContentType 'application/json') - Start-Sleep 3 - $GroupID = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/groups?`$filter=startswith(displayName,'AdminAgents')" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method Get -ContentType 'application/json').value.id - Write-Host "Id is $GroupID" - $AddingToAdminAgent = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/groups/$($GroupID)/members/`$ref" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body "{ `"@odata.id`": `"https://graph.microsoft.com/v1.0/directoryObjects/$($SPN.id)`"}" -ContentType 'application/json') - Write-Host 'Added to adminagents' - $attempt ++ - } catch { - $attempt ++ - } - } until ($attempt -gt 5) - } else { - $app = Get-Content '.\Cache_SAMSetup\SAMManifestNoPartner.json' - $AppId = (Invoke-RestMethod 'https://graph.microsoft.com/v1.0/applications' -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body $app -ContentType 'application/json') - $rows.appid = [string]($AppId.appId) - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - } - $AppPassword = (Invoke-RestMethod "https://graph.microsoft.com/v1.0/applications/$($AppID.id)/addPassword" -Headers @{ authorization = "Bearer $($Token.Access_Token)" } -Method POST -Body '{"passwordCredential":{"displayName":"CIPPInstall"}}' -ContentType 'application/json').secretText - Set-AzKeyVaultSecret -VaultName $kv -Name 'tenantid' -SecretValue (ConvertTo-SecureString -String $TenantId -AsPlainText -Force) - Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationid' -SecretValue (ConvertTo-SecureString -String $Appid.appid -AsPlainText -Force) - Set-AzKeyVaultSecret -VaultName $kv -Name 'applicationsecret' -SecretValue (ConvertTo-SecureString -String $AppPassword -AsPlainText -Force) - $Results = @{'message' = 'Created application. Waiting 30 seconds for Azure propagation'; step = $step } - } else { - $step = 1 - $Results = @{ message = "Your code is $($SAMSetup.user_code). Enter the code " ; step = $step; url = $SAMSetup.verification_uri } - } - + 3 { + + $step = 4 + $Results = @{'message' = 'Received token.'; step = $step } + + } - switch ($request.query.step) { - 2 { - $step = 2 - $TenantId = $Rows.tenantid - $AppID = $rows.appid - $PartnerSetup = $Rows.partnersetup - $SetupPhase = $rows.SamSetup = [string]($FirstLogonRefreshtoken | ConvertTo-Json) - Add-CIPPAzDataTableEntity @Table -Entity $Rows -Force | Out-Null - $URL = ($Request.headers.'x-ms-original-url').split('?') | Select-Object -First 1 - $Validated = $Rows.validated - if ($Validated) { $step = 3 } - $Results = @{ message = 'Give the next approval by clicking ' ; step = $step; url = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/authorize?scope=https://graph.microsoft.com/.default+offline_access+openid+profile&response_type=code&client_id=$($appid)&redirect_uri=$($url)" } - } - 3 { - - $step = 4 - $Results = @{'message' = 'Received token.'; step = $step } - - - } - 4 { - Remove-AzDataTableEntity @Table -Entity $Rows - - $step = 5 - $Results = @{'message' = 'setup completed.'; step = $step - } - } + 4 { + Remove-AzDataTableEntity @Table -Entity $Rows + + $step = 5 + $Results = @{'message' = 'setup completed.'; step = $step + } } + } - } catch { - $Results = [pscustomobject]@{'Results' = "Failed. $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.message)" ; step = $step } - } + } catch { + $Results = [pscustomobject]@{'Results' = "Failed. $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.message)" ; step = $step } + } - # Associate values to output bindings by calling 'Push-OutputBinding'. - Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ - StatusCode = [HttpStatusCode]::OK - Body = $Results - }) + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $Results + }) } diff --git a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 index 97a499bdfc82..0d3092fc54c3 100644 --- a/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 +++ b/Modules/CIPPCore/Public/Get-CIPPAuthentication.ps1 @@ -2,23 +2,35 @@ function Get-CIPPAuthentication { [CmdletBinding()] param ( - $APIName = "Get Keyvault Authentication" + $APIName = 'Get Keyvault Authentication' ) + $Variables = @('ApplicationId', 'ApplicationSecret', 'TenantId', 'RefreshToken') try { - Connect-AzAccount -Identity - - @('ApplicationId','ApplicationSecret','TenantId','RefreshToken') | Foreach-Object { - Set-Item -path ENV:$_ -value (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name $_ -AsPlainText -ErrorAction Stop) -Force + if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $Table = Get-CIPPTable -tablename 'DevSecrets' + $Secret = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'Secret' and RowKey eq 'Secret'" + if (!$Secret) { + throw 'Development variables not set' + } + foreach ($Var in $Variables) { + if ($Secret.$Var) { + Set-Item -Path ENV:$Var -Value $Secret.$Var -Force -ErrorAction Stop + } + } + } else { + Connect-AzAccount -Identity + + $Variables | ForEach-Object { + Set-Item -Path ENV:$_ -Value (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name $_ -AsPlainText -ErrorAction Stop) -Force + } } - $ENV:SetFromProfile = $true - Write-LogMessage -message "Reloaded authentication data from KeyVault" -Sev 'debug' -API "CIPP Authentication" + Write-LogMessage -message 'Reloaded authentication data from KeyVault' -Sev 'debug' -API 'CIPP Authentication' - return $true - } - catch { - Write-LogMessage -message "Could not retrieve keys from Keyvault: $($_.Exception.Message)" -Sev 'CRITICAL' -API "CIPP Authentication" + return $true + } catch { + Write-LogMessage -message "Could not retrieve keys from Keyvault: $($_.Exception.Message)" -Sev 'CRITICAL' -API 'CIPP Authentication' return $false } } diff --git a/UpdateTokens/run.ps1 b/UpdateTokens/run.ps1 index 8f80a365bbb3..ed20d6a67fbf 100644 --- a/UpdateTokens/run.ps1 +++ b/UpdateTokens/run.ps1 @@ -6,18 +6,26 @@ $currentUTCtime = (Get-Date).ToUniversalTime() $Refreshtoken = (Get-GraphToken -ReturnRefresh $true).Refresh_token -if ($env:MSI_SECRET) { - Disable-AzContextAutosave -Scope Process | Out-Null - $AzSession = Connect-AzAccount -Identity -} - -$KV = $ENV:WEBSITE_DEPLOYMENT_ID - -if ($Refreshtoken) { - Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $Refreshtoken -AsPlainText -Force) -} -else { - Write-LogMessage -message "Could not update refresh token. Will try again in 7 days." -sev "CRITICAL" +if ($env:AzureWebJobsStorage -eq 'UseDevelopmentStorage=true') { + $Table = Get-CIPPTable -tablename 'DevSecrets' + $Secret = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'Secret' and RowKey eq 'Secret'" + if ($Secret) { + $Secret.RefreshToken = $Refreshtoken + Add-AzDataTableEntity @Table -Entity $Secret + } else { + Write-LogMessage -message 'Could not update refresh token. Will try again in 7 days.' -sev 'CRITICAL' + } +} else { + if ($env:MSI_SECRET) { + Disable-AzContextAutosave -Scope Process | Out-Null + $AzSession = Connect-AzAccount -Identity + } + $KV = $ENV:WEBSITE_DEPLOYMENT_ID + if ($Refreshtoken) { + Set-AzKeyVaultSecret -VaultName $kv -Name 'RefreshToken' -SecretValue (ConvertTo-SecureString -String $Refreshtoken -AsPlainText -Force) + } else { + Write-LogMessage -message 'Could not update refresh token. Will try again in 7 days.' -sev 'CRITICAL' + } } # Write an information log with the current time. From daa89c8735a577996d40ffa1649a5c24f0176e61 Mon Sep 17 00:00:00 2001 From: Roel van der Wegen Date: Wed, 21 Feb 2024 10:14:31 +0100 Subject: [PATCH 29/55] Minor wording fix --- Modules/DNSHealth/1.0.7/DNSHealth.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/DNSHealth/1.0.7/DNSHealth.psm1 b/Modules/DNSHealth/1.0.7/DNSHealth.psm1 index b69e40274c16..749a158a5fa6 100644 --- a/Modules/DNSHealth/1.0.7/DNSHealth.psm1 +++ b/Modules/DNSHealth/1.0.7/DNSHealth.psm1 @@ -1179,7 +1179,7 @@ function Read-MXRecord { catch { Write-Verbose $_.Exception.Message } } - $ValidationPasses.Add('Mail exchanger records record(s) are present for this domain.') | Out-Null + $ValidationPasses.Add('Mail exchanger record(s) are present for this domain.') | Out-Null $MXRecords = $MXRecords | Sort-Object -Property Priority # Attempt to identify mail provider based on MX record From 9a86a42e653322f9660948e47b939e155587a759 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 21 Feb 2024 11:39:37 +0100 Subject: [PATCH 30/55] add urlonly --- Modules/CIPPCore/Public/Entrypoints/Invoke-ListSites.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSites.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSites.ps1 index 9a0d7a228765..51f31ef28b70 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSites.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListSites.ps1 @@ -52,6 +52,10 @@ Function Invoke-ListSites { $StatusCode = [HttpStatusCode]::Forbidden $GraphRequest = $ErrorMessage } + if ($Request.query.URLOnly -eq 'true') { + $GraphRequest = $GraphRequest | Where-Object { $null -ne $_.URL } + } + # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = $StatusCode From 38533bd7543aa75bc4bfb3f18e749702a8f103a4 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 21 Feb 2024 11:57:11 +0100 Subject: [PATCH 31/55] solves issue with deleting templates by overwriting the guid. --- .../Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 index abd31c65b7cd..d9c02d090fb2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListIntuneTemplates.ps1 @@ -32,8 +32,8 @@ Function Invoke-ListIntuneTemplates { $data = $_.RAWJson | ConvertFrom-Json $data | Add-Member -NotePropertyName 'displayName' -NotePropertyValue $_.Displayname -Force $data | Add-Member -NotePropertyName 'description' -NotePropertyValue $_.Description -Force - $data | Add-Member -NotePropertyName 'Type' -NotePropertyValue $_.Type - $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID + $data | Add-Member -NotePropertyName 'Type' -NotePropertyValue $_.Type -Force + $data | Add-Member -NotePropertyName 'GUID' -NotePropertyValue $_.GUID -Force $data } | Sort-Object -Property displayName } From 70c051eca557652a9e1859a295740ff0d00e4476 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 21 Feb 2024 13:06:44 +0100 Subject: [PATCH 32/55] add device actions --- .../Entrypoints/Invoke-ExecDeviceDelete.ps1 | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ExecDeviceDelete.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecDeviceDelete.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecDeviceDelete.ps1 new file mode 100644 index 000000000000..843764a6d5d4 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecDeviceDelete.ps1 @@ -0,0 +1,35 @@ +using namespace System.Net + +Function Invoke-ExecDeviceDelete { + <# + .FUNCTIONALITY + Entrypoint + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + + # Interact with query parameters or the body of the request. + + + try { + $url = "https://graph.microsoft.com/beta/devices/$($request.query.id)" + if ($Request.query.action -eq 'delete') { + $ActionResult = New-GraphPOSTRequest -uri $url -type DELETE -tenantid $Request.Query.TenantFilter + } else { + $ActionResult = New-GraphPOSTRequest -uri $url -type PATCH -tenantid $Request.Query.TenantFilter -body '{"accountEnabled": false }' + } + $body = [pscustomobject]@{'Results' = "Executed action $($Request.query.action) on $($Request.query.id)" } + } catch { + $body = [pscustomobject]@{'Results' = "Failed to queue action $($Request.query.action) on $($request.query.id): $($_.Exception.Message)" } + } + + # Associate values to output bindings by calling 'Push-OutputBinding'. + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = [HttpStatusCode]::OK + Body = $body + }) + +} From d5d762dab618804a8cb51ef90f4549dccb3c6133 Mon Sep 17 00:00:00 2001 From: jonc3tech <153545031+jonc3tech@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:25:58 -0500 Subject: [PATCH 33/55] adds check for basic complexity requirements to New-passworstring --- .../Public/GraphHelper/New-passwordString.ps1 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/GraphHelper/New-passwordString.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-passwordString.ps1 index 6793c5cc17b3..5869c370108e 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-passwordString.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-passwordString.ps1 @@ -13,6 +13,23 @@ function New-passwordString { $Words = Get-Content .\words.txt (Get-Random -InputObject $words -Count 4) -join '-' } else { - -join ('abcdefghkmnrstuvwxyzABCDEFGHKLMNPRSTUVWXYZ23456789$%&*#'.ToCharArray() | Get-Random -Count $count) + # Generate a complex password with a maximum of 100 tries + $maxTries = 100 + $tryCount = 0 + + do { + $Password = -join ('abcdefghkmnrstuvwxyzABCDEFGHKLMNPRSTUVWXYZ23456789$%&*#'.ToCharArray() | Get-Random -Count $count) + + $containsUppercase = $Password -cmatch '[A-Z]' + $containsLowercase = $Password -cmatch '[a-z]' + $containsDigit = $Password -cmatch '\d' + $containsSpecialChar = $Password -cmatch "[$%&*#]" + + $isComplex = $containsUppercase -and $containsLowercase -and $containsDigit -and $containsSpecialChar + + $tryCount++ + } while (!$isComplex -and ($tryCount -lt $maxTries)) + + $Password } } From 725e7bb3eee1d16795dcd8ca2e7b671863f03d9b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 21 Feb 2024 16:59:02 -0500 Subject: [PATCH 34/55] Cleanup graph explorer import/export --- .../Entrypoints/Invoke-ExecGraphExplorerPreset.ps1 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGraphExplorerPreset.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGraphExplorerPreset.ps1 index b4d51d4f5d18..883d43e2fce6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGraphExplorerPreset.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGraphExplorerPreset.ps1 @@ -21,21 +21,25 @@ Function Invoke-ExecGraphExplorerPreset { $Id = (New-Guid).Guid } 'Save' { - $Id = $Request.Body.values.reportTemplate.value + $Id = $Request.Body.preset.reportTemplate.value } 'Delete' { - $Id = $Request.Body.values.reportTemplate.value + $Id = $Request.Body.preset.reportTemplate.value + } + default { + $Request.Body.Action = 'Copy' + $Id = (New-Guid).Guid } } - $params = $Request.Body.values | Select-Object endpoint, '$filter', '$select', '$count', '$expand', '$search', NoPagination, '$top', IsShared + $params = $Request.Body.preset | Select-Object endpoint, '$filter', '$select', '$count', '$expand', '$search', NoPagination, '$top', IsShared $Preset = [PSCustomObject]@{ PartitionKey = 'Preset' RowKey = [string]$Id id = [string]$Id - name = [string]$Request.Body.values.name + name = [string]$Request.Body.preset.name Owner = [string]$Username - IsShared = $Request.Body.values.IsShared + IsShared = $Request.Body.preset.IsShared params = [string](ConvertTo-Json -InputObject $params -Compress) } From a2df2906eb7ef8ce65173801b7560ea877748eea Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 11:23:16 +0100 Subject: [PATCH 35/55] added force writes --- .../NinjaOne/Invoke-NinjaOneTenantSync.ps1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index 05b4ecbcaaac..295e3289cd20 100644 --- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -653,7 +653,7 @@ function Invoke-NinjaOneTenantSync { M365ID = $device.id } $DeviceMap.Add($DeviceMapItem) - Add-CIPPAzDataTableEntity @DeviceMapTable -Entity $DeviceMapItem + Add-CIPPAzDataTableEntity @DeviceMapTable -Entity $DeviceMapItem -Force } elseif ($MappedDevice.NinjaOneID -ne $MatchedNinjaDevice.id) { $MappedDevice.NinjaOneID = $MatchedNinjaDevice.id @@ -742,7 +742,7 @@ function Invoke-NinjaOneTenantSync { PartitionKey = $Customer.CustomerId RowKey = $device.AzureADDeviceId RawDevice = "$($ParsedDevice | ConvertTo-Json -Depth 100 -Compress)" - } + } -Force $ParsedDevices.add($ParsedDevice) @@ -1264,7 +1264,7 @@ function Invoke-NinjaOneTenantSync { } - Add-CIPPAzDataTableEntity @UsersTable -Entity $ParsedUser + Add-CIPPAzDataTableEntity @UsersTable -Entity $ParsedUser -Force $ParsedUsers.add($ParsedUser) @@ -1330,7 +1330,7 @@ function Invoke-NinjaOneTenantSync { } | ConvertTo-Json -Depth 100)" } $NinjaUserUpdates.Add($UpdateObject) - Add-CIPPAzDataTableEntity @UsersUpdateTable -Entity $UpdateObject + Add-CIPPAzDataTableEntity @UsersUpdateTable -Entity $UpdateObject -Force } else { $CreateObject = [PSCustomObject]@{ @@ -1345,7 +1345,7 @@ function Invoke-NinjaOneTenantSync { } | ConvertTo-Json -Depth 100)" } $NinjaUserCreation.Add($CreateObject) - Add-CIPPAzDataTableEntity @UsersUpdateTable -Entity $CreateObject + Add-CIPPAzDataTableEntity @UsersUpdateTable -Entity $CreateObject -Force } @@ -1399,7 +1399,7 @@ function Invoke-NinjaOneTenantSync { M365ID = $Field.value } $UsersMap.Add($UserMapItem) - Add-CIPPAzDataTableEntity @UsersMapTable -Entity $UserMapItem + Add-CIPPAzDataTableEntity @UsersMapTable -Entity $UserMapItem -Force } elseif ($MappedUser.NinjaOneID -ne $UserDoc.documentId) { $MappedUser.NinjaOneID = $UserDoc.documentId @@ -1476,7 +1476,7 @@ function Invoke-NinjaOneTenantSync { M365ID = $Field.value } $UsersMap.Add($UserMapItem) - Add-CIPPAzDataTableEntity @UsersMapTable -Entity $UserMapItem + Add-CIPPAzDataTableEntity @UsersMapTable -Entity $UserMapItem -Force } elseif ($MappedUser.NinjaOneID -ne $UserDoc.documentId) { $MappedUser.NinjaOneID = $UserDoc.documentId From 2e4d9fc2c3c864e926d481ea0a40e6210dc375fa Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 11:54:07 +0100 Subject: [PATCH 36/55] continue on failed conversion --- .../CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index 295e3289cd20..971adfcddfb9 100644 --- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -2039,7 +2039,7 @@ function Invoke-NinjaOneTenantSync { ### Fetch BPA Data $Table = get-cipptable 'cachebpav2' - $BPAData = (Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$($Customer.customerId)' and RowKey eq 'CIPP Best Practices v1.0 - Table view'") + $BPAData = (Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq '$($Customer.customerId)'") if ($Null -ne $BPAData.Timestamp) { ## BPA Data Widgets @@ -2062,7 +2062,7 @@ function Invoke-NinjaOneTenantSync { # Unused Licenses $WidgetData.add([PSCustomObject]@{ Value = $( - $BPAUnusedLicenses = (($BpaData.Unusedlicenses | ConvertFrom-Json).availableUnits | Measure-Object -Sum).sum + $BPAUnusedLicenses = (($BpaData.Unusedlicenses | ConvertFrom-Json -ErrorAction SilentlyContinue).availableUnits | Measure-Object -Sum).sum if ($BPAUnusedLicenses -ne 0) { $ResultColour = '#D53948' } else { @@ -2308,7 +2308,8 @@ function Invoke-NinjaOneTenantSync { Get-NormalizedError -Message $_.ErrorDetails.Message } else { $_.Exception.message - } Write-Error "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message" + } + Write-Error "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message" Write-LogMessage -API 'NinjaOneSync' -user 'NinjaOneSync' -message "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message" -Sev 'Error' $CurrentItem | Add-Member -NotePropertyName lastEndTime -NotePropertyValue ([string]$((Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))) -Force $CurrentItem | Add-Member -NotePropertyName lastStatus -NotePropertyValue 'Failed' -Force From 30c8959d4471833321819d07ce6e367f7e6e6ba2 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 12:04:17 +0100 Subject: [PATCH 37/55] update to latest bpa --- Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index 971adfcddfb9..5ea8ce7755c9 100644 --- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -2072,7 +2072,7 @@ function Invoke-NinjaOneTenantSync { ) Description = 'Unused Licenses' Colour = $ResultColour - Link = "https://$CIPPUrl/tenant/standards/bpa-report?SearchNow=true&Report=CIPP+Best+Practices+v1.0+-+Tenant+view&tenantFilter=$($Customer.customerId)" + Link = "https://$CIPPUrl/tenant/standards/bpa-report?SearchNow=true&Report=CIPP+Best+Practices+v1.5+-+Tenant+view&tenantFilter=$($Customer.customerId)" }) @@ -2103,7 +2103,7 @@ function Invoke-NinjaOneTenantSync { ) Description = 'Password Never Expires' Colour = $ResultColour - Link = "https://$CIPPUrl/tenant/standards/bpa-report?SearchNow=true&Report=CIPP+Best+Practices+v1.0+-+Tenant+view&tenantFilter=$($Customer.customerId)" + Link = "https://$CIPPUrl/tenant/standards/bpa-report?SearchNow=true&Report=CIPP+Best+Practices+v1.5+-+Tenant+view&tenantFilter=$($Customer.customerId)" }) # oAuth App Consent From 4c1c0bc29dbe8cd9ef247f59cea8f0e19e3d7f10 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 16:15:19 +0100 Subject: [PATCH 38/55] deduplication fix --- .../Entrypoints/Push-SchedulerAlert.ps1 | 13 ------------ .../Public/GraphHelper/Write-AlertMessage.ps1 | 20 ++++++++++--------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 index d9800f40a34a..8955adccb16c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 @@ -23,19 +23,6 @@ function Push-SchedulerAlert { } Push-OutputBinding -Name QueueItemOut -Value $QueueItem } - - $Table = Get-CIPPTable - $PartitionKey = Get-Date -UFormat '%Y%m%d' - $Filter = "PartitionKey eq '{0}' and Tenant eq '{1}'" -f $PartitionKey, $tenant.tenant - $currentlog = Get-CIPPAzDataTableEntity @Table -Filter $Filter - - $AlertsTable = Get-CIPPTable -Table cachealerts - $CurrentAlerts = (Get-CIPPAzDataTableEntity @AlertsTable -Filter $Filter) - $CurrentAlerts | ForEach-Object { - if ($_.Message -notin $currentlog.Message) { Write-LogMessage -message $_.Message -API 'Alerts' -tenant $tenant.tenant -sev Alert -tenantid $Tenant.tenantid } - Remove-AzDataTableEntity @AlertsTable -Entity $_ | Out-Null - } - } catch { $Message = 'Exception on line {0} - {1}' -f $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message Write-LogMessage -message $Message -API 'Alerts' -tenant $tenant.tenant -sev Error diff --git a/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 b/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 index 567f1c05cb77..0636fb67ccbe 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 @@ -3,14 +3,16 @@ function Write-AlertMessage($message, $tenant = 'None', $tenantId = $null) { .FUNCTIONALITY Internal #> - $Table = Get-CIPPTable -tablename cachealerts - $PartitionKey = (Get-Date -UFormat '%Y%m%d').ToString() - $TableRow = @{ - 'Tenant' = [string]$tenant - 'Message' = [string]$message - 'PartitionKey' = $PartitionKey - 'RowKey' = ([guid]::NewGuid()).ToString() + #Do duplicate detection, if no duplicate, write. + $Table = Get-CIPPTable -tablename CippLogs + $PartitionKey = Get-Date -UFormat '%Y%m%d' + $Filter = "PartitionKey eq '{0}' and Message eq '{1}' and Tenant eq '{2}'" -f $PartitionKey, $message.Replace("'", "''"), $tenant + $ExistingMessage = Get-CIPPAzDataTableEntity @Table -Filter $Filter + if (!$ExistingMessage) { + Write-Host 'No duplicate message found, writing to log' + Write-LogMessage -message $message -tenant $tenant -sev 'Alert' -tenantId $tenantId -user 'CIPP' + } else { + Write-Host 'Alerts: Duplicate entry found, not writing to log' + } - $Table.Entity = $TableRow - Add-CIPPAzDataTableEntity @Table | Out-Null } \ No newline at end of file From 71e9e7dcef9593a1aa74a792a886b46bd8d3db65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 22 Feb 2024 22:42:23 +0100 Subject: [PATCH 39/55] Change parameter that does not exist --- .../Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 index 7d5bb92bfad5..e9182bb95717 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPasswordExpireDisabled.ps1 @@ -13,9 +13,9 @@ function Invoke-CIPPStandardPasswordExpireDisabled { $DomainswithoutPassExpire | ForEach-Object { try { New-GraphPostRequest -type Patch -tenantid $Tenant -uri "https://graph.microsoft.com/beta/domains/$($_.id)" -body '{"passwordValidityPeriodInDays": 2147483647 }' - Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled Password Expiration for $($_.name)." -sev Info + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled Password Expiration for $($_.id)." -sev Info } catch { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Password Expiration for $($_.name). Error: $($_.exception.message)" -sev Error + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Password Expiration for $($_.id). Error: $($_.exception.message)" -sev Error } } } else { @@ -26,7 +26,7 @@ function Invoke-CIPPStandardPasswordExpireDisabled { if ($Settings.alert) { if ($DomainswithoutPassExpire) { - Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for the following $($DomainswithoutPassExpire.Count) domains: $($DomainswithoutPassExpire -join ', ')" -sev Alert + Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is not disabled for the following $($DomainswithoutPassExpire.Count) domains: $($DomainswithoutPassExpire.id -join ', ')" -sev Alert } else { Write-LogMessage -API 'Standards' -tenant $tenant -message "Password Expiration is disabled for all $($GraphRequest.Count) domains." -sev Info } From 2ed22c6ada1d4793a71656c9f4af15e5967a3037 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 22:47:32 +0100 Subject: [PATCH 40/55] fix schedule task waits --- .../Entrypoints/Push-SchedulerAlert.ps1 | 21 ++++++++++++++----- .../NinjaOne/Invoke-NinjaOneTenantSync.ps1 | 6 ++---- .../Public/Get-ExtensionRateLimit.ps1 | 8 +++---- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 index 8955adccb16c..81b9acf6a8ae 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 @@ -16,12 +16,23 @@ function Push-SchedulerAlert { $IgnoreList = @('Etag', 'PartitionKey', 'Timestamp', 'RowKey', 'tenantid', 'tenant', 'type') $alertList = $Alerts | Select-Object * -ExcludeProperty $IgnoreList foreach ($task in ($AlertList.psobject.members | Where-Object { $_.MemberType -EQ 'NoteProperty' -and $_.value -eq $True }).name) { - $QueueItem = [pscustomobject]@{ - tenant = $tenant.tenant - tenantid = $tenant.tenantid - FunctionName = "CIPPAlert$($Task)" + $Table = Get-CIPPTable -TableName AlertRunCheck + $Filter = "PartitionKey eq '{0}' and RowKey eq '{1}' and Timestamp ge datetime'{2}'" -f $tenant.tenant, $task, (Get-Date).AddMinutes(-10).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss') + $ExistingMessage = Get-CIPPAzDataTableEntity @Table -Filter $Filter + if (!$ExistingMessage) { + $QueueItem = [pscustomobject]@{ + tenant = $tenant.tenant + tenantid = $tenant.tenantid + FunctionName = "CIPPAlert$($Task)" + } + Push-OutputBinding -Name QueueItemOut -Value $QueueItem + $QueueItem | Add-Member -MemberType NoteProperty -Name 'RowKey' -Value $task + $QueueItem | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $tenant.tenant + Add-CIPPAzDataTableEntity @Table -Entity $QueueItem -Force + } else { + Write-Host 'Alerts: Duplicate entry found, not writing to log' } - Push-OutputBinding -Name QueueItemOut -Value $QueueItem + } } catch { $Message = 'Exception on line {0} - {1}' -f $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 index 5ea8ce7755c9..ad3e211cc633 100644 --- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 +++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 @@ -7,11 +7,9 @@ function Invoke-NinjaOneTenantSync { $StartQueueTime = Get-Date Write-Host "$(Get-Date) - Starting NinjaOne Sync" - # Stagger start - Start-Sleep -Milliseconds (Get-Random -Minimum 0 -Maximum 5001) - + # Stagger start # Check Global Rate Limiting - $CurrentMap = Get-ExtensionRateLimit -ExtensionName 'NinjaOne' -ExtensionPartitionKey 'NinjaOrgsMapping' -RateLimit 5 -WaitTime 60 + $CurrentMap = Get-ExtensionRateLimit -ExtensionName 'NinjaOne' -ExtensionPartitionKey 'NinjaOrgsMapping' -RateLimit 5 -WaitTime 10 $StartTime = Get-Date diff --git a/Modules/CippExtensions/Public/Get-ExtensionRateLimit.ps1 b/Modules/CippExtensions/Public/Get-ExtensionRateLimit.ps1 index 069dec362229..2a0e718402f4 100644 --- a/Modules/CippExtensions/Public/Get-ExtensionRateLimit.ps1 +++ b/Modules/CippExtensions/Public/Get-ExtensionRateLimit.ps1 @@ -3,14 +3,14 @@ function Get-ExtensionRateLimit($ExtensionName, $ExtensionPartitionKey, $RateLim $MappingTable = Get-CIPPTable -TableName CippMapping $CurrentMap = (Get-CIPPAzDataTableEntity @MappingTable -Filter "PartitionKey eq '$ExtensionPartitionKey'") $CurrentMap | ForEach-Object { - if ($Null -ne $_.lastEndTime -and $_.lastEndTime -ne ''){ - $_.lastEndTime = (Get-Date($_.lastEndTime)) + if ($Null -ne $_.lastEndTime -and $_.lastEndTime -ne '') { + $_.lastEndTime = (Get-Date($_.lastEndTime)) } else { $_ | Add-Member -NotePropertyName lastEndTime -NotePropertyValue $Null -Force } if ($Null -ne $_.lastStartTime -and $_.lastStartTime -ne '') { - $_.lastStartTime = (Get-Date($_.lastStartTime)) + $_.lastStartTime = (Get-Date($_.lastStartTime)) } else { $_ | Add-Member -NotePropertyName lastStartTime -NotePropertyValue $Null -Force } @@ -18,7 +18,7 @@ function Get-ExtensionRateLimit($ExtensionName, $ExtensionPartitionKey, $RateLim # Check Global Rate Limiting try { - $ActiveJobs = $CurrentMap | Where-Object { ($Null -ne $_.lastStartTime) -and ($_.lastStartTime -gt (Get-Date).AddMinutes(-10)) -and ($Null -eq $_.lastEndTime -or $_.lastStartTime -gt $_.lastEndTime) } + $ActiveJobs = $CurrentMap | Where-Object { ($Null -ne $_.lastStartTime) -and ($_.lastStartTime -gt (Get-Date).AddMinutes(-10)) -and ($Null -eq $_.lastEndTime -or $_.lastStartTime -gt $_.lastEndTime) } } catch { $ActiveJobs = 'FirstRun' } From 4fffd5853c2cd65ac197065b3445cb591084fc03 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 22 Feb 2024 22:52:22 +0100 Subject: [PATCH 41/55] write host added --- Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 index 81b9acf6a8ae..540e7c175c9b 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 @@ -26,11 +26,11 @@ function Push-SchedulerAlert { FunctionName = "CIPPAlert$($Task)" } Push-OutputBinding -Name QueueItemOut -Value $QueueItem - $QueueItem | Add-Member -MemberType NoteProperty -Name 'RowKey' -Value $task - $QueueItem | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $tenant.tenant + $QueueItem | Add-Member -MemberType NoteProperty -Name 'RowKey' -Value $task -Force + $QueueItem | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $tenant.tenant -Force Add-CIPPAzDataTableEntity @Table -Entity $QueueItem -Force } else { - Write-Host 'Alerts: Duplicate entry found, not writing to log' + Write-Host 'ALERTS: Duplicate run found. Ignoring. Tenant: {0}, Task: {1}' -f $tenant.tenant, $task } } From 4b73b1a7b6f4ce61f12f4f98a514f06d9fbfdb05 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 22 Feb 2024 17:08:32 -0500 Subject: [PATCH 42/55] Add ListProperties query parameter --- .../Entrypoints/Invoke-ListGraphRequest.ps1 | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 index 2e32585d341d..04106b6dfc5c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGraphRequest.ps1 @@ -93,17 +93,31 @@ function Invoke-ListGraphRequest { $GraphRequestParams.SkipCache = [System.Boolean]$Request.Query.SkipCache } + if ($Request.Query.ListProperties) { + $GraphRequestParams.NoPagination = $true + $GraphRequestParams.Parameters.'$select' = '' + if ($Request.Query.TenantFilter -eq 'AllTenants') { + $GraphRequestParams.TenantFilter = (Get-Tenants | Select-Object -First 1).customerId + } + } + Write-Host ($GraphRequestParams | ConvertTo-Json) $Metadata = $GraphRequestParams try { $Results = Get-GraphRequestList @GraphRequestParams - if ($Results.Queued -eq $true) { - $Metadata.Queued = $Results.Queued - $Metadata.QueueMessage = $Results.QueueMessage - $Metadata.QueuedId = $Results.QueueId - $Results = @() + + if ($Request.Query.ListProperties) { + $Columns = ($Results | Select-Object -First 1).PSObject.Properties.Name + $Results = $Columns | Where-Object { @('Tenant', 'CippStatus') -notcontains $_ } + } else { + if ($Results.Queued -eq $true) { + $Metadata.Queued = $Results.Queued + $Metadata.QueueMessage = $Results.QueueMessage + $Metadata.QueuedId = $Results.QueueId + $Results = @() + } } $GraphRequestData = [PSCustomObject]@{ Results = @($Results) From 81278a1182c17deadd93be323c51c1564a959b40 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 22 Feb 2024 18:42:57 -0500 Subject: [PATCH 43/55] Queue statistics tracking --- .../Public/Entrypoints/Push-CIPPStandard.ps1 | 8 +++-- .../GraphHelper/Write-CippFunctionStats.ps1 | 34 +++++++++++++++++++ Modules/CippEntrypoints/CippEntrypoints.psm1 | 21 +++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPStandard.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPStandard.ps1 index 03848da177c9..89a9024a9389 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPStandard.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPStandard.ps1 @@ -8,5 +8,9 @@ function Push-CIPPStandard { $Standard = $QueueItem.Standard $FunctionName = 'Invoke-CIPPStandard{0}' -f $Standard Write-Host "We'll be running $FunctionName" - & $FunctionName -Tenant $Tenant -Settings $QueueItem.Settings -} \ No newline at end of file + try { + & $FunctionName -Tenant $Tenant -Settings $QueueItem.Settings -ErrorAction Stop + } catch { + throw $_.Exception.Message + } +} diff --git a/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 b/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 new file mode 100644 index 000000000000..020462605ea8 --- /dev/null +++ b/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 @@ -0,0 +1,34 @@ +function Write-CippFunctionStats { + <# + .FUNCTIONALITY + Internal + #> + Param( + [string]$FunctionType, + $Entity, + [DateTime]$Start, + [DateTime]$End, + [int]$Duration, + [string]$ErrorMsg = '' + ) + try { + $Table = Get-CIPPTable -tablename CippFunctionStats + $RowKey = [string](New-Guid).Guid + # Flatten data to json string + $Entity.PartitionKey = $FunctionType + $Entity.RowKey = $RowKey + $Entity.Start = $Start + $Entity.End = $End + $Entity.Duration = $Duration + $Entity.ErrorMsg = $ErrorMsg + $Entity = [PSCustomObject]$Entity + foreach ($Property in $Entity.PSObject.Properties.Name) { + if ($Entity.$Property.GetType().Name -in ('Hashtable', 'PSCustomObject')) { + $Entity.$Property = [string]($Entity.$Property | ConvertTo-Json -Compress) + } + } + Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force + } catch { + Write-Host "Exception logging stats $($_.Exception.Message)" + } +} diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 7e376917303d..100f1c4cba27 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -19,6 +19,7 @@ function Receive-CippHttpTrigger { function Receive-CippQueueTrigger { Param($QueueItem, $TriggerMetadata) + $Start = (Get-Date).ToUniversalTime() $APIName = $TriggerMetadata.FunctionName Set-Location (Get-Item $PSScriptRoot).Parent.Parent.FullName $FunctionName = 'Push-{0}' -f $APIName @@ -26,8 +27,26 @@ function Receive-CippQueueTrigger { QueueItem = $QueueItem TriggerMetadata = $TriggerMetadata } + try { + & $FunctionName @QueueTrigger + } catch { + $ErrorMsg = $_.Exception.Message + } - & $FunctionName @QueueTrigger + $End = (Get-Date).ToUniversalTime() + $TimeSpan = New-TimeSpan -Start $Start -End $End + $Duration = [int]$TimeSpan.TotalSeconds + + $Stats = @{ + FunctionType = 'Queue' + Entity = $QueueItem + Start = $Start + End = $End + Duration = $Duration + ErrorMsg = $ErrorMsg + } + Write-Information '####### Adding stats' + Write-CippFunctionStats @Stats } Export-ModuleMember -Function @('Receive-CippHttpTrigger', 'Receive-CippQueueTrigger') From dad044e0fbfd630d0d440b024679f4978ee97f92 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 22 Feb 2024 22:38:48 -0500 Subject: [PATCH 44/55] Function Stats --- .../Entrypoints/Invoke-ListFunctionStats.ps1 | 96 +++++++++++++++++++ .../GraphHelper/Write-CippFunctionStats.ps1 | 4 +- Modules/CippEntrypoints/CippEntrypoints.psm1 | 3 - 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 new file mode 100644 index 000000000000..a9903b33ac16 --- /dev/null +++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListFunctionStats.ps1 @@ -0,0 +1,96 @@ +using namespace System.Net + +Function Invoke-ListFunctionStats { + <# + .FUNCTIONALITY + Entrypoint + #> + [CmdletBinding()] + param($Request, $TriggerMetadata) + + $APIName = $TriggerMetadata.FunctionName + Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' + + # Write to the Azure Functions log stream. + Write-Host 'PowerShell HTTP trigger function processed a request.' + # Interact with query parameters or the body of the request. + + try { + $TenantFilter = $Request.Query.TenantFilter + $PartitionKey = $Request.Query.FunctionType + + $Timestamp = if (![string]::IsNullOrEmpty($Request.Query.Interval) -and ![string]::IsNullOrEmpty($Request.Query.Time)) { + switch ($Request.Query.Interval) { + 'Days' { + (Get-Date).AddDays(-$Request.Query.Time).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffK') + } + 'Hours' { + (Get-Date).AddHours(-$Request.Query.Time).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffK') + } + 'Minutes' { + (Get-Date).AddMinutes(-$Request.Query.Time).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffK') + } + } + } else { + (Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffK') + } + $Table = Get-CIPPTable -tablename 'CippFunctionStats' + + if (!$PartitionKey) { $PartitionKey = 'Queue' } + if (![string]::IsNullOrEmpty($TenantFilter) -and $TenantFilter -ne 'AllTenants') { + $TenantQuery = " and (tenant eq '{0}' or Tenant eq '{0}' or Tenantid eq '{0}' or tenantid eq '{0}')" -f $TenantFilter + } else { + $TenantQuery = '' + } + $Filter = "PartitionKey eq '{0}' and Start ge datetime'{1}'{2}" -f $PartitionKey, $Timestamp, $TenantQuery + + $Entries = Get-CIPPAzDataTableEntity @Table -Filter $Filter + $FunctionList = $Entries | Group-Object -Property FunctionName + $StandardList = $Entries | Where-Object { $_.Standard } | Group-Object -Property Standard + $FunctionStats = foreach ($Function in $FunctionList) { + $Stats = $Function.Group | Measure-Object -Property Duration -AllStats + [PSCustomObject]@{ + 'Name' = $Function.Name + 'ExecutionCount' = $Function.Count + 'TotalSeconds' = $Stats.Sum + 'MaxSeconds' = $Stats.Maximum + 'AvgSeconds' = $Stats.Average + } + } + $StandardStats = foreach ($Standard in $StandardList) { + $Stats = $Standard.Group | Measure-Object -Property Duration -AllStats + [PSCustomObject]@{ + 'Name' = $Standard.Name + 'ExecutionCount' = $Standard.Count + 'TotalSeconds' = $Stats.Sum + 'MaxSeconds' = $Stats.Maximum + 'AvgSeconds' = $Stats.Average + } + } + $Status = [HttpStatusCode]::OK + $Body = @{ + Results = @{ + Functions = @($FunctionStats) + Standards = @($StandardStats) + } + Metadata = @{ + Filter = $Filter + } + } + } catch { + $Status = [HttpStatusCode]::BadRequest + $Body = @{ + Results = @() + Metadata = @{ + Filter = $Filter + Exception = $_.Exception.Message + } + } + } + + Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ + StatusCode = $Status + Body = $Body + }) -Clobber + +} diff --git a/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 b/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 index 020462605ea8..cac4bf0a3173 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1 @@ -8,12 +8,14 @@ function Write-CippFunctionStats { $Entity, [DateTime]$Start, [DateTime]$End, - [int]$Duration, [string]$ErrorMsg = '' ) try { $Table = Get-CIPPTable -tablename CippFunctionStats $RowKey = [string](New-Guid).Guid + $TimeSpan = New-TimeSpan -Start $Start -End $End + $Duration = [int]$TimeSpan.TotalSeconds + # Flatten data to json string $Entity.PartitionKey = $FunctionType $Entity.RowKey = $RowKey diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 100f1c4cba27..3073f1d30ef9 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -34,15 +34,12 @@ function Receive-CippQueueTrigger { } $End = (Get-Date).ToUniversalTime() - $TimeSpan = New-TimeSpan -Start $Start -End $End - $Duration = [int]$TimeSpan.TotalSeconds $Stats = @{ FunctionType = 'Queue' Entity = $QueueItem Start = $Start End = $End - Duration = $Duration ErrorMsg = $ErrorMsg } Write-Information '####### Adding stats' From ee7c13f00a6bab916df44e2c398a6e820c885a80 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 11:06:24 +0100 Subject: [PATCH 45/55] remove += usage --- .../Invoke-CIPPStandardEnableMailboxAuditing.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 index fcdc684d1f37..3a9e7ef1eacd 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailboxAuditing.ps1 @@ -42,15 +42,15 @@ function Invoke-CIPPStandardEnableMailboxAuditing { } } - if ($Mailboxes.Count -eq 0 -and $BypassMailboxes.Count -eq 0) { + $LogMessage = if ($Mailboxes.Count -eq 0 -and $BypassMailboxes.Count -eq 0) { # Make log message smaller if both are already in the desired state - $LogMessage += 'User level mailbox audit already enabled and mailbox audit bypass already disabled for all mailboxes' + 'User level mailbox audit already enabled and mailbox audit bypass already disabled for all mailboxes' } else { if ($Mailboxes.Count -eq 0) { - $LogMessage += 'User level mailbox audit already enabled for all mailboxes. ' + 'User level mailbox audit already enabled for all mailboxes. ' } if ($BypassMailboxes.Count -eq 0) { - $LogMessage += 'Mailbox audit bypass already disabled for all mailboxes' + 'Mailbox audit bypass already disabled for all mailboxes' } } From 70f362eee28535d4c10af51cb186e69bef08138b Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 11:39:59 +0100 Subject: [PATCH 46/55] fix for duplicate alert run --- Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 index 540e7c175c9b..5b32b6fb3c51 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 @@ -30,7 +30,7 @@ function Push-SchedulerAlert { $QueueItem | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $tenant.tenant -Force Add-CIPPAzDataTableEntity @Table -Entity $QueueItem -Force } else { - Write-Host 'ALERTS: Duplicate run found. Ignoring. Tenant: {0}, Task: {1}' -f $tenant.tenant, $task + Write-Host ('ALERTS: Duplicate run found. Ignoring. Tenant: {0}, Task: {1}' -f $tenant.tenant, $task) } } From 537408f057fdbfa82b133837883ce5c1a52a00d8 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:24:00 +0100 Subject: [PATCH 47/55] fix default setting issue --- .../Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 index 3ec9e8b7d9a2..1f3c9c1d0a91 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 @@ -7,7 +7,7 @@ function Push-SchedulerCIPPNotifications { $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" $Config = [pscustomobject](Get-CIPPAzDataTableEntity @Table -Filter $Filter) - $Settings = [System.Collections.ArrayList]@('Alerts') + $Settings = [System.Collections.ArrayList]@('Alert') $Config.psobject.properties.name | ForEach-Object { $settings.add($_) } $severity = $Config.Severity -split ',' Write-Host "Our Severity table is: $severity" From 5b4f6dbabf2661c65efa7d560fb2bfb4b58b7d60 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:25:06 +0100 Subject: [PATCH 48/55] scheduler timer back to 15 minutes --- Scheduler_GetQueue/function.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scheduler_GetQueue/function.json b/Scheduler_GetQueue/function.json index d0f59a682e3c..73fa51771c60 100644 --- a/Scheduler_GetQueue/function.json +++ b/Scheduler_GetQueue/function.json @@ -2,7 +2,7 @@ "bindings": [ { "name": "Timer", - "schedule": "0 0 * * * *", + "schedule": "0 */15 * * * *", "direction": "in", "type": "timerTrigger" }, From 4eec27d8425ae7c828ef218f1b7a68bc88d210bd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:35:42 +0100 Subject: [PATCH 49/55] add write host --- Modules/CippEntrypoints/CippEntrypoints.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 3073f1d30ef9..3714731668b8 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -19,6 +19,7 @@ function Receive-CippHttpTrigger { function Receive-CippQueueTrigger { Param($QueueItem, $TriggerMetadata) + Write-Host "#### Running $APINAME" $Start = (Get-Date).ToUniversalTime() $APIName = $TriggerMetadata.FunctionName Set-Location (Get-Item $PSScriptRoot).Parent.Parent.FullName From e45b151ac780c663d66276d5580563e3b49d92e0 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:36:17 +0100 Subject: [PATCH 50/55] move write host --- .../Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 index 581c56ebd962..82bcde9bb74f 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 @@ -7,12 +7,13 @@ function Push-CIPPAlertAppSecretExpiry { ) $LastRunTable = Get-CIPPTable -Table AlertLastRun - Write-Host "Checking app expire for $($QueueItem.tenant)" + try { $Filter = "RowKey eq 'AppSecretExpiry' and PartitionKey eq '{0}'" -f $QueueItem.tenantid $LastRun = Get-CIPPAzDataTableEntity @LastRunTable -Filter $Filter $Yesterday = (Get-Date).AddDays(-1) if (-not $LastRun.Timestamp.DateTime -or ($LastRun.Timestamp.DateTime -le $Yesterday)) { + Write-Host "Checking app expire for $($QueueItem.tenant)" New-GraphGetRequest -uri "https://graph.microsoft.com/beta/applications?`$select=appId,displayName,passwordCredentials" -tenantid $QueueItem.tenant | ForEach-Object { foreach ($App in $_) { Write-Host "checking $($App.displayName)" From 2055b3014bd36d7d743f093bb467a0536b56ef91 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:46:03 +0100 Subject: [PATCH 51/55] positioning change --- Modules/CippEntrypoints/CippEntrypoints.psm1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CippEntrypoints/CippEntrypoints.psm1 b/Modules/CippEntrypoints/CippEntrypoints.psm1 index 3714731668b8..d6d80cdcf143 100644 --- a/Modules/CippEntrypoints/CippEntrypoints.psm1 +++ b/Modules/CippEntrypoints/CippEntrypoints.psm1 @@ -19,9 +19,10 @@ function Receive-CippHttpTrigger { function Receive-CippQueueTrigger { Param($QueueItem, $TriggerMetadata) - Write-Host "#### Running $APINAME" + $Start = (Get-Date).ToUniversalTime() $APIName = $TriggerMetadata.FunctionName + Write-Host "#### Running $APINAME" Set-Location (Get-Item $PSScriptRoot).Parent.Parent.FullName $FunctionName = 'Push-{0}' -f $APIName $QueueTrigger = @{ From 6874629bf65bd5c9c1b901d0f0564a1bb37ea0d5 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:55:03 +0100 Subject: [PATCH 52/55] revert change --- .../Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 | 2 +- Scheduler_GetQueue/function.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 index 1f3c9c1d0a91..3ec9e8b7d9a2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 @@ -7,7 +7,7 @@ function Push-SchedulerCIPPNotifications { $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'" $Config = [pscustomobject](Get-CIPPAzDataTableEntity @Table -Filter $Filter) - $Settings = [System.Collections.ArrayList]@('Alert') + $Settings = [System.Collections.ArrayList]@('Alerts') $Config.psobject.properties.name | ForEach-Object { $settings.add($_) } $severity = $Config.Severity -split ',' Write-Host "Our Severity table is: $severity" diff --git a/Scheduler_GetQueue/function.json b/Scheduler_GetQueue/function.json index 73fa51771c60..d0f59a682e3c 100644 --- a/Scheduler_GetQueue/function.json +++ b/Scheduler_GetQueue/function.json @@ -2,7 +2,7 @@ "bindings": [ { "name": "Timer", - "schedule": "0 */15 * * * *", + "schedule": "0 0 * * * *", "direction": "in", "type": "timerTrigger" }, From 2cf3800cb5cc907fd2509cde3fb840061404996a Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 13:57:03 +0100 Subject: [PATCH 53/55] fixes alerts email --- Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 b/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 index 0636fb67ccbe..4d9fd8095059 100644 --- a/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/Write-AlertMessage.ps1 @@ -10,7 +10,7 @@ function Write-AlertMessage($message, $tenant = 'None', $tenantId = $null) { $ExistingMessage = Get-CIPPAzDataTableEntity @Table -Filter $Filter if (!$ExistingMessage) { Write-Host 'No duplicate message found, writing to log' - Write-LogMessage -message $message -tenant $tenant -sev 'Alert' -tenantId $tenantId -user 'CIPP' + Write-LogMessage -message $message -tenant $tenant -sev 'Alert' -tenantId $tenantId -user 'CIPP' -API 'Alerts' } else { Write-Host 'Alerts: Duplicate entry found, not writing to log' From 2664772262689bed9d57cbdb713ae7a68170bca6 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 14:39:02 +0100 Subject: [PATCH 54/55] add standard --- .../Invoke-CIPPStandardMessageExpiration.ps1 | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMessageExpiration.ps1 diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMessageExpiration.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMessageExpiration.ps1 new file mode 100644 index 000000000000..294729a36583 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMessageExpiration.ps1 @@ -0,0 +1,34 @@ +function Invoke-CIPPStandardMessageExpiration { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + $MessageExpiration = (New-ExoRequest -tenantid $Tenant -cmdlet 'Get-TransportConfig').messageExpiration + + If ($Settings.remediate) { + Write-Host 'Time to remediate' + if ($MessageExpiration -ne '12:00:00') { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Set-TransportConfig' -cmdParams @{MessageExpiration = '12:00:00' } + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Set transport configuration message expiration to 12 hours' -sev Info + } catch { + $ErrorMessage = Get-NormalizedError -Message $_.Exception.Message + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to set transport configuration message expiration to 12 hours. Error: $ErrorMessage" -sev Debug + } + } + + } + if ($Settings.alert) { + if ($MessageExpiration -ne '12:00:00') { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Transport configuration message expiration is set to 12 hours' -sev Info + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Transport configuration message expiration is not set to 12 hours' -sev Alert + } + } + if ($Settings.report) { + if ($MessageExpiration -ne '12:00:00') { $MessageExpiration = $false } else { $MessageExpiration = $true } + Add-CIPPBPAField -FieldName 'messageExpiration' -FieldValue [bool]$MessageExpiration -StoreAs bool -Tenant $tenant + } +} From fba3cd9492c9706caf528f3ada1b6c925979c93f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 23 Feb 2024 14:57:38 +0100 Subject: [PATCH 55/55] version up --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index 1b47e8f3efe7..7cbea073bea1 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -5.1.2 \ No newline at end of file +5.2.0 \ No newline at end of file