none
Revisit VBScript with CCM_SoftwareUpdatesManager - Cross Post RRS feed

  • Question

  • Hi All,

    I saw this thread:  VBSCRIPT call WMI Method on array.  I originally asked on the SCCM forum here, but it was suggested I might get a better answer in a scripting forum.   So here I am ;-)

    It was an attempt to convert a short PowerShell script to VBScript, so it can be used in specific use cases (these are for me older servers and clients without PowerShell installed / enabled).

    For sure I can see why the original script was failing, because when I look at the Powershell it is based upon there is a missing step:

    PowerShell

    # This is a simpple get of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK 
    $MissingUpdates = Get-WmiObject -Class CCM_SoftwareUpdate -Filter ComplianceState=0 -Namespace root\CCM\ClientSDK 
     
    # The following is done to do 2 things: Get the missing updates (ComplianceState=0)  
    # and take the PowerShell object and turn it into an array of WMI objects 
    $MissingUpdatesReformatted = @($MissingUpdates | ForEach-Object {if($_.ComplianceState -eq 0){[WMI]$_.__PATH}}) 
     
    # The following is the invoke of the CCM_SoftwareUpdatesManager.InstallUpdates with our found updates 
    # NOTE: the command in the ArgumentList is intentional, as it flattens the Object into a System.Array for us 
    # The WMI method requires it in this format. 
    $InstallReturn = Invoke-WmiMethod -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$MissingUpdatesReformatted) -Namespace root\ccm\clientsdk 

    VBScript

    Set objWMIService = GetObject("winmgmts:\\.\root\ccm\ClientSDK")
    Set objInstall = GetObject("winmgmts:\\.\root\ccm\ClientSDK:CCM_SoftwareUpdatesManager")
    Set colItems = objWMIService.ExecQuery("SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState=0")
    objInstall.InstallUpdates colItems

    The problem is the missing step, before you can execute the objInstall.InstallUpdates you have to convert the Collection into an Array (error returned is "SWbemObjectEx: Generic Failure"),.

    The way it is done in PowerShell is to create a new array of WMI objects using:

    {[WMI]$_.__PATH}

    But I have no idea if this is even possible in VBScript.

    So my question -> does anyone know if creating an array of WMI objects within VBScript is possible?

    Kind regards,
    drH

    • Moved by Bill_Stewart Wednesday, September 5, 2018 9:57 PM Off-topic
    Tuesday, June 19, 2018 9:53 AM

