Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-MsrcSecurityBulletinHtml $monthOfInterest = '2017-Jun' throws The input object cannot be bound to any parameters for the command... #20

Closed
mm1382 opened this issue Jun 13, 2017 · 5 comments
Labels

Comments

@mm1382
Copy link

mm1382 commented Jun 13, 2017

For this month, Jun-2017 module Get-MsrcSecurityBulletinHtml throws an error it doesn't for earlier months, e.g., April.

PS C:\temp> Install-Module MSRCSecurityUpdates -Force
PS C:\temp> Set-MSRCApiKey -ApiKey "[REDACTED]" -Verbose
VERBOSE: Performing the operation "Set item" on target "[REDACTED]".
VERBOSE: Successfully set your API Key required by cmdlets of this module. Calls to the MSRC APIs will now use your API key.
VERBOSE: Successfully defined a msrcApiUrl global variable that points to https://api.msrc.microsoft.com
VERBOSE: Successfully defined a msrcApiVersion global variable that points to api-version=2016-08-01
PS C:\temp> $monthOfInterest = '2017-Jun'
PS C:\temp> Get-MsrcCvrfDocument -ID $monthOfInterest -Verbose | Get-MsrcSecurityBulletinHtml -Verbose | Out-File c:\temp\MSRCSecurityUpdates-${monthOfInterest}.html
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01 with 0-byte payload
VERBOSE: received 2183597-byte response of content type application/json; charset=utf-8
Get-MsrcSecurityBulletinHtml : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:54

  • Get-MsrcCvrfDocument -ID $monthOfInterest -Verbose | Get-MsrcSecurityBulletinHtm ...
  •                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: ({
      "DocumentT...
      }
      ]
      }:PSObject) [Get-MsrcSecurityBulletinHtml], ParameterBindingException
    • FullyQualifiedErrorId : InputObjectNotBound,Get-MsrcSecurityBulletinHtml

PS C:\temp> Get-MsrcCvrfDocument -ID $monthOfInterest -Verbose | Out-File c:\temp\foo.txt
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01 with 0-byte payload
VERBOSE: received 2183597-byte response of content type application/json; charset=utf-8

The output for June is different, as shown below.

PS C:\temp> Get-MsrcCvrfDocument -ID $monthOfInterest -Verbose | Out-File c:\temp\foo-Apr.txt
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-Apr?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-Apr?api-version=2016-08-01 with 0-byte payload
VERBOSE: received 898987-byte response of content type application/json; charset=utf-8
PS C:\temp> $monthOfInterest
2017-Apr
PS C:\temp> $monthOfInterest = '2017-Jun'
PS C:\temp> Get-MsrcCvrfDocument -ID $monthOfInterest -Verbose | Out-File c:\temp\foo-Jun.txt
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-Jun?api-version=2016-08-01 with 0-byte payload
VERBOSE: received 2183597-byte response of content type application/json; charset=utf-8
PS C:\temp> gc C:\temp\foo-Apr.txt | select -first 10

