Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ function Invoke-AddOfficeApp {
param($Request, $TriggerMetadata)

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

$results = foreach ($Tenant in $tenants) {
$Results = foreach ($Tenant in $Tenants) {
try {
$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' }
$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' }
if (!$ExistingO365) {
# Check if custom XML is provided
if ($request.body.useCustomXml -and $request.body.customXml) {
if ($Request.Body.useCustomXml -and $Request.Body.customXml) {
# Use custom XML configuration
$ObjBody = [pscustomobject]@{
'@odata.type' = '#microsoft.graph.officeSuiteApp'
'displayName' = 'Microsoft 365 Apps for Windows 10 and later'
'description' = 'Microsoft 365 Apps for Windows 10 and later'
'informationUrl' = 'https://products.office.com/en-us/explore-office-for-home'
'privacyInformationUrl' = 'https://privacy.microsoft.com/en-us/privacystatement'
'isFeatured' = $true
'publisher' = 'Microsoft'
'notes' = ''
Expand All @@ -38,7 +41,7 @@ function Invoke-AddOfficeApp {
}
} else {
# Use standard configuration
$Arch = if ($request.body.arch) { 'x64' } else { 'x86' }
$Arch = if ($Request.Body.arch) { 'x64' } else { 'x86' }
$products = @('o365ProPlusRetail')
$ExcludedApps = [pscustomobject]@{
infoPath = $true
Expand All @@ -54,26 +57,27 @@ function Invoke-AddOfficeApp {
access = $false
bing = $false
}
foreach ($ExcludedApp in $request.body.excludedApps.value) {
$ExcludedApps.$excludedapp = $true
foreach ($ExcludedApp in $Request.Body.excludedApps.value) {
$ExcludedApps.$ExcludedApp = $true
}
$ObjBody = [pscustomobject]@{
'@odata.type' = '#microsoft.graph.officeSuiteApp'
'displayName' = 'Microsoft 365 Apps for Windows 10 and later'
'description' = 'Microsoft 365 Apps for Windows 10 and later'
'informationUrl' = 'https://products.office.com/en-us/explore-office-for-home'
'privacyInformationUrl' = 'https://privacy.microsoft.com/en-us/privacystatement'
'isFeatured' = $true
'publisher' = 'Microsoft'
'notes' = ''
'owner' = 'Microsoft'
'autoAcceptEula' = [bool]$request.body.AcceptLicense
'autoAcceptEula' = [bool]$Request.Body.AcceptLicense
'excludedApps' = $ExcludedApps
'officePlatformArchitecture' = $Arch
'officeSuiteAppDefaultFileFormat' = 'OfficeOpenXMLFormat'
'localesToInstall' = @($request.body.languages.value)
'shouldUninstallOlderVersionsOfOffice' = [bool]$request.body.RemoveVersions
'updateChannel' = $request.body.updateChannel.value
'useSharedComputerActivation' = [bool]$request.body.SharedComputerActivation
'localesToInstall' = @($Request.Body.languages.value)
'shouldUninstallOlderVersionsOfOffice' = [bool]$Request.Body.RemoveVersions
'updateChannel' = $Request.Body.updateChannel.value
'useSharedComputerActivation' = [bool]$Request.Body.SharedComputerActivation
'productIds' = $products
'largeIcon' = @{
'@odata.type' = 'microsoft.graph.mimeContent'
Expand All @@ -88,25 +92,24 @@ function Invoke-AddOfficeApp {
"Office deployment already exists for $($Tenant)"
continue
}
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Added Office profile to $($tenant)" -Sev 'Info'
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Added Office profile to $($Tenant)" -Sev 'Info'
if ($AssignTo) {
$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)
New-graphPostRequest -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($OfficeAppID.id)/assign" -tenantid $tenant -Body $AssignO365 -type POST
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Assigned Office to $AssignTo" -Sev 'Info'
New-GraphPOSTRequest -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($OfficeAppID.id)/assign" -tenantid $Tenant -Body $AssignO365 -type POST
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Assigned Office to $AssignTo" -Sev 'Info'
}
"Successfully added Office App for $($Tenant)"
} catch {
"Failed to add Office App for $($Tenant): $($_.Exception.Message)"
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($tenant) -message "Failed to add Office App. Error: $($_.Exception.Message)" -Sev 'Error'
$ErrorMessage = Get-CippException -Exception $_
"Failed to add Office App for $($Tenant): $($ErrorMessage.NormalizedError)"
Write-LogMessage -headers $Headers -API $APIName -tenant $($Tenant) -message "Failed to add Office App. Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -Logdata $ErrorMessage
continue
}

}

$body = [pscustomobject]@{'Results' = $results }

return ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
Body = @{'Results' = $Results }
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ function Invoke-ExecGetRecoveryKey {
# Interact with query parameters or the body of the request.
$TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
$GUID = $Request.Query.GUID ?? $Request.Body.GUID
$RecoveryKeyType = $Request.Body.RecoveryKeyType ?? 'BitLocker'

try {
$Result = Get-CIPPBitLockerKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers
switch ($RecoveryKeyType) {
'BitLocker' { $Result = Get-CIPPBitLockerKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers }
'FileVault' { $Result = Get-CIPPFileVaultKey -Device $GUID -TenantFilter $TenantFilter -APIName $APIName -Headers $Headers }
default { throw "Invalid RecoveryKeyType specified: $RecoveryKeyType." }
}
$StatusCode = [HttpStatusCode]::OK
} catch {
$Result = $_.Exception.Message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ function Invoke-ListGroups {
groupInfo = ($RawGraphRequest | Where-Object { $_.id -eq 1 }).body | Select-Object *, @{ Name = 'primDomain'; Expression = { $_.mail -split '@' | Select-Object -Last 1 } },
@{Name = 'teamsEnabled'; Expression = { if ($_.resourceProvisioningOptions -like '*Team*') { $true } else { $false } } },
@{Name = 'calculatedGroupType'; Expression = {
if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
}
}, @{Name = 'dynamicGroupBool'; Expression = { if ($_.groupTypes -contains 'DynamicMembership') { $true } else { $false } } }
members = ($RawGraphRequest | Where-Object { $_.id -eq 2 }).body.value
Expand All @@ -105,11 +105,10 @@ function Invoke-ListGroups {
@{Name = 'membersCsv'; Expression = { $_.members.userPrincipalName -join ',' } },
@{Name = 'teamsEnabled'; Expression = { if ($_.resourceProvisioningOptions -like '*Team*') { $true }else { $false } } },
@{Name = 'calculatedGroupType'; Expression = {

if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
}
},
@{Name = 'dynamicGroupBool'; Expression = { if ($_.groupTypes -contains 'DynamicMembership') { $true } else { $false } } }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Function Invoke-ListUserGroups {
function Invoke-ListUserGroups {
<#
.FUNCTIONALITY
Entrypoint
Expand All @@ -22,10 +22,10 @@ Function Invoke-ListUserGroups {
@{ Name = 'OnPremisesSync'; Expression = { $_.onPremisesSyncEnabled } },
@{ Name = 'IsAssignableToRole'; Expression = { $_.isAssignableToRole } },
@{ Name = 'calculatedGroupType'; Expression = {
if ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
if (!$_.mailEnabled -and $_.securityEnabled) { 'Security' }
if ($_.groupTypes -contains 'Unified') { 'Microsoft 365' }
if (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (!$_.securityEnabled)) { 'Distribution List' }
elseif ($_.mailEnabled -and $_.securityEnabled) { 'Mail-Enabled Security' }
elseif (-not $_.mailEnabled -and $_.securityEnabled) { 'Security' }
elseif (([string]::isNullOrEmpty($_.groupTypes)) -and ($_.mailEnabled) -and (-not $_.securityEnabled)) { 'Distribution List' }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Function Invoke-ListSites {
function Invoke-ListSites {
<#
.FUNCTIONALITY
Entrypoint
Expand All @@ -11,23 +11,21 @@ Function Invoke-ListSites {


$TenantFilter = $Request.Query.TenantFilter
$Type = $request.query.Type
$UserUPN = $request.query.UserUPN
$Type = $Request.Query.Type
$UserUPN = $Request.Query.UserUPN

if (!$TenantFilter) {
return ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::BadRequest
Body = 'TenantFilter is required'
})
return
}

if (!$Type) {
return ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::BadRequest
Body = 'Type is required'
})
return
}

$Tenant = Get-Tenants -TenantFilter $TenantFilter
Expand Down
28 changes: 28 additions & 0 deletions Modules/CIPPCore/Public/Get-CIPPBitlockerKey.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
<#
.SYNOPSIS
Retrieves BitLocker recovery keys for a managed device from Microsoft Graph API.

.DESCRIPTION
This function queries the Microsoft Graph API to retrieve all BitLocker recovery keys
associated with a specified device. It handles cases where no key is found and provides appropriate
logging and error handling.
.PARAMETER Device
The ID of the device for which to retrieve BitLocker recovery keys.

.PARAMETER TenantFilter
The tenant ID to filter the request to the appropriate tenant.

.PARAMETER APIName
The name of the API operation for logging purposes. Defaults to 'Get BitLocker key'.

.PARAMETER Headers
The headers to include in the request, typically used for authentication and logging.

.OUTPUTS
Array of PSCustomObject with properties:
- resultText: Formatted string containing the key ID and key value
- copyField: The raw key value
- state: Status of the operation ('success')

Or a string message if no keys are found.
#>

function Get-CIPPBitLockerKey {
[CmdletBinding()]
Expand Down
63 changes: 63 additions & 0 deletions Modules/CIPPCore/Public/Get-CIPPFileVaultKey.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<#
.SYNOPSIS
Retrieves the FileVault recovery key for a managed device from Microsoft Graph API.

.DESCRIPTION
This function makes a request to the Microsoft Graph API to retrieve the FileVault recovery key
for a specified managed device. It handles cases where no key is found and provides appropriate
logging and error handling.

.PARAMETER Device
The GUID of the managed device for which to retrieve the FileVault key.

.PARAMETER TenantFilter
The tenant ID to filter the request to the appropriate tenant.

.PARAMETER APIName
The name of the API operation for logging purposes. Defaults to 'Get FileVault key'.

.PARAMETER Headers
The headers to include in the request, typically used for authentication and logging.

.OUTPUTS
PSCustomObject with properties:
- resultText: Formatted string containing the key
- copyField: The raw key value
- state: Status of the operation ('success')

Or a string message if no key is found.

#>

function Get-CIPPFileVaultKey {
[CmdletBinding()]
param (
$Device,
$TenantFilter,
$APIName = 'Get FileVault key',
$Headers
)

try {
$GraphRequest = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$Device/getFileVaultKey" -tenantid $TenantFilter

if ([string]::IsNullOrEmpty($GraphRequest)) {
$Result = "No FileVault recovery key found for $($Device)"
Write-LogMessage -headers $Headers -API $APIName -message $Result -Sev Info -tenant $TenantFilter
return $Result
}

Write-LogMessage -headers $Headers -API $APIName -message "Retrieved FileVault recovery key for $($Device)" -Sev Info -tenant $TenantFilter
return [PSCustomObject]@{
resultText = "Key: $($GraphRequest)"
copyField = $GraphRequest
state = 'success'
}
} catch {
$ErrorMessage = Get-CippException -Exception $_
$Result = "Could not retrieve FileVault recovery key for $($Device). Error: $($ErrorMessage.NormalizedError)"
Write-LogMessage -headers $Headers -API $APIName -message $Result -Sev Error -tenant $TenantFilter -LogData $ErrorMessage
throw $Result
}

}
Loading