Skip to content

Commit 3d2cf1c

Browse files
committed
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into dev
2 parents 1e0a3d6 + c0b83b6 commit 3d2cf1c

File tree

9 files changed

+650
-59
lines changed

9 files changed

+650
-59
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using namespace System.Net
2+
3+
function Invoke-ExecModifyContactPerms {
4+
<#
5+
.FUNCTIONALITY
6+
Entrypoint
7+
.ROLE
8+
Exchange.Mailbox.ReadWrite
9+
#>
10+
[CmdletBinding()]
11+
param($Request, $TriggerMetadata)
12+
13+
$APIName = $Request.Params.CIPPEndpoint
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
16+
17+
$Username = $Request.Body.userID
18+
$TenantFilter = $Request.Body.tenantFilter
19+
$Permissions = $Request.Body.permissions
20+
21+
Write-LogMessage -headers $Headers -API $APIName -message "Processing request for user: $Username, tenant: $TenantFilter" -Sev 'Debug'
22+
23+
if ($null -eq $Username) {
24+
Write-LogMessage -headers $Headers -API $APIName -message 'Username is null' -Sev 'Error'
25+
$body = [pscustomobject]@{'Results' = @('Username is required') }
26+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
27+
StatusCode = [HttpStatusCode]::BadRequest
28+
Body = $Body
29+
})
30+
return
31+
}
32+
33+
try {
34+
$UserId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($Username)" -tenantid $TenantFilter).id
35+
Write-LogMessage -headers $Headers -API $APIName -message "Retrieved user ID: $UserId" -Sev 'Debug'
36+
} catch {
37+
Write-LogMessage -headers $Headers -API $APIName -message "Failed to get user ID: $($_.Exception.Message)" -Sev 'Error'
38+
$body = [pscustomobject]@{'Results' = @("Failed to get user ID: $($_.Exception.Message)") }
39+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
40+
StatusCode = [HttpStatusCode]::NotFound
41+
Body = $Body
42+
})
43+
return
44+
}
45+
46+
$Results = [System.Collections.Generic.List[string]]::new()
47+
$HasErrors = $false
48+
49+
# Convert permissions to array format if it's an object with numeric keys
50+
if ($Permissions -is [PSCustomObject]) {
51+
if ($Permissions.PSObject.Properties.Name -match '^\d+$') {
52+
$Permissions = $Permissions.PSObject.Properties.Value
53+
} else {
54+
$Permissions = @($Permissions)
55+
}
56+
}
57+
58+
Write-LogMessage -headers $Headers -API $APIName -message "Processing $($Permissions.Count) permission entries" -Sev 'Debug'
59+
60+
foreach ($Permission in $Permissions) {
61+
Write-LogMessage -headers $Headers -API $APIName -message "Processing permission: $($Permission | ConvertTo-Json)" -Sev 'Debug'
62+
63+
$PermissionLevel = $Permission.PermissionLevel.value ?? $Permission.PermissionLevel
64+
$Modification = $Permission.Modification
65+
$CanViewPrivateItems = $Permission.CanViewPrivateItems ?? $false
66+
$FolderName = $Permission.FolderName ?? 'Contact'
67+
$SendNotificationToUser = $Permission.SendNotificationToUser ?? $false
68+
69+
Write-LogMessage -headers $Headers -API $APIName -message "Permission Level: $PermissionLevel, Modification: $Modification, CanViewPrivateItems: $CanViewPrivateItems, FolderName: $FolderName" -Sev 'Debug'
70+
71+
# Handle UserID as array or single value
72+
$TargetUsers = @($Permission.UserID | ForEach-Object { $_.value ?? $_ })
73+
74+
Write-LogMessage -headers $Headers -API $APIName -message "Target Users: $($TargetUsers -join ', ')" -Sev 'Debug'
75+
76+
foreach ($TargetUser in $TargetUsers) {
77+
try {
78+
Write-LogMessage -headers $Headers -API $APIName -message "Processing target user: $TargetUser" -Sev 'Debug'
79+
$Params = @{
80+
APIName = $APIName
81+
Headers = $Headers
82+
RemoveAccess = if ($Modification -eq 'Remove') { $TargetUser } else { $null }
83+
TenantFilter = $TenantFilter
84+
UserID = $UserId
85+
folderName = $FolderName
86+
UserToGetPermissions = $TargetUser
87+
LoggingName = $TargetUser
88+
Permissions = $PermissionLevel
89+
SendNotificationToUser = $SendNotificationToUser
90+
}
91+
92+
# Write-Host "Request params: $($Params | ConvertTo-Json)"
93+
$Result = Set-CIPPContactPermission @Params
94+
95+
$null = $Results.Add($Result)
96+
} catch {
97+
$HasErrors = $true
98+
$null = $Results.Add("$($_.Exception.Message)")
99+
}
100+
}
101+
}
102+
103+
if ($Results.Count -eq 0) {
104+
Write-LogMessage -headers $Headers -API $APIName -message 'No results were generated from the operation' -Sev 'Warning'
105+
$null = $Results.Add('No results were generated from the operation. Please check the logs for more details.')
106+
$HasErrors = $true
107+
}
108+
109+
$Body = [pscustomobject]@{'Results' = @($Results) }
110+
111+
# Associate values to output bindings by calling 'Push-OutputBinding'.
112+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
113+
StatusCode = if ($HasErrors) { [HttpStatusCode]::InternalServerError } else { [HttpStatusCode]::OK }
114+
Body = $Body
115+
})
116+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using namespace System.Net
2+
3+
Function Invoke-ListContactPermissions {
4+
<#
5+
.FUNCTIONALITY
6+
Entrypoint
7+
.ROLE
8+
Exchange.Mailbox.Read
9+
#>
10+
[CmdletBinding()]
11+
param($Request, $TriggerMetadata)
12+
13+
$APIName = $Request.Params.CIPPEndpoint
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
16+
17+
$UserID = $Request.Query.UserID
18+
$TenantFilter = $Request.Query.tenantFilter
19+
20+
try {
21+
$GetContactParam = @{Identity = $UserID; FolderScope = 'Contacts' }
22+
$ContactFolder = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderStatistics' -anchor $UserID -cmdParams $GetContactParam | Select-Object -First 1 -ExcludeProperty *data.type*
23+
$ContactParam = @{Identity = "$($UserID):\$($ContactFolder.name)" }
24+
$Mailbox = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-Mailbox' -cmdParams @{Identity = $UserID }
25+
$GraphRequest = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderPermission' -anchor $UserID -cmdParams $ContactParam -UseSystemMailbox $true | Select-Object Identity, User, AccessRights, FolderName, @{ Name = 'MailboxInfo'; Expression = { $Mailbox } }
26+
27+
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Contact permissions listed for $($TenantFilter)" -sev Debug
28+
$StatusCode = [HttpStatusCode]::OK
29+
} catch {
30+
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
31+
$StatusCode = [HttpStatusCode]::Forbidden
32+
$GraphRequest = $ErrorMessage
33+
}
34+
35+
# Associate values to output bindings by calling 'Push-OutputBinding'.
36+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
37+
StatusCode = $StatusCode
38+
Body = @($GraphRequest)
39+
})
40+
41+
}
Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using namespace System.Net
22