DocumentTitle : @{Value=April 2017 Security Updates}
DocumentType : @{Value=Security Update}
DocumentPublisher : @{ContactDetails=; IssuingAuthority=; Type=0}
DocumentTracking : @{Identification=; Status=2; Version=1.0; RevisionHistory=System.Object[];
InitialReleaseDate=2017-04-11T07:00:00; CurrentReleaseDate=2017-04-11T07:00:00}
DocumentNotes : {@{Title=Release Notes; Audience=Public; Type=1; Ordinal=1; Value=

The April security
release consists of security updates for the following software:



    PS C:\temp> gc C:\temp\foo-Jun.txt | select -first 10
    {
    "DocumentTitle": {
    "Value": "June 2017 Security Release"
    },
    "DocumentType": {
    "Value": "Security Update"
    },
    "DocumentPublisher": {
    "ContactDetails": {
    "Value": "secure@microsoft.com"

@craig-martin
Copy link
Contributor

Thanks for filing the issue, much appreciated!

Have you tried Get-MsrcVulnerabilityReportHtml? We've been putting more working that function and are considering removing the old one (Get-MsrcSecurityBulletinHtml).

Note: if we remove Get-MsrcSecurityBulletinHtml you will still be able to get it via older versions of the module on the PowerShell Gallery, like this:

Install-Module -Name MsrcSecurityUpdates -MaximumVersion 1.7.2

@rsola
Copy link
Contributor

rsola commented Jun 15, 2017

Hi. I'm in no way related to the team which develops the MSRC PowerShell module. I'm only a somewhat advanced Windows user. I can reproduce this issue on PowerShell 4.0. PowerShell 3.0 may be affected as well but Invoke-RestMethod is broken in that version anyway.

The problem lies on the JsonObject class that Invoke-RestMethod uses to convert the server response to a PowerShell object, provided the Content-Type header specifies "application/json". The ConvertFromJson method creates an instance of JavaScriptSerializer from the System.Web.Extensions assembly to deserialize the JSON-formatted response into a collection of arrays and dictionaries. This class has a MaxJsonLength property that is initialized to 2097152 characters by default. When the server response exceeds this limit, the Deserialize method of JavaScriptSerializer throws ArgumentException. Invoke-RestMethod discards this exception silently and returns the original string instead.

You may think ConvertFrom-Json should do the trick, but it won't. In fact, ConvertFrom-Json also relies on JsonObject but it doesn't catch any exceptions. If you execute Get-MsrcCvrfDocument -ID 2017-Jun | ConvertFrom-Json, the following error message appears: "Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property."

PowerShell 5.0 and 5.1 are not affected because JsonObject raises the value of the MaxJsonLength property to Int32.MaxValue (2147483647). It is very unlikely to hit that limit in practice.

Workaround

If you can't upgrade your version of PowerShell, you can check if the data returned by Get-MsrcCvrfDocument is a string (I believe $data -is [string] should work), then create a JavaScriptSerializer instance, set its MaxJsonLength property to a sensible value and call DeserializeObject yourself. However, this is not enough. The JavaScriptSerializer deserializer returns a collection which Get-MsrcSecurityBulletinHtml and Get-MsrcVulnerabilityReportHtml don't understand. Those collection objects must be converted to PowerShell objects first. JsonObject does this transformation as part of its Deserialize methods, but the implementation is not accessible from outside.

Florian Feldhaus provides alternative helper functions in the Stack Overflow discussion ConvertFrom-Json max length. Chris Wahl discusses the problem as well in Deserializing Large JSON Payloads into a PowerShell Hashtable.
Important: the ParseJsonObject function has a bug. When $item equals zero, the if ($item) test will evaluate to false. Therefore, the else block will assign $null to $parsedItem instead of the number zero. You might want to replace the entire if-else block with ParseItem $item. The original code causes Get-MsrcVulnerabilityReportHtml to emit a lot of "Could not determine the Impact from the Threats" warnings.

@ms-AlexDavis
Copy link
Contributor

ms-AlexDavis commented Jun 15, 2017

@rsola Thanks for digging though and finding out the root cause! I have to say, that was one of the best technical write ups i have read in a while!

@rsola
Copy link
Contributor

rsola commented Jun 16, 2017

Thank you, @ms-AlexDavis! I appreciate your words. I encountered this problem myself and I wanted to know why it happened. Not everyone runs the latest, shiniest version of Windows PowerShell. 😉
I came here and I was lucky to find the message written by @mm1382. This situation encouraged me to research the problem and share my findings. Determining the root cause of an issue is sometimes hard but very rewarding. It is even more satisfying when you know you helped someone. English is not my native language, so writing for an international audience can be a bit of a challenge.

@mm1382
Copy link
Author

mm1382 commented Jun 18, 2017

Thanks, @craig-martin
But, using Get-MsrcVulnerabilityReportHtml instead of Get-MsrcSecurityBulletinHtml
as detailed in Microsoft Blog, throws the same error:

PS D:\WSUS-install> Get-MsrcCvrfDocument -ID 2017-Mar | Get-MsrcVulnerabilityReportHtml | Out-File -FilePath 2017-Mar-Cvrf-CVE-Summary.html
Get-MsrcVulnerabilityReportHtml : The input object cannot be bound to any parameters for the command either because
the command does not take pipeline input or the input and its properties do not match any of the parameters that take
pipeline input.
At line:1 char:37

  • Get-MsrcCvrfDocument -ID 2017-Mar | Get-MsrcVulnerabilityReportHtml | Out-File - ...
  •                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: ({
      "DocumentT...
      }
      ]
      }:PSObject) [Get-MsrcVulnerabilityReportHtml], ParameterBindingException
    • FullyQualifiedErrorId : InputObjectNotBound,Get-MsrcVulnerabilityReportHtml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants