MSEndpointMgr / IntuneWin32App

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

"HTTP Status BadRequest" when creating an application #49

Closed aaronparker closed 1 year ago

aaronparker commented 2 years ago

This is an FYI, not an issue. I came across the following issue when using version 1.3.5 of the module (this wasn't an issue with 1.3.3).

The following is logged when creating a package for Microsoft Teams MSI installer:

VERBOSE: Successfully created Win32 app package object
WARNING: Request to https://graph.microsoft.com/Beta/deviceAppManagement/mobileApps failed with HTTP Status BadRequest 
and description: Bad Request
WARNING: Failed to create Win32 app using constructed body. Passing converted body as JSON to output.

Notice that in my App.json which defines the Microsoft Teams package, it has the following details, which includes the (em dash) character in the description. The creation of the package was falling over on this character - after removing this, the package was created successfully.

  "Information": {
    "DisplayName": "Microsoft Teams 1.5.00.21668 x64",
    "Description": "More is possible with Microsoft Teams. Stay connected and access shared content any time to learn, plan, and innovate—together.",
    "Publisher": "Microsoft",
    "InformationURL": "https://www.microsoft.com/microsoft-teams/",
    "PrivacyURL": "https://go.microsoft.com/fwlink/?LinkId=521839"
  }

Note though, this might be fixed with Utf8 support #10

NickolajA commented 2 years ago

Thanks Aaron. 1.3.6 that was just released now uses utf8 encoding in the content type. Could you please see if that fixes this issue?

aaronparker commented 2 years ago

Will do.

aaronparker commented 2 years ago

Looks great, thank-you. Here's an example with ImageGlass and Thai characters

ScreenShot 2022-10-03 at 08 49 01 ScreenShot 2022-10-03 at 08 48 22
baartch commented 2 years ago

Hello all. I am new to this PSModule and I just tried the demo with 7-zip in your README and I also get a HTTP status BadRequest. At least in Windows Powershell 5.1. In PS Core 7.2.6 the error cannot be displayed... see below. Am I doing something wrong?

Btw, I just saw, that under msiInformation the publisher is null. Maybe there is an issue?

PS C:\Users\myUserName> get-module "IntuneWin32App"

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.3.6      IntuneWin32App                      {Add-IntuneWin32App, Add-IntuneWin32AppAssignment, Add-IntuneWin32AppAssignmentAllDevices, Add-Int...

PS C:\Users\myUserName> Connect-MSIntuneGraph -TenantID 123456-1234-1234-1234-123456789012

Name                           Value
----                           -----
Authorization                  Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6Im5yckhVY0JObGRHeGMwTUotLXRpZXYyeGRBUDdVZVZOcnpxQWJwWUlKZ3ciLCJhbGciOiJSUzI1NiIsIng1dCI6Ij...
Content-Type                   application/json
ExpiresOn                      04.10.2022 07:53:16

PS C:\Users\myUserName> $IntuneWinFile = "C:\Win32Apps\Output\7z2201-x64.intunewin"
PS C:\Users\myUserName> test-path $IntuneWinFile
True
PS C:\Users\myUserName> $IntuneWinMetaData = Get-IntuneWin32AppMetaData -FilePath $IntuneWinFile
PS C:\Users\myUserName>
PS C:\Users\myUserName> # Create custom display name like 'Name' and 'Version'
PS C:\Users\myUserName> $DisplayName = $IntuneWinMetaData.ApplicationInfo.Name + " " + $IntuneWinMetaData.ApplicationInfo.MsiInfo.MsiProductVersion
PS C:\Users\myUserName> $Publisher = $IntuneWinMetaData.ApplicationInfo.MsiInfo.MsiPublisher
PS C:\Users\myUserName>
PS C:\Users\myUserName> # Create requirement rule for all platforms and Windows 10 20H2
PS C:\Users\myUserName> $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2"
PS C:\Users\myUserName>
PS C:\Users\myUserName> # Create MSI detection rule
PS C:\Users\myUserName> $DetectionRule = New-IntuneWin32AppDetectionRuleMSI -ProductCode $IntuneWinMetaData.ApplicationInfo.MsiInfo.MsiProductCode -ProductVersionOperator "greaterThanOrEqual" -ProductVersion $IntuneWinMetaData.ApplicationInfo.MsiInfo.MsiProductVersion
PS C:\Users\myUserName>
PS C:\Users\myUserName> # Add new MSI Win32 app
PS C:\Users\myUserName> Add-IntuneWin32App -FilePath $IntuneWinFile -DisplayName $DisplayName -Description "Install 7-zip application" -Publisher $Publisher -InstallExperience "system" -RestartBehavior "suppress" -DetectionRule $DetectionRule -RequirementRule $RequirementRule -Verbose
VERBOSE: Current authentication token expires in (minutes): 24
VERBOSE: Attempting to gather additional meta data from .intunewin file: C:\Win32Apps\Output\7z2201-x64.intunewin
VERBOSE: Successfully gathered additional meta data from .intunewin file
VERBOSE: Start constructing basic layout of Win32 app body
VERBOSE: Constructed the basic layout for 'MSI' Win32 app body type
VERBOSE: Detection rule objects passed validation checks, attempting to add to existing Win32 app body
VERBOSE: Retrieving default set of return codes for Win32 app body construction
VERBOSE: Adding array of return codes to Win32 app body construction
VERBOSE: Attempting to create Win32 app using constructed body converted to JSON content
VERBOSE: POST https://graph.microsoft.com/Beta/deviceAppManagement/mobileApps
WARNING: Request to https://graph.microsoft.com/Beta/deviceAppManagement/mobileApps failed with HTTP Status BadRequest and description: Bad Request
WARNING: Failed to create Win32 app using constructed body. Passing converted body as JSON to output.
WARNING: {
    "@odata.type":  "#microsoft.graph.win32LobApp",
    "applicableArchitectures":  "x64,x86",
    "description":  "Install 7-zip application",
    "developer":  "",
    "displayVersion":  "",
    "owner":  "",
    "notes":  "",
    "informationUrl":  "",
    "privacyInformationUrl":  "",
    "isFeatured":  false,
    "displayName":  "7-Zip 22.01 (x64 edition) 22.01.00.0",
    "fileName":  "IntunePackage.intunewin",
    "setupFilePath":  "7z2201-x64.msi",
    "installCommandLine":  "msiexec.exe /i \"7z2201-x64.msi\"",
    "uninstallCommandLine":  "msiexec.exe /x \"{23170F69-40C1-2702-2201-000001000000}\"",
    "installExperience":  {
                              "deviceRestartBehavior":  "suppress",
                              "runAsAccount":  "system"
                          },
    "minimumSupportedWindowsRelease":  "2H20",
    "minimumFreeDiskSpaceInMB":  "null",
    "minimumMemoryInMB":  "null",
    "minimumNumberOfProcessors":  "null",
    "minimumCpuSpeedInMHz":  "null",
    "msiInformation":  {
                           "requiresReboot":  false,
                           "productVersion":  "22.01.00.0",
                           "publisher":  null,
                           "productCode":  "{23170F69-40C1-2702-2201-000001000000}",
                           "upgradeCode":  "{23170F69-40C1-2702-0000-000004000000}",
                           "productName":  "7-Zip 22.01 (x64 edition) 22.01.00.0",
                           "packageType":  "DualPurpose"
                       },
    "publisher":  "Igor Pavlov",
    "runAs32bit":  false,
    "detectionRules":  [
                           {
                               "@odata.type":  "#microsoft.graph.win32LobAppProductCodeDetection",
                               "productCode":  "{23170F69-40C1-2702-2201-000001000000}",
                               "productVersionOperator":  "greaterThanOrEqual",
                               "productVersion":  "22.01.00.0"
                           }
                       ],
    "returnCodes":  [
                        {
                            "returnCode":  0,
                            "type":  "success"
                        },
                        {
                            "returnCode":  1707,
                            "type":  "success"
                        },
                        {
                            "returnCode":  3010,
                            "type":  "softReboot"
                        },
                        {
                            "returnCode":  1641,
                            "type":  "hardReboot"
                        },
                        {
                            "returnCode":  1618,
                            "type":  "retry"
                        }
                    ]
}
PS C:\Users\myUserName>

And this is how it looks in PS Core 7.2.6

PS C:\Users\myUserName> Add-IntuneWin32App -FilePath $IntuneWinFile -DisplayName $DisplayName -Description "Install 7-zip application" -Publisher $Publisher -InstallExperience "system" -RestartBehavior "suppress" -DetectionRule $DetectionRule -RequirementRule $RequirementRule -Verbose
VERBOSE: Current authentication token expires in (minutes): 12
VERBOSE: Attempting to gather additional meta data from .intunewin file: C:\Win32Apps\Output\7z2201-x64.intunewin
VERBOSE: Successfully gathered additional meta data from .intunewin file
VERBOSE: Start constructing basic layout of Win32 app body
VERBOSE: Constructed the basic layout for 'MSI' Win32 app body type
VERBOSE: Detection rule objects passed validation checks, attempting to add to existing Win32 app body
VERBOSE: Retrieving default set of return codes for Win32 app body construction
VERBOSE: Adding array of return codes to Win32 app body construction
VERBOSE: Attempting to create Win32 app using constructed body converted to JSON content
VERBOSE: POST https://graph.microsoft.com/Beta/deviceAppManagement/mobileApps
WARNING: An error occurred while creating the Win32 application. Error message: Method invocation failed because [System.Net.Http.HttpResponseMessage] does not contain a method named 'GetResponseStream'.
PS C:\Users\myUserName>

PS C:\Users\myUserName> $Error[0].Exception

ErrorRecord                 : Method invocation failed because [System.Net.Http.HttpResponseMessage] does not contain a method named 'GetResponseStream'.
WasThrownFromThrowStatement : False
TargetSite                  : Void CheckActionPreference(System.Management.Automation.Language.FunctionContext, System.Exception)
Message                     : Method invocation failed because [System.Net.Http.HttpResponseMessage] does not contain a method named 'GetResponseStream'.
Data                        : {System.Management.Automation.Interpreter.InterpretedFrameInfo}
InnerException              :
HelpLink                    :
Source                      : System.Management.Automation
HResult                     : -2146233087
StackTrace                  :    at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
                                 at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
                                 at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                                 at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                                 at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
                                 at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
                                 at System.Management.Automation.PSScriptCmdlet.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
                                 at System.Management.Automation.PSScriptCmdlet.DoEndProcessing()
                                 at System.Management.Automation.CommandProcessorBase.Complete()

PS C:\Users\myUserName> $Error[1].Exception

Response       : StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
                 {
                   Transfer-Encoding: chunked
                   Strict-Transport-Security: max-age=31536000
                   request-id: cc66c9cb-e476-4936-8fa1-d3dc3046d31b
                   client-request-id: cc66c9cb-e476-4936-8fa1-d3dc3046d31b
                   x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Europe","Slice":"E","Ring":"4","ScaleUnit":"004","RoleInstance":"DB1PEPF00026494"}}
                   Date: Tue, 04 Oct 2022 06:38:06 GMT
                   Content-Type: application/json
                 }
StatusCode     :
TargetSite     : Void ThrowTerminatingError(System.Management.Automation.ErrorRecord)
Message        : Response status code does not indicate success: 400 (Bad Request).
Data           : {}
InnerException :
HelpLink       :
Source         : System.Management.Automation
HResult        : -2146233088
StackTrace     :    at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)
SSKLCP commented 1 year ago

Hey, I ran into the issue above and have some notes about it. Could be good for a fix but workaround-able. PowerShell 7 doesn't seem to work with this. It looks like an issue with Invoke-RestMethod. Maybe a similar issue here: https://github.com/KelvinTegelaar/AutotaskAPI/issues/20 Maybe that could help fix it, I don't 100% understand to be honest.

In regards to this "BadRequest" issue above. @baartch It seems that this is broken from update 1.3.6 as it cannot process the string "null" as a value for the rules like "minimumMemoryInMB". If you set your requirement rule to have values for all the numeric properties then it works without issue. In my case I added 1 for each field as that should work in any environment:

$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "x64" -MinimumSupportedWindowsRelease "1903" -MinimumFreeDiskSpaceInMB "1" -MinimumMemoryInMB "1" -MinimumNumberOfProcessors "1" -MinimumCPUSpeedInMHz "1"

Hope this helps :)

NickolajA commented 1 year ago

I've looked into this a bit more, and I can say that I made a mistake in 1.3.6. It has been corrected, and I've now successfully tested the following types of requirement rules which is working:

$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2"
$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2" -MinimumFreeDiskSpaceInMB 100
$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2" -MinimumFreeDiskSpaceInMB 100 -MinimumMemoryInMB 1024
$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2" -MinimumFreeDiskSpaceInMB 100 -MinimumMemoryInMB 1024 -MinimumNumberOfProcessors 2
$RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "All" -MinimumSupportedWindowsRelease "20H2" -MinimumFreeDiskSpaceInMB 100 -MinimumMemoryInMB 1024 -MinimumNumberOfProcessors 2 -MinimumCPUSpeedInMHz 1000
NickolajA commented 1 year ago

This will be included in 1.4.0 that's going to be released shortly. Sorry for the inconvenience!