Private/Invoke-IntuneContentCommit.ps1
<#
.SYNOPSIS Commits the uploaded Win32 content to Intune Created on: 30/12/2024 Updated on: 01/01/2025 Created by: Ben Whitmore Filename: Invoke-IntuneContentCommit.ps1 .DESCRIPTION This function commits the uploaded Win32 content to Intune by creating a commit request and waiting for processing. .PARAMETER Win32AppId The ID of the Win32 app .PARAMETER ContentVersion The ID of the content version .PARAMETER ContentRequestId The ID of the content request .PARAMETER EncryptionInfo The encryption information for the file .PARAMETER RetryCount The number of times to retry the commit request if it fails .PARAMETER RetryDelay The number of seconds to delay between retries .PARAMETER LogId Component name for logging .EXAMPLE Invoke-IntuneContentCommit -Win32AppId $Win32AppId -ContentVersion $ContentVersion -ContentRequestId $ContentRequestId -EncryptionInfo $EncryptionInfo -LogId "CommitWin32Content" #> function Invoke-IntuneContentCommit { param ( [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'The ID of the Win32 app')] [string]$Win32AppId, [Parameter(Mandatory = $true, Position = 1, HelpMessage = 'The content version ID')] [string]$ContentVersion, [Parameter(Mandatory = $true, Position = 2, HelpMessage = 'The ID of the content request')] [string]$ContentRequestId, [Parameter(Mandatory = $true, Position = 3, HelpMessage = 'The encryption information for the file')] [string]$EncryptionInfo, [Parameter(Mandatory = $false, Position = 4, HelpMessage = 'The number of times to retry the commit request if it fails')] [int]$RetryCount = 10, [Parameter(Mandatory = $false, Position = 5, HelpMessage = 'The number of seconds to delay between retries')] [int]$RetryDelay = 5, [Parameter(Mandatory = $false, HelpMessage = 'Component name for logging')] [string]$LogId = $($MyInvocation.MyCommand).Name ) process { try { # Prepare the JSON for the commit request $EncryptionInfoObject = $EncryptionInfo | ConvertFrom-Json $json = @{ "fileEncryptionInfo" = $EncryptionInfoObject } $commitJSONEntry = $json | ConvertTo-Json -Compress # Resource Uri for the commit request $commitUri = "deviceAppManagement/mobileApps/{0}/microsoft.graph.win32LobApp/contentVersions/{1}/files/{2}" -f $Win32AppId, $ContentVersion, $ContentRequestId # Commit the content try { $commitPostResponse = Invoke-MgGraphRequestCustom -Method POST -Resource "$($commitUri)/commit" -Body $commitJSONEntry Write-LogAndHost -Message ("Commit request sent successfully to {0}:" -f $commitUri) -LogId $LogId -ForegroundColor Green Write-LogAndHost -Message ("Commit Body: {0}" -f $commitJSONEntry) -LogId $LogId -ForegroundColor Green } catch { Write-LogAndHost -Message ("Failed to commit content to {0}: {1}" -f $commitUri, $_.Exception.Message) -LogId $LogId -Severity 3 throw } # Check upload state $success = $false $attempt = 1 do { try { # Make the GET request to check upload state $statusResponse = Invoke-MgGraphRequestCustom -Method GET -Resource $commitUri # Check if the upload state is acceptable if (($statusResponse.uploadState) -eq "commitFileSuccess" ) { Write-LogAndHost -Message ("Upload state is '{0}'." -f ($statusResponse.uploadState)) -LogId $LogId -ForegroundColor Green $success = $true } elseif (($statusResponse.uploadState) -eq "commitFileFailed" ) { $contentReadyOutput = [ordered]@{} foreach ($property in $statusResponse.GetEnumerator() | Sort-Object -Property Key) { # Skip the manifest property (it's too long to output!) if ($property.Key -ne 'manifest') { $contentReadyOutput[$property.Key] = $property.Value } } $contentReadyOutputJson = $contentReadyOutput | ConvertTo-Json -Compress Write-Log -Message ("Upload state is '{0}'. The commit failed. The response was: {1}" -f ($statusResponse.uploadState), $contentReadyOutputJson) -LogId $LogId -Severity 2 $success = $false break } else { Write-LogAndHost -Message ("Attempt {0}/{1}. Upload state is '{2}'. Waiting for commit..." -f $attempt, $RetryCount, ($statusResponse.uploadState)) -LogId $LogId -Severity 2 Start-Sleep -Seconds $RetryDelay } } catch { # Log error and decide whether to retry Write-LogAndHost -Message ("Attempt {0}/{1} failed. Error: {2}" -f $attempt, $RetryCount, $_.Exception.Message) -LogId $LogId -Severity 2 Write-LogAndHost -Message ("Attempt {0}/{1} failed. Retrying in {2} seconds." -f $attempt, $RetryCount, $RetryDelay) -LogId $LogId -Severity 2 Start-Sleep -Seconds $RetryDelay } # Increment attempt counter only after each iteration $attempt++ } while (-not $success -and $attempt -le $RetryCount) if ($success) { Write-LogAndHost -Message "Commit operation completed successfully." -LogId $LogId -ForegroundColor Green # Now update the app with the committed content version Write-LogAndHost -Message ("Updating committed content version for app {0} to {1}..." -f $Win32Appid, $ContentVersion) -LogId $LogId -ForegroundColor Cyan $updateAppUri = "deviceAppManagement/mobileApps/$($Win32AppId)" $updateData = @{ "@odata.type" = "#microsoft.graph.Win32LobApp" committedContentVersion = $contentVersion } $updateDataJson = $updateData | ConvertTo-Json -Compress Write-LogAndHost -Message ("Committed content version data: {0}" -f $updateDataJson) -LogId $LogId -ForegroundColor Green try { $updateResponse = Invoke-MgGraphRequestCustom -Method PATCH -Resource $updateAppUri -Body $updateDataJson Write-LogAndHost -Message ("Successfully updated the content version in Intune for '{0}'" -f $Win32AppId) -LogId $LogId -ForegroundColor Green return $true } catch { Write-LogAndHost -Message ("Failed to update app {0} with committed content version: {1}" -f $Win32AppId, $_.Exception.Message) -LogId $LogId -Severity 3 return $false } } } catch { Write-LogAndHost -Message ("Commit operation failed: {0}" -f $_.Exception.Message) -LogId $LogId -Severity 3 return $false } } } |