Skip to content

Commit ae76351

Browse files
authored
Merge pull request #533 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 7f2a751 + 28b03c6 commit ae76351

File tree

11 files changed

+220
-44
lines changed

11 files changed

+220
-44
lines changed

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Applications/Invoke-AddOfficeApp.ps1

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,25 @@ function Invoke-AddOfficeApp {
99
param($Request, $TriggerMetadata)
1010

1111
# Input bindings are passed in via param block.
12-
$Tenants = $Request.body.selectedTenants.defaultDomainName
12+
$Tenants = $Request.Body.selectedTenants.defaultDomainName
13+
$Headers = $Request.Headers
14+
$APIName = $Request.Params.CIPPEndpoint
1315
if ('AllTenants' -in $Tenants) { $Tenants = (Get-Tenants).defaultDomainName }
14-
$AssignTo = if ($request.body.Assignto -ne 'on') { $request.body.Assignto }
16+
$AssignTo = if ($Request.Body.AssignTo -ne 'on') { $Request.Body.AssignTo }
1517

16-
$results = foreach ($Tenant in $tenants) {
18+
$Results = foreach ($Tenant in $Tenants) {
1719
try {
18-
$ExistingO365 = New-graphGetRequest -Uri 'https://graph.microsoft.com/beta/deviceAppManagement/mobileApps' -tenantid $tenant | Where-Object { $_.displayname -eq 'Microsoft 365 Apps for Windows 10 and later' }
20+
$ExistingO365 = New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/deviceAppManagement/mobileApps' -tenantid $Tenant | Where-Object { $_.displayName -eq 'Microsoft 365 Apps for Windows 10 and later' }
1921
if (!$ExistingO365) {
2022
# Check if custom XML is provided
21-
if ($request.body.useCustomXml -and $request.body.customXml) {
23+
if ($Request.Body.useCustomXml -and $Request.Body.customXml) {
2224
# Use custom XML configuration
2325
$ObjBody = [pscustomobject]@{
2426
'@odata.type' = '#microsoft.graph.officeSuiteApp'
2527
'displayName' = 'Microsoft 365 Apps for Windows 10 and later'
2628
'description' = 'Microsoft 365 Apps for Windows 10 and later'
2729
'informationUrl' = 'https://products.office.com/en-us/explore-office-for-home'
30+
'privacyInformationUrl' = 'https://privacy.microsoft.com/en-us/privacystatement'
2831
'isFeatured' = $true
2932
'publisher' = 'Microsoft'
3033
'notes' = ''
@@ -38,7 +41,7 @@ function Invoke-AddOfficeApp {
3841
}
3942
} else {
4043
# Use standard configuration
41-
$Arch = if ($request.body.arch) { 'x64' } else { 'x86' }
44+
$Arch = if ($Request.Body.arch) { 'x64' } else { 'x86' }
4245
$products = @('o365ProPlusRetail')
4346
$ExcludedApps = [pscustomobject]@{
4447
infoPath = $true
@@ -54,26 +57,27 @@ function Invoke-AddOfficeApp {
5457
access = $false
5558
bing = $false
5659
}
57-
foreach ($ExcludedApp in $request.body.excludedApps.value) {
58-
$ExcludedApps.$excludedapp = $true
60+
foreach ($ExcludedApp in $Request.Body.excludedApps.value) {
61+
$ExcludedApps.$ExcludedApp = $true
5962
}
6063
$ObjBody = [pscustomobject]@{
6164
'@odata.type' = '#microsoft.graph.officeSuiteApp'
6265
'displayName' = 'Microsoft 365 Apps for Windows 10 and later'
6366
'description' = 'Microsoft 365 Apps for Windows 10 and later'
6467
'informationUrl' = 'https://products.office.com/en-us/explore-office-for-home'
68+
'privacyInformationUrl' = 'https://privacy.microsoft.com/en-us/privacystatement'
6569
'isFeatured' = $true
6670
'publisher' = 'Microsoft'
6771
'notes' = ''
6872
'owner' = 'Microsoft'
69-
'autoAcceptEula' = [bool]$request.body.AcceptLicense
73+
'autoAcceptEula' = [bool]$Request.Body.AcceptLicense
7074
'excludedApps' = $ExcludedApps
7175
'officePlatformArchitecture' = $Arch
7276
'officeSuiteAppDefaultFileFormat' = 'OfficeOpenXMLFormat'
73-
'localesToInstall' = @($request.body.languages.value)
74-
'shouldUninstallOlderVersionsOfOffice' = [bool]$request.body.RemoveVersions
75-
'updateChannel' = $request.body.updateChannel.value
76-
'useSharedComputerActivation' = [bool]$request.body.SharedComputerActivation
77+
'localesToInstall' = @($Request.Body.languages.value)
78+
'shouldUninstallOlderVersionsOfOffice' = [bool]$Request.Body.RemoveVersions
79+
'updateChannel' = $Request.Body.updateChannel.value
80+
'useSharedComputerActivation' = [bool]$Request.Body.SharedComputerActivation
7781
'productIds' = $products
7882
'largeIcon' = @{
7983
'@odata.type' = 'microsoft.graph.mimeContent'
@@ -88,25 +92,24 @@ function Invoke-AddOfficeApp {
8892
"Office deployment already exists for $($Tenant)"
8993
continue
9094
}
91-
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Added Office profile to $($tenant)" -Sev 'Info'
95+
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Added Office profile to $($Tenant)" -Sev 'Info'
9296
if ($AssignTo) {
9397
$AssignO365 = if ($AssignTo -ne 'AllDevicesAndUsers') { '{"mobileAppAssignments":[{"@odata.type":"#microsoft.graph.mobileAppAssignment","target":{"@odata.type":"#microsoft.graph.' + $($AssignTo) + 'AssignmentTarget"},"intent":"Required"}]}' } else { '{"mobileAppAssignments":[{"@odata.type":"#microsoft.graph.mobileAppAssignment","target":{"@odata.type":"#microsoft.graph.allDevicesAssignmentTarget"},"intent":"Required"},{"@odata.type":"#microsoft.graph.mobileAppAssignment","target":{"@odata.type":"#microsoft.graph.allLicensedUsersAssignmentTarget"},"intent":"Required"}]}' } Write-Host ($AssignO365)
94-
New-graphPostRequest -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($OfficeAppID.id)/assign" -tenantid $tenant -Body $AssignO365 -type POST
95-
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Assigned Office to $AssignTo" -Sev 'Info'
98+
New-GraphPOSTRequest -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($OfficeAppID.id)/assign" -tenantid $Tenant -Body $AssignO365 -type POST
99+
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Assigned Office to $AssignTo" -Sev 'Info'
96100
}
97101
"Successfully added Office App for $($Tenant)"
98102
} catch {
99-
"Failed to add Office App for $($Tenant): $($_.Exception.Message)"
100-
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Failed to add Office App. Error: $($_.Exception.Message)" -Sev 'Error'
103+
$ErrorMessage = Get-CippException -Exception $_
104+
"Failed to add Office App for $($Tenant): $($ErrorMessage.NormalizedError)"
105+
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Failed to add Office App. Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -Logdata $ErrorMessage
101106
continue
102107
}
103108

104109
}
105110

106-
$body = [pscustomobject]@{'Results' = $results }
107-
108111
return ([HttpResponseContext]@{
109112
StatusCode = [HttpStatusCode]::OK
110-
Body = $body
113+
Body = @{'Results' = $Results }
111114
})
112115
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ function Invoke-ExecGetRecoveryKey {
1515
# Interact with query parameters or the body of the request.
1616
$TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
1717
$GUID = $Request.Query.GUID ?? $Request.Body.GUID
18+
$RecoveryKeyType = $Request.Body.RecoveryKeyType ?? 'BitLocker'
1819

1920
try {
20-
$Result = Get-CIPPBitLockerKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers
21+
switch ($RecoveryKeyType) {
22+
'BitLocker' { $Result = Get-CIPPBitLockerKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers }
23+
'FileVault' { $Result = Get-CIPPFileVaultKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers }
24+
default { throw "Invalid RecoveryKeyType specified: $RecoveryKeyType." }
25+
}
2126
$StatusCode = [HttpStatusCode]::OK
2227
} catch {
2328
$Result = $_.Exception.Message

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ function Invoke-ListGroups {
8888
groupInfo = ($RawGraphRequest | Where-Object { $_.id -eq 1 }).body | Select-Object *, @{ Name = 'primDomain'; Expression = { $_.mail -split '@' | Select-Object -Last 1 } },
8989
@{Name = 'teamsEnabled'; Expression = { if ($_.resourceProvisioningOptions -like '*Team*') { $true } else { $false } } },
9090
@{Name = 'calculatedGroupType'; Expression = {
91-
if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
92-
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
9391
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
94-
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
92+
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
93+
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
94+
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
9595
}
9696
}, @{Name = 'dynamicGroupBool'; Expression = { if ($_.groupTypes -contains 'DynamicMembership') { $true } else { $false } } }
9797
members = ($RawGraphRequest | Where-Object { $_.id -eq 2 }).body.value
@@ -105,11 +105,10 @@ function Invoke-ListGroups {
105105
@{Name = 'membersCsv'; Expression = { $_.members.userPrincipalName -join ',' } },
106106
@{Name = 'teamsEnabled'; Expression = { if ($_.resourceProvisioningOptions -like '*Team*') { $true }else { $false } } },
107107
@{Name = 'calculatedGroupType'; Expression = {
108-
109-
if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
110-
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
111108
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
112-
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
109+
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
110+
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
111+
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
113112
}
114113
},
115114
@{Name = 'dynamicGroupBool'; Expression = { if ($_.groupTypes -contains 'DynamicMembership') { $true } else { $false } } }

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Function Invoke-ListUserGroups {
1+
function Invoke-ListUserGroups {
22
<#
33
.FUNCTIONALITY
44
Entrypoint
@@ -22,10 +22,10 @@ Function Invoke-ListUserGroups {
2222
@{ Name = 'OnPremisesSync'; Expression = { $_.onPremisesSyncEnabled } },
2323
@{ Name = 'IsAssignableToRole'; Expression = { $_.isAssignableToRole } },
2424
@{ Name = 'calculatedGroupType'; Expression = {
25-
if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
26-
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
2725
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
28-
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
26+
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
27+
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
28+
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
2929
}
3030
}
3131

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Teams-Sharepoint/Invoke-ListSites.ps1

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Function Invoke-ListSites {
1+
function Invoke-ListSites {
22
<#
33
.FUNCTIONALITY
44
Entrypoint
@@ -11,23 +11,21 @@ Function Invoke-ListSites {
1111

1212

1313
$TenantFilter = $Request.Query.TenantFilter
14-
$Type = $request.query.Type
15-
$UserUPN = $request.query.UserUPN
14+
$Type = $Request.Query.Type
15+
$UserUPN = $Request.Query.UserUPN
1616

1717
if (!$TenantFilter) {
1818
return ([HttpResponseContext]@{
1919
StatusCode = [HttpStatusCode]::BadRequest
2020
Body = 'TenantFilter is required'
2121
})
22-
return
2322
}
2423

2524
if (!$Type) {
2625
return ([HttpResponseContext]@{
2726
StatusCode = [HttpStatusCode]::BadRequest
2827
Body = 'Type is required'
2928
})
30-
return
3129
}
3230

3331
$Tenant = Get-Tenants -TenantFilter $TenantFilter

Modules/CIPPCore/Public/Get-CIPPBitlockerKey.ps1

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieves BitLocker recovery keys for a managed device from Microsoft Graph API.
4+
5+
.DESCRIPTION
6+
This function queries the Microsoft Graph API to retrieve all BitLocker recovery keys
7+
associated with a specified device. It handles cases where no key is found and provides appropriate
8+
logging and error handling.
9+
.PARAMETER Device
10+
The ID of the device for which to retrieve BitLocker recovery keys.
11+
12+
.PARAMETER TenantFilter
13+
The tenant ID to filter the request to the appropriate tenant.
14+
15+
.PARAMETER APIName
16+
The name of the API operation for logging purposes. Defaults to 'Get BitLocker key'.
17+
18+
.PARAMETER Headers
19+
The headers to include in the request, typically used for authentication and logging.
20+
21+
.OUTPUTS
22+
Array of PSCustomObject with properties:
23+
- resultText: Formatted string containing the key ID and key value
24+
- copyField: The raw key value
25+
- state: Status of the operation ('success')
26+
27+
Or a string message if no keys are found.
28+
#>
129

230
function Get-CIPPBitLockerKey {
331
[CmdletBinding()]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieves the FileVault recovery key for a managed device from Microsoft Graph API.
4+
5+
.DESCRIPTION
6+
This function makes a request to the Microsoft Graph API to retrieve the FileVault recovery key
7+
for a specified managed device. It handles cases where no key is found and provides appropriate
8+
logging and error handling.
9+
10+
.PARAMETER Device
11+
The GUID of the managed device for which to retrieve the FileVault key.
12+
13+
.PARAMETER TenantFilter
14+
The tenant ID to filter the request to the appropriate tenant.
15+
16+
.PARAMETER APIName
17+
The name of the API operation for logging purposes. Defaults to 'Get FileVault key'.
18+
19+
.PARAMETER Headers
20+
The headers to include in the request, typically used for authentication and logging.
21+
22+
.OUTPUTS
23+
PSCustomObject with properties:
24+
- resultText: Formatted string containing the key
25+
- copyField: The raw key value
26+
- state: Status of the operation ('success')
27+
28+
Or a string message if no key is found.
29+
30+
#>
31+
32+
function Get-CIPPFileVaultKey {
33+
[CmdletBinding()]
34+
param (
35+
$Device,
36+
$TenantFilter,
37+
$APIName = 'Get FileVault key',
38+
$Headers
39+
)
40+
41+
try {
42+
$GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$Device/getFileVaultKey" -tenantid $TenantFilter
43+
44+
if ([string]::IsNullOrEmpty($GraphRequest)) {
45+
$Result = "No FileVault recovery key found for $($Device)"
46+
Write-LogMessage -headers $Headers -API $APIName -message $Result -Sev Info -tenant $TenantFilter
47+
return $Result
48+
}
49+
50+
Write-LogMessage -headers $Headers -API $APIName -message "Retrieved FileVault recovery key for $($Device)" -Sev Info -tenant $TenantFilter
51+
return [PSCustomObject]@{
52+
resultText = "Key: $($GraphRequest)"
53+
copyField = $GraphRequest
54+
state = 'success'
55+
}
56+
} catch {
57+
$ErrorMessage = Get-CippException -Exception $_
58+
$Result = "Could not retrieve FileVault recovery key for $($Device). Error: $($ErrorMessage.NormalizedError)"
59+
Write-LogMessage -headers $Headers -API $APIName -message $Result -Sev Error -tenant $TenantFilter -LogData $ErrorMessage
60+
throw $Result
61+
}
62+
63+
}

0 commit comments

Comments
 (0)