Skip to content

Commit 63e6f41

Browse files
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into dev
2 parents a65b81a + 2b04950 commit 63e6f41

16 files changed

+498
-71
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
function Get-CIPPAlertEntraConnectSyncStatus {
3+
<#
4+
.FUNCTIONALITY
5+
Entrypoint
6+
#>
7+
[CmdletBinding()]
8+
param(
9+
[Parameter(Mandatory = $false)]
10+
[Alias('input')]
11+
$InputValue,
12+
$TenantFilter
13+
)
14+
try {
15+
# Set Hours with fallback to 72 hours
16+
$Hours = if ($InputValue) { [int]$InputValue } else { 72 }
17+
$ConnectSyncStatus = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/organization?$select=onPremisesLastPasswordSyncDateTime,onPremisesLastSyncDateTime,onPremisesSyncEnabled' -tenantid $TenantFilter
18+
19+
if ($ConnectSyncStatus.onPremisesSyncEnabled -eq $true) {
20+
$LastPasswordSync = $ConnectSyncStatus.onPremisesLastPasswordSyncDateTime
21+
$SyncDateTime = $ConnectSyncStatus.onPremisesLastSyncDateTime
22+
# Get the older of the two sync times
23+
$LastSync = if ($SyncDateTime -lt $LastPasswordSync) { $SyncDateTime } else { $LastPasswordSync }
24+
25+
if ($LastSync -lt (Get-Date).AddHours(-$Hours).ToUniversalTime()) {
26+
$AlertData = "Entra Connect Sync for $($TenantFilter) has not run for over $Hours hours. Last sync was at $($LastSync.ToString('o'))"
27+
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
28+
}
29+
}
30+
} catch {
31+
Write-AlertMessage -tenant $($TenantFilter) -message "Could not get Entra Connect Sync Status for $($TenantFilter): $(Get-NormalizedError -message $_.Exception.message)"
32+
}
33+
}

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserTenant.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Push-DomainAnalyserTenant {
2020
return
2121
} else {
2222
try {
23-
# Remove domains that are not wanted, and used for cloud signature services
23+
# Remove domains that are not wanted, and used for cloud signature services. Same exclusions also found in Invoke-CIPPStandardAddDKIM
2424
$ExclusionDomains = @(
2525
'*.microsoftonline.com'
2626
'*.exclaimer.cloud'

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecEditCalendarPermissions.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ function Invoke-ExecEditCalendarPermissions {
2121
$Permissions = $Request.Query.Permissions ?? $Request.Body.Permissions.value
2222
$FolderName = $Request.Query.FolderName ?? $Request.Body.FolderName
2323
$RemoveAccess = $Request.Query.RemoveAccess ?? $Request.Body.RemoveAccess.value
24+
$CanViewPrivateItems = $Request.Query.CanViewPrivateItems ?? $Request.Body.CanViewPrivateItems
2425

2526
try {
2627
if ($RemoveAccess) {
2728
$Result = Set-CIPPCalendarPermission -Headers $Headers -UserID $UserID -FolderName $FolderName -RemoveAccess $RemoveAccess -TenantFilter $TenantFilter
2829
} else {
29-
$Result = Set-CIPPCalendarPermission -Headers $Headers -UserID $UserID -FolderName $FolderName -TenantFilter $TenantFilter -UserToGetPermissions $UserToGetPermissions -Permissions $Permissions
30+
$Result = Set-CIPPCalendarPermission -Headers $Headers -UserID $UserID -FolderName $FolderName -TenantFilter $TenantFilter -UserToGetPermissions $UserToGetPermissions -Permissions $Permissions -CanViewPrivateItems $CanViewPrivateItems
3031
}
3132
$StatusCode = [HttpStatusCode]::OK
3233
} catch {

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/MEM/Invoke-EditIntuneScript.ps1

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,110 @@ function Invoke-EditIntuneScript {
1414
$Headers = $Request.Headers
1515
Write-LogMessage -Headers $Headers -API $APINAME -message 'Accessed this API' -Sev Debug
1616

17-
$graphUrl = "https://graph.microsoft.com/beta"
18-
switch($Request.Method) {
19-
"GET" {
20-
$parms = @{
21-
uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Query.ScriptId)"
22-
tenantid = $Request.Query.TenantFilter
17+
$graphUrl = 'https://graph.microsoft.com/beta'
18+
19+
# Define the endpoint based on script type
20+
function Get-ScriptEndpoint {
21+
param (
22+
[Parameter(Mandatory = $true)]
23+
[string]$ScriptType
24+
)
25+
26+
switch ($ScriptType) {
27+
'Windows' { return 'deviceManagement/deviceManagementScripts' }
28+
'MacOS' { return 'deviceManagement/deviceShellScripts' }
29+
'Remediation' { return 'deviceManagement/deviceHealthScripts' }
30+
'Linux' { return 'deviceManagement/configurationPolicies' }
31+
default { return 'deviceManagement/deviceManagementScripts' }
32+
}
33+
}
34+
35+
switch ($Request.Method) {
36+
'GET' {
37+
# First get the script type by querying the script ID
38+
$scriptId = $Request.Query.ScriptId
39+
$scriptTypeFound = $false
40+
41+
# Try each endpoint to find the script
42+
foreach ($scriptType in @('Windows', 'MacOS', 'Remediation', 'Linux')) {
43+
$endpoint = Get-ScriptEndpoint -ScriptType $scriptType
44+
$parms = @{
45+
uri = "$graphUrl/$endpoint/$scriptId"
46+
tenantid = $Request.Query.TenantFilter
47+
}
48+
49+
try {
50+
$intuneScript = New-GraphGetRequest @parms -ErrorAction Stop
51+
if ($intuneScript) {
52+
$intuneScript | Add-Member -MemberType NoteProperty -Name scriptType -Value $scriptType -Force
53+
$scriptTypeFound = $true
54+
break
55+
}
56+
} catch {
57+
# Script not found in this endpoint, try next one
58+
continue
59+
}
2360
}
2461

25-
$intuneScript = New-GraphGetRequest @parms
26-
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
27-
StatusCode = [HttpStatusCode]::OK
28-
Body = $intuneScript
29-
})
62+
if ($scriptTypeFound) {
63+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
64+
StatusCode = [HttpStatusCode]::OK
65+
Body = $intuneScript
66+
})
67+
} else {
68+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
69+
StatusCode = [HttpStatusCode]::NotFound
70+
Body = "Script with ID $scriptId was not found in any endpoint."
71+
})
72+
}
3073
}
31-
"PATCH" {
74+
'PATCH' {
75+
# Parse the script data to determine type
76+
$scriptData = $Request.Body.IntuneScript | ConvertFrom-Json
77+
$scriptType = $Request.Body.ScriptType
78+
79+
if (-not $scriptType) {
80+
# Try to determine script type from the request body
81+
if ($scriptData.PSObject.Properties.Name -contains '@odata.type') {
82+
switch ($scriptData.'@odata.type') {
83+
'#microsoft.graph.deviceManagementScript' { $scriptType = 'Windows' }
84+
'#microsoft.graph.deviceShellScript' { $scriptType = 'MacOS' }
85+
'#microsoft.graph.deviceHealthScript' { $scriptType = 'Remediation' }
86+
default {
87+
if ($scriptData.platforms -eq 'linux' -and $scriptData.templateReference.templateFamily -eq 'deviceConfigurationScripts') {
88+
$scriptType = 'Linux'
89+
} else {
90+
$scriptType = 'Windows' # Default to Windows if no definitive type found
91+
}
92+
}
93+
}
94+
}
95+
}
96+
97+
$endpoint = Get-ScriptEndpoint -ScriptType $scriptType
3298
$parms = @{
33-
uri = "$graphUrl/deviceManagement/deviceManagementScripts/$($Request.Body.ScriptId)"
99+
uri = "$graphUrl/$endpoint/$($Request.Body.ScriptId)"
34100
tenantid = $Request.Body.TenantFilter
35-
body = $Request.Body.IntuneScript
101+
body = $Request.Body.IntuneScript
102+
}
103+
104+
try {
105+
$patchResult = New-GraphPOSTRequest @parms -type 'PATCH'
106+
$body = [pscustomobject]@{'Results' = $patchResult }
107+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
108+
StatusCode = [HttpStatusCode]::OK
109+
Body = $body
110+
})
111+
} catch {
112+
$ErrorMessage = Get-CippException -Exception $_
113+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
114+
StatusCode = [HttpStatusCode]::BadRequest
115+
Body = "Failed to update script: $($ErrorMessage.NormalizedError)"
116+
})
36117
}
37-
$patchResult = New-GraphPOSTRequest @parms -type "PATCH"
38-
$body = [pscustomobject]@{'Results' = $patchResult }
39-
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
40-
StatusCode = [HttpStatusCode]::OK
41-
Body = $body
42-
})
43118
}
44-
"POST" {
45-
Write-Output "Adding script"
119+
'POST' {
120+
Write-Output 'Adding script'
46121
}
47122
}
48123
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecCreateTAP.ps1

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,28 @@ Function Invoke-ExecCreateTAP {
1919
$UserID = $Request.Query.ID ?? $Request.Body.ID
2020

2121
try {
22-
$Result = New-CIPPTAP -userid $UserID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers
22+
$TAPResult = New-CIPPTAP -userid $UserID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers
23+
24+
# Create results array with both TAP and UserID as separate items
25+
$Results = @(
26+
$TAPResult,
27+
@{
28+
resultText = "User ID: $UserID"
29+
copyField = $UserID
30+
state = 'success'
31+
}
32+
)
33+
2334
$StatusCode = [HttpStatusCode]::OK
2435
} catch {
25-
$Result = Get-NormalizedError -message $($_.Exception.Message)
36+
$Results = Get-NormalizedError -message $($_.Exception.Message)
2637
$StatusCode = [HttpStatusCode]::InternalServerError
2738
}
2839

2940
# Associate values to output bindings by calling 'Push-OutputBinding'.
3041
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
3142
StatusCode = $StatusCode
32-
Body = @{'Results' = $Result }
43+
Body = @{'Results' = $Results }
3344
})
3445

