Private/Publish-IntuneWin32AppContent.ps1
|
function Publish-IntuneWin32AppContent { <# .SYNOPSIS Uploads the content of a .intunewin package to an existing Win32 app and commits it. .DESCRIPTION Microsoft Graph v1.0 flow for Win32 app content: 1. POST mobileApps/{id}/microsoft.graph.win32LobApp/contentVersions (https://learn.microsoft.com/graph/api/intune-apps-mobileappcontent-create) 2. POST .../contentVersions/{id}/files with name, size, sizeEncrypted, manifest and isDependency (https://learn.microsoft.com/graph/api/intune-apps-mobileappcontentfile-create) 3. Wait for uploadState azureStorageUriRequestSuccess, then upload the encrypted content to azureStorageUri in blocks (Send-IntuneContentFile) 4. POST .../files/{id}/commit with fileEncryptionInfo from Detection.xml (https://learn.microsoft.com/graph/api/intune-apps-mobileappcontentfile-commit) 5. Wait for uploadState commitFileSuccess, then PATCH the app with committedContentVersion (https://learn.microsoft.com/graph/api/intune-apps-win32lobapp-update) #> [CmdletBinding()] [OutputType([string])] param ( [Parameter(Mandatory)] [string]$AppId, [Parameter(Mandatory)] [string]$IntuneWinPath, [int]$PollIntervalSeconds = 5, [int]$TimeoutSeconds = 600 ) $AppUri = "v1.0/deviceAppManagement/mobileApps/$AppId" $EncryptedPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "IntunePackage-$([guid]::NewGuid().ToString('N')).bin" try { $Package = Read-IntuneWinPackage -Path $IntuneWinPath -ExtractTo $EncryptedPath -ErrorAction Stop Write-Verbose "Creating a content version for app $AppId." $ContentVersion = Invoke-MgGraphRequest -Method POST -Uri "$AppUri/microsoft.graph.win32LobApp/contentVersions" -Body '{}' -ContentType 'application/json' -OutputType PSObject -ErrorAction Stop $FilesUri = "$AppUri/microsoft.graph.win32LobApp/contentVersions/$($ContentVersion.id)/files" $FileBody = [ordered]@{ '@odata.type' = '#microsoft.graph.mobileAppContentFile' name = $Package.FileName size = $Package.UnencryptedContentSize sizeEncrypted = $Package.EncryptedContentSize manifest = $null isDependency = $false } | ConvertTo-Json -Compress Write-Verbose "Creating the content file $($Package.FileName)." $File = Invoke-MgGraphRequest -Method POST -Uri $FilesUri -Body $FileBody -ContentType 'application/json' -OutputType PSObject -ErrorAction Stop $FileUri = "$FilesUri/$($File.id)" $File = Wait-IntuneContentFileState -FileUri $FileUri -State azureStorageUriRequestSuccess -PollIntervalSeconds $PollIntervalSeconds -TimeoutSeconds $TimeoutSeconds Send-IntuneContentFile -Path $EncryptedPath -SasUri $File.azureStorageUri -FileUri $FileUri -PollIntervalSeconds $PollIntervalSeconds Write-Verbose 'Committing the content file.' $CommitBody = @{ fileEncryptionInfo = $Package.EncryptionInfo } | ConvertTo-Json -Depth 5 -Compress $null = Invoke-MgGraphRequest -Method POST -Uri "$FileUri/commit" -Body $CommitBody -ContentType 'application/json' -ErrorAction Stop $null = Wait-IntuneContentFileState -FileUri $FileUri -State commitFileSuccess -PollIntervalSeconds $PollIntervalSeconds -TimeoutSeconds $TimeoutSeconds Write-Verbose "Setting committedContentVersion to $($ContentVersion.id)." $PatchBody = @{ '@odata.type' = '#microsoft.graph.win32LobApp' committedContentVersion = [string]$ContentVersion.id } | ConvertTo-Json -Compress $null = Invoke-MgGraphRequest -Method PATCH -Uri $AppUri -Body $PatchBody -ContentType 'application/json' -ErrorAction Stop [string]$ContentVersion.id } finally { if (Test-Path -Path $EncryptedPath) { Remove-Item -Path $EncryptedPath -Force -ErrorAction SilentlyContinue } } } |