diff --git a/Durable_BECRun/run.ps1 b/Durable_BECRun/run.ps1 index 49d358ff3fca..377ca2c5533b 100644 --- a/Durable_BECRun/run.ps1 +++ b/Durable_BECRun/run.ps1 @@ -2,7 +2,7 @@ param($Context) #$Context does not allow itself to be cast to a pscustomobject for some reason, so we convert $context = $Context | ConvertTo-Json | ConvertFrom-Json $APIName = $TriggerMetadata.FunctionName -Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Accessed this API" -Sev "Debug" +Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug' $TenantFilter = $Context.input.tenantfilter $SuspectUser = $Context.input.userid $UserName = $Context.input.username @@ -10,38 +10,37 @@ Write-Host "Working on $UserName" try { $startDate = (Get-Date).AddDays(-7) $endDate = (Get-Date) - $auditLog = (New-ExoRequest -tenantid $Tenantfilter -cmdlet "Get-AdminAuditLogConfig").UnifiedAuditLogIngestionEnabled + $auditLog = (New-ExoRequest -tenantid $Tenantfilter -cmdlet 'Get-AdminAuditLogConfig').UnifiedAuditLogIngestionEnabled $7dayslog = if ($auditLog -eq $false) { - $ExtractResult = "AuditLog is disabled. Cannot perform full analysis" - } - else { + $ExtractResult = 'AuditLog is disabled. Cannot perform full analysis' + } else { $sessionid = Get-Random -Minimum 10000 -Maximum 99999 $operations = @( - "New-InboxRule", - "Set-InboxRule", - "UpdateInboxRules", - "Remove-MailboxPermission", - "Add-MailboxPermission", - "UpdateCalendarDelegation", - "AddFolderPermissions", - "MailboxLogin", - "UserLoggedIn" + 'New-InboxRule', + 'Set-InboxRule', + 'UpdateInboxRules', + 'Remove-MailboxPermission', + 'Add-MailboxPermission', + 'UpdateCalendarDelegation', + 'AddFolderPermissions', + 'MailboxLogin', + 'UserLoggedIn' ) $startDate = (Get-Date).AddDays(-7) $endDate = (Get-Date) $SearchParam = @{ - SessionCommand = "ReturnLargeSet" + SessionCommand = 'ReturnLargeSet' Operations = $operations sessionid = $sessionid startDate = $startDate endDate = $endDate } do { - New-ExoRequest -tenantid $Tenantfilter -cmdlet "Search-unifiedAuditLog" -cmdParams $SearchParam -Anchor $Username + New-ExoRequest -tenantid $Tenantfilter -cmdlet 'Search-unifiedAuditLog' -cmdParams $SearchParam -Anchor $Username Write-Host "Retrieved $($logsTenant.count) logs" -ForegroundColor Yellow $logsTenant } while ($LogsTenant.count % 5000 -eq 0 -and $LogsTenant.count -ne 0) - $ExtractResult = "Succesfully extracted logs from auditlog" + $ExtractResult = 'Succesfully extracted logs from auditlog' } Try { $URI = "https://graph.microsoft.com/beta/auditLogs/signIns?`$filter=(userId eq '$SuspectUser')&`$top=1&`$orderby=createdDateTime desc" @@ -50,13 +49,12 @@ try { @{ Name = 'AppDisplayName'; Expression = { $_.resourceDisplayName } }, @{ Name = 'Status'; Expression = { if (($_.conditionalAccessStatus -eq 'Success' -or 'Not Applied') -and $_.status.errorCode -eq 0) { 'Success' } else { 'Failed' } } }, @{ Name = 'IPAddress'; Expression = { $_.ipAddress } } - } - catch { + } catch { $LastSignIn = [PSCustomObject]@{ - AppDisplayName = "Unknown - could not retrieve information. No access to sign-in logs" - CreatedDateTime = "Unknown" - Id = "0" - Status = "Could not retrieve additional details" + AppDisplayName = 'Unknown - could not retrieve information. No access to sign-in logs' + CreatedDateTime = 'Unknown' + Id = '0' + Status = 'Could not retrieve additional details' } } #List all users devices @@ -64,15 +62,13 @@ try { $base64IdentityParam = [Convert]::ToBase64String($Bytes) Try { $Devices = New-GraphGetRequest -uri "https://outlook.office365.com:443/adminapi/beta/$($TenantFilter)/mailbox('$($base64IdentityParam)')/MobileDevice/Exchange.GetMobileDeviceStatistics()/?IsEncoded=True" -Tenantid $tenantfilter -scope ExchangeOnline - } - catch { + } catch { $Devices = $null } - $PermissionsLog = ($7dayslog | Where-Object -Property Operations -In "Remove-MailboxPermission", "Add-MailboxPermission", "UpdateCalendarDelegation", "AddFolderPermissions" ).AuditData | ConvertFrom-Json -Depth 100 | ForEach-Object { + $PermissionsLog = ($7dayslog | Where-Object -Property Operations -In 'Remove-MailboxPermission', 'Add-MailboxPermission', 'UpdateCalendarDelegation', 'AddFolderPermissions' ).AuditData | ConvertFrom-Json -Depth 100 | ForEach-Object { $perms = if ($_.Parameters) { - $_.Parameters | ForEach-Object { if ($_.Name -eq "AccessRights") { $_.Value } } - } - else + $_.Parameters | ForEach-Object { if ($_.Name -eq 'AccessRights') { $_.Value } } + } else { $_.item.ParentFolder.MemberRights } $objectID = if ($_.ObjectID) { $_.ObjectID } else { $($_.MailboxOwnerUPN) + $_.item.ParentFolder.Path } [pscustomobject]@{ @@ -83,43 +79,42 @@ try { } } - $RulesLog = @(($7dayslog | Where-Object -Property Operations -In "New-InboxRule", "Set-InboxRule", "UpdateInboxRules").AuditData | ConvertFrom-Json) | ForEach-Object { + $RulesLog = @(($7dayslog | Where-Object -Property Operations -In 'New-InboxRule', 'Set-InboxRule', 'UpdateInboxRules').AuditData | ConvertFrom-Json) | ForEach-Object { Write-Host ($_ | ConvertTo-Json) [pscustomobject]@{ ClientIP = $_.ClientIP CreationTime = $_.CreationTime UserId = $_.UserId - RuleName = ($_.OperationProperties | ForEach-Object { if ($_.Name -eq "RuleName") { $_.Value } }) - RuleCondition = ($_.OperationProperties | ForEach-Object { if ($_.Name -eq "RuleCondition") { $_.Value } }) + RuleName = ($_.OperationProperties | ForEach-Object { if ($_.Name -eq 'RuleName') { $_.Value } }) + RuleCondition = ($_.OperationProperties | ForEach-Object { if ($_.Name -eq 'RuleCondition') { $_.Value } }) } } $PasswordChanges = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`select=lastPasswordChangeDateTime,displayname,UserPrincipalName" -Tenantid $tenantfilter | Where-Object { $_.lastPasswordChangeDateTime -gt $startDate } - $NewUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users?`$select=displayname,UserPrincipalName,CreatedDateTime" -Tenantid $tenantfilter | Where-Object { $_.CreatedDateTime -gt $startDate } + $NewUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users?`$select=displayname,UserPrincipalName,CreatedDateTime" -Tenantid $tenantfilter | Where-Object { $_.CreatedDateTime -gt $startDate } $MFADevices = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($SuspectUser)/authentication/methods" -Tenantid $tenantfilter $NewSPs = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/servicePrincipals?`$select=displayName,createdDateTime,id,AppDisplayName&`$filter=createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -Tenantid $tenantfilter - $Last50Logons = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/auditLogs/signIns?`$top=50&`$orderby=createdDateTime desc" -tenantid $TenantFilter -noPagination $true -verbose | Select-Object @{ Name = 'CreatedDateTime'; Expression = { $(($_.createdDateTime | Out-String) -replace '\r\n') } }, + $Last50Logons = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/auditLogs/signIns?`$top=50&`$orderby=createdDateTime desc" -tenantid $TenantFilter -noPagination $true -verbose | Select-Object @{ Name = 'CreatedDateTime'; Expression = { $(($_.createdDateTime | Out-String) -replace '\r\n') } }, id, @{ Name = 'AppDisplayName'; Expression = { $_.resourceDisplayName } }, @{ Name = 'Status'; Expression = { if (($_.conditionalAccessStatus -eq 'Success' -or 'Not Applied') -and $_.status.errorCode -eq 0) { 'Success' } else { 'Failed' } } }, @{ Name = 'IPAddress'; Expression = { $_.ipAddress } }, UserPrincipalName $Results = [PSCustomObject]@{ - AddedApps = $NewSPs - SuspectUserMailboxLogons = $Last50Logons + AddedApps = @($NewSPs) + SuspectUserMailboxLogons = @($Last50Logons) LastSuspectUserLogon = @($LastSignIn) SuspectUserDevices = @($Devices) NewRules = @($RulesLog) MailboxPermissionChanges = @($PermissionsLog) NewUsers = @($NewUsers) - MFADevices = $MFADevices - ChangedPasswords = $PasswordChanges + MFADevices = @($MFADevices) + ChangedPasswords = @($PasswordChanges) ExtractedAt = (Get-Date).ToString('s') ExtractResult = $ExtractResult } -} -catch { +} catch { $errMessage = Get-NormalizedError -message $_.Exception.Message - $results = [pscustomobject]@{"Results" = "$errMessage" } + $results = [pscustomobject]@{'Results' = "$errMessage" } } $Table = Get-CippTable -tablename 'cachebec' @@ -128,5 +123,5 @@ Add-CIPPAzDataTableEntity @Table -Entity @{ UserId = $Context.input.userid Results = "$($results | ConvertTo-Json -Depth 10)" RowKey = $Context.input.userid - PartitionKey = "bec" + PartitionKey = 'bec' } \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1 index d47e79878fd4..9567039fe8e4 100644 --- a/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1 +++ b/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1 @@ -19,7 +19,6 @@ function Remove-CIPPGroupMember( $Message = "Successfully removed user $($Member) from $GroupId." Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $Message -Sev 'Info' return $message - return } catch { $message = "Failed to remove user $($Member) from $($GroupId): $($_.Exception.Message)" Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $message -Sev 'error' diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 new file mode 100644 index 000000000000..d352fd8b33f0 --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 @@ -0,0 +1,54 @@ +function Invoke-CIPPStandardDisableOutlookAddins { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + $CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-RoleAssignmentPolicy' | Where-Object { $_.IsDefault -eq $true } + $Roles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps') + $RolesToRemove = foreach ($Role in $Roles) { + if ($CurrentInfo.AssignedRoles -contains $Role) { + $Role + } + } + + if ($Settings.remediate) { + if ($RolesToRemove) { + $Errors = [System.Collections.Generic.List[string]]::new() + + foreach ($Role in $RolesToRemove) { + try { + New-ExoRequest -tenantid $Tenant -cmdlet 'Get-ManagementRoleAssignment' -cmdparams @{ RoleAssignee = $CurrentInfo.Identity; Role = $Role } | ForEach-Object { + New-ExoRequest -tenantid $Tenant -cmdlet 'Remove-ManagementRoleAssignment' -cmdparams @{ Identity = $_.Guid; Confirm = $false } -UseSystemMailbox $true + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled Outlook add-in role: $Role" -sev Debug + } + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable Outlook add-in role: $Role Error: $($_.exception.message)" -sev Error + $Errors.Add($Role) + } + } + + if ($Errors.Count -gt 0) { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from installing Outlook add-ins. Roles: $($Errors -join ', ')" -sev Error + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled users from installing Outlook add-ins. Roles removed: $($RolesToRemove -join ', ')" -sev Info + $RolesToRemove = $null + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users installing Outlook add-ins already disabled' -sev Info + } + } + + if ($Settings.alert) { + if ($RolesToRemove) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not disabled from installing Outlook add-ins.' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are disabled from installing Outlook add-ins.' -sev Info + } + } + if ($Settings.report) { + if ($RolesToRemove) { $State = $false } else { $State = $true } + Add-CIPPBPAField -FieldName 'DisabledOutlookAddins' -FieldValue [bool]$State -StoreAs bool -Tenant $tenant + } +} \ No newline at end of file diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharePointLegacyAuth.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharePointLegacyAuth.ps1 new file mode 100644 index 000000000000..87178367ab5c --- /dev/null +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableSharePointLegacyAuth.ps1 @@ -0,0 +1,37 @@ +function Invoke-CIPPStandardDisableSharePointLegacyAuth { + <# + .FUNCTIONALITY + Internal + #> + param($Tenant, $Settings) + + $CurrentInfo = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/admin/sharepoint/settings?$select=isLegacyAuthProtocolsEnabled' -tenantid $Tenant -AsApp $true + + If ($Settings.remediate) { + + if ($CurrentInfo.isLegacyAuthProtocolsEnabled) { + try { + $body = '{"isLegacyAuthProtocolsEnabled": "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 SharePoint basic authentication' -sev Info + $CurrentInfo.isLegacyAuthProtocolsEnabled = $false + } catch { + Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable SharePoint basic authentication. Error: $($_.exception.message)" -sev Error + } + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SharePoint basic authentication is already disabled' -sev Info + } + } + if ($Settings.alert) { + + if ($CurrentInfo.isLegacyAuthProtocolsEnabled) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SharePoint basic authentication is enabled' -sev Alert + } else { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'SharePoint basic authentication is disabled' -sev Info + } + } + if ($Settings.report) { + + Add-CIPPBPAField -FieldName 'SharePointLegacyAuthEnabled' -FieldValue [bool]$CurrentInfo.isLegacyAuthProtocolsEnabled -StoreAs bool -Tenant $tenant + } +} diff --git a/version_latest.txt b/version_latest.txt index acf69b48b843..3bff059174b8 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -5.1.0 \ No newline at end of file +5.1.1 \ No newline at end of file