3546
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Administration/Tenant/Invoke-EditTenant.ps1

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using namespace System.Net
22

3-
Function Invoke-EditTenant {
3+
function Invoke-EditTenant {
44
<#
55
.FUNCTIONALITY
66
Entrypoint,AnyTenant
@@ -11,8 +11,9 @@ Function Invoke-EditTenant {
1111
param($Request, $TriggerMetadata)
1212

1313
$APIName = $Request.Params.CIPPEndpoint
14+
$Headers = $Request.Headers
1415

15-
Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
16+
Write-LogMessage -headers $Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
1617

1718
$customerId = $Request.Body.customerId
1819
$tenantAlias = $Request.Body.tenantAlias
@@ -46,9 +47,9 @@ Function Invoke-EditTenant {
4647
}
4748

4849
# Update tenant groups
49-
$CurrentMembers = Get-CIPPAzDataTableEntity @GroupMembersTable -Filter "customerId eq '$customerId'"
50+
$CurrentGroupMemberships = Get-CIPPAzDataTableEntity @GroupMembersTable -Filter "customerId eq '$customerId'"
5051
foreach ($Group in $tenantGroups) {
51-
$GroupEntity = $CurrentMembers | Where-Object { $_.GroupId -eq $Group.groupId }
52+
$GroupEntity = $CurrentGroupMemberships | Where-Object { $_.GroupId -eq $Group.groupId }
5253
if (!$GroupEntity) {
5354
$GroupEntity = @{
5455
PartitionKey = 'Member'
@@ -61,8 +62,8 @@ Function Invoke-EditTenant {
6162
}
6263

6364
# Remove any groups that are no longer selected
64-
foreach ($Group in $CurrentMembers) {
65-
if ($tenantGroups -notcontains $Group.GroupId) {
65+
foreach ($Group in $CurrentGroupMemberships) {
66+
if ($tenantGroups.GroupId -notcontains $Group.GroupId) {
6667
Remove-AzDataTableEntity @GroupMembersTable -Entity $Group
6768
}
6869
}
@@ -76,7 +77,7 @@ Function Invoke-EditTenant {
7677
Body = $response
7778
})
7879
} catch {
79-
Write-LogMessage -headers $Request.Headers -tenant $customerId -API $APINAME -message "Edit Tenant failed. The error is: $($_.Exception.Message)" -Sev 'Error'
80+
Write-LogMessage -headers $Headers -tenant $customerId -API $APINAME -message "Edit Tenant failed. The error is: $($_.Exception.Message)" -Sev 'Error'
8081
$response = @{
8182
state = 'error'
8283
resultText = $_.Exception.Message

Modules/CIPPCore/Public/New-CIPPTAP.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ function New-CIPPTAP {
1111
$GraphRequest = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/users/$($userid)/authentication/temporaryAccessPassMethods" -tenantid $TenantFilter -type POST -body '{}' -verbose
1212
Write-LogMessage -headers $Headers -API $APIName -message "Created Temporary Access Password (TAP) for $userid" -Sev 'Info' -tenant $TenantFilter
1313
return @{
14-
resultText = "The TAP for this user is $($GraphRequest.temporaryAccessPass) - This TAP is usable for the next $($GraphRequest.LifetimeInMinutes) minutes"
14+
resultText = "The TAP for $userid is $($GraphRequest.temporaryAccessPass) - This TAP is usable for the next $($GraphRequest.LifetimeInMinutes) minutes"
15+
userid = $userid
1516
copyField = $GraphRequest.temporaryAccessPass
1617
temporaryAccessPass = $GraphRequest.temporaryAccessPass
1718
lifetimeInMinutes = $GraphRequest.LifetimeInMinutes

Modules/CIPPCore/Public/Set-CIPPCalendarPermission.ps1

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ function Set-CIPPCalendarPermission {
99
$folderName,
1010
$UserToGetPermissions,
1111
$LoggingName,
12-
$Permissions
12+
$Permissions,
13+
[bool]$CanViewPrivateItems
1314
)
1415

1516
try {
@@ -26,6 +27,10 @@ function Set-CIPPCalendarPermission {
2627
AccessRights = @($Permissions)
2728
User = $UserToGetPermissions
2829
}
30+
31+
if ($CanViewPrivateItems) {
32+
$CalParam | Add-Member -NotePropertyName 'SharingPermissionFlags' -NotePropertyValue 'Delegate,CanViewPrivateItems'
33+
}
2934

3035
if ($RemoveAccess) {
3136
if ($PSCmdlet.ShouldProcess("$UserID\$folderName", "Remove permissions for $LoggingName")) {
@@ -42,6 +47,9 @@ function Set-CIPPCalendarPermission {
4247
}
4348
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantFilter -message "Successfully set Calendar permissions $Permissions for $LoggingName on $UserID." -sev Info
4449
$Result = "Successfully set permissions on folder $($CalParam.Identity). The user $LoggingName now has $Permissions permissions on this folder."
50+
if ($CanViewPrivateItems) {
51+
$Result += " The user can also view private items."
52+
}
4553
}
4654
}
4755
} catch {

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,36 @@ function Invoke-CIPPStandardAddDKIM {
6666
return
6767
}
6868

69+
# Same exclusions also found in Push-DomainAnalyserTenant
70+
$ExclusionDomains = @(
71+
'*.microsoftonline.com'
72+
'*.exclaimer.cloud'
73+
'*.excl.cloud'
74+
'*.codetwo.online'
75+
'*.call2teams.com'
76+
'*.signature365.net'
77+
'*.myteamsconnect.io'
78+
'*.teams.dstny.com'
79+
)
6980

70-
$AllDomains = ($BatchResults | Where-Object { $_.DomainName }).DomainName
71-
$DKIM = $BatchResults | Where-Object { $_.Domain } | Select-Object Domain, Enabled, Status
81+
$AllDomains = ($BatchResults | Where-Object { $_.DomainName }).DomainName | ForEach-Object {
82+
$Domain = $_
83+
foreach ($ExclusionDomain in $ExclusionDomains) {
84+
if ($Domain -like $ExclusionDomain) {
85+
$Domain = $null
86+
}
87+
}
88+
if ($null -ne $Domain) { $Domain }
89+
}
90+
$DKIM = $BatchResults | Where-Object { $_.Domain } | Select-Object Domain, Enabled, Status | ForEach-Object {
91+
$Domain = $_
92+
foreach ($ExclusionDomain in $ExclusionDomains) {
93+
if ($Domain.Domain -like $ExclusionDomain) {
94+
$Domain = $null
95+
}
96+
}
97+
if ($null -ne $Domain) { $Domain }
98+
}
7299

73100
# List of domains for each way to enable DKIM
74101
$NewDomains = $AllDomains | Where-Object { $DKIM.Domain -notcontains $_ }

0 commit comments

Comments
 (0)