All replies

  • In both cases you must enumerate the collection and call each member separately.

    In VBScript you would use "For Each".


    \_(ツ)_/

    Tuesday, June 19, 2018 5:29 PM
  • Hi jrv,

    This approach wont work, the function objInstall.InstallUpdates() requires an array.   Please see the reference:

    https://docs.microsoft.com/en-us/sccm/develop/reference/core/clients/sdk/installupdates-method-in-class-ccm_softwareupdatesmanager

    Kind regards,
    Paul


    Thursday, June 21, 2018 2:03 PM
  • A collection is an array.


    \_(ツ)_/

    Thursday, June 21, 2018 2:06 PM
  • It might well be, but performing that code doesn't work and I don't know why.   Any advise or possible way to troubleshoot further appreciated.
    Tuesday, June 26, 2018 1:26 PM
  • $ccmsum = [wmiclass]'\\.\root\ccm\ClientSDK:CCM_SoftwareUpdatesManager'
    $colItems = @(Get-WmiObject CCM_SoftwareUpdate -Filter 'ComplianceState=0')
    $ccmsum.InstallUpdates($colItems)
    
    


    \_(ツ)_/

    Tuesday, June 26, 2018 2:24 PM
  • That I think is PowerShell code and not VBScript.   

    This topic is about how to make the function work in VBScript.   

    Therefore, that code is no good to me.  Some of the servers I wish to execute it on are old [Windows 2008 r1 / Windows 2003 r2] and I cannot assume they have PowerShell installed as until Windows 2008 r2 it was not installed as default.   

    I am happy if the answer is simply 'No - not possible' but the question has been asked many times and no one has ever confirmed this before...

    Tuesday, June 26, 2018 3:02 PM
  • Then I will restate.  The following returns a collection:

    SetcolItems =objWMIService.ExecQuery("SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState=0")

    WMI in VBScript always returns a collection of items.  A collection is an array.

    Your generic failure is likely due to a configuration issue with the classes or access to the resources.

    VBScript is obsolete.  You should not be using it.


    \_(ツ)_/

    Tuesday, June 26, 2018 3:14 PM
  • To retrieve the instances if that is what is needed.

    Dim a(colitems.count)
    i = 0
    For Each item in colItems
         Set obj = GetObject(item._Path)
         Set $a(i) = obj
         i = i + 1
    Next
    


    \_(ツ)_/

    Tuesday, June 26, 2018 3:21 PM
  • I got a bit further (array error) but get an error with _Path:

    Dim a()               
    Redim a(colItems.count)
    i = 0
    For Each item in colItems
         Set obj = GetObject(item._Path)
         Set a(i) = obj
         i = i + 1
    Next
    Error (with relative line number):

    test.vbs(5, 52) Microsoft VBScript compilation error: Invalid character

    Any thoughts?
    Wednesday, June 27, 2018 10:58 AM
  • Does "item" contain a path property?  "Invalid character" likely indicates a bad copy/paste.


    \_(ツ)_/


    • Edited by jrv Wednesday, June 27, 2018 11:02 AM
    Wednesday, June 27, 2018 11:01 AM
  • Yes it did, although I struggled to get the system __PATH property out, so I cheated a bit, as they are all in the same format and directly linked to the UpdateID property of the item.

    Therefore i could manage to get a new object linked to the update:

    Set objSWbemLocator = CreateObject ("WbemScripting.SWbemLocator")
    Set objSWbemServices = objSWbemLocator.ConnectServer (".","root\ccm\ClientSDK")
    objSWbemServices.Security_.ImpersonationLevel = 3 
    Set colItems = objSWbemServices.InstancesOf("CCM_SoftwareUpdate")
    Dim arrItems()
    Redim arrItems(colItems.Count)
    i=0
    For Each objItem In colItems	
       StringToWrite="\\.\ROOT\ccm\ClientSDK:CCM_SoftwareUpdate.UpdateID=" & Chr(34) & objItem.UpdateID & Chr(34)
       Set obj = GetObject("winmgmts:" & StringToWrite)
       arrItems(i)=obj
       i=i+1
    Next
    Set objInstall = GetObject("winmgmts:\\.\root\ccm\ClientSDK:CCM_SoftwareUpdatesManager")
    Set Return=objInstall.InstallUpdates(arrItems)
    

    However it won't let me make the array member be the object:

    test.vbs(11, 4) Microsoft VBScript runtime error: Object doesn't support this property or method

    Is there any other VB data type I could use?   

    My other thought was could I build a temporary WMI class and use this to hold the data and delete it afterwards?

    Wednesday, June 27, 2018 1:30 PM
  • Thismline is syntactically wrong.

    Set Return=objInstall.InstallUpdates(arrItems)

    This:

    return = objInstall.InstallUpdates(arrItems)

    "return" is not an object. It is an integer.


    \_(ツ)_/

    Wednesday, June 27, 2018 2:36 PM
  • Hi,

    Thanks for this -> but the error is with this line:

    arrItems(i)=obj

    This returns "Object doesn't support this property or method"

    Wednesday, June 27, 2018 8:15 PM
  • Hi,

    Thanks for this -> but the error is with this line:

    arrItems(i)=obj

    This returns "Object doesn't support this property or method"

    It is an object and requires a "Set"

    Set arrItems(i)=obj


    \_(ツ)_/

    Wednesday, June 27, 2018 8:28 PM
  • Thanks for that, that now works and the array is created. However:

    return=objInstall.InstallUpdates(arrItems)

    This now returns:

    test.vbs(X, 1) SWbemObjectEx: Invalid parameter

    Any other thoughts?

    Wednesday, June 27, 2018 9:16 PM
  • Apparently your information on how to use the classes is incorrect. 

    The classes were written with PowerShell as the target and may not work in VBS.  Just use PowerShell.  There is no need for VBS anymore. It is obsolete.


    \_(ツ)_/

    Wednesday, June 27, 2018 9:27 PM
  • Apparently your information on how to use the classes is incorrect. 

    Care to expand by what you mean by this statement?   

    Wednesday, June 27, 2018 9:31 PM
  • Apparently your information on how to use the classes is incorrect. 

    Care to expand by what you mean by this statement?   

    Because it doesn't work.

    Have you tried PowerShell?


    \_(ツ)_/

    Wednesday, June 27, 2018 9:33 PM
  • Just use PowerShell

    And as I said, if I could rely upon PowerShell being available on the boxes I wish to execute the code, I would be using it.   Hence the requirement for an alternative [e.g VBScript]...

    Wednesday, June 27, 2018 9:34 PM
  • Have you tried PowerShell?


    \_(ツ)_/

    Yep, it works just find on my Windows 2008r2 boxes and above which have it natively installed.
    Wednesday, June 27, 2018 9:35 PM
  • All current versions of Windows include PowerShell.


    \_(ツ)_/

    Wednesday, June 27, 2018 9:37 PM
  • I know, but unfortunately not everyone has the luxury to work with only current versions of Windows.   

    Although they make up the majority of the scope of servers we operate, it is allowed for risks raised in business areas to be 'accepted' if the financial cost of the upgrade significantly outways the cost of the risk of the system being taken down in the event of an incident.   So in my enterprise, and I suspect many others, out of date versions of Windows Server running business applications exist.   

    I'm just trying to achieve something which means I can take one common approach on them all...

    Apparently your information on how to use the classes is incorrect. 

    Care to expand by what you mean by this statement?   

    Because it doesn't work.

    Can you help me understand WHY it doesn't work -> I knew it didn't work at the beginning of the thread.  Is it something to do with the array type differing in PowerShell?

    Wednesday, June 27, 2018 9:45 PM
  • I suggest you post in the CCM forum for issues with their SDK and classes.  They are highly specific to CCM and no to PowerShell.

    The classes are very poorly documented and little is said about using them in other than PowerShell.

    Your companies choice to retain unsupported software will put you in this corner frequently.  I suggest getting a corporate extended support agreement and calling MS support for this issue.


    \_(ツ)_/

    Wednesday, June 27, 2018 9:49 PM