3-
Function Invoke-AddAutopilotConfig {
3+
function Invoke-AddAutopilotConfig {
44
<#
55
.FUNCTIONALITY
66
Entrypoint
@@ -14,42 +14,34 @@ Function Invoke-AddAutopilotConfig {
1414
$Headers = $Request.Headers
1515
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
1616

17-
18-
19-
2017
# Input bindings are passed in via param block.
21-
$Tenants = $Request.body.selectedTenants.value
22-
$AssignTo = if ($request.body.Assignto -ne 'on') { $request.body.Assignto }
23-
$Profbod = [pscustomobject]$Request.body
24-
$usertype = if ($Profbod.NotLocalAdmin -eq 'true') { 'standard' } else { 'administrator' }
25-
$DeploymentMode = if ($profbod.DeploymentMode -eq 'true') { 'shared' } else { 'singleUser' }
18+
$Tenants = $Request.Body.selectedTenants.value
19+
$Profbod = [pscustomobject]$Request.Body
20+
$UserType = if ($Profbod.NotLocalAdmin -eq 'true') { 'standard' } else { 'administrator' }
21+
$DeploymentMode = if ($Profbod.DeploymentMode -eq 'true') { 'shared' } else { 'singleUser' }
2622
$profileParams = @{
27-
displayname = $request.body.Displayname
28-
description = $request.body.Description
29-
usertype = $usertype
23+
DisplayName = $Request.Body.DisplayName
24+
Description = $Request.Body.Description
25+
UserType = $UserType
3026
DeploymentMode = $DeploymentMode
31-
assignto = $AssignTo
32-
devicenameTemplate = $Profbod.deviceNameTemplate
33-
allowWhiteGlove = $Profbod.allowWhiteGlove
34-
CollectHash = $Profbod.collectHash
35-
hideChangeAccount = $Profbod.hideChangeAccount
36-
hidePrivacy = $Profbod.hidePrivacy
37-
hideTerms = $Profbod.hideTerms
27+
AssignTo = $Request.Body.Assignto
28+
DeviceNameTemplate = $Profbod.DeviceNameTemplate
29+
AllowWhiteGlove = $Profbod.allowWhiteGlove
30+
CollectHash = $Profbod.CollectHash
31+
HideChangeAccount = $Profbod.HideChangeAccount
32+
HidePrivacy = $Profbod.HidePrivacy
33+
HideTerms = $Profbod.HideTerms
3834
Autokeyboard = $Profbod.Autokeyboard
3935
Language = $ProfBod.languages.value
4036
}
41-
$results = foreach ($Tenant in $tenants) {
42-
$profileParams['tenantFilter'] = $Tenant
37+
$Results = foreach ($tenant in $Tenants) {
38+
$profileParams['tenantFilter'] = $tenant
4339
Set-CIPPDefaultAPDeploymentProfile @profileParams
4440
}
45-
$body = [pscustomobject]@{'Results' = $results }
4641

4742
# Associate values to output bindings by calling 'Push-OutputBinding'.
4843
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
4944
StatusCode = [HttpStatusCode]::OK
50-
Body = $body
45+
Body = @{'Results' = $Results }
5146
})
52-
53-
54-
5547
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using namespace System.Net
2+
3+
function Invoke-RemoveAutopilotConfig {
4+
<#
5+
.FUNCTIONALITY
6+
Entrypoint
7+
.ROLE
8+
Endpoint.Autopilot.ReadWrite
9+
#>
10+
[CmdletBinding()]
11+
param($Request, $TriggerMetadata)
12+
13+
$APIName = $Request.Params.CIPPEndpoint
14+
$Headers = $Request.Headers
15+
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'
16+
17+
# Interact with query parameters or the body of the request.
18+
$TenantFilter = $Request.Body.tenantFilter
19+
$ProfileId = $Request.Body.ID
20+
$DisplayName = $Request.Body.displayName
21+
$Assignments = $Request.Body.assignments
22+
23+
try {
24+
# Validate required parameters
25+
if ([string]::IsNullOrEmpty($ProfileId)) {
26+
throw 'Profile ID is required'
27+
}
28+
29+
if ([string]::IsNullOrEmpty($TenantFilter)) {
30+
throw 'Tenant filter is required'
31+
}
32+
33+
# Call the helper function to delete the autopilot profile
34+
$params = @{
35+
ProfileId = $ProfileId
36+
DisplayName = $DisplayName
37+
TenantFilter = $TenantFilter
38+
Assignments = $Assignments
39+
Headers = $Headers
40+
APIName = $APIName
41+
}
42+
$Result = Remove-CIPPAutopilotProfile @params
43+
$StatusCode = [HttpStatusCode]::OK
44+
45+
} catch {
46+
$ErrorMessage = $_.Exception.Message
47+
$Result = $ErrorMessage
48+
$StatusCode = [HttpStatusCode]::InternalServerError
49+
}
50+
51+
# Associate values to output bindings by calling 'Push-OutputBinding'.
52+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
53+
StatusCode = $StatusCode
54+
Body = @{'Results' = "$Result" }
55+
})
56+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
function Remove-CIPPAutopilotProfile {
2+
param(
3+
$ProfileId,
4+
$DisplayName,
5+
$TenantFilter,
6+
$Assignments,
7+
$Headers,
8+
$APIName = 'Remove Autopilot Profile'
9+
)
10+
11+
12+
try {
13+
14+
try {
15+
$DisplayName = $null -eq $DisplayName ? $ProfileId : $DisplayName
16+
if ($Assignments.Count -gt 0) {
17+
Write-Host "Profile $ProfileId has $($Assignments.Count) assignments, removing them first"
18+
throw
19+
}
20+
21+
$null = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$ProfileId" -tenantid $TenantFilter -type DELETE
22+
$Result = "Successfully deleted Autopilot profile '$($DisplayName)'"
23+
Write-LogMessage -Headers $Headers -API $APIName -tenant $TenantFilter -message $Result -Sev 'Info'
24+
return $Result
25+
} catch {
26+
27+
# Profile could not be deleted, there is probably an assignment still referencing it. The error is bloody useless here, and we just need to try some stuff
28+
if ($null -eq $Assignments) {
29+
$Assignments = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$ProfileId/assignments" -tenantid $TenantFilter
30+
}
31+
32+
# Remove all assignments
33+
if ($Assignments -and $Assignments.Count -gt 0) {
34+
foreach ($Assignment in $Assignments) {
35+
try {
36+
# Use the assignment ID directly as provided by the API
37+
$AssignmentId = $Assignment.id
38+
$null = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$ProfileId/assignments/$AssignmentId" -tenantid $TenantFilter -type DELETE
39+
40+
} catch {
41+
# Handle the case where the assignment might reference a deleted group
42+
try {
43+
if ($Assignment.target -and $Assignment.target.'@odata.type' -eq '#microsoft.graph.groupAssignmentTarget') {
44+
$GroupId = $Assignment.target.groupId
45+
$AlternativeAssignmentId = "${ProfileId}_${GroupId}"
46+
$null = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$ProfileId/assignments/$AlternativeAssignmentId" -tenantid $TenantFilter -type DELETE
47+
}
48+
} catch {
49+
throw "Could not remove assignment $AssignmentId"
50+
}
51+
}
52+
}
53+
}
54+
# Retry deleting the profile after removing assignments
55+
$null = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/$ProfileId" -tenantid $TenantFilter -type DELETE
56+
$Result = "Successfully deleted Autopilot profile '$($DisplayName)' "
57+
Write-LogMessage -Headers $Headers -API $APIName -tenant $TenantFilter -message $Result -Sev 'Info'
58+
return $Result
59+
}
60+
61+
} catch {
62+
$ErrorMessage = Get-CippException -Exception $_
63+
$ErrorText = "Failed to delete Autopilot profile $ProfileId. Error: $($ErrorMessage.NormalizedError)"
64+
Write-LogMessage -Headers $Headers -API $APIName -tenant $TenantFilter -message $ErrorText -Sev 'Error' -LogData $ErrorMessage
65+
throw $ErrorText
66+
}
67+
}

0 commit comments

Comments
 (0)