1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Intune Win32アプリ 巨大アプリの更新をPowershellで実行する

Last updated at Posted at 2025-04-28

はじめに

Intune Win32アプリでは、最大で30GBまでのアプリの登録が可能です。とはいえ大きなサイズのアプリの登録はアップロードの箇所で相当な時間がかかることから、手作業での実行はきついです。
MSのGraph Powershellのサンプルを利用して、より効率的にアップロードする方法がないか調べてみました。

利用できるスクリプト

こちらにあるスクリプトを利用すると、Win32アプリの登録から更新までいろいろできるようです、使い勝手もいろいろと改善されているようです。

一方、本家MSさんのGraph SDK powershellの中では以下のようなサンプルが公開されています。

https://github.com/microsoft/mggraph-intune-samples
https://github.com/microsoft/mggraph-intune-samples/tree/main/LOB_Application
https://github.com/microsoft/mggraph-intune-samples/blob/main/LOB_Application/Win32_Application_Update.ps1

なるべくならばMSさんの公式のものを利用してみたくなることから、このサンプルで実験をしてみます。

テストと改修

テスト的に8GBほどのinstall.intunewinファイルを事前に作成しておきます。
また、Win32アプリは事前に空の中身で登録しておきます。

その後、サンプルの関数を呼び出す形でこのように実行してみます。

LargeSizeupdate.ps1
# ここでサンプルのファイルをdot sourceしておき、関数を利用できるようにします。
. ".\Win32_Application_Update.ps1"

# これはGraph使う前に必ず必要なおまじないです。認証をします。
Connect-MgGraph

# あらかじめ登録したWin32アプリのIDと作成済のintunewinファイルのパスを指定します。
Invoke-Win32AppUpdate -AppId "2bdc5c92-cc6b-477d-9ee2-7b2624136910" -UpdateAppContentOnly $true -SourceFile ".\install.intunewin"

Win32アプリのIDはブラウザ上で以下のように確認も可能です。
対象アプリを開いた状態で、アドレスバーに長いIDが確認できます。

image.png

そして実行してみると、数々のトラブルが。。1つずつ解決していきます。

トラブルその1

image.png

これは簡単ですね、Uint32ではファイルサイズが収まらないのでしょう、Uint32の箇所をUint64に変更して解決です。

Win32_Application_Update.ps1

		# Upload the file to Azure Storage
		Write-Host "Uploading the file to Azure Storage..." -ForegroundColor Yellow
		$file = WaitForFileProcessing $fileUri "AzureStorageUriRequest"
		[UInt64]$BlockSizeMB = 4
		UploadFileToAzureStorage $file.azureStorageUri $IntuneWinFile $BlockSizeMB  $fileUri

トラブルその2

image.png

更新後少しの間はアップロードが進行したのですが。。途中でこのようなエラーです。403とはこれいかに。。
前述のIntuneWIn32Appなどを参考にさせていただいたところ、Win32アプリの実体はAzure Blobにアップロードしているようなのですが、そのSASに期限があるようです。アップロード中でも定期的に更新しないとこのようなエラーが出るようです。そこで、UploadFileToAzureStorage関数を改良します、SASのRenewalをロジックとして入れました。450000 msec = 7.5分毎に更新しています。

