packer-plugin-windows-update
packer-plugin-windows-update copied to clipboard
How To Install Specific KBs?
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?
Try with a -in or -contains operator and let me know how it goes.
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)
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?
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",
]
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
}```
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