MSEndpointMgr / IntuneWin32App

Provides a set of functions to manage all aspects of Win32 apps in Microsoft Intune.
MIT License
351 stars 91 forks source link

Add-IntuneWin32App.ps1 'CommitFile' failed error with PowerShell 7.4.0 #128

Open jaspain opened 12 months ago

jaspain commented 12 months ago

Using PowerShell 7.40, Microsoft.Graph 2.91, IntuneWinAppUtil.exe 1.85, and IntuneWin32App 1.42, Add-Intunewin32App.ps1 generates the warnings:

WARNING: Intune service request for operation 'CommitFile' failed
WARNING: Failed to create Win32 app, commit file request operation failed

The intunewin file upload fails. Using PowerShell 7.39 instead of 7.40 along with the same versions of the other components, the upload succeeds. See Add-IntuneWin32App.ps1, line 621.

jaspain commented 11 months ago

Looking at this further, the error occurs in Add-Intunewin32App.ps1, line 617. The request to commit the uploaded content returns a commitFileFailed response with PowerShell 7.4.0, commitFileSuccess with PowerShell 7.3.9.

I created a simplified test environment by excerpting the code and data needed to create a 7-Zip Intune app DebugAddingIntuneWin32App.zip. Here the error occurs at Test-AddingIntuneWin32App.ps1, line 449, with PowerShell 7.4.0. The 7-Zip Intune app is successfully created with PowerShell 7.3.9. To run the test environment, install the desired version of PowerShell 7, along with modules Microsoft.Graph 2.91, IntuneWin32App 1.42, and MSAL.PS 4.37.0.0. Connect-MSIntuneGraph to your tenant, and execute Test-AddingIntuneWin32App.ps1.

Verbose output of the test environment is included in the zip file: Test-AddingIntuneWin32App v7.3.9 Output.txt and Test-AddingIntuneWin32App v7.4.0 Output.txt. Comparing these two files, one difference that stands out is in line 19 of both files where the content encoding is iso-8859-1 for v7.3.9 and utf-8 with 7.40. The payload sizes in line 15 are different as well. It's not clear what's going on here, but note that the Invoke-AzureStorageBlobUploadChunk function in Test-AddingIntuneWin32App.ps1, line 214, specifies iso-8859-1 encoding. This bears further investigation.

jaspain commented 11 months ago

I think the problem is with Invoke-WebRequest in function Invoke-AzureStorageBlobUploadChunk (see PowerShell\Modules\IntuneWin32App\1.4.2\Private\Invoke-AzureStorageBlobUploadChunk.ps1, line 43). The documetation Invoke-WebRequest states in the Description section "Beginning in PowerShell 7.4, character encoding for requests defaults to UTF-8 instead of ASCII. If you need a different encoding, you must set the charset attribute in the Content-Type header."

jaspain commented 11 months ago

Ok. That's the problem. Here's the proposed fix: PowerShell\Modules\IntuneWin32App\1.4.2\Private\Invoke-AzureStorageBlobUploadChunk.ps1, insert after line 38: "content-type" = "text/plain; charset=iso-8859-1"

The definition of $Headers becomes:

    $Headers = @{
        "content-type" = "text/plain; charset=iso-8859-1"
        "x-ms-blob-type" = "BlockBlob"
    }

This should work in PowerShell 5, where the ContentType parameter of PowerShell 7's Invoke-WebRequest isn't implemented. I tested it and confirmed that it works in PowerShell 7.39, where this is the default content type anyway, and in PowerShell 7.40, where this content type needs to be explicitly set to override the default utf-8.

fabrisodotps1 commented 11 months ago

I can confirm this behavior and the suggested fix also works. Thank you for the detailed analysis @jaspain

MarkMae commented 11 months ago

@jaspain Top! Thank you for the work! 👍

jaspain commented 10 months ago

Remains an issue in v1.4.3.

NickolajA commented 10 months ago

Excellent analysis @jaspain, thank you! I'll have this fixed in 1.4.4.

jaspain commented 10 months ago

Thank you, @NickolajA. Jeff.

abidkayanimoj commented 9 months ago

Thank you, @jaspain. I ended up with this error last week and finally a colleague of mine found your article and pass it to me. it works.

Frank-Geisler commented 8 months ago

Hey @jaspain! Thank you very much for your fix. This worked for me as well :)

jaspain commented 8 months ago

@NickolajA I'm confirming that v1.4.4 resolves this issue in an environment using the current versions of PowerShell 7.41, Microsoft.Graph 2.15.0, and IntuneWinAppUtil.exe 1.86. The intunewin file upload is successful. Thank you.

MarkMae commented 4 months ago

First, thank you for the fix!

Now I get the following error:

WARNING: Failed to finalize Azure Storage blob upload. Error message: The given key 'Content-Type' was not present in the dictionary.

SunsparcSolaris commented 3 months ago

First, thank you for the fix!

Now I get the following error:

WARNING: Failed to finalize Azure Storage blob upload. Error message: The given key 'Content-Type' was not present in the dictionary.

Same is happening to me, despite updating all modules. Powershell version 7.4.4 latest.

WARNING: Failed to finalize Azure Storage blob upload. Error message: The given key 'Content-Type' was not present in the dictionary. WARNING: Intune service request for operation 'CommitFile' failed WARNING: Failed to create Win32 app, commit file request operation failed

jaspain commented 3 months ago

@SunsparcSolaris This has been working for me with PowerShell 7.4.4 and IntuneWin32App 1.4.4. Here are the changes needed to the original Invoke-AzureStorageGLobUploadFinalize.ps1.

Starting after line 36 (lines 35 and 36 shown for context):

$XML += '</BlockList>'

    $Headers = @{
        "content-type" = "text/plain; charset=iso-8859-1"
    }
    try {
        $WebResponse = Invoke-RestMethod -Uri $Uri -Method "Put" -Headers $Headers -Body $XML -ErrorAction Stop
    }

Note the addition of the -Headers parameter to the call to Invoke-RestMethod.

SunsparcSolaris commented 3 months ago

$Headers = @{ "content-type" = "text/plain; charset=iso-8859-1" } try { $WebResponse = Invoke-RestMethod -Uri $Uri -Method "Put" -Headers $Headers -Body $XML -ErrorAction Stop }

Nope, this isn't working for me. I copy/pasted exactly. Even closed the Pwsh 7 window out completely and opened a fresh one.

EDIT: Disregard. There was a discrepancy between installation location that I sorted out and then applied the fix. Module was not being imported from correct location.

jaspain commented 3 months ago

@SunsparcSolaris Makes sense, but how frustrating. I used Install-Module -Name IntuneWin32App -Scope AllUsers, which puts the code at C:\Program Files\PowerShell\Modules\IntuneWin32App\1.4.4. Without the -Scope parameter, it ends up in your user profile directory by default.