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

How To Install Specific KBs? #94

Open
TigerC10 opened this issue Jun 20, 2021 · 6 comments
Open

How To Install Specific KBs? #94

TigerC10 opened this issue Jun 20, 2021 · 6 comments

Comments

@TigerC10
Copy link

README indicates:

Inside an expression, the Windows Update IUpdate interface can be referenced by the $_ variable.

I need to install a specific KB (or two, if applicable). Looking at the linked docs, I noticed that IUpdate::get_KBArticleIDs is a method that returns an IStringCollection - So, assuming that getter fronts a property of the same name here's what I tried:

  provisioner "windows-update" {
    search_criteria = "IsInstalled=0"
    filters = [
      "include:$_.KBArticleIDs.Contains('KB4038782') -or $_.KBArticleIDs.Contains('KB4038782')",
    ]
    update_limit = 2
  }

This gave the following error:

ERROR: Method invocation failed because [System.__ComObject] does not contain a method named 'Contains'.
ERROR: at <ScriptBlock>, <No file>: line 1
ERROR: at Test-IncludeUpdate, C:\Windows\Temp\packer-windows-update.ps1: line 158
ERROR: at <ScriptBlock>, C:\Windows\Temp\packer-windows-update.ps1: line 195
ERROR: at <ScriptBlock>, <No file>: line 1
ERROR EXCEPTION: System.Management.Automation.RuntimeException: Method invocation failed because [System.__ComObject] does not contain a method named 'Contains'.
ERROR EXCEPTION:    at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
ERROR EXCEPTION:    at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
ERROR EXCEPTION:    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
ERROR EXCEPTION:    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
ERROR EXCEPTION:    at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
ERROR EXCEPTION:    at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
ERROR EXCEPTION:    at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
ERROR EXCEPTION:    at System.Management.Automation.ScriptBlock.<>c__DisplayClass57_0.<InvokeWithPipe>b__0()
ERROR EXCEPTION:    at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
ERROR EXCEPTION:    at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Boolean propagateAllExceptionsToTop, List`1 variablesToDefine, Dictionary`2 functionsToDefine, Object[] args)
ERROR EXCEPTION:    at System.Management.Automation.ScriptBlock.DoInvokeReturnAsIs(Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Object[] args)
ERROR EXCEPTION:    at Microsoft.PowerShell.Commands.WhereObjectCommand.ProcessRecord()
ERROR EXCEPTION:    at System.Management.Automation.CommandProcessor.ProcessRecord()

Now, either this collection doesn't have a Contains method, or I need to typecast this before I can call the Contains method.

So, I did this:

  provisioner "windows-update" {
    search_criteria = "IsInstalled=0"
    filters = [
      "include:([system.collections.specialized.stringcollection] $_.KBArticleIDs).Contains('KB4038782') -or ([system.collections.specialized.stringcollection] $_.KBArticleIDs).Contains('KB4038782')",
    ]
    update_limit = 2
  }

And it apparently works. But, uh, does it have to be this complicated? Can we get maybe a syntax sugar to wrap this up in a nice little bow?

@rgl
Copy link
Owner

rgl commented Jun 20, 2021

Try with a -in or -contains operator and let me know how it goes.

@Stunkymonkey
Copy link

Stunkymonkey commented Oct 4, 2023

I tried this excluding update and still all updates get installed:

  provisioner "windows-update" {
    search_criteria = "AutoSelectOnWebSites=1 and IsInstalled=0"
    filters = [
      "exclude:$_.Title -Like '*Preview*'",
      "exclude:$_.InstallationBehavior.CanRequestUserInput",
      "exclude:$_.KBArticleIDs -Contains 'KB5030219'",
      "include:$true",
    ]
  }

still shows (not skipping):

 virtualbox-iso.win-11: Found Windows update (2023-09-12; 130700.99 MB): 2023-09 Cumulative Update for Windows 11 Version 22H2 for x64-based Systems (KB5030219)

@Stunkymonkey
Copy link

using "exclude:$_.Title -Like '*Cumulative*'", will result in

virtualbox-iso.win-11: Skipped (filter) Windows update (2023-09-12; 130700.99 MB): 2023-09 Cumulative Update for Windows 11 Version 22H2 for x64-based Systems (KB5030219)

Is it possible to exclude only the specific KB and use the "2023-08 Cumulative Update" instead?

@Stunkymonkey
Copy link

ok got it. The KB in-front is not correct. The correct code is:

    filters = [
      "exclude:$_.Title -Like '*Preview*'",
      "exclude:$_.InstallationBehavior.CanRequestUserInput",
      "exclude:$_.KBArticleIDs -Contains '5030219'",
      "include:$true",
    ]

@tusharsappal
Copy link

tusharsappal commented Feb 21, 2024

Following up on this , how can I install specific KBs , I tried with I got the exlcusion , but how can i pass list of KB IDs to the script to form the expression ?

Please advise .

Will something like work ?

provisioner "windows-update" {
    search_criteria = "IsInstalled=0"
    filters = [
      "include:$_.KBArticleIDs.Contains('4038782') -or $_.KBArticleIDs.Contains('4038782')",
    ]
    update_limit = 2
  }```

@BorysMariusz
Copy link

Following up on this , how can I install specific KBs , I tried with I got the exlcusion , but how can i pass list of KB IDs to the script to form the expression ?

Please advise .

Will something like work ?

provisioner "windows-update" {
    search_criteria = "IsInstalled=0"
    filters = [
      "include:$_.KBArticleIDs.Contains('4038782') -or $_.KBArticleIDs.Contains('4038782')",
    ]
    update_limit = 2
  }```

@tusharsappal did you find a way to install specific KBs

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

No branches or pull requests

5 participants