diff --git a/DomainAnalyser_All/run.ps1 b/DomainAnalyser_All/run.ps1
index 0317848a5a236..81678cbe8c988 100644
--- a/DomainAnalyser_All/run.ps1
+++ b/DomainAnalyser_All/run.ps1
@@ -10,8 +10,7 @@ try {
$ValidResolvers = @('Google', 'CloudFlare', 'Quad9')
if ($ValidResolvers -contains $Config.Resolver) {
$Resolver = $Config.Resolver
- }
- else {
+ } else {
$Resolver = 'Google'
$Config = @{
PartitionKey = 'Domains'
@@ -20,8 +19,7 @@ try {
}
Add-CIPPAzDataTableEntity @ConfigTable -Entity $Config -Force
}
-}
-catch {
+} catch {
$Resolver = 'Google'
}
Set-DnsResolver -Resolver $Resolver
@@ -30,8 +28,7 @@ $Domain = $DomainObject.rowKey
try {
$Tenant = $DomainObject.TenantDetails | ConvertFrom-Json -ErrorAction Stop
-}
-catch {
+} catch {
$Tenant = @{Tenant = 'None' }
}
@@ -90,15 +87,13 @@ $MXFailCount = $MXRecord.ValidationFails | Measure-Object | Select-Object -Expan
if ($MXFailCount -eq 0) {
$Result.MXPassTest = $true
$ScoreDomain += $Scores.MXRecommended
-}
-else {
+} else {
$ScoreExplanation.Add('MX record did not pass validation') | Out-Null
}
if ([string]::IsNullOrEmpty($MXRecord.MailProvider)) {
$Result.MailProvider = 'Unknown'
-}
-else {
+} else {
$Result.MailProvider = $MXRecord.MailProvider.Name
}
@@ -109,22 +104,19 @@ try {
$Result.ActualSPFRecord = $SPFRecord.Record
if ($SPFRecord.RecordCount -eq 1) {
$ScoreDomain += $Scores.SPFPresent
- }
- else {
+ } else {
$ScoreExplanation.Add('Multiple SPF records detected') | Out-Null
}
- }
- else {
+ } else {
$Result.ActualSPFRecord = 'No SPF Record'
$ScoreExplanation.Add('No SPF Record Found') | Out-Null
}
-}
-catch {
+} catch {
$Message = 'SPF Exception: {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message
Write-LogMessage -API 'DomainAnalyser' -tenant $tenant.tenant -message $Message -sev Error
throw $Message
}
-
+
# Check SPF Record
$Result.SPFPassAll = $false
@@ -135,8 +127,7 @@ $SPFFailCount = $SPFRecord.ValidationFails | Measure-Object | Select-Object -Exp
if ($SPFFailCount -eq 0) {
$ScoreDomain += $Scores.SPFCorrectAll
$Result.SPFPassAll = $true
-}
-else {
+} else {
$ScoreExplanation.Add('SPF record did not pass validation') | Out-Null
}
@@ -147,19 +138,18 @@ try {
If ([string]::IsNullOrEmpty($DMARCPolicy.Record)) {
$Result.DMARCPresent = $false
$ScoreExplanation.Add('No DMARC Records Found') | Out-Null
- }
- else {
+ } else {
$Result.DMARCPresent = $true
$ScoreDomain += $Scores.DMARCPresent
- $Result.DMARCFullPolicy = $DMARCResults.Record
- if ($DMARCPolicy.Policy -eq 'reject' -and $DMARCPolicy.SubdomainPolicy -eq 'reject') {
+ $Result.DMARCFullPolicy = $DMARCPolicy.Record
+ if ($DMARCPolicy.Policy -eq 'reject' -and $DMARCPolicy.SubdomainPolicy -eq 'reject') {
$Result.DMARCActionPolicy = 'Reject'
$ScoreDomain += $Scores.DMARCSetReject
}
- if ($DMARCPolicy.Policy -eq 'none') {
+ if ($DMARCPolicy.Policy -eq 'none') {
$Result.DMARCActionPolicy = 'None'
- $ScoreExplanation.Add('DMARC is not being enforced') | Out-Null
+ $ScoreExplanation.Add('DMARC is not being enforced') | Out-Null
}
if ($DMARCPolicy.Policy -eq 'quarantine') {
$Result.DMARCActionPolicy = 'Quarantine'
@@ -171,8 +161,7 @@ try {
if ($ReportEmailCount -gt 0) {
$Result.DMARCReportingActive = $true
$ScoreDomain += $Scores.DMARCReportingActive
- }
- else {
+ } else {
$Result.DMARCReportingActive = $False
$ScoreExplanation.Add('DMARC Reporting not Configured') | Out-Null
}
@@ -180,14 +169,12 @@ try {
if ($DMARCPolicy.Percent -eq 100) {
$Result.DMARCPercentagePass = $true
$ScoreDomain += $Scores.DMARCPercentageGood
- }
- else {
+ } else {
$Result.DMARCPercentagePass = $false
- $ScoreExplanation.Add('DMARC Not Checking All Messages') | Out-Null
+ $ScoreExplanation.Add('DMARC Not Checking All Messages') | Out-Null
}
}
-}
-catch {
+} catch {
$Message = 'DMARC Exception: {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message
Write-LogMessage -API 'DomainAnalyser' -tenant $tenant.tenant -message $Message -sev Error
throw $Message
@@ -201,13 +188,11 @@ try {
if (($DNSSECFailCount + $DNSSECWarnCount) -eq 0) {
$Result.DNSSECPresent = $true
$ScoreDomain += $Scores.DNSSECPresent
- }
- else {
+ } else {
$Result.DNSSECPresent = $false
- $ScoreExplanation.Add('DNSSEC Not Configured or Enabled') | Out-Null
+ $ScoreExplanation.Add('DNSSEC Not Configured or Enabled') | Out-Null
}
-}
-catch {
+} catch {
$Message = 'DNSSEC Exception: {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message
Write-LogMessage -API 'DomainAnalyser' -tenant $tenant.tenant -message $Message -sev Error
throw $Message
@@ -216,27 +201,26 @@ catch {
# DKIM Check
try {
$DkimParams = @{
- Domain = $Domain
+ Domain = $Domain
+ FallbackToMicrosoftSelectors = $true
}
if (![string]::IsNullOrEmpty($DomainObject.DkimSelectors)) {
$DkimParams.Selectors = $DomainObject.DkimSelectors | ConvertFrom-Json
}
$DkimRecord = Read-DkimRecord @DkimParams -ErrorAction Stop
-
+
$DkimRecordCount = $DkimRecord.Records | Measure-Object | Select-Object -ExpandProperty Count
$DkimFailCount = $DkimRecord.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count
#$DkimWarnCount = $DkimRecord.ValidationWarns | Measure-Object | Select-Object -ExpandProperty Count
if ($DkimRecordCount -gt 0 -and $DkimFailCount -eq 0) {
$Result.DKIMEnabled = $true
$ScoreDomain += $Scores.DKIMActiveAndWorking
- }
- else {
+ } else {
$Result.DKIMEnabled = $false
- $ScoreExplanation.Add('DKIM Not Configured') | Out-Null
+ $ScoreExplanation.Add('DKIM Not Configured') | Out-Null
}
-}
-catch {
+} catch {
$Message = 'DKIM Exception: {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message
Write-LogMessage -API 'DomainAnalyser' -tenant $tenant.tenant -message $Message -sev Error
throw $Message
diff --git a/Durable_BECRun/run.ps1 b/Durable_BECRun/run.ps1
index 49d358ff3fca0..377ca2c5533b0 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/ListMailboxRulesAllTenants/run.ps1 b/ListMailboxRulesAllTenants/run.ps1
index 28782db5e6cb9..36b671ad11f6f 100644
--- a/ListMailboxRulesAllTenants/run.ps1
+++ b/ListMailboxRulesAllTenants/run.ps1
@@ -3,51 +3,59 @@ param([string] $QueueItem, $TriggerMetadata)
# Write out the queue message and metadata to the information log.
Write-Host "PowerShell queue trigger function processed work item: $QueueItem"
-$Tenants = if ($QueueItem -ne "AllTenants") {
+
+$Tenants = if ($QueueItem -ne 'AllTenants') {
[PSCustomObject]@{
defaultDomainName = $QueueItem
}
-}
-else {
+} else {
Get-Tenants
}
-$Tenants | ForEach-Object -Parallel {
+$Tenants | ForEach-Object -Parallel {
$domainName = $_.defaultDomainName
- Import-Module '.\Modules\CIPPcore'
+ Import-Module CippCore
+ Import-Module AzBobbyTables
+ $Table = Get-CIPPTable -TableName cachembxrules
try {
-
- $Rules = New-ExoRequest -tenantid $domainName -cmdlet "Get-Mailbox" | ForEach-Object -Parallel {
- New-ExoRequest -Anchor $_.UserPrincipalName -tenantid $domainName -cmdlet "Get-InboxRule" -cmdParams @{Mailbox = $_.GUID }
+ $Rules = New-ExoRequest -tenantid $domainName -cmdlet 'Get-Mailbox' -Select 'userPrincipalName,GUID' | ForEach-Object -Parallel {
+ Import-Module CippCore
+ $MbxRules = New-ExoRequest -Anchor $_.UserPrincipalName -tenantid $using:domainName -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $_.GUID }
+ foreach ($Rule in $MbxRules) {
+ $Rule | Add-Member -NotePropertyName 'UserPrincipalName' -NotePropertyValue $_.userPrincipalName
+ $Rule
+ }
}
- foreach ($Rule in $Rules) {
- $GraphRequest = @{
- Rules = [string]($Rule | ConvertTo-Json)
- RowKey = [string](New-Guid).guid
+ if (($Rules | Measure-Object).Count -gt 0) {
+ foreach ($Rule in $Rules) {
+ $GraphRequest = [PSCustomObject]@{
+ Rules = [string]($Rule | ConvertTo-Json)
+ RowKey = [string](New-Guid).guid
+ Tenant = [string]$domainName
+ PartitionKey = 'mailboxrules'
+ }
+
+ }
+ } else {
+ $Rules = @{
+ Name = 'No rules found'
+ } | ConvertTo-Json
+ $GraphRequest = [PSCustomObject]@{
+ Rules = [string]$Rules
+ RowKey = [string]$domainName
Tenant = [string]$domainName
PartitionKey = 'mailboxrules'
}
- $Table = Get-CIPPTable -TableName cachembxrules
- Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null
}
- }
- catch {
+ } catch {
$Rules = @{
Name = "Could not connect to tenant $($_.Exception.message)"
} | ConvertTo-Json
- $GraphRequest = @{
+ $GraphRequest = [PSCustomObject]@{
Rules = [string]$Rules
RowKey = [string]$domainName
Tenant = [string]$domainName
-
PartitionKey = 'mailboxrules'
}
- $Table = Get-CIPPTable -TableName cachembxrules
- Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null
}
+ Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null
}
-
-
-
-$Table = Get-CIPPTable -TableName cachembxrules
-Write-Host "$($GraphRequest.RowKey) - $($GraphRequest.tenant)"
-Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force | Out-Null
diff --git a/Modules/CIPPCore/Public/Add-CIPPGroupMember.ps1 b/Modules/CIPPCore/Public/Add-CIPPGroupMember.ps1
new file mode 100644
index 0000000000000..2ff3c406102b4
--- /dev/null
+++ b/Modules/CIPPCore/Public/Add-CIPPGroupMember.ps1
@@ -0,0 +1,29 @@
+function Add-CIPPGroupMember(
+ [string]$ExecutingUser,
+ [string]$GroupType,
+ [string]$GroupId,
+ [string]$Member,
+ [string]$TenantFilter,
+ [string]$APIName = 'Add Group Member'
+) {
+ try {
+ if ($member -like '*#EXT#*') { $member = [System.Web.HttpUtility]::UrlEncode($member) }
+ $MemberIDs = 'https://graph.microsoft.com/v1.0/directoryObjects/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($member)" -tenantid $TenantFilter).id
+ $addmemberbody = "{ `"members@odata.bind`": $(ConvertTo-Json @($MemberIDs)) }"
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
+ $Params = @{ Identity = $GroupId; Member = $member; BypassSecurityGroupManagerCheck = $true }
+ New-ExoRequest -tenantid $TenantFilter -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
+ } else {
+ New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($GroupId)" -tenantid $TenantFilter -type patch -body $addmemberbody -Verbose
+ }
+ $Message = "Successfully added user $($Member) to $GroupId."
+ Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $Message -Sev 'Info'
+ return $message
+ return
+ } catch {
+ $message = "Failed to add user $($Member) to $($GroupId): $($_.Exception.Message)"
+ Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $message -Sev 'error'
+ return $message
+ }
+
+}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddAlert.ps1
index b2ac6be603846..9bc6df14e4243 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddAlert.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddAlert.ps1
@@ -56,7 +56,7 @@ Function Invoke-AddAlert {
$params = @{
TenantFilter = $_.defaultDomainName
auditLogAPI = $true
- operations = 'Audit.AzureActiveDirectory,Audit.Exchange,Audit.SharePoint,Audit.General'
+ operations = $Request.body.ifs.selection
BaseURL = $URL
ExecutingUser = $Request.headers.'x-ms-client-principal'
}
@@ -73,7 +73,7 @@ Function Invoke-AddAlert {
$params = @{
TenantFilter = $tenant
auditLogAPI = $true
- operations = 'Audit.AzureActiveDirectory,Audit.Exchange,Audit.SharePoint,Audit.General'
+ operations = $Request.body.ifs.selection
BaseURL = $URL
ExecutingUser = $Request.headers.'x-ms-client-principal'
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddCATemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddCATemplate.ps1
index 9c5d7ee1261e4..7fc95e0d7af16 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddCATemplate.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddCATemplate.ps1
@@ -15,9 +15,8 @@ Function Invoke-AddCATemplate {
try {
$GUID = (New-Guid).GUID
$JSON = if ($request.body.rawjson) {
- ([pscustomobject]$request.body.rawjson) | ConvertFrom-Json
- }
- else {
+ ConvertFrom-Json -InputObject ([pscustomobject]$request.body.rawjson)
+ } else {
([pscustomobject]$Request.body) | ForEach-Object {
$NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name
$_ | Select-Object -Property $NonEmptyProperties
@@ -44,7 +43,7 @@ Function Invoke-AddCATemplate {
$JSON | Add-Member -NotePropertyName 'LocationInfo' -NotePropertyValue @($IncludeJSON, $ExcludeJSON)
- $JSON = ($JSON | ConvertTo-Json -Depth 100)
+ $JSON = (ConvertTo-Json -Depth 100 -InputObject $JSON )
$Table = Get-CippTable -tablename 'templates'
$Table.Force = $true
Add-CIPPAzDataTableEntity @Table -Entity @{
@@ -53,12 +52,11 @@ Function Invoke-AddCATemplate {
PartitionKey = 'CATemplate'
GUID = "$GUID"
}
- Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created Transport Rule Template $($Request.body.name) with GUID $GUID" -Sev 'Debug'
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created CA Template $($Request.body.name) with GUID $GUID" -Sev 'Debug'
$body = [pscustomobject]@{'Results' = 'Successfully added template' }
- }
- catch {
- Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create Transport Rule Template: $($_.Exception.Message)" -Sev 'Error'
+ } catch {
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to create CA Template: $($_.Exception.Message)" -Sev 'Error'
$body = [pscustomobject]@{'Results' = "Intune Template Deployment failed: $($_.Exception.Message)" }
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddSharedMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddSharedMailbox.ps1
index 5426ea863112f..c3017c7cf8815 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddSharedMailbox.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddSharedMailbox.ps1
@@ -9,34 +9,54 @@ Function Invoke-AddSharedMailbox {
param($Request, $TriggerMetadata)
$APIName = $TriggerMetadata.FunctionName
- Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
+ $User = $request.headers.'x-ms-client-principal'
+ Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug'
+
+ $Results = [System.Collections.ArrayList]@()
$groupobj = $Request.body
+ $Aliases = $groupobj.addedAliases -Split '\n'
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
try {
- $email = "$($groupobj.username)@$($groupobj.domain)"
+ $Email = "$($groupobj.username)@$($groupobj.domain)"
$BodyToship = [pscustomobject] @{
'displayName' = $groupobj.Displayname
'name' = $groupobj.username
- 'primarySMTPAddress' = $email
+ 'primarySMTPAddress' = $Email
Shared = $true
-
}
- New-ExoRequest -tenantid $Request.body.tenantid -cmdlet 'New-Mailbox' -cmdparams $BodyToship
+ $AddSharedRequest = New-ExoRequest -tenantid $groupobj.tenantid -cmdlet 'New-Mailbox' -cmdparams $BodyToship
+ $Body = $Results.add("Successfully created shared mailbox: $Email.")
+ Write-LogMessage -user $User -API $APINAME -tenant $($groupobj.tenantid) -message "Created shared mailbox $($groupobj.displayname) with email $Email" -Sev 'Info'
- $body = [pscustomobject]@{'Results' = 'Successfully created shared mailbox.' }
- Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($groupobj.tenantid) -message "Created group $($groupobj.displayname) with id $($GraphRequest.id) for " -Sev 'Info'
+ } catch {
+ Write-LogMessage -user $User -API $APINAME -tenant $($groupobj.tenantid) -message "Failed to create shared mailbox. Error: $($_.Exception.Message)" -Sev 'Error'
+ $Body = $Results.add("Failed to create Shared Mailbox. $($_.Exception.Message)")
}
- catch {
- Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $($groupobj.tenantid) -message "Group creation API failed. $($_.Exception.Message)" -Sev 'Error'
- $body = [pscustomobject]@{'Results' = "Failed to create Shared Mailbox. $($_.Exception.Message)" }
+ try {
+ if ($Aliases) {
+
+ Start-Sleep 3 # Sleep since there is apparently a race condition with the mailbox creation if we don't delay for a lil bit
+ $AliasBodyToShip = [pscustomobject] @{
+ 'Identity' = $AddSharedRequest.Guid
+ 'EmailAddresses' = @{'@odata.type' = '#Exchange.GenericHashTable'; Add = $Aliases }
+ }
+ $AliasBodyToShip
+ New-ExoRequest -tenantid $groupobj.tenantid -cmdlet 'Set-Mailbox' -cmdparams $AliasBodyToShip -UseSystemMailbox $true
+ Write-LogMessage -user $User -API $APINAME -tenant $($groupobj.tenantid) -message "Added aliases to $Email : $($Aliases -join ',')" -Sev 'Info'
+ $Body = $results.add("Added Aliases to $Email : $($Aliases -join ',')")
+ }
+ } catch {
+ Write-LogMessage -user $User -API $APINAME -tenant $($groupobj.tenantid) -message "Failed to add aliases to $Email : $($_.Exception.Message)" -Sev 'Error'
+ $Body = $results.add("ERROR: Failed to add aliases to $Email : $($_.Exception.Message)")
}
+ $Body = [pscustomobject] @{ 'Results' = @($results) }
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-AddUser.ps1
index 1e68886225370..8845a0a8987c4 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 = $TriggerMetadata.FunctionName
+ $APIName = "AddUser"
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
$Results = [System.Collections.ArrayList]@()
@@ -107,11 +107,17 @@ Function Invoke-AddUser {
$results.Add($CopyFrom.Success -join ', ')
$results.Add($CopyFrom.Error -join ', ')
}
+
+ $copyFromResults = @{
+ 'Success' = $CopyFrom.Success
+ 'Error' = $CopyFrom.Error
+ }
+
$body = [pscustomobject] @{
'Results' = @($results)
'Username' = $UserprincipalName
'Password' = $password
- 'CopyFrom' = $CopyFrom
+ 'CopyFrom' = $copyFromResults
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditGroup.ps1
index 7e002adccdfe8..135ddf5a44ba6 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditGroup.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditGroup.ps1
@@ -13,6 +13,7 @@ Function Invoke-EditGroup {
$Results = [System.Collections.ArrayList]@()
$userobj = $Request.body
+ $GroupType = $userobj.groupType -join ','
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
@@ -22,20 +23,21 @@ Function Invoke-EditGroup {
$AddMembers | ForEach-Object {
try {
$member = $_
+
if ($member -like '*#EXT#*') { $member = [System.Web.HttpUtility]::UrlEncode($member) }
$MemberIDs = 'https://graph.microsoft.com/v1.0/directoryObjects/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($member)" -tenantid $Userobj.tenantid).id
$addmemberbody = "{ `"members@odata.bind`": $(ConvertTo-Json @($MemberIDs)) }"
- if ($userobj.groupType -eq 'Distribution list' -or $userobj.groupType -eq 'Mail-Enabled Security') {
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
$Params = @{ Identity = $userobj.groupid; Member = $member; BypassSecurityGroupManagerCheck = $true }
New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
} else {
New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)" -tenantid $Userobj.tenantid -type patch -body $addmemberbody -Verbose
}
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Added $member to $($userobj.groupName) group" -Sev 'Info'
- $body = $results.add("Success. $member has been added")
+ $null = $results.add("Success. $member has been added to $($userobj.groupName)")
} catch {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to add member $member to $($userobj.groupName). Error:$($_.Exception.Message)" -Sev 'Error'
- $body = $results.add("Failed to add member $member to $($userobj.groupName): $($_.Exception.Message)")
+ $null = $results.add("Failed to add member $member to $($userobj.groupName): $($_.Exception.Message)")
}
}
@@ -50,13 +52,13 @@ Function Invoke-EditGroup {
$Params = @{ Identity = $userobj.groupid; Member = $member; BypassSecurityGroupManagerCheck = $true }
New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Added $member to $($userobj.groupName) group" -Sev 'Info'
- $body = $results.add("Success. $member has been added")
+ $null = $results.add("Success. $member has been added to $($userobj.groupName)")
} else {
Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message 'You cannot add a contact to a security group' -Sev 'Error'
- $body = $results.add('You cannot add a contact to a security group')
+ $null = $results.add('You cannot add a contact to a security group')
}
} catch {
- $body = $results.add("Failed to add member $member to $($userobj.groupName): $($_.Exception.Message)")
+ $null = $results.add("Failed to add member $member to $($userobj.groupName): $($_.Exception.Message)")
}
}
@@ -67,7 +69,7 @@ Function Invoke-EditGroup {
if ($RemoveMembers) {
$RemoveMembers | ForEach-Object {
$member = $_
- if ($userobj.groupType -eq 'Distribution list' -or $userobj.groupType -eq 'Mail-Enabled Security') {
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
$Params = @{ Identity = $userobj.groupid; Member = $member ; BypassSecurityGroupManagerCheck = $true }
New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
} else {
@@ -75,12 +77,12 @@ Function Invoke-EditGroup {
New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/members/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE
}
Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Removed $member from $($userobj.groupName) group" -Sev 'Info'
- $body = $results.add("Success. Member $member has been removed")
+ $null = $results.add("Success. Member $member has been removed from $($userobj.groupName)")
}
}
} catch {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to remove $RemoveMembers from $($userobj.groupName). Error:$($_.Exception.Message)" -Sev 'Error'
- $body = $results.add("Could not remove $RemoveMembers from $($userobj.groupName). $($_.Exception.Message)")
+ $null = $results.add("Could not remove $RemoveMembers from $($userobj.groupName). $($_.Exception.Message)")
}
$AddOwners = $userobj.Addowner.value
@@ -90,11 +92,11 @@ Function Invoke-EditGroup {
try {
$ID = 'https://graph.microsoft.com/beta/users/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($_)" -tenantid $Userobj.tenantid).id
Write-Host $ID
- $AddOwner = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/owners/`$ref" -tenantid $Userobj.tenantid -type POST -body ('{"@odata.id": "' + $ID + '"}')
+ $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/owners/`$ref" -tenantid $Userobj.tenantid -type POST -body ('{"@odata.id": "' + $ID + '"}')
Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Added owner $_ to $($userobj.groupName) group" -Sev 'Info'
- $body = $results.add("Success. $_ has been added")
+ $null = $results.add("Success. $_ has been added $($userobj.groupName)")
} catch {
- $body = $results.add("Failed to add owner $_ to $($userobj.groupName): Error:$($_.Exception.Message)")
+ $null = $results.add("Failed to add owner $_ to $($userobj.groupName): Error:$($_.Exception.Message)")
}
}
@@ -112,9 +114,9 @@ Function Invoke-EditGroup {
$MemberInfo = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($_)" -tenantid $Userobj.tenantid)
New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($userobj.groupid)/owners/$($MemberInfo.id)/`$ref" -tenantid $Userobj.tenantid -type DELETE
Write-LogMessage -API $APINAME -tenant $Userobj.tenantid -user $request.headers.'x-ms-client-principal' -message "Removed $($MemberInfo.UserPrincipalname) from $($userobj.displayname) group" -Sev 'Info'
- $body = $results.add("Success. Member $_ has been removed from $($userobj.groupName)")
+ $null = $results.add("Success. Member $_ has been removed from $($userobj.groupName)")
} catch {
- $body = $results.add("Failed to remove $_ from $($userobj.groupName): $($_.Exception.Message)")
+ $null = $results.add("Failed to remove $_ from $($userobj.groupName): $($_.Exception.Message)")
}
}
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1
index 132ccd3af8af0..e869d88293114 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-EditUser.ps1
@@ -15,6 +15,8 @@ Function Invoke-EditUser {
$Results = [System.Collections.ArrayList]@()
$licenses = ($userobj | Select-Object 'License_*').psobject.properties.value
$Aliases = if ($userobj.AddedAliases) { ($userobj.AddedAliases).Split([Environment]::NewLine) }
+ $AddToGroups = $Request.body.AddToGroups
+ $RemoveFromGroups = $Request.body.RemoveFromGroups
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
@@ -44,19 +46,27 @@ Function Invoke-EditUser {
}
} | ForEach-Object {
$NonEmptyProperties = $_.psobject.Properties | Select-Object -ExpandProperty Name
- $_ | Select-Object -Property $NonEmptyProperties | ConvertTo-Json
+ $_ | Select-Object -Property $NonEmptyProperties
}
- $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)" -tenantid $Userobj.tenantid -type PATCH -body $BodyToship -verbose
+ if ($userobj.addedAttributes) {
+ Write-Host 'Found added attribute'
+ Write-Host "Added attributes: $($userobj.addedAttributes | ConvertTo-Json)"
+ $userobj.addedAttributes.getenumerator() | ForEach-Object {
+ $results.add("Edited property $($_.Key) with value $($_.Value)")
+ $bodytoShip | Add-Member -NotePropertyName $_.Key -NotePropertyValue $_.Value -Force
+ }
+ }
+ $bodyToShip = ConvertTo-Json -Depth 10 -InputObject $BodyToship -Compress
+ $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)" -tenantid $Userobj.tenantid -type PATCH -body $BodyToship -verbose
$results.add( 'Success. The user has been edited.' )
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "Edited user $($userobj.displayname) with id $($userobj.Userid)" -Sev 'Info'
if ($userobj.password) {
$passwordProfile = [pscustomobject]@{'passwordProfile' = @{ 'password' = $userobj.password; 'forceChangePasswordNextSignIn' = [boolean]$UserObj.mustchangepass } } | ConvertTo-Json
- $GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)" -tenantid $Userobj.tenantid -type PATCH -body $PasswordProfile -verbose
+ $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)" -tenantid $Userobj.tenantid -type PATCH -body $PasswordProfile -verbose
$results.add("Success. The password has been set to $($userobj.password)")
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "Reset $($userobj.displayname)'s Password" -Sev 'Info'
}
- }
- catch {
+ } catch {
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "User edit API failed. $($_.Exception.Message)" -Sev 'Error'
$results.add( "Failed to edit user. $($_.Exception.Message)")
}
@@ -75,14 +85,13 @@ Function Invoke-EditUser {
$LicenseBody = '{"addLicenses": [' + $LicList + '], "removeLicenses": ' + $LicensesToRemove + '}'
if ($userobj.RemoveAllLicenses) { $LicenseBody = '{"addLicenses": [], "removeLicenses": ' + $LicensesToRemove + '}' }
Write-Host $LicenseBody
- $LicRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)/assignlicense" -tenantid $Userobj.tenantid -type POST -body $LicenseBody -verbose
+ $null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userobj.Userid)/assignlicense" -tenantid $Userobj.tenantid -type POST -body $LicenseBody -verbose
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "Changed user $($userobj.displayname) license. Sent info: $licensebody" -Sev 'Info'
$results.add( 'Success. User license has been edited.' )
}
- }
- catch {
+ } catch {
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "License assign API failed. $($_.Exception.Message)" -Sev 'Error'
$results.add( "We've failed to assign the license. $($_.Exception.Message)")
}
@@ -98,8 +107,7 @@ Function Invoke-EditUser {
$results.add( 'Success. added aliasses to user.')
}
- }
- catch {
+ } catch {
Write-LogMessage -API $APINAME -tenant ($UserObj.tenantid) -user $request.headers.'x-ms-client-principal' -message "Alias API failed. $($_.Exception.Message)" -Sev 'Error'
$results.add( "Successfully edited user. The password is $password. We've failed to create the Aliases: $($_.Exception.Message)")
}
@@ -108,6 +116,77 @@ Function Invoke-EditUser {
$CopyFrom = Set-CIPPCopyGroupMembers -ExecutingUser $request.headers.'x-ms-client-principal' -tenantid $Userobj.tenantid -CopyFromId $Request.body.CopyFrom -UserID $UserprincipalName -TenantFilter $Userobj.tenantid
$results.AddRange($CopyFrom)
}
+
+ if ($AddToGroups) {
+ $AddToGroups | ForEach-Object {
+
+ $GroupType = $_.value.groupType -join ','
+ $GroupID = $_.value.groupid
+ $GroupName = $_.value.groupName
+ Write-Host "About to add $($UserObj.userPrincipalName) to $GroupName. Group ID is: $GroupID and type is: $GroupType"
+
+ try {
+
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
+
+ Write-Host 'Adding to group via Add-DistributionGroupMember '
+ $Params = @{ Identity = $GroupID; Member = $UserObj.Userid; BypassSecurityGroupManagerCheck = $true }
+ New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Add-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
+
+ } else {
+
+ Write-Host 'Adding to group via Graph'
+ $UserBody = [PSCustomObject]@{
+ '@odata.id' = "https://graph.microsoft.com/beta/directoryObjects/$($UserObj.Userid)"
+ }
+ $UserBodyJSON = ConvertTo-Json -Compress -Depth 10 -InputObject $UserBody
+ New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$GroupID/members/`$ref" -tenantid $Userobj.tenantid -type POST -body $UserBodyJSON -Verbose
+
+ }
+
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Added $($UserObj.DisplayName) to $GroupName group" -Sev 'Info'
+ $null = $results.add("Success. $($UserObj.DisplayName) has been added to $GroupName")
+ } catch {
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to add member $($UserObj.DisplayName) to $GroupName. Error:$($_.Exception.Message)" -Sev 'Error'
+ $null = $results.add("Failed to add member $($UserObj.DisplayName) to $GroupName : $($_.Exception.Message)")
+ }
+
+ }
+ }
+
+ if ($RemoveFromGroups) {
+ $RemoveFromGroups | ForEach-Object {
+
+ $GroupType = $_.value.groupType -join ','
+ $GroupID = $_.value.groupid
+ $GroupName = $_.value.groupName
+ Write-Host "About to remove $($UserObj.userPrincipalName) from $GroupName. Group ID is: $GroupID and type is: $GroupType"
+
+ try {
+
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
+
+ Write-Host 'Removing From group via Remove-DistributionGroupMember '
+ $Params = @{ Identity = $GroupID; Member = $UserObj.Userid; BypassSecurityGroupManagerCheck = $true }
+ New-ExoRequest -tenantid $Userobj.tenantid -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
+
+ } else {
+
+ Write-Host 'Removing From group via Graph'
+ New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$GroupID/members/$($UserObj.Userid)/`$ref" -tenantid $Userobj.tenantid -type DELETE
+
+ }
+
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Removed $($UserObj.DisplayName) from $GroupName group" -Sev 'Info'
+ $null = $results.add("Success. $($UserObj.DisplayName) has been removed from $GroupName")
+ } catch {
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $Userobj.tenantid -message "Failed to remove member $($UserObj.DisplayName) from $GroupName. Error:$($_.Exception.Message)" -Sev 'Error'
+ $null = $results.add("Failed to remove member $($UserObj.DisplayName) from $GroupName : $($_.Exception.Message)")
+ }
+
+ }
+ }
+
$body = @{'Results' = @($results) }
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGDAPInvite.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGDAPInvite.ps1
index ff9a8d8568436..d6a5965f20559 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGDAPInvite.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGDAPInvite.ps1
@@ -68,6 +68,7 @@ Function Invoke-ExecGDAPInvite {
} catch {
$Message = 'Error creating GDAP relationship'
Write-Host "GDAP ERROR: $($_.Exception.Message)"
+ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $env:TenantID -message "$($Message): $($_.Exception.Message)" -Sev 'Error'
}
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created GDAP Invite - $InviteUrl" -Sev 'Info'
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSetSharePointMember.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSetSharePointMember.ps1
new file mode 100644
index 0000000000000..0a031a0af5d31
--- /dev/null
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSetSharePointMember.ps1
@@ -0,0 +1,29 @@
+using namespace System.Net
+
+Function Invoke-ExecSetSharePointMember {
+ <#
+ .FUNCTIONALITY
+ Entrypoint
+ #>
+ [CmdletBinding()]
+ param($Request, $TriggerMetadata)
+ $GroupId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/groups?`$filter=mail eq '$($Request.Body.GroupID)'" -tenantid $Request.Body.TenantFilter).id
+ if ($Request.body.SharePointType -eq 'Group') {
+ if ($Request.body.Add -eq $true) {
+ $Results = Add-CIPPGroupMember -GroupType 'Team' -GroupID $GroupID -Member $Request.Body.input -TenantFilter $Request.Body.TenantFilter -ExecutingUser $request.headers.'x-ms-client-principal'
+ } else {
+ $UserID = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($Request.Body.input)" -tenantid $Request.Body.TenantFilter).id
+ $Results = Remove-CIPPGroupMember -GroupType 'Team' -GroupID $GroupID -Member $UserID -TenantFilter $Request.Body.TenantFilter -ExecutingUser $request.headers.'x-ms-client-principal'
+ }
+ } else {
+ $Results = 'This type of SharePoint site is not supported.'
+ }
+ $body = [pscustomobject]@{'Results' = $Results }
+
+ # Associate values to output bindings by calling 'Push-OutputBinding'.
+ Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
+ StatusCode = [HttpStatusCode]::OK
+ Body = $body
+ })
+
+}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSharePointOwner.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSharePointOwner.ps1
new file mode 100644
index 0000000000000..398f070db9eeb
--- /dev/null
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ExecSharePointOwner.ps1
@@ -0,0 +1,26 @@
+using namespace System.Net
+
+Function Invoke-ExecSharePointOwner {
+ <#
+ .FUNCTIONALITY
+ Entrypoint
+ #>
+ [CmdletBinding()]
+ param($Request, $TriggerMetadata)
+
+ $APIName = $TriggerMetadata.FunctionName
+ $tenantFilter = $Request.Body.TenantFilter
+ try {
+ $State = Set-CIPPSharePointOwner -tenantFilter $tenantFilter -userid $request.body.UPN -OnedriveAccessUser $request.body.input -ExecutingUser $ExecutingUser -APIName $APIName -RemovePermission $request.body.RemovePermission -URL $Request.Body.URL
+ $Results = [pscustomobject]@{'Results' = "$State" }
+ } catch {
+ $Results = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" }
+ }
+
+ # 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/Entrypoints/Invoke-ListDomainHealth.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1
index 6d2d1d1106ef4..dfbd465144484 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListDomainHealth.ps1
@@ -75,7 +75,8 @@ Function Invoke-ListDomainHealth {
}
'ReadDkimRecord' {
$DkimQuery = @{
- Domain = $Request.Query.Domain
+ Domain = $Request.Query.Domain
+ FallbackToMicrosoftSelectors = $true
}
if ($Request.Query.Selector) {
$DkimQuery.Selectors = ($Request.Query.Selector).trim() -split '\s*,\s*'
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1
index c2196b1a4e4a6..d25ccd2c6d9fe 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListGroups.ps1
@@ -71,7 +71,7 @@ Function Invoke-ListGroups {
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $StatusCode
- Body = @($GraphRequest)
+ Body = @($GraphRequest | Sort-Object displayName)
})
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1
index b65dba4fdd095..a4ca980ba7d3c 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListMailboxRules.ps1
@@ -18,6 +18,8 @@ Function Invoke-ListMailboxRules {
# Interact with query parameters or the body of the request.
$TenantFilter = $Request.Query.TenantFilter
+ $Table = Get-CIPPTable -TableName cachembxrules
+ $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).Addhours(-1)
if (!$Rows) {
Push-OutputBinding -Name mbxrulequeue -Value $TenantFilter
@@ -27,22 +29,14 @@ Function Invoke-ListMailboxRules {
}
} else {
if ($TenantFilter -ne 'AllTenants') {
- $Table = Get-CIPPTable -TableName cachembxrules
- $Rows = Get-CIPPAzDataTableEntity @Table | Where-Object -Property Timestamp -GT (Get-Date).Addhours(-1)
- $GraphRequest = $Rows | Where-Object -Property Tenant -EQ $TenantFilter | ForEach-Object {
- $NewObj = $_.Rules | ConvertFrom-Json
- $NewObj | Add-Member -NotePropertyName 'Tenant' -NotePropertyValue $TenantFilter
- $NewObj
- }
- } else {
- $GraphRequest = New-ExoRequest -tenantid $tenantFilter -cmdlet 'Get-Mailbox' -Select 'userPrincipalName,GUID' | ForEach-Object {
- New-ExoRequest -Anchor $_.UserPrincipalName -tenantid $tenantFilter -cmdlet 'Get-InboxRule' -cmdParams @{Mailbox = $_.GUID }
- }
+ $Rows = $Rows | Where-Object -Property Tenant -EQ $TenantFilter
+ }
+ $GraphRequest = $Rows | ForEach-Object {
+ $NewObj = $_.Rules | ConvertFrom-Json
+ $NewObj | Add-Member -NotePropertyName 'Tenant' -NotePropertyValue $_.Tenant
+ $NewObj
}
}
- #Remove all old cache
- #Remove-AzDataTableEntity @Table -Entity (Get-CIPPAzDataTableEntity @Table -Property PartitionKey, RowKey, Timestamp | Where-Object -Property Timestamp -LT (Get-Date).AddMinutes(-15))
-
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUserMailboxDetails.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUserMailboxDetails.ps1
index 6a043ace73b23..22f5665696c4e 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUserMailboxDetails.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUserMailboxDetails.ps1
@@ -94,7 +94,7 @@ Function Invoke-ListUserMailboxDetails {
}
$forwardingaddress = if ($MailboxDetailedRequest.ForwardingAddress) {
- $MailboxDetailedRequest.ForwardingAddress
+ (New-GraphGetRequest -tenantid $TenantFilter -uri "https://graph.microsoft.com/beta/users/$($MailboxDetailedRequest.ForwardingAddress)").UserPrincipalName
} elseif ($MailboxDetailedRequest.ForwardingSmtpAddress -and $MailboxDetailedRequest.ForwardingAddress) {
$MailboxDetailedRequest.ForwardingAddress + ' ' + $MailboxDetailedRequest.ForwardingSmtpAddress
} else {
diff --git a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUsers.ps1 b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUsers.ps1
index 961117510a0ed..50c2d13f45250 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUsers.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Invoke-ListUsers.ps1
@@ -10,7 +10,7 @@ Function Invoke-ListUsers {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
- $selectlist = 'id', 'accountEnabled', 'businessPhones', 'city', 'createdDateTime', 'companyName', 'country', 'department', 'displayName', 'faxNumber', 'givenName', 'isResourceAccount', 'jobTitle', 'mail', 'mailNickname', 'mobilePhone', 'onPremisesDistinguishedName', 'officeLocation', 'onPremisesLastSyncDateTime', 'otherMails', 'postalCode', 'preferredDataLocation', 'preferredLanguage', 'proxyAddresses', 'showInAddressList', 'state', 'streetAddress', 'surname', 'usageLocation', 'userPrincipalName', 'userType', 'assignedLicenses', 'onPremisesSyncEnabled', 'LicJoined', 'Aliases', 'primDomain', 'Tenant', 'CippStatus'
+ $selectlist = 'id', 'accountEnabled', 'displayName', 'userPrincipalName', 'userType', 'createdDateTime', 'companyName', 'country', 'department', 'businessPhones', 'city', 'faxNumber', 'givenName', 'isResourceAccount', 'jobTitle', 'mobilePhone', 'officeLocation', 'postalCode', 'preferredDataLocation', 'preferredLanguage', 'mail', 'mailNickname', 'proxyAddresses', 'Aliases', 'otherMails', 'showInAddressList', 'state', 'streetAddress', 'surname', 'usageLocation', 'LicJoined', 'assignedLicenses', 'onPremisesSyncEnabled', 'OnPremisesImmutableId', 'onPremisesDistinguishedName', 'onPremisesLastSyncDateTime', 'primDomain', 'Tenant', 'CippStatus'
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
$ConvertTable = Import-Csv Conversiontable.csv | Sort-Object -Property 'guid' -Unique
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1
index 65501b405c169..581c56ebd962e 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertAppSecretExpiry.ps1
@@ -33,7 +33,7 @@ function Push-CIPPAlertAppSecretExpiry {
Add-CIPPAzDataTableEntity @LastRunTable -Entity $LastRun -Force
}
} catch {
- throw $_
+
}
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAdmins.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAdmins.ps1
index 26baebfccf93e..b0c8056e1f036 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAdmins.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAdmins.ps1
@@ -6,19 +6,19 @@ function Push-CIPPAlertMFAAdmins {
$TriggerMetadata
)
try {
- $CAPolicies = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies' -tenantid $QueueItem.tenant -ErrorAction Stop)
+ $CAPolicies = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies?$top=999' -tenantid $QueueItem.tenant -ErrorAction Stop)
foreach ($Policy in $CAPolicies) {
if ($policy.grantControls.customAuthenticationFactors -eq 'RequireDuoMfa') {
$DuoActive = $true
}
- if (!$DuoActive) {
- $users = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?$filter=IsAdmin eq true' -tenantid $($QueueItem.tenant) | Where-Object -Property 'isMfaRegistered' -EQ $false
- if ($users) {
- Write-AlertMessage -tenant $QueueItem.tenant -message "The following admins do not have MFA registered: $($users.UserPrincipalName -join ', ')"
- }
- } else {
- Write-LogMessage -message 'Potentially using Duo for MFA, could not check MFA status for Admins with 100% accuracy' -API 'MFA Alerts - Informational' -tenant $QueueItem.tenant -sev Info
+ }
+ if (!$DuoActive) {
+ $users = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?$top=999&$filter=IsAdmin eq true' -tenantid $($QueueItem.tenant) | Where-Object -Property 'isMfaRegistered' -EQ $false
+ if ($users) {
+ Write-AlertMessage -tenant $QueueItem.tenant -message "The following admins do not have MFA registered: $($users.UserPrincipalName -join ', ')"
}
+ } else {
+ Write-LogMessage -message 'Potentially using Duo for MFA, could not check MFA status for Admins with 100% accuracy' -API 'MFA Alerts - Informational' -tenant $QueueItem.tenant -sev Info
}
} catch {
Write-LogMessage -message "Failed to check MFA status for Admins: $($_.exception.message)" -API 'MFA Alerts - Informational' -tenant $QueueItem.tenant -sev Error
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAlertUsers.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAlertUsers.ps1
index 520c84be33c5c..3537616d02edc 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAlertUsers.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertMFAAlertUsers.ps1
@@ -6,22 +6,14 @@ function Push-CIPPAlertMFAAlertUsers {
$TriggerMetadata
)
try {
- $LastRunTable = Get-CIPPTable -Table AlertLastRun
- $Filter = "RowKey eq 'MFAAllUsers' 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)) {
- $users = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?$filter=isMfaRegistered eq false' -tenantid $($QueueItem.tenant)
- if ($users) {
- Write-AlertMessage -tenant $QueueItem.tenant -message "The following users do not have MFA registered: $($users.UserPrincipalName -join ', ')"
- }
+
+ $users = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?$filter=isMfaRegistered eq false and userType eq ''member''&$select=userPrincipalName,lastUpdatedDateTime,isMfaRegistered' -tenantid $($QueueItem.tenant)
+ if ($users) {
+ Write-AlertMessage -tenant $QueueItem.tenant -message "The following $($users.Count) users do not have MFA registered: $($users.UserPrincipalName -join ', ')"
}
+
} catch {
Write-LogMessage -message "Failed to check MFA status for all users: $($_.exception.message)" -API 'MFA Alerts - Informational' -tenant $QueueItem.tenant -sev Info
}
- $LastRun = @{
- RowKey = 'MFAAllUsers'
- PartitionKey = $QueueItem.tenantid
- }
- Add-CIPPAzDataTableEntity @LastRunTable -Entity $LastRun -Force
+
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertNoCAConfig.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertNoCAConfig.ps1
index 72bd6d90b151a..17b5363a1c545 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertNoCAConfig.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertNoCAConfig.ps1
@@ -15,7 +15,7 @@ function Push-CIPPAlertNoCAConfig {
}
}
} catch {
- Write-AlertMessage -tenant $($QueueItem.tenant) -message "Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
+ Write-AlertMessage -tenant $($QueueItem.tenant) -message "Conditional Access Config Alert: Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
}
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertOverusedLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertOverusedLicenses.ps1
index bd96b03266cda..af90000fa4d0e 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertOverusedLicenses.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertOverusedLicenses.ps1
@@ -22,6 +22,6 @@ function Push-CIPPAlertOverusedLicenses {
}
}
} catch {
- Write-AlertMessage -tenant $($QueueItem.tenant) -message "Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
+ Write-AlertMessage -tenant $($QueueItem.tenant) -message "Overused Licenses Alert Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
}
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1
index 9adaa80ceca6f..1e5f940644795 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertQuotaUsed.ps1
@@ -9,12 +9,13 @@ function Push-CIPPAlertQuotaUsed {
try {
New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/getMailboxUsageDetail(period='D7')?`$format=application/json" -tenantid $QueueItem.tenant | ForEach-Object {
+ if ($_.StorageUsedInBytes -eq 0) { continue }
$PercentLeft = [math]::round($_.StorageUsedInBytes / $_.prohibitSendReceiveQuotaInBytes * 100)
if ($PercentLeft -gt 90) {
Write-AlertMessage -tenant $($QueueItem.tenant) -message "$($_.UserPrincipalName): Mailbox has less than 10% space left. Mailbox is $PercentLeft% full"
}
}
} catch {
- Write-AlertMessage -tenant $($QueueItem.tenant) -message "Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
+ Write-AlertMessage -tenant $($QueueItem.tenant) -message "Mailbox Quota Alert Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
}
}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertUnusedLicenses.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertUnusedLicenses.ps1
index c2e7beeb65220..2bd58f8b6178e 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertUnusedLicenses.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-CIPPAlertUnusedLicenses.ps1
@@ -7,21 +7,21 @@ function Push-CIPPAlertUnusedLicenses {
)
- try {
- $LicenseTable = Get-CIPPTable -TableName ExcludedLicenses
- $ExcludedSkuList = Get-CIPPAzDataTableEntity @LicenseTable
- New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/subscribedSkus' -tenantid $QueueItem.tenant | ForEach-Object {
- $skuid = $_
- foreach ($sku in $skuid) {
- if ($sku.skuId -in $ExcludedSkuList.GUID) { continue }
- $PrettyName = ($ConvertTable | Where-Object { $_.GUID -eq $sku.skuid }).'Product_Display_Name' | Select-Object -Last 1
- if (!$PrettyName) { $PrettyName = $sku.skuPartNumber }
- if ($sku.prepaidUnits.enabled - $sku.consumedUnits -gt 0) {
- Write-AlertMessage -tenant $($QueueItem.tenant) -message "$PrettyName has unused licenses. Using $($_.consumedUnits) of $($_.prepaidUnits.enabled)."
- }
- }
+ try {
+ $LicenseTable = Get-CIPPTable -TableName ExcludedLicenses
+ $ExcludedSkuList = Get-CIPPAzDataTableEntity @LicenseTable
+ New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/subscribedSkus' -tenantid $QueueItem.tenant | ForEach-Object {
+ $skuid = $_
+ foreach ($sku in $skuid) {
+ if ($sku.skuId -in $ExcludedSkuList.GUID) { continue }
+ $PrettyName = ($ConvertTable | Where-Object { $_.GUID -eq $sku.skuid }).'Product_Display_Name' | Select-Object -Last 1
+ if (!$PrettyName) { $PrettyName = $sku.skuPartNumber }
+ if ($sku.prepaidUnits.enabled - $sku.consumedUnits -gt 0) {
+ Write-AlertMessage -tenant $($QueueItem.tenant) -message "$PrettyName has unused licenses. Using $($_.consumedUnits) of $($_.prepaidUnits.enabled)."
}
- } catch {
- Write-AlertMessage -tenant $($QueueItem.tenant) -message "Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
}
}
+ } catch {
+ Write-AlertMessage -tenant $($QueueItem.tenant) -message "Unused Licenses Alert Error occurred: $(Get-NormalizedError -message $_.Exception.message)"
+ }
+}
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-ListGraphRequestQueue.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-ListGraphRequestQueue.ps1
index 126e8d14335de..82f12e1df6652 100644
--- a/Modules/CIPPCore/Public/Entrypoints/Push-ListGraphRequestQueue.ps1
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-ListGraphRequestQueue.ps1
@@ -19,7 +19,7 @@ function Push-ListGraphRequestQueue {
$PartitionKey = $QueueItem.PartitionKey
- $TableName = ('cache{0}' -f ($QueueItem.Endpoint -replace '[^A-Za-z0-9]'))[0..63] -join ''
+ $TableName = ('cache{0}' -f ($QueueItem.Endpoint -replace '[^A-Za-z0-9]'))[0..62] -join ''
Write-Host $TableName
$Table = Get-CIPPTable -TableName $TableName
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1
new file mode 100644
index 0000000000000..d9800f40a34a3
--- /dev/null
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerAlert.ps1
@@ -0,0 +1,43 @@
+function Push-SchedulerAlert {
+ param (
+ $QueueItem, $TriggerMetadata
+ )
+ $Tenant = $QueueItem
+ try {
+ $Table = Get-CIPPTable -Table SchedulerConfig
+ if ($Tenant.tag -eq 'AllTenants') {
+ $Filter = "RowKey eq 'AllTenants' and PartitionKey eq 'Alert'"
+ } else {
+ $Filter = "RowKey eq '{0}' and PartitionKey eq 'Alert'" -f $Tenant.tenantid
+ }
+ $Alerts = Get-CIPPAzDataTableEntity @Table -Filter $Filter
+
+
+ $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)"
+ }
+ 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
+ }
+}
\ No newline at end of file
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1
new file mode 100644
index 0000000000000..3ec9e8b7d9a21
--- /dev/null
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-SchedulerCIPPNotifications.ps1
@@ -0,0 +1,164 @@
+function Push-SchedulerCIPPNotifications {
+ param (
+ $QueueItem, $TriggerMetadata
+ )
+
+ $Table = Get-CIPPTable -TableName SchedulerConfig
+ $Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'"
+ $Config = [pscustomobject](Get-CIPPAzDataTableEntity @Table -Filter $Filter)
+
+ $Settings = [System.Collections.ArrayList]@('Alerts')
+ $Config.psobject.properties.name | ForEach-Object { $settings.add($_) }
+ $severity = $Config.Severity -split ','
+ Write-Host "Our Severity table is: $severity"
+ if (!$severity) {
+ $severity = [System.Collections.ArrayList]@('Info', 'Error', 'Warning', 'Critical', 'Alert')
+ }
+ Write-Host "Our Severity table is: $severity"
+ $Table = Get-CIPPTable
+ $PartitionKey = Get-Date -UFormat '%Y%m%d'
+ $Filter = "PartitionKey eq '{0}'" -f $PartitionKey
+ $Currentlog = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object {
+ $_.API -In $Settings -and $_.SentAsAlert -ne $true -and $_.Severity -In $severity
+ }
+ Write-Host ($Currentlog).count
+ #email try
+ try {
+ if ($config.onePerTenant) {
+ if ($Config.email -like '*@*' -and $null -ne $CurrentLog) {
+ $JSONRecipients = $Config.email.split(',').trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } }
+ $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1)
+ foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) {
+ $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) -replace '
', '' | Out-String
+ $JSONBody = @"
+ {
+ "message": {
+ "subject": "$($Tenant): CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))",
+ "body": {
+ "contentType": "HTML",
+ "content": "You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log:
+
+
+ $($HTMLLog)
+
+ "
+ },
+ "toRecipients": [
+ $($JSONRecipients)
+ ]
+ },
+ "saveToSentItems": "false"
+ }
+"@
+ New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -type POST -body ($JSONBody)
+ Write-LogMessage -API 'Alerts' -message "Sent alerts to: $($JSONRecipients)" -tenant $Tenant -sev Debug
+ }
+ }
+ } else {
+ if ($Config.email -like '*@*' -and $null -ne $CurrentLog) {
+ $JSONRecipients = $Config.email.split(',').trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } }
+ $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1)
+ $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | ConvertTo-Html -frag) -replace '', '' | Out-String
+ $JSONBody = @"
+ {
+ "message": {
+ "subject": "CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))",
+ "body": {
+ "contentType": "HTML",
+ "content": "You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log:
+
+
+ $($HTMLLog)
+
+ "
+ },
+ "toRecipients": [
+ $($JSONRecipients)
+ ]
+ },
+ "saveToSentItems": "false"
+ }
+"@
+ New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -type POST -body ($JSONBody)
+ Write-LogMessage -API 'Alerts' -message "Sent alerts to: $($Config.email)" -tenant 'All Tenants' -sev Debug
+ }
+ }
+ } catch {
+ Write-Host "Could not send alerts to email: $($_.Exception.message)"
+ Write-LogMessage -API 'Alerts' -message "Could not send alerts to: $($_.Exception.message)" -tenant 'All Tenants' -sev error
+ }
+
+
+ try {
+ Write-Host $($config | ConvertTo-Json)
+ Write-Host $config.webhook
+ if ($Config.webhook -ne '' -and $null -ne $CurrentLog) {
+ switch -wildcard ($config.webhook) {
+
+ '*webhook.office.com*' {
+ $Log = $Currentlog | ConvertTo-Html -frag | Out-String
+ $JSonBody = "{`"text`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log.
$Log`"}"
+ Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
+ }
+
+ '*slack.com*' {
+ $Log = $Currentlog | ForEach-Object {
+ $JSonBody = @"
+ {"blocks":[{"type":"header","text":{"type":"plain_text","text":"New Alert from CIPP","emoji":true}},{"type":"section","fields":[{"type":"mrkdwn","text":"*DateTime:*\n$($_.Timestamp)"},{"type":"mrkdwn","text":"*Tenant:*\n$($_.Tenant)"},{"type":"mrkdwn","text":"*API:*\n$($_.API)"},{"type":"mrkdwn","text":"*User:*\n$($_.Username)."}]},{"type":"section","text":{"type":"mrkdwn","text":"*Message:*\n$($_.Message)"}}]}
+"@
+ Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
+ }
+ }
+
+ '*discord.com*' {
+ $Log = $Currentlog | ConvertTo-Html -frag | Out-String
+ $JSonBody = "{`"content`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log. $Log`"}"
+ Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
+ }
+ default {
+ $Log = $Currentlog | ConvertTo-Json -Compress
+ $JSonBody = $Log
+ Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
+ }
+ }
+ Write-LogMessage -API 'Alerts' -tenant $Tenant -message "Sent Webhook to $($config.webhook)" -sev Debug
+ }
+
+ $UpdateLogs = $CurrentLog | ForEach-Object {
+ $_.SentAsAlert = $true
+ $_
+ }
+ if ($UpdateLogs) {
+ Add-CIPPAzDataTableEntity @Table -Entity $UpdateLogs -Force
+ }
+ } catch {
+ Write-Host "Could not send alerts to webhook: $($_.Exception.message)"
+ Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -tenant $Tenant -sev error
+ }
+
+ if ($config.sendtoIntegration) {
+ try {
+ foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) {
+ $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) -replace '', '' | Out-String
+ $Alert = @{
+ TenantId = $Tenant
+ AlertText = " $($htmllog)"
+ AlertTitle = "$tenant CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))"
+ }
+ New-CippExtAlert -Alert $Alert
+ $UpdateLogs = $CurrentLog | ForEach-Object {
+ $_.SentAsAlert = $true
+ $_
+ }
+ if ($UpdateLogs) {
+ Add-CIPPAzDataTableEntity @Table -Entity $UpdateLogs -Force
+ }
+ }
+ } catch {
+ Write-Host "Could not send alerts to ticketing system: $($_.Exception.message)"
+ Write-LogMessage -API 'Alerts' -tenant $Tenant -message "Could not send alerts to ticketing system: $($_.Exception.message)" -sev Error
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/Modules/CIPPCore/Public/Entrypoints/Push-Schedulerwebhookcreation.ps1 b/Modules/CIPPCore/Public/Entrypoints/Push-Schedulerwebhookcreation.ps1
new file mode 100644
index 0000000000000..82e1a47d55c5b
--- /dev/null
+++ b/Modules/CIPPCore/Public/Entrypoints/Push-Schedulerwebhookcreation.ps1
@@ -0,0 +1,7 @@
+function Push-Schedulerwebhookcreation
+ {
+ param (
+ $QueueItem, $TriggerMetadata
+ )
+
+}
\ No newline at end of file
diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
index 88fb8492350e3..42bdbfcd53560 100644
--- a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
+++ b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
@@ -56,6 +56,7 @@ function Get-NormalizedError {
'*The property value exceeds the maximum allowed size (64KB)*' { 'One of the values exceeds the maximum allowed size (64KB).' }
'*Unable to initialize the authorization context*' { 'Your GDAP configuration does not allow us to write to this tenant, please check your group mappings and tenant onboarding.' }
'*Providers.Common.V1.CoreException*' { '403 (Access Denied) - We cannot connect to this tenant.' }
+ '*Authentication failed. MFA required*' { 'Authentication failed. MFA required' }
Default { $message }
}
diff --git a/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1
index 7da2b800b3c91..0d45ac6311df0 100644
--- a/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1
+++ b/Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1
@@ -35,7 +35,7 @@ function Invoke-CIPPOffboardingJob {
}
{ $_.'OnedriveAccess' -ne '' } {
- $Options.OnedriveAccess | ForEach-Object { Set-CIPPOnedriveAccess -tenantFilter $tenantFilter -userid $username -OnedriveAccessUser $_.value -ExecutingUser $ExecutingUser -APIName $APIName }
+ $Options.OnedriveAccess | ForEach-Object { Set-CIPPSharePointOwner -tenantFilter $tenantFilter -userid $username -OnedriveAccessUser $_.value -ExecutingUser $ExecutingUser -APIName $APIName }
}
{ $_.'AccessNoAutomap' -ne '' } {
diff --git a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1 b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1
index 1f698dc9f4758..fee8af4c24be7 100644
--- a/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1
+++ b/Modules/CIPPCore/Public/Invoke-CIPPWebhookProcessing.ps1
@@ -52,6 +52,7 @@ function Invoke-CippWebhookProcessing {
$ExtendedPropertiesIgnoreList = @(
'OAuth2:Authorize'
+ 'OAuth2:Token'
'SAS:EndAuth'
'SAS:ProcessAuth'
)
diff --git a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1
index d4af47d3325ac..5fd635238470d 100644
--- a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1
+++ b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1
@@ -73,7 +73,9 @@ function New-CIPPCAPolicy {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Matched a CA policy with the existing Named Location: $($location.displayName)" -Sev 'Info'
} else {
+ if ($location.countriesAndRegions) { $location.countriesAndRegions = @($location.countriesAndRegions) }
$Body = ConvertTo-Json -InputObject $Location
+ Write-Host "Trying to create named location with: $body"
$GraphRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -body $body -Type POST -tenantid $tenantfilter
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created new Named Location: $($location.displayName)" -Sev 'Info'
[pscustomobject]@{
@@ -83,10 +85,9 @@ function New-CIPPCAPolicy {
}
}
}
- Write-Host 'here5'
foreach ($location in $JSONObj.conditions.locations.includeLocations) {
- Write-Host "Replacting $location"
+ Write-Host "Replacing $location"
$lookup = $LocationLookupTable | Where-Object -Property name -EQ $location
Write-Host "Found $lookup"
if (!$lookup) { continue }
diff --git a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1 b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1
index 16877c1e65242..6eac507448ecb 100644
--- a/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1
+++ b/Modules/CIPPCore/Public/New-CIPPGraphSubscription.ps1
@@ -15,10 +15,28 @@ function New-CIPPGraphSubscription {
)
$CIPPID = (New-Guid).GUID
$WebhookTable = Get-CIPPTable -TableName webhookTable
-
+ Write-Host "Operations are: $operations"
try {
if ($auditLogAPI) {
- $EventTypes = @('Audit.AzureActiveDirectory', 'Audit.Exchange', 'Audit.SharePoint', 'Audit.General')
+ $MappingTable = [pscustomobject]@{
+ 'UserLoggedIn' = 'Audit.AzureActiveDirectory'
+ 'Add member to role.' = 'Audit.AzureActiveDirectory'
+ 'Disable account.' = 'Audit.AzureActiveDirectory'
+ 'Update StsRefreshTokenValidFrom Timestamp.' = 'Audit.AzureActiveDirectory'
+ 'Enable account.' = 'Audit.AzureActiveDirectory'
+ 'Disable Strong Authentication.' = 'Audit.AzureActiveDirectory'
+ 'Reset user password.' = 'Audit.AzureActiveDirectory'
+ 'Add service principal.' = 'Audit.AzureActiveDirectory'
+ 'HostedIP' = 'Audit.AzureActiveDirectory'
+ 'badRepIP' = 'Audit.AzureActiveDirectory'
+ 'UserLoggedInFromUnknownLocation' = 'Audit.AzureActiveDirectory'
+ 'customfield' = 'AnyLog'
+ 'anyAlert' = 'AnyLog'
+ 'New-InboxRule' = 'Audit.Exchange'
+ 'Set-InboxRule' = 'Audit.Exchange'
+ }
+ $EventTypes = $operations | Where-Object { $MappingTable.$_ } | ForEach-Object { $MappingTable.$_ }
+ if ('anyLog' -in $EventTypes) { $EventTypes = @('Audit.AzureActiveDirectory', 'Audit.Exchange', 'Audit.SharePoint', 'Audit.General') }
foreach ($EventType in $EventTypes) {
$CIPPID = (New-Guid).GUID
$Resource = $EventType
@@ -42,7 +60,7 @@ function New-CIPPGraphSubscription {
WebhookNotificationUrl = [string]$CIPPAuditURL
}
Add-CIPPAzDataTableEntity @WebhookTable -Entity $WebhookRow
-
+ Write-Host "Creating webhook subscription for $EventType"
$AuditLog = New-GraphPOSTRequest -uri "https://manage.office.com/api/v1.0/$($TenantFilter)/activity/feed/subscriptions/start?contentType=$EventType&PublisherIdentifier=$($TenantFilter)" -tenantid $TenantFilter -type POST -scope 'https://manage.office.com/.default' -body $AuditLogparams -verbose
Write-LogMessage -user $ExecutingUser -API $APIName -message "Created Webhook subscription for $($TenantFilter) for the log $($EventType)" -Sev 'Info' -tenant $TenantFilter
diff --git a/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1 b/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1
new file mode 100644
index 0000000000000..9567039fe8e4b
--- /dev/null
+++ b/Modules/CIPPCore/Public/Remove-CIPPGroupMember.ps1
@@ -0,0 +1,28 @@
+function Remove-CIPPGroupMember(
+ [string]$ExecutingUser,
+ [string]$GroupType,
+ [string]$GroupId,
+ [string]$Member,
+ [string]$TenantFilter,
+ [string]$APIName = 'Remove Group Member'
+) {
+ try {
+ if ($member -like '*#EXT#*') { $member = [System.Web.HttpUtility]::UrlEncode($member) }
+ $MemberIDs = 'https://graph.microsoft.com/v1.0/directoryObjects/' + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($member)" -tenantid $TenantFilter).id
+ $addmemberbody = "{ `"members@odata.bind`": $(ConvertTo-Json @($MemberIDs)) }"
+ if ($GroupType -eq 'Distribution list' -or $GroupType -eq 'Mail-Enabled Security') {
+ $Params = @{ Identity = $GroupId; Member = $member; BypassSecurityGroupManagerCheck = $true }
+ New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-DistributionGroupMember' -cmdParams $params -UseSystemMailbox $true
+ } else {
+ New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($GroupId)/members/$($Member)/`$ref" -tenantid $TenantFilter -type DELETE -body '{}' -Verbose
+ }
+ $Message = "Successfully removed user $($Member) from $GroupId."
+ Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $Message -Sev 'Info'
+ return $message
+ } catch {
+ $message = "Failed to remove user $($Member) from $($GroupId): $($_.Exception.Message)"
+ Write-LogMessage -user $ExecutingUser -API $APIName -tenant $TenantFilter -message $message -Sev 'error'
+ return $message
+ }
+
+}
diff --git a/Modules/CIPPCore/Public/SAMManifest.json b/Modules/CIPPCore/Public/SAMManifest.json
index fc887aed506b2..f4ee6e523f9a0 100644
--- a/Modules/CIPPCore/Public/SAMManifest.json
+++ b/Modules/CIPPCore/Public/SAMManifest.json
@@ -154,14 +154,7 @@
{ "id": "b27a61ec-b99c-4d6a-b126-c4375d08ae30", "type": "Scope" },
{ "id": "84bccea3-f856-4a8a-967b-dbe0a3d53a64", "type": "Scope" },
{ "id": "280b3b69-0437-44b1-bc20-3b2fca1ee3e9", "type": "Scope" },
- {
- "id": "885f682f-a990-4bad-a642-36736a74b0c7",
- "type": "Scope"
- },
- {
- "id": "c2d95988-7604-4ba1-aaed-38a5f82a51c7",
- "type": "Scope"
- }
+ { "id": "885f682f-a990-4bad-a642-36736a74b0c7", "type": "Scope" }
]
},
{
diff --git a/Modules/CIPPCore/Public/Set-CIPPCopyGroupMembers.ps1 b/Modules/CIPPCore/Public/Set-CIPPCopyGroupMembers.ps1
index 098c0fc41b944..cfd851f589eb5 100644
--- a/Modules/CIPPCore/Public/Set-CIPPCopyGroupMembers.ps1
+++ b/Modules/CIPPCore/Public/Set-CIPPCopyGroupMembers.ps1
@@ -5,17 +5,17 @@ function Set-CIPPCopyGroupMembers(
[string]$TenantFilter,
[string]$APIName = "Copy User Groups"
) {
- $MemberIDs = "https://graph.microsoft.com/v1.0/directoryObjects/" + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$UserId" -tenantid $TenantFilter).id
+ $MemberIDs = "https://graph.microsoft.com/v1.0/directoryObjects/" + (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$UserId" -tenantid $TenantFilter).id
$AddMemberBody = "{ `"members@odata.bind`": $(ConvertTo-Json @($MemberIDs)) }"
-
+
$Success = New-Object System.Collections.ArrayList
$Errors = New-Object System.Collections.ArrayList
- (New-GraphGETRequest -uri "https://graph.microsoft.com/beta/users/$CopyFromId/memberOf" -tenantid $TenantFilter) | Where-Object { $_.GroupTypes -notin "DynamicMemberShip" } | ForEach-Object {
+ (New-GraphGETRequest -uri "https://graph.microsoft.com/beta/users/$CopyFromId/memberOf" -tenantid $TenantFilter) | Where-Object { $_.GroupTypes -notin "herohero" } | ForEach-Object {
try {
$MailGroup = $_
if ($MailGroup.MailEnabled -and $Mailgroup.ResourceProvisioningOptions -notin "Team") {
$Params = @{ Identity = $MailGroup.mail; Member = $UserId; BypassSecurityGroupManagerCheck = $true }
- New-ExoRequest -tenantid $TenantFilter -cmdlet "Add-DistributionGroupMember" -cmdParams $params -UseSystemMailbox $true
+ New-ExoRequest -tenantid $TenantFilter -cmdlet "Add-DistributionGroupMember" -cmdParams $params -UseSystemMailbox $true
}
else {
$GroupResult = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/groups/$($_.id)" -tenantid $TenantFilter -type patch -body $AddMemberBody -Verbose
diff --git a/Modules/CIPPCore/Public/Set-CIPPOneDriveAccess.ps1 b/Modules/CIPPCore/Public/Set-CIPPSharePointOwner.ps1
similarity index 59%
rename from Modules/CIPPCore/Public/Set-CIPPOneDriveAccess.ps1
rename to Modules/CIPPCore/Public/Set-CIPPSharePointOwner.ps1
index 53cdaf9def8ef..3acdfc3d314f1 100644
--- a/Modules/CIPPCore/Public/Set-CIPPOneDriveAccess.ps1
+++ b/Modules/CIPPCore/Public/Set-CIPPSharePointOwner.ps1
@@ -1,15 +1,24 @@
-function Set-CIPPOnedriveAccess {
+function Set-CIPPSharePointOwner {
[CmdletBinding()]
param (
$userid,
$OnedriveAccessUser,
$TenantFilter,
- $APIName = 'Manage OneDrive Access',
- $ExecutingUser
+ $APIName = 'Manage SharePoint Owner',
+ $RemovePermission,
+ $ExecutingUser,
+ $URL
)
+ if ($RemovePermission -eq $true) {
+ $SiteAdmin = 'false'
+ } else {
+ $SiteAdmin = 'true'
+ }
try {
- $URL = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($UserId)/Drives" -asapp $true -tenantid $TenantFilter).WebUrl
+ if (!$URL) {
+ $URL = (New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/users/$($UserId)/Drives" -asapp $true -tenantid $TenantFilter).WebUrl
+ }
$OnMicrosoft = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains?$top=999' -tenantid $TenantFilter | Where-Object -Property isInitial -EQ $true).id.split('.') | Select-Object -First 1
$AdminUrl = "https://$($OnMicrosoft)-admin.sharepoint.com"
$XML = @"
@@ -22,7 +31,7 @@ function Set-CIPPOnedriveAccess {
$URL
$OnedriveAccessUser
- true
+ $SiteAdmin
@@ -30,15 +39,18 @@ function Set-CIPPOnedriveAccess {
"@
$request = New-GraphPostRequest -scope "$AdminURL/.default" -tenantid $TenantFilter -Uri "$AdminURL/_vti_bin/client.svc/ProcessQuery" -Type POST -Body $XML -ContentType 'text/xml'
+ Write-Host $($request)
if (!$request.ErrorInfo.ErrorMessage) {
- Write-LogMessage -user $ExecutingUser -API $APIName -message "Gave $($OnedriveAccessUser) access to $($userid) OneDrive" -Sev 'Info' -tenant $TenantFilter
- return "User's OneDrive URL is $URL. Access has been given to $($OnedriveAccessUser)"
+ $Message = "$($OnedriveAccessUser) has been $($RemovePermission ? 'removed from' : 'given') access to $URL"
+ Write-LogMessage -user $ExecutingUser -API $APIName -message $Message -Sev 'Info' -tenant $TenantFilter
+ return $Message
} else {
- Write-LogMessage -user $ExecutingUser -API $APIName -message "Failed to give OneDrive Access: $($request.ErrorInfo.ErrorMessage)" -Sev 'Info' -tenant $TenantFilter
- return "Failed to give OneDrive Access: $($request.ErrorInfo.ErrorMessage)"
+ $message = "Failed to change access: $($request.ErrorInfo.ErrorMessage)"
+ Write-LogMessage -user $ExecutingUser -API $APIName -message $message -Sev 'Info' -tenant $TenantFilter
+ return $message
}
} catch {
- Write-LogMessage -user $ExecutingUser -API $APIName -message "Could not add new owner to OneDrive $($OnedriveAccessUser) on $($userid)" -Sev 'Error' -tenant $TenantFilter
- return "Could not add owner to OneDrive for $($userid). Error: $($_.Exception.Message)"
+ Write-LogMessage -user $ExecutingUser -API $APIName -message "Could not add new owner to $($OnedriveAccessUser) on $URL" -Sev 'Error' -tenant $TenantFilter
+ return "Could not add owner for $($URL). Error: $($_.Exception.Message)"
}
}
diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1
index ecf181d8497ae..9b6eb90127108 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1
@@ -4,28 +4,55 @@ function Invoke-CIPPStandardAddDKIM {
Internal
#>
param($Tenant, $Settings)
- $DKIM = (New-ExoRequest -tenantid $tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object -Property Enabled -EQ $false
+
+ $AllDomains = (New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/domains' -tenantid $Tenant | Where-Object { $_.supportedServices -contains 'Email' }).id
+ $DKIM = (New-ExoRequest -tenantid $tenant -cmdlet 'Get-DkimSigningConfig') | Select-Object Domain, Enabled, Status
+
+ # List of domains for each way to enable DKIM
+ $NewDomains = $AllDomains | Where-Object { $DKIM.Domain -notcontains $_ }
+ $SetDomains = $DKIM | Where-Object { $AllDomains -contains $_.Domain -and $_.Enabled -eq $false }
+
If ($Settings.remediate) {
- try {
- $DKIM | ForEach-Object {
- (New-ExoRequest -tenantid $tenant -cmdlet 'New-DkimSigningConfig' -cmdparams @{ KeySize = 2048; DomainName = $_.Identity; Enabled = $true } -useSystemMailbox $true)
+ $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++
}
- Write-LogMessage -API 'Standards' -tenant $tenant -message 'Enabled DKIM Setup' -sev Info
-
- } catch {
- Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to enable DKIM. Error: $($_.exception.message)" -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
}
}
if ($Settings.alert) {
- if ($DKIM) {
+ if ($null -eq $NewDomains -and $null -eq $SetDomains) {
Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is enabled for all available domains' -sev Info
} else {
- Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is not enabled for all available domains' -sev Alert
+ $NoDKIM = ($NewDomains + $SetDomains.Domain) -join ';'
+ Write-LogMessage -API 'Standards' -tenant $tenant -message "DKIM is not enabled for: $NoDKIM" -sev Alert
}
}
if ($Settings.report) {
- Add-CIPPBPAField -FieldName 'DKIM' -FieldValue [bool]$DKIM -StoreAs bool -Tenant $tenant
+ 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-CIPPStandardDisableM365GroupUsers.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1
index 125025a40b83f..bbb62f9b0b928 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1
@@ -11,12 +11,12 @@ function Invoke-CIPPStandardDisableM365GroupUsers {
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)" -Type POST -Body $CurrentState -ContentType 'application/json')
+ 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'
+ ($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value = 'false'
$body = "{values : $($CurrentState.values | ConvertTo-Json -Compress)}"
- (New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type patch -Body $body -ContentType 'application/json')
+ 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'
diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableOutlookAddins.ps1
new file mode 100644
index 0000000000000..d352fd8b33f06
--- /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 0000000000000..87178367ab5c2
--- /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/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1
index 738420ebe73ae..fc2b34dda7b18 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardMailContacts.ps1
@@ -13,13 +13,13 @@ function Invoke-CIPPStandardMailContacts {
$Body = [pscustomobject]@{}
switch ($Contacts) {
{ $Contacts.MarketingContact } { $body | Add-Member -NotePropertyName marketingNotificationEmails -NotePropertyValue @($Contacts.MarketingContact) }
- { $Contacts.SecurityContact } { $body | Add-Member -NotePropertyName securityComplianceNotificationMails -NotePropertyValue @($Contacts.SecurityContact) }
+ { $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 } }
}
Write-Host (ConvertTo-Json -InputObject $body)
- New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/organization/$($TenantID.id)" -asApp $true -Type patch -Body (ConvertTo-Json -InputObject $body) -ContentType 'application/json'
- Write-LogMessage -API 'Standards' -tenant $tenant -message "Contact email's set." -sev Info
+ 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
}
diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1
index 307ebdfada1cf..1816a15ca9983 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardOutBoundSpamAlert.ps1
@@ -7,10 +7,10 @@ function Invoke-CIPPStandardOutBoundSpamAlert {
If ($Settings.remediate) {
$Contacts = $settings.OutboundSpamContact
try {
- New-ExoRequest -tenantid $tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdparams @{ Identity = 'Default'; NotifyOutboundSpam = $true; NotifyOutboundSpamRecipients = $Contacts.OutboundSpamContact } -useSystemMailbox $true
- Write-LogMessage -API 'Standards' -tenant $tenant -message "Set outbound spam filter alert to $($Contacts.OutboundSpamContact)" -sev Info
+ 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.OutboundSpamContact). $($_.exception.message)" -sev Error
+ Write-LogMessage -API 'Standards' -tenant $tenant -message "Could not set outbound spam contact to $($Contacts). $($_.exception.message)" -sev Error
}
}
if ($Settings.alert) {
diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1
index 2ce2937ab1739..5246d658f5de8 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRotateDKIM.ps1
@@ -4,24 +4,29 @@ function Invoke-CIPPStandardRotateDKIM {
Internal
#>
param($Tenant, $Settings)
- $DKIM = (New-ExoRequest -tenantid $tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object { $_.Selector1KeySize -EQ 1024 -and $_.Enabled -eq $true }
+ $DKIM = (New-ExoRequest -tenantid $tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object { $_.Selector1KeySize -Eq 1024 -and $_.Enabled -eq $true }
+
If ($Settings.remediate) {
- try {
- $DKIM | ForEach-Object {
- (New-ExoRequest -tenantid $tenant -cmdlet 'Rotate-DkimSigningConfig' -cmdparams @{ KeySize = 2048; Identity = $_.Identity } -useSystemMailbox $true)
+
+ $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
}
- Write-LogMessage -API 'Standards' -tenant $tenant -message 'Rotated DKIM' -sev Info
-
- } catch {
- Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to rotate DKIM Error: $($_.exception.message)" -sev Error
}
+ Write-LogMessage -API 'Standards' -tenant $tenant -message 'Rotated DKIM' -sev Info
}
- if ($Settings.alert) {
- $DKIM | ForEach-Object {
- Write-LogMessage -API 'Standards' -tenant $tenant -message "DKIM is not rotated for $($_.Identity)" -sev Alert
+ if ($Settings.alert) {
+ if ($null -eq $DKIM) {
+ Write-LogMessage -API 'Standards' -tenant $tenant -message 'DKIM is rotated for all domains' -sev Info
+ } else {
+ Write-LogMessage -API 'Standards' -tenant $tenant -message "DKIM is not rotated for $($DKIM.Identity -join ';')" -sev Alert
}
}
+
if ($Settings.report) {
Add-CIPPBPAField -FieldName 'DKIM' -FieldValue $DKIM -StoreAs json -Tenant $tenant
}
diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1
index e7e177a3cdcec..0003bddc0be44 100644
--- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1
+++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardsharingCapability.ps1
@@ -9,17 +9,17 @@ function Invoke-CIPPStandardsharingCapability {
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
+ 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
+ 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) {
- Write-LogMessage -API 'Standards' -tenant $tenant -message "Sharing level is set to $($Settings.level)" -sev Info
+ 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
+ Write-LogMessage -API 'Standards' -tenant $tenant -message "Sharing level is not set to $($Settings.Level)" -sev Alert
}
}
if ($Settings.report) {
diff --git a/Modules/DNSHealth/1.0.6/DNSHealth.psd1 b/Modules/DNSHealth/1.0.6/DNSHealth.psd1
deleted file mode 100644
index 257d08264fb19..0000000000000
--- a/Modules/DNSHealth/1.0.6/DNSHealth.psd1
+++ /dev/null
@@ -1,137 +0,0 @@
-#
-# Module manifest for module 'DNSHealth'
-#
-# Generated by: John Duprey
-#
-# Generated on: 06/15/2023
-#
-
-@{
-
-# Script module or binary module file associated with this manifest.
-RootModule = 'DNSHealth.psm1'
-
-# Version number of this module.
-ModuleVersion = '1.0.6'
-
-# Supported PSEditions
-# CompatiblePSEditions = @()
-
-# ID used to uniquely identify this module
-GUID = 'a300d2b0-d468-46d1-88a3-e442a76b655b'
-
-# Author of this module
-Author = 'John Duprey'
-
-# Company or vendor of this module
-CompanyName = 'Unknown'
-
-# Copyright statement for this module
-Copyright = '2023 John Duprey'
-
-# Description of the functionality provided by this module
-Description = 'CIPP DNS Health Check Module'
-
-# Minimum version of the PowerShell engine required by this module
-PowerShellVersion = '7.0'
-
-# Name of the PowerShell host required by this module
-# PowerShellHostName = ''
-
-# Minimum version of the PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
-# DotNetFrameworkVersion = ''
-
-# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
-# ClrVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-# ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-# RequiredModules = @()
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-ScriptsToProcess = @()
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
-# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
-
-# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-# NestedModules = @()
-
-# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
-FunctionsToExport = 'Read-DmarcPolicy', 'Read-MtaStsPolicy', 'Read-DkimRecord',
- 'Read-MtaStsRecord', 'Read-MXRecord', 'Read-NSRecord', 'Read-SPFRecord',
- 'Read-TlsRptRecord', 'Read-WhoisRecord', 'Resolve-DnsHttpsQuery',
- 'Set-DnsResolver', 'Test-DNSSEC', 'Test-HttpsCertificate',
- 'Test-MtaSts'
-
-# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
-CmdletsToExport = '*'
-
-# Variables to export from this module
-VariablesToExport = '*'
-
-# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
-AliasesToExport = '*'
-
-# DSC resources to export from this module
-# DscResourcesToExport = @()
-
-# List of all modules packaged with this module
-# ModuleList = @()
-
-# List of all files packaged with this module
-# FileList = @()
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
-PrivateData = @{
-
- PSData = @{
-
- # Tags applied to this module. These help with module discovery in online galleries.
- # Tags = @()
-
- # A URL to the license for this module.
- # LicenseUri = ''
-
- # A URL to the main website for this project.
- ProjectUri = 'https://github.com/johnduprey/DNSHealth'
-
- # A URL to an icon representing this module.
- # IconUri = ''
-
- # ReleaseNotes of this module
- # ReleaseNotes = ''
-
- # Prerelease string of this module
- # Prerelease = ''
-
- # Flag to indicate whether the module requires explicit user acceptance for install/update/save
- # RequireLicenseAcceptance = $false
-
- # External dependent modules of this module
- # ExternalModuleDependencies = @()
-
- } # End of PSData hashtable
-
-
-} # End of PrivateData hashtable
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
-
-}
-
diff --git a/Modules/DNSHealth/1.0.7/DNSHealth.psd1 b/Modules/DNSHealth/1.0.7/DNSHealth.psd1
new file mode 100644
index 0000000000000..56383a3e37f30
--- /dev/null
+++ b/Modules/DNSHealth/1.0.7/DNSHealth.psd1
@@ -0,0 +1,131 @@
+#
+# Module manifest for module 'DNSHealth'
+#
+# Generated by: John Duprey
+#
+# Generated on: 2023-02-03
+#
+
+@{
+
+ # Script module or binary module file associated with this manifest.
+ RootModule = 'DNSHealth.psm1'
+
+ # Version number of this module.
+ ModuleVersion = '1.0.7'
+
+ # Supported PSEditions
+ # CompatiblePSEditions = @()
+
+ # ID used to uniquely identify this module
+ GUID = 'a300d2b0-d468-46d1-88a3-e442a76b655b'
+
+ # Author of this module
+ Author = 'John Duprey'
+
+ # Company or vendor of this module
+ CompanyName = ''
+
+ # Copyright statement for this module
+ Copyright = '2023 John Duprey'
+
+ # Description of the functionality provided by this module
+ Description = 'CIPP DNS Health Check Module'
+
+ # Minimum version of the PowerShell engine required by this module
+ PowerShellVersion = '7.0'
+
+ # Name of the PowerShell host required by this module
+ # PowerShellHostName = ''
+
+ # Minimum version of the PowerShell host required by this module
+ # PowerShellHostVersion = ''
+
+ # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
+ # DotNetFrameworkVersion = ''
+
+ # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
+ # ClrVersion = ''
+
+ # Processor architecture (None, X86, Amd64) required by this module
+ # ProcessorArchitecture = ''
+
+ # Modules that must be imported into the global environment prior to importing this module
+ #RequiredModules = @('')
+
+ # Assemblies that must be loaded prior to importing this module
+ # RequiredAssemblies = @()
+
+ # Script files (.ps1) that are run in the caller's environment prior to importing this module.
+ ScriptsToProcess = @()
+
+ # Type files (.ps1xml) to be loaded when importing this module
+ # TypesToProcess = @()
+
+ # Format files (.ps1xml) to be loaded when importing this module
+ # FormatsToProcess = @()
+
+ # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
+ # NestedModules = @()
+
+ # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
+ FunctionsToExport = @('Read-DmarcPolicy','Read-MtaStsPolicy','Read-DkimRecord','Read-MtaStsRecord','Read-MXRecord','Read-NSRecord','Read-SPFRecord','Read-TlsRptRecord','Read-WhoisRecord','Resolve-DnsHttpsQuery','Set-DnsResolver','Test-DNSSEC','Test-HttpsCertificate','Test-MtaSts')
+
+ # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
+ #CmdletsToExport = '*'
+
+ # Variables to export from this module
+ #VariablesToExport = '*'
+
+ # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
+ #AliasesToExport = '*'
+
+ # DSC resources to export from this module
+ # DscResourcesToExport = @()
+
+ # List of all modules packaged with this module
+ # ModuleList = @()
+
+ # List of all files packaged with this module
+ # FileList = @()
+
+ # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
+ PrivateData = @{
+
+ PSData = @{
+
+ # Tags applied to this module. These help with module discovery in online galleries.
+ # Tags = @()
+
+ # A URL to the license for this module.
+ # LicenseUri = ''
+
+ # A URL to the main website for this project.
+ ProjectUri = 'https://github.com/johnduprey/DNSHealth'
+
+ # A URL to an icon representing this module.
+ # IconUri = ''
+
+ # ReleaseNotes of this module
+ # ReleaseNotes = ''
+
+ # Prerelease string of this module
+ # Prerelease = ''
+
+ # Flag to indicate whether the module requires explicit user acceptance for install/update/save
+ # RequireLicenseAcceptance = $false
+
+ # External dependent modules of this module
+ #ExternalModuleDependencies = @()
+
+ } # End of PSData hashtable
+
+ } # End of PrivateData hashtable
+
+ # HelpInfo URI of this module
+ # HelpInfoURI = ''
+
+ # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
+ #DefaultCommandPrefix = ''
+
+}
diff --git a/Modules/DNSHealth/1.0.6/DNSHealth.psm1 b/Modules/DNSHealth/1.0.7/DNSHealth.psm1
similarity index 98%
rename from Modules/DNSHealth/1.0.6/DNSHealth.psm1
rename to Modules/DNSHealth/1.0.7/DNSHealth.psm1
index 253a66b1d0be5..b69e40274c166 100644
--- a/Modules/DNSHealth/1.0.6/DNSHealth.psm1
+++ b/Modules/DNSHealth/1.0.7/DNSHealth.psm1
@@ -1,4 +1,5 @@
-#Region './Private/Get-DomainMacros.ps1' 0
+#Region './Private/Get-DomainMacros.ps1' -1
+
function Get-DomainMacros {
[CmdletBinding()]
Param(
@@ -25,7 +26,8 @@ function Get-DomainMacros {
$MacroExpand
}
#EndRegion './Private/Get-DomainMacros.ps1' 26
-#Region './Private/Get-RsaPublicKeyInfo.ps1' 0
+#Region './Private/Get-RsaPublicKeyInfo.ps1' -1
+
function Get-RsaPublicKeyInfo {
<#
.SYNOPSIS
@@ -192,7 +194,8 @@ namespace SevenTiny.Bantina.Security {
[SevenTiny.Bantina.Security.RSACommon]::CreateRsaProviderFromPublicKey($EncodedString)
}
#EndRegion './Private/Get-RsaPublicKeyInfo.ps1' 166
-#Region './Private/Get-ServerCertificateValidation.ps1' 0
+#Region './Private/Get-ServerCertificateValidation.ps1' -1
+
function Get-ServerCertificateValidation {
<#
.SYNOPSIS
@@ -274,7 +277,8 @@ namespace CyberDrain.CIPP {
[CyberDrain.CIPP.CertificateCheck]::GetServerCertificate($Url, $FollowRedirect)
}
#EndRegion './Private/Get-ServerCertificateValidation.ps1' 81
-#Region './Public/Policies/Read-DmarcPolicy.ps1' 0
+#Region './Public/Policies/Read-DmarcPolicy.ps1' -1
+
function Read-DmarcPolicy {
<#
.SYNOPSIS
@@ -549,7 +553,8 @@ function Read-DmarcPolicy {
$DmarcAnalysis
}
#EndRegion './Public/Policies/Read-DmarcPolicy.ps1' 274
-#Region './Public/Policies/Read-MtaStsPolicy.ps1' 0
+#Region './Public/Policies/Read-MtaStsPolicy.ps1' -1
+
function Read-MtaStsPolicy {
<#
.SYNOPSIS
@@ -676,7 +681,8 @@ function Read-MtaStsPolicy {
$StsPolicyAnalysis
}
#EndRegion './Public/Policies/Read-MtaStsPolicy.ps1' 126
-#Region './Public/Records/Read-DkimRecord.ps1' 0
+#Region './Public/Records/Read-DkimRecord.ps1' -1
+
function Read-DkimRecord {
<#
.SYNOPSIS
@@ -704,7 +710,10 @@ function Read-DkimRecord {
[string]$Domain,
[Parameter()]
- [System.Collections.Generic.List[string]]$Selectors = @()
+ [System.Collections.Generic.List[string]]$Selectors = @(),
+
+ [Parameter()]
+ [switch]$FallbackToMicrosoftSelectors
)
$MXRecord = $null
@@ -728,21 +737,28 @@ function Read-DkimRecord {
# MX lookup, check for defined selectors
try {
$MXRecord = Read-MXRecord -Domain $Domain
- foreach ($Selector in $MXRecord.Selectors) {
- try {
- $Selectors.Add($Selector) | Out-Null
+ if ($MXRecord.Selectors) {
+ foreach ($Selector in $MXRecord.Selectors) {
+ try {
+ $Selectors.Add($Selector) | Out-Null
+ } catch { Write-Verbose $_.Exception.Message }
}
-
- catch { Write-Verbose $_.Exception.Message }
}
- $DkimAnalysis.MailProvider = $MXRecord.MailProvider
- if ($MXRecord.MailProvider.PSObject.Properties.Name -contains 'MinimumSelectorPass') {
- $MinimumSelectorPass = $MXRecord.MailProvider.MinimumSelectorPass
+ if ($MXRecord.MailProvider) {
+ $DkimAnalysis.MailProvider = $MXRecord.MailProvider
+ if ($MXRecord.MailProvider.PSObject.Properties.Name -contains 'MinimumSelectorPass') {
+ $MinimumSelectorPass = $MXRecord.MailProvider.MinimumSelectorPass
+ }
+ $DkimAnalysis.Selectors = $Selectors
}
- $DkimAnalysis.Selectors = $Selectors
- }
+ } catch { Write-Verbose $_.Exception.Message }
- catch { Write-Verbose $_.Exception.Message }
+ # Fallback to Microsoft DKIM selectors
+ if ($FallbackToMicrosoftSelectors.IsPresent -and ($Selectors | Measure-Object | Select-Object -ExpandProperty Count) -eq 0) {
+ $MinimumSelectorPass = 1
+ $Selectors.Add('selector1')
+ $Selectors.Add('selector2')
+ }
# Get unique selectors
$Selectors = $Selectors | Sort-Object -Unique
@@ -936,8 +952,9 @@ function Read-DkimRecord {
# Return analysis
$DkimAnalysis
}
-#EndRegion './Public/Records/Read-DkimRecord.ps1' 260
-#Region './Public/Records/Read-MtaStsRecord.ps1' 0
+#EndRegion './Public/Records/Read-DkimRecord.ps1' 270
+#Region './Public/Records/Read-MtaStsRecord.ps1' -1
+
function Read-MtaStsRecord {
<#
.SYNOPSIS
@@ -1074,7 +1091,8 @@ function Read-MtaStsRecord {
$StsAnalysis
}
#EndRegion './Public/Records/Read-MtaStsRecord.ps1' 136
-#Region './Public/Records/Read-MXRecord.ps1' 0
+#Region './Public/Records/Read-MXRecord.ps1' -1
+
function Read-MXRecord {
<#
.SYNOPSIS
@@ -1228,7 +1246,8 @@ function Read-MXRecord {
$MXResults
}
#EndRegion './Public/Records/Read-MXRecord.ps1' 153
-#Region './Public/Records/Read-NSRecord.ps1' 0
+#Region './Public/Records/Read-NSRecord.ps1' -1
+
function Read-NSRecord {
<#
.SYNOPSIS
@@ -1292,7 +1311,8 @@ function Read-NSRecord {
$NSResults
}
#EndRegion './Public/Records/Read-NSRecord.ps1' 63
-#Region './Public/Records/Read-SPFRecord.ps1' 0
+#Region './Public/Records/Read-SPFRecord.ps1' -1
+
function Read-SpfRecord {
<#
.SYNOPSIS
@@ -1846,7 +1866,8 @@ function Read-SpfRecord {
$SpfResults
}
#EndRegion './Public/Records/Read-SPFRecord.ps1' 553
-#Region './Public/Records/Read-TlsRptRecord.ps1' 0
+#Region './Public/Records/Read-TlsRptRecord.ps1' -1
+
function Read-TlsRptRecord {
<#
.SYNOPSIS
@@ -1998,7 +2019,8 @@ function Read-TlsRptRecord {
$TlsRptAnalysis
}
#EndRegion './Public/Records/Read-TlsRptRecord.ps1' 151
-#Region './Public/Records/Read-WhoisRecord.ps1' 0
+#Region './Public/Records/Read-WhoisRecord.ps1' -1
+
function Read-WhoisRecord {
<#
.SYNOPSIS
@@ -2174,7 +2196,8 @@ function Read-WhoisRecord {
$WhoisResults
}
#EndRegion './Public/Records/Read-WhoisRecord.ps1' 175
-#Region './Public/Resolver/Resolve-DnsHttpsQuery.ps1' 0
+#Region './Public/Resolver/Resolve-DnsHttpsQuery.ps1' -1
+
function Resolve-DnsHttpsQuery {
<#
.SYNOPSIS
@@ -2253,7 +2276,8 @@ function Resolve-DnsHttpsQuery {
return $Results
}
#EndRegion './Public/Resolver/Resolve-DnsHttpsQuery.ps1' 78
-#Region './Public/Resolver/Set-DnsResolver.ps1' 0
+#Region './Public/Resolver/Set-DnsResolver.ps1' -1
+
function Set-DnsResolver {
[CmdletBinding(SupportsShouldProcess)]
Param(
@@ -2289,7 +2313,8 @@ function Set-DnsResolver {
}
}
#EndRegion './Public/Resolver/Set-DnsResolver.ps1' 35
-#Region './Public/Tests/Test-DNSSEC.ps1' 0
+#Region './Public/Tests/Test-DNSSEC.ps1' -1
+
function Test-DNSSEC {
<#
.SYNOPSIS
@@ -2368,7 +2393,8 @@ function Test-DNSSEC {
$DSResults
}
#EndRegion './Public/Tests/Test-DNSSEC.ps1' 78
-#Region './Public/Tests/Test-HttpsCertificate.ps1' 0
+#Region './Public/Tests/Test-HttpsCertificate.ps1' -1
+
function Test-HttpsCertificate {
<#
.SYNOPSIS
@@ -2529,7 +2555,8 @@ function Test-HttpsCertificate {
$CertificateTests
}
#EndRegion './Public/Tests/Test-HttpsCertificate.ps1' 160
-#Region './Public/Tests/Test-MtaSts.ps1' 0
+#Region './Public/Tests/Test-MtaSts.ps1' -1
+
function Test-MtaSts {
<#
.SYNOPSIS
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/AppRiver.json b/Modules/DNSHealth/1.0.7/MailProviders/AppRiver.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/AppRiver.json
rename to Modules/DNSHealth/1.0.7/MailProviders/AppRiver.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/BarracudaESS.json b/Modules/DNSHealth/1.0.7/MailProviders/BarracudaESS.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/BarracudaESS.json
rename to Modules/DNSHealth/1.0.7/MailProviders/BarracudaESS.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Google.json b/Modules/DNSHealth/1.0.7/MailProviders/Google.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Google.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Google.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Intermedia.json b/Modules/DNSHealth/1.0.7/MailProviders/Intermedia.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Intermedia.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Intermedia.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Microsoft365.json b/Modules/DNSHealth/1.0.7/MailProviders/Microsoft365.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Microsoft365.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Microsoft365.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Mimecast.json b/Modules/DNSHealth/1.0.7/MailProviders/Mimecast.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Mimecast.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Mimecast.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Null.json b/Modules/DNSHealth/1.0.7/MailProviders/Null.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Null.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Null.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Proofpoint.json b/Modules/DNSHealth/1.0.7/MailProviders/Proofpoint.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Proofpoint.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Proofpoint.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Reflexion.json b/Modules/DNSHealth/1.0.7/MailProviders/Reflexion.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Reflexion.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Reflexion.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/Sophos.json b/Modules/DNSHealth/1.0.7/MailProviders/Sophos.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/Sophos.json
rename to Modules/DNSHealth/1.0.7/MailProviders/Sophos.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/SpamTitan.json b/Modules/DNSHealth/1.0.7/MailProviders/SpamTitan.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/SpamTitan.json
rename to Modules/DNSHealth/1.0.7/MailProviders/SpamTitan.json
diff --git a/Modules/DNSHealth/1.0.6/MailProviders/_template.json b/Modules/DNSHealth/1.0.7/MailProviders/_template.json
similarity index 100%
rename from Modules/DNSHealth/1.0.6/MailProviders/_template.json
rename to Modules/DNSHealth/1.0.7/MailProviders/_template.json
diff --git a/Modules/DNSHealth/1.0.6/PSGetModuleInfo.xml b/Modules/DNSHealth/1.0.7/PSGetModuleInfo.xml
similarity index 82%
rename from Modules/DNSHealth/1.0.6/PSGetModuleInfo.xml
rename to Modules/DNSHealth/1.0.7/PSGetModuleInfo.xml
index 3ef782dbd75c7..baad9e9643b84 100644
--- a/Modules/DNSHealth/1.0.6/PSGetModuleInfo.xml
+++ b/Modules/DNSHealth/1.0.7/PSGetModuleInfo.xml
@@ -7,13 +7,13 @@
DNSHealth
- 1.0.6
+ 1.0.7
Module
CIPP DNS Health Check Module
John Duprey
johnduprey
2023 John Duprey
- 2023-06-15T12:02:08-04:00
+ 2024-02-02T21:41:51-05:00
@@ -36,7 +36,7 @@
- Function
+ Command
@@ -58,8 +58,15 @@
- Command
+ Cmdlet
+
+
+
+
+
+ Function
+
Read-DmarcPolicy
@@ -80,23 +87,16 @@
- Workflow
-
-
-
-
-
-
- RoleCapability
-
+ DscResource
+
- Cmdlet
-
+ Workflow
+
- DscResource
-
+ RoleCapability
+
@@ -121,25 +121,24 @@
True
True
0
- 39
- 27746
- 6/15/2023 12:02:08 PM -04:00
- 6/15/2023 12:02:08 PM -04:00
- 6/15/2023 12:02:08 PM -04:00
+ 78
+ 27851
+ 2/2/2024 9:41:51 PM -05:00
+ 2/2/2024 9:41:51 PM -05:00
+ 2/2/2024 9:41:51 PM -05:00
PSModule PSFunction_Read-DmarcPolicy PSCommand_Read-DmarcPolicy PSFunction_Read-MtaStsPolicy PSCommand_Read-MtaStsPolicy PSFunction_Read-DkimRecord PSCommand_Read-DkimRecord PSFunction_Read-MtaStsRecord PSCommand_Read-MtaStsRecord PSFunction_Read-MXRecord PSCommand_Read-MXRecord PSFunction_Read-NSRecord PSCommand_Read-NSRecord PSFunction_Read-SPFRecord PSCommand_Read-SPFRecord PSFunction_Read-TlsRptRecord PSCommand_Read-TlsRptRecord PSFunction_Read-WhoisRecord PSCommand_Read-WhoisRecord PSFunction_Resolve-DnsHttpsQuery PSCommand_Resolve-DnsHttpsQuery PSFunction_Set-DnsResolver PSCommand_Set-DnsResolver PSFunction_Test-DNSSEC PSCommand_Test-DNSSEC PSFunction_Test-HttpsCertificate PSCommand_Test-HttpsCertificate PSFunction_Test-MtaSts PSCommand_Test-MtaSts PSIncludes_Function
False
- 2023-06-15T12:02:08Z
- 1.0.6
+ 2024-02-02T21:41:51Z
+ 1.0.7
John Duprey
false
Module
- DNSHealth.nuspec|MailProviders\SpamTitan.json|DNSHealth.psd1|MailProviders\Null.json|DNSHealth.psm1|MailProviders\BarracudaESS.json|MailProviders\Microsoft365.json|MailProviders\AppRiver.json|MailProviders\Google.json|MailProviders\Sophos.json|MailProviders\_template.json|MailProviders\Reflexion.json|MailProviders\Intermedia.json|MailProviders\Proofpoint.json|MailProviders\Mimecast.json
+ DNSHealth.nuspec|MailProviders\BarracudaESS.json|MailProviders\Reflexion.json|MailProviders\Null.json|MailProviders\SpamTitan.json|DNSHealth.psd1|MailProviders\Microsoft365.json|MailProviders\Sophos.json|MailProviders\Proofpoint.json|DNSHealth.psm1|MailProviders\_template.json|MailProviders\Google.json|MailProviders\Intermedia.json|MailProviders\AppRiver.json|MailProviders\Mimecast.json
a300d2b0-d468-46d1-88a3-e442a76b655b
7.0
- Unknown
- C:\Users\JDDoS\Documents\GitHub\CIPP-API\Modules\DNSHealth\1.0.6
+ C:\GitHub\CIPP Workspace\CIPP-API\Modules\DNSHealth\1.0.7
diff --git a/Scheduler_Alert/function.json b/Scheduler_Alert/function.json
deleted file mode 100644
index b8758df62b9d5..0000000000000
--- a/Scheduler_Alert/function.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "bindings": [
- {
- "name": "tenant",
- "direction": "in",
- "type": "activityTrigger"
- },
- {
- "type": "queue",
- "direction": "out",
- "name": "QueueItem",
- "queueName": "CIPPGenericQueue"
- }
- ]
-}
diff --git a/Scheduler_Alert/run.ps1 b/Scheduler_Alert/run.ps1
deleted file mode 100644
index 1a7cca3527e33..0000000000000
--- a/Scheduler_Alert/run.ps1
+++ /dev/null
@@ -1,46 +0,0 @@
-param($tenant)
-
-try {
-
- $Table = Get-CIPPTable -Table SchedulerConfig
- if ($Tenant.tag -eq 'AllTenants') {
- $Filter = "RowKey eq 'AllTenants' and PartitionKey eq 'Alert'"
- } else {
- $Filter = "RowKey eq '{0}' and PartitionKey eq 'Alert'" -f $Tenant.tenantid
- }
- $Alerts = Get-CIPPAzDataTableEntity @Table -Filter $Filter
-
-
- $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)"
- }
- Push-OutputBinding -Name QueueItem -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
- }
-
- [PSCustomObject]@{
- ReturnedValues = $true
- }
-} catch {
- $Message = 'Exception on line {0} - {1}' -f $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message
- Write-LogMessage -message $Message -API 'Alerts' -tenant $tenant.tenant -sev Error
- [PSCustomObject]@{
- ReturnedValues = $false
- }
-}
diff --git a/Scheduler_CIPPNotifications/function.json b/Scheduler_CIPPNotifications/function.json
deleted file mode 100644
index 2d4ea9094b246..0000000000000
--- a/Scheduler_CIPPNotifications/function.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "bindings": [
- {
- "name": "tenant",
- "direction": "in",
- "type": "activityTrigger"
- }
- ]
-}
\ No newline at end of file
diff --git a/Scheduler_CIPPNotifications/run.ps1 b/Scheduler_CIPPNotifications/run.ps1
deleted file mode 100644
index 512f015f0fc98..0000000000000
--- a/Scheduler_CIPPNotifications/run.ps1
+++ /dev/null
@@ -1,164 +0,0 @@
-param($tenant)
-
-
-$Table = Get-CIPPTable -TableName SchedulerConfig
-$Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'"
-$Config = [pscustomobject](Get-CIPPAzDataTableEntity @Table -Filter $Filter)
-
-$Settings = [System.Collections.ArrayList]@('Alerts')
-$Config.psobject.properties.name | ForEach-Object { $settings.add($_) }
-$severity = $Config.Severity -split ','
-Write-Host "Our Severity table is: $severity"
-if (!$severity) {
- $severity = [System.Collections.ArrayList]@('Info', 'Error', 'Warning', 'Critical', 'Alert')
-}
-Write-Host "Our Severity table is: $severity"
-$Table = Get-CIPPTable
-$PartitionKey = Get-Date -UFormat '%Y%m%d'
-$Filter = "PartitionKey eq '{0}'" -f $PartitionKey
-$Currentlog = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object {
- $_.API -In $Settings -and $_.SentAsAlert -ne $true -and $_.Severity -In $severity
-}
-Write-Host ($Currentlog).count
-#email try
-try {
- if ($config.onePerTenant) {
- if ($Config.email -like '*@*' -and $null -ne $CurrentLog) {
- $JSONRecipients = $Config.email.split(',').trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } }
- $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1)
- foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) {
- $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) -replace '', '' | Out-String
- $JSONBody = @"
- {
- "message": {
- "subject": "$($Tenant): CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))",
- "body": {
- "contentType": "HTML",
- "content": "You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log:
-
-
- $($HTMLLog)
-
- "
- },
- "toRecipients": [
- $($JSONRecipients)
- ]
- },
- "saveToSentItems": "false"
- }
-"@
- New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -type POST -body ($JSONBody)
- Write-LogMessage -API 'Alerts' -message "Sent alerts to: $($JSONRecipients)" -tenant $Tenant -sev Debug
- }
- }
- } else {
- if ($Config.email -like '*@*' -and $null -ne $CurrentLog) {
- $JSONRecipients = $Config.email.split(',').trim() | ForEach-Object { if ($_ -like '*@*') { '{ "EmailAddress": { "Address": "' + $_ + '" } }, ' } }
- $JSONRecipients = ([string]$JSONRecipients).Substring(0, ([string]$JSONRecipients).Length - 1)
- $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | ConvertTo-Html -frag) -replace '', '' | Out-String
- $JSONBody = @"
- {
- "message": {
- "subject": "CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))",
- "body": {
- "contentType": "HTML",
- "content": "You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log:
-
-
- $($HTMLLog)
-
- "
- },
- "toRecipients": [
- $($JSONRecipients)
- ]
- },
- "saveToSentItems": "false"
- }
-"@
- New-GraphPostRequest -uri 'https://graph.microsoft.com/v1.0/me/sendMail' -tenantid $env:TenantID -type POST -body ($JSONBody)
- Write-LogMessage -API 'Alerts' -message "Sent alerts to: $($Config.email)" -tenant 'All Tenants' -sev Debug
- }
- }
-} catch {
- Write-Host "Could not send alerts to email: $($_.Exception.message)"
- Write-LogMessage -API 'Alerts' -message "Could not send alerts to: $($_.Exception.message)" -tenant 'All Tenants' -sev error
-}
-
-
-try {
- Write-Host $($config | ConvertTo-Json)
- Write-Host $config.webhook
- if ($Config.webhook -ne '' -and $null -ne $CurrentLog) {
- switch -wildcard ($config.webhook) {
-
- '*webhook.office.com*' {
- $Log = $Currentlog | ConvertTo-Html -frag | Out-String
- $JSonBody = "{`"text`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log.
$Log`"}"
- Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
- }
-
- '*slack.com*' {
- $Log = $Currentlog | ForEach-Object {
- $JSonBody = @"
- {"blocks":[{"type":"header","text":{"type":"plain_text","text":"New Alert from CIPP","emoji":true}},{"type":"section","fields":[{"type":"mrkdwn","text":"*DateTime:*\n$($_.Timestamp)"},{"type":"mrkdwn","text":"*Tenant:*\n$($_.Tenant)"},{"type":"mrkdwn","text":"*API:*\n$($_.API)"},{"type":"mrkdwn","text":"*User:*\n$($_.Username)."}]},{"type":"section","text":{"type":"mrkdwn","text":"*Message:*\n$($_.Message)"}}]}
-"@
- Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
- }
- }
-
- '*discord.com*' {
- $Log = $Currentlog | ConvertTo-Html -frag | Out-String
- $JSonBody = "{`"content`": `"You've setup your alert policies to be alerted whenever specific events happen. We've found some of these events in the log. $Log`"}"
- Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
- }
- default {
- $Log = $Currentlog | ConvertTo-Json -Compress
- $JSonBody = $Log
- Invoke-RestMethod -Uri $config.webhook -Method POST -ContentType 'Application/json' -Body $JSONBody
- }
- }
- Write-LogMessage -API 'Alerts' -tenant $Tenant -message "Sent Webhook to $($config.webhook)" -sev Debug
- }
-
- $UpdateLogs = $CurrentLog | ForEach-Object {
- $_.SentAsAlert = $true
- $_
- }
- if ($UpdateLogs) {
- Add-CIPPAzDataTableEntity @Table -Entity $UpdateLogs -Force
- }
-} catch {
- Write-Host "Could not send alerts to webhook: $($_.Exception.message)"
- Write-LogMessage -API 'Alerts' -message "Could not send alerts to : $($_.Exception.message)" -tenant $Tenant -sev error
-}
-
-if ($config.sendtoIntegration) {
- try {
- foreach ($tenant in ($CurrentLog.Tenant | Sort-Object -Unique)) {
- $HTMLLog = ($CurrentLog | Select-Object Message, API, Tenant, Username, Severity | Where-Object -Property tenant -EQ $tenant | ConvertTo-Html -frag) -replace '', '' | Out-String
- $Alert = @{
- TenantId = $Tenant
- AlertText = " $($htmllog)"
- AlertTitle = "$tenant CIPP Alert: Alerts found starting at $((Get-Date).AddMinutes(-15))"
- }
- New-CippExtAlert -Alert $Alert
- $UpdateLogs = $CurrentLog | ForEach-Object {
- $_.SentAsAlert = $true
- $_
- }
- if ($UpdateLogs) {
- Add-CIPPAzDataTableEntity @Table -Entity $UpdateLogs -Force
- }
- }
- } catch {
- Write-Host "Could not send alerts to ticketing system: $($_.Exception.message)"
- Write-LogMessage -API 'Alerts' -tenant $Tenant -message "Could not send alerts to ticketing system: $($_.Exception.message)" -sev Error
- }
-}
-
-
-[PSCustomObject]@{
- ReturnedValues = $true
-}
diff --git a/Scheduler_Extensions/function.json b/Scheduler_Extensions/function.json
index a0b7faadd73dc..f3e5317f409ac 100644
--- a/Scheduler_Extensions/function.json
+++ b/Scheduler_Extensions/function.json
@@ -2,7 +2,7 @@
"bindings": [
{
"name": "Timer",
- "schedule": "0 */15 * * * *",
+ "schedule": "0 0 */2 * * *",
"direction": "in",
"type": "timerTrigger"
},
diff --git a/Scheduler_Extensions/run.ps1 b/Scheduler_Extensions/run.ps1
index c6ce09744cbdd..66af8649ebf76 100644
--- a/Scheduler_Extensions/run.ps1
+++ b/Scheduler_Extensions/run.ps1
@@ -6,7 +6,7 @@ $Table = Get-CIPPTable -TableName Extensionsconfig
$Configuration = ((Get-AzDataTableEntity @Table).config | ConvertFrom-Json)
-Write-Host "Started Scheduler for Extensions"
+Write-Host 'Started Scheduler for Extensions'
# NinjaOne Extension
if ($Configuration.NinjaOne.Enabled -eq $True) {
@@ -42,7 +42,7 @@ if ($Configuration.NinjaOne.Enabled -eq $True) {
$TenantsToProcess = Get-AzDataTableEntity @CIPPMapping -Filter $Filter | Where-Object { $Null -ne $_.NinjaOne -and $_.NinjaOne -ne '' }
if ($Null -eq $LastRunTime -or $LastRunTime -le (Get-Date).addhours(-25) -or $TimeSetting -eq $CurrentInterval) {
- Write-Host "Executing"
+ Write-Host 'Executing'
foreach ($Tenant in $TenantsToProcess | Sort-Object lastEndTime) {
Push-OutputBinding -Name NinjaProcess -Value @{
'NinjaAction' = 'SyncTenant'
@@ -55,7 +55,7 @@ if ($Configuration.NinjaOne.Enabled -eq $True) {
$AddObject = @{
PartitionKey = 'NinjaConfig'
RowKey = 'NinjaLastRunTime'
- 'SettingValue' = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffK")
+ 'SettingValue' = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffK')
}
Add-AzDataTableEntity @Table -Entity $AddObject -Force
@@ -76,7 +76,7 @@ if ($Configuration.NinjaOne.Enabled -eq $True) {
$_ | Add-Member -NotePropertyName lastStartTime -NotePropertyValue $Null -Force
}
}
- $CatchupTenants = $TenantsToProcess | where-object { (((($_.lastEndTime -eq $Null) -or ($_.lastStartTime -gt $_.lastEndTime)) -and ($_.lastStartTime -lt (Get-Date).AddMinutes(-30)))) -or ($_.lastStartTime -lt $LastRunTime) }
+ $CatchupTenants = $TenantsToProcess | Where-Object { (((($_.lastEndTime -eq $Null) -or ($_.lastStartTime -gt $_.lastEndTime)) -and ($_.lastStartTime -lt (Get-Date).AddMinutes(-30)))) -or ($_.lastStartTime -lt $LastRunTime) }
foreach ($Tenant in $CatchupTenants) {
Push-OutputBinding -Name NinjaProcess -Value @{
'NinjaAction' = 'SyncTenant'
@@ -84,8 +84,8 @@ if ($Configuration.NinjaOne.Enabled -eq $True) {
}
Start-Sleep -Seconds 1
}
- if (($CatchupTenants | Measure-Object).count -gt 0){
- Write-LogMessage -API 'NinjaOneSync' -user 'CIPP' -message "NinjaOne Synchronization Catchup Queued for $(($CatchupTenants | Measure-Object).count) Tenants" -Sev 'Info'
+ if (($CatchupTenants | Measure-Object).count -gt 0) {
+ Write-LogMessage -API 'NinjaOneSync' -user 'CIPP' -message "NinjaOne Synchronization Catchup Queued for $(($CatchupTenants | Measure-Object).count) Tenants" -Sev 'Info'
}
}
diff --git a/Scheduler_GetQueue/function.json b/Scheduler_GetQueue/function.json
index b31f1ad213526..d0f59a682e3cc 100644
--- a/Scheduler_GetQueue/function.json
+++ b/Scheduler_GetQueue/function.json
@@ -1,9 +1,16 @@
{
"bindings": [
{
- "name": "name",
- "type": "activityTrigger",
- "direction": "in"
+ "name": "Timer",
+ "schedule": "0 0 * * * *",
+ "direction": "in",
+ "type": "timerTrigger"
+ },
+ {
+ "type": "queue",
+ "direction": "out",
+ "name": "QueueItem",
+ "queueName": "CIPPGenericQueue"
}
]
-}
\ No newline at end of file
+}
diff --git a/Scheduler_GetQueue/run.ps1 b/Scheduler_GetQueue/run.ps1
index 3d495bd852641..f14ccc274dd49 100644
--- a/Scheduler_GetQueue/run.ps1
+++ b/Scheduler_GetQueue/run.ps1
@@ -1,9 +1,9 @@
-param($name)
+param($Timer)
$Table = Get-CIPPTable -TableName SchedulerConfig
$Tenants = Get-CIPPAzDataTableEntity @Table | Where-Object -Property PartitionKey -NE 'WebhookAlert'
-$object = foreach ($Tenant in $Tenants) {
+$Tasks = foreach ($Tenant in $Tenants) {
if ($Tenant.tenant -ne 'AllTenants') {
[pscustomobject]@{
Tenant = $Tenant.tenant
@@ -23,6 +23,19 @@ $object = foreach ($Tenant in $Tenants) {
}
}
}
-}
+}
-$object
\ No newline at end of file
+foreach ($Task in $Tasks) {
+ $QueueItem = [pscustomobject]@{
+ Tenant = $task.tenant
+ Tenantid = $task.tenantid
+ Tag = $task.tag
+ Type = $task.type
+ FunctionName = "Scheduler$($Task.Type)"
+ }
+ try {
+ Push-OutputBinding -Name QueueItem -Value $QueueItem
+ } catch {
+ Write-Host "Could not launch queue item for $($Task.tenant): $($_.Exception.Message)"
+ }
+}
\ No newline at end of file
diff --git a/Scheduler_Orchestration/function.json b/Scheduler_Orchestration/function.json
deleted file mode 100644
index 7326b39c184da..0000000000000
--- a/Scheduler_Orchestration/function.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "bindings": [
- {
- "name": "Context",
- "type": "orchestrationTrigger",
- "direction": "in"
- }
- ]
-}
\ No newline at end of file
diff --git a/Scheduler_Orchestration/run.ps1 b/Scheduler_Orchestration/run.ps1
deleted file mode 100644
index 0014b630fe380..0000000000000
--- a/Scheduler_Orchestration/run.ps1
+++ /dev/null
@@ -1,32 +0,0 @@
-param($Context)
-
-$DurableRetryOptions = @{
- FirstRetryInterval = (New-TimeSpan -Seconds 5)
- MaxNumberOfAttempts = 3
- BackoffCoefficient = 2
-}
-$RetryOptions = New-DurableRetryOptions @DurableRetryOptions
-
-try {
- $Batch = Invoke-ActivityFunction -FunctionName 'Scheduler_GetQueue' -Input 'LetsGo'
- if (($Batch | Measure-Object).Count -gt 0) {
-
- $ParallelTasks = foreach ($Item in $Batch) {
- try {
- Invoke-DurableActivity -FunctionName "Scheduler_$($item['Type'])" -Input $item -NoWait -RetryOptions $RetryOptions -ErrorAction Stop
- }
- catch {
- Write-Host 'Could not start:'
- Write-Host ($item | ConvertTo-Json)
- }
- }
- $Outputs = Wait-ActivityFunction -Task $ParallelTasks
- if (-not $Outputs['DataReturned']) {
- Write-Host 'Errors detected'
- }
- }
-}
-catch {}
-finally {
- Write-LogMessage -API 'Scheduler' -tenant $tenant -message 'Scheduler Ran.' -sev Debug
-}
\ No newline at end of file
diff --git a/Scheduler_Timer/function.json b/Scheduler_Timer/function.json
deleted file mode 100644
index 56e4cf0cfda12..0000000000000
--- a/Scheduler_Timer/function.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "bindings": [
- {
- "name": "Timer",
- "schedule": "0 0 * * * *",
- "direction": "in",
- "type": "timerTrigger"
- },
- {
- "name": "starter",
- "type": "durableClient",
- "direction": "in"
- }
- ]
-}
diff --git a/Scheduler_Timer/run.ps1 b/Scheduler_Timer/run.ps1
deleted file mode 100644
index f62c2909b58da..0000000000000
--- a/Scheduler_Timer/run.ps1
+++ /dev/null
@@ -1,8 +0,0 @@
-using namespace System.Net
-
-param($Timer)
-
-$InstanceId = Start-NewOrchestration -FunctionName 'Scheduler_Orchestration'
-Write-Host "Started orchestration with ID = '$InstanceId'"
-New-OrchestrationCheckStatusResponse -Request $timer -InstanceId $InstanceId
-
diff --git a/Z_CIPPQueueTrigger/function.json b/Z_CIPPQueueTrigger/function.json
index c048325fc3133..4d818463ea75b 100644
--- a/Z_CIPPQueueTrigger/function.json
+++ b/Z_CIPPQueueTrigger/function.json
@@ -7,6 +7,12 @@
"type": "queueTrigger",
"direction": "in",
"queueName": "CIPPGenericQueue"
+ },
+ {
+ "type": "queue",
+ "direction": "out",
+ "name": "QueueItemOut",
+ "queueName": "CIPPGenericQueue"
}
]
}
diff --git a/host.json b/host.json
index 00c49cbf24903..b1667f1e9bbb4 100644
--- a/host.json
+++ b/host.json
@@ -10,10 +10,7 @@
},
"extensions": {
"queues": {
- "maxDequeueCount": 3
+ "maxDequeueCount": 1
}
- },
- "logging": {
- "fileLoggingMode": "never"
}
}
diff --git a/version_latest.txt b/version_latest.txt
index 25b08bbc78f00..3bff059174b83 100644
--- a/version_latest.txt
+++ b/version_latest.txt
@@ -1 +1 @@
-5.0.5
\ No newline at end of file
+5.1.1
\ No newline at end of file