Win32_Application_Update.ps1
function UploadFileToAzureStorage($sasUri, $filepath, $blockSizeMB,  $fileUri) {
	# Chunk size in MiB
	$chunkSizeInBytes = (1024 * 1024 * $blockSizeMB)

	# Read the whole file and find the total chunks.
	#[byte[]]$bytes = Get-Content $filepath -Encoding byte;
	# Using ReadAllBytes method as the Get-Content used alot of memory on the machine
	$fileStream = [System.IO.File]::OpenRead($filepath)
	$chunks = [Math]::Ceiling($fileStream.Length / $chunkSizeInBytes)

	# Upload each chunk.
	$ids = @()
	$cc = 1
	$chunk = 0

	# Start the timer for SAS URI renewal
	$SASRenewalTimer = [System.Diagnostics.Stopwatch]::StartNew()


	while ($fileStream.Position -lt $fileStream.Length) {
		$id = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($chunk.ToString("0000")))
		$ids += $id

		$size = [Math]::Min($chunkSizeInBytes, $fileStream.Length - $fileStream.Position)
		$body = New-Object byte[] $size
		$fileStream.Read($body, 0, $size) > $null
		$totalBytes += $size

		Write-Progress -Activity "Uploading File to Azure Storage" -Status "Uploading chunk $cc of $chunks" -PercentComplete ($cc / $chunks * 100)
		$cc++

		UploadAzureStorageChunk $sasUri $id $body | Out-Null
		$chunk++

	    # Ensure the SAS Uri is renewed
		if ($SASRenewalTimer.ElapsedMilliseconds -ge 450000) {
			Write-Host -Message "SAS Uri renewal is required, attempting to renew"
			$RenewSASURIRequest = Invoke-MgGraphRequest -uri "$($fileUri)/renewUpload" -Method "POST" -Body "{}"
			$Stage = "AzureStorageUriRenewal"
			do {
				$GraphRequest = Invoke-MgGraphRequest -uri $fileUri -Method "GET"
				switch ($GraphRequest.uploadState) {
					"$($Stage)Pending" {
						Write-Host -Message "Intune service request for operation '$($Stage)' is in pending state, sleeping for 10 seconds"
						Start-Sleep -Seconds 10
					}
					"$($Stage)Failed" {
						Write-Host -Message "Intune service request for operation '$($Stage)' failed"
						throw
					}
					"$($Stage)TimedOut" {
						Write-Host -Message "Intune service request for operation '$($Stage)' timed out"
						throw
					}
				}
			}
			until ($GraphRequest.uploadState -like "$($Stage)Success")
			Write-Host -Message "Intune service request for operation '$($Stage)' was successful with uploadState: $($GraphRequest.uploadState)"

			$SASRenewalTimer.Restart()
		}
	}

	# Stop timer
	$SASRenewalTimer.Stop()

	$fileStream.Close()
	Write-Progress -Completed -Activity "Uploading File to Azure Storage"

	# Finalize the upload.
	FinalizeAzureStorageUpload $sasUri $ids | Out-Null
}

トラブルその3

SAS更新を入れると、こんな風に定期的に更新がされる為か、アップロードも順調でした。

image.png

ところが最後の最後で失敗です。。400エラーとは

image.png

これだけはよくわからずだったのですが、試しに最後のUpdateの前に、スリープを180秒=3分いれてみると、なんと動作します。

Win32_Application_Update.ps1

		# Commit the file to the service
		Invoke-MgCommitDeviceAppManagementMobileAppMicrosoftGraphWin32LobAppContentVersionFile -MobileAppId $mobileAppId -MobileAppContentId $ContentVersionId -MobileAppContentFileId $ContentVersionFileId -BodyParameter $params

		# Wait for the file to be processed
		Write-Host "Waiting for the file to be processed..." -ForegroundColor Yellow
		$file = WaitForFileProcessing $fileUri "CommitFile"

		Start-Sleep -Seconds 180

        # Check if we are only updating the content
		if ($UpdateAppContentOnly) {
			$params = @{
				"@odata.type"           = "#microsoft.graph.win32LobApp"
				committedContentVersion = "$ContentVersionId"
			}
		}
		else {
			$params = $mobileAppBody
			$params.committedContentVersion = "$ContentVersionId"
		}

		$params = $params | ConvertTo-Json

		# Update the application with the new content version
		Write-Host "Updating the application with the new content version..." -ForegroundColor Yellow
		Update-MgDeviceAppManagementMobileApp -MobileAppId $mobileAppId -BodyParameter $params
        

ようやく正常に動作が完了するようになりましたが、アップロード時間はかかりますね。

image.png

MSさんのサンプルもここまで大きなサイズのアップロードは考慮していなかったようですね。

更新したファイルはこちらです。Pull requestも出してみました。

2025/5/6追記、Pull Requestですが無事Mergeされました

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?