locked
VBS - Having issues trying to delete duplicate UEFI firmware objects in BCM/NVRAM RRS feed

  • Question

  • We've been using SCCM 2012 R2 to test deployments of Window 8.1 to UEFI-enabled Lenovo laptops. We found that when you image these laptops over and over again a new "Windows Boot Manager" entry is created as a boot option each time. After much hair pulling, we finally found a couple references to the issue:

    http://technet.microsoft.com/en-us/library/cc749510(v=ws.10).aspx

    http://jeff.squarecontrol.com/archives/184/comment-page-1#comment-355

    In that second link, particularly the comment referenced, someone posted a VBS that will use WMI to automatically clean up firmware boot loader entries. This would be great since we could just add a task sequence step during SCCM OSD, and not have to do it manually like the Technet entry wants us to. 

    The problem is I'm not great with scripting, and can usually get by modifying someone else's script. This time, however, I can't get this one to work for the life of me. So you don't have to keep looking at the second link, here's the contents of the script:

    option explicit
    
    dim strComputer
    dim strFilePath
    
    dim objLocator
    dim objRootWMI
    dim objBCD
    dim objBCDStore
    dim objFWBL
    dim colObjects
    dim objElement
    dim strTemp
    
    Const BcdLibraryString_Description = &h12000004
    Const Firmware = &h101FFFFF
    
    strComputer = “.”
    strFilePath = “TEMPSTORE”
    
    ‘Connect to WMI
    set ObjLocator = CreateObject(“WbemScripting.SWbemLocator”)
    set objRootWMI = ObjLocator.ConnectServer(strComputer, “root\wmi”)
    objRootWMI.Security_.ImpersonationLevel = 3
    
    strTemp = “winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore”
    
    ‘———————————————————————-
    ‘ Open the BcdStore.
    ‘———————————————————————-
    
    set objBCD = GetObject( strTemp )
    
    if Err.number 0 then
    WScript.Echo “ERROR: GetObject(” & strTemp & “) failed rc=” & Hex(Err.number) & ” ” & Err.Description’
    WScript.Quit(1)
    end if
    
    if not objBCD.OpenStore(strFilePath, objBcdStore ) then
    WScript.Echo “ERROR: Could not open the BCD system store.”
    WScript.Quit(1)
    end if
    
    set objBCD = nothing
    
    ‘———————————————————————-
    ‘ Enumerate the Firmware Boot Manager.
    ‘———————————————————————-
    
    if not objBcdStore.EnumerateObjects(Firmware, colObjects ) then
    WScript.Echo “ERROR: objBcdStore.EnumberateObjects( Firmware ) failed.”
    WScript.Quit(1)
    end if
    
    for each objFWBL in colObjects
    
    if not objFWBL.GetElement( BcdLibraryString_Description, objElement ) then
    WScript.Echo “ERROR: Firmware Boot Loader GetElement for ” & Hex(BcdLibraryString_Description) & ” failed.”
    WScript.Quit(1)
    end if
    
    if not BcdStore.DeleteObjectobjFWBL.Id) then
    WScript.Echo “ERROR: Could not delete Firmware Boot Loader Item: ” & objElement.String
    WScript.Quit(1)
    end if
    
    WScript.Echo “Deleted Firmware Boot Loader Item: ” & objElement.String
    
    next
    
    set objFWBL = nothing
    set objBcdStore = nothing
    set objLocator = nothing
    set objRootWMI = nothing

    After pasting that into VBSedit the first thing I did was fix all the quotation marks that invariably get jacked up when copy/pasting from webpages. I also noticed a random single quote mark at the end of line 35 that I figured was a typo, so I removed it:

    WScript.Echo “ERROR: GetObject(” & strTemp & “) failed rc=” & Hex(Err.number) & ” ” & Err.Description’

    However, after that got fixed, I'm still getting an error "script.vbs (34, 15) Microsoft VBScript compilation error: Expected 'Then'". I'm guessing that line 34 needs some kind of logical operator for the "If Err.number 0 then" statement. But, I can't figure out what it would be, i.e. <> 0, = 0, etc.

    Just to play around with it I tried both, and still get errors regarding line 35. So, I'm guessing something is really messed up around there. I would really appreciate anyone that could give me some guidance as my forehead is sore from banging it into the keyboard. Thanks. 

    Tuesday, September 23, 2014 6:11 PM

Answers

All replies

  • Line 35 lacks an Equal sign.
    Many of the other lines use non-ASCII single or double quotes. The version below uses the correct symbols.

    option explicit
    dim strComputer
    dim strFilePath
    dim objLocator
    dim objRootWMI
    dim objBCD
    dim objBCDStore
    dim objFWBL
    dim colObjects
    dim objElement
    dim strTemp

    Const BcdLibraryString_Description = &h12000004
    Const Firmware = &h101FFFFF

    strComputer ="."
    strFilePath = "TEMPSTORE"

    'Connect to WMI
    set ObjLocator = CreateObject("WbemScripting.SWbemLocator")
    set objRootWMI = ObjLocator.ConnectServer(strComputer, "root\wmi")
    objRootWMI.Security_.ImpersonationLevel = 3

    strTemp = "winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore"

    '———————————————————————-
    ' Open the BcdStore.
    '———————————————————————-

    set objBCD = GetObject( strTemp )

    if Err.Number=0 then
    WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
    WScript.Quit(1)
    end if

    if not objBCD.OpenStore(strFilePath, objBcdStore ) then
    WScript.Echo "ERROR: Could not open the BCD system store."
    WScript.Quit(1)
    end if

    set objBCD = nothing
    '———————————————————————-
    ' Enumerate the Firmware Boot Manager.
    '———————————————————————-

    if not objBcdStore.EnumerateObjects(Firmware, colObjects ) then
    WScript.Echo "ERROR: objBcdStore.EnumberateObjects( Firmware ) failed."
    WScript.Quit(1)
    end if

    for each objFWBL in colObjects

    if not objFWBL.GetElement( BcdLibraryString_Description, objElement ) then
    WScript.Echo "ERROR: Firmware Boot Loader GetElement for " & Hex(BcdLibraryString_Description) & " failed."
    WScript.Quit(1)
    end if

    if not BcdStore.DeleteObjectobjFWBL.Id then
    WScript.Echo "ERROR: Could not delete Firmware Boot Loader Item: " & objElement.String
    WScript.Quit(1)
    end if

    WScript.Echo "Deleted Firmware Boot Loader Item: " & objElement.String

    next

    set objFWBL = nothing
    set objBcdStore = nothing
    set objLocator = nothing
    set objRootWMI = Nothing

    Tuesday, September 23, 2014 6:43 PM
  • Line 35 lacks an Equal sign.
    Many of the other lines use non-ASCII single or double quotes. The version below uses the correct symbols.

    option explicit
    dim strComputer
    dim strFilePath
    dim objLocator
    dim objRootWMI
    dim objBCD
    dim objBCDStore
    dim objFWBL
    dim colObjects
    dim objElement
    dim strTemp

    Const BcdLibraryString_Description = &h12000004
    Const Firmware = &h101FFFFF

    strComputer ="."
    strFilePath = "TEMPSTORE"

    'Connect to WMI
    set ObjLocator = CreateObject("WbemScripting.SWbemLocator")
    set objRootWMI = ObjLocator.ConnectServer(strComputer, "root\wmi")
    objRootWMI.Security_.ImpersonationLevel = 3

    strTemp = "winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore"

    '———————————————————————-
    ' Open the BcdStore.
    '———————————————————————-

    set objBCD = GetObject( strTemp )

    if Err.Number=0 then
    WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
    WScript.Quit(1)
    end if

    if not objBCD.OpenStore(strFilePath, objBcdStore ) then
    WScript.Echo "ERROR: Could not open the BCD system store."
    WScript.Quit(1)
    end if

    set objBCD = nothing
    '———————————————————————-
    ' Enumerate the Firmware Boot Manager.
    '———————————————————————-

    if not objBcdStore.EnumerateObjects(Firmware, colObjects ) then
    WScript.Echo "ERROR: objBcdStore.EnumberateObjects( Firmware ) failed."
    WScript.Quit(1)
    end if

    for each objFWBL in colObjects

    if not objFWBL.GetElement( BcdLibraryString_Description, objElement ) then
    WScript.Echo "ERROR: Firmware Boot Loader GetElement for " & Hex(BcdLibraryString_Description) & " failed."
    WScript.Quit(1)
    end if

    if not BcdStore.DeleteObjectobjFWBL.Id then
    WScript.Echo "ERROR: Could not delete Firmware Boot Loader Item: " & objElement.String
    WScript.Quit(1)
    end if

    WScript.Echo "Deleted Firmware Boot Loader Item: " & objElement.String

    next

    set objFWBL = nothing
    set objBcdStore = nothing
    set objLocator = nothing
    set objRootWMI = Nothing

    Right. Like I was saying in my post, I replaced all the quotes and double quotes, and also tried = 0 for that line. I just copy/pasted what you wrote and I still get the same error as when I tried it before:

    ERROR: GetObject(winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore) failed rc=0 

    ***** script completed - exit code: 1 *****

    Wednesday, September 24, 2014 4:58 PM
  • Right. Like I was saying in my post, I replaced all the quotes and double quotes, and also tried = 0 for that line. I just copy/pasted what you wrote and I still get the same error as when I tried it before:

    ERROR: GetObject(winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore) failed rc=0 

    ***** script completed - exit code: 1 *****

    No, you do not get the same error. Your initial error was "script.vbs (34, 15) Microsoft VBScript compilation error: Expected 'Then'". This was a syntax error that got flagged by the code interpreter. Your current error could be an execution error although I wonder whether it might be a typographical error. Have a look at your code. It reads:

    if Err.Number=0 then
      WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
      WScript.Quit(1)
    end if

    This does not make much sense. Since an error condition causes Err.Number to be non-zero, the code might have to read

    if Err.Number <> 0 then
      WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
      WScript.Quit(1)
    end if


    Wednesday, September 24, 2014 5:19 PM
  • Right. Like I was saying in my post, I replaced all the quotes and double quotes, and also tried = 0 for that line. I just copy/pasted what you wrote and I still get the same error as when I tried it before:

    ERROR: GetObject(winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore) failed rc=0 

    ***** script completed - exit code: 1 *****

    No, you do not get the same error. Your initial error was "script.vbs (34, 15) Microsoft VBScript compilation error: Expected 'Then'". This was a syntax error that got flagged by the code interpreter. Your current error could be an execution error although I wonder whether it might be a typographical error. Have a look at your code. It reads:

    if Err.Number=0 then
      WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
      WScript.Quit(1)
    end if

    This does not make much sense. Since an error condition causes Err.Number to be non-zero, the code might have to read

    if Err.Number <> 0 then
      WScript.Echo "ERROR: GetObject(" & strTemp & ") failed rc=" & Hex(Err.number) & " " & Err.Description
      WScript.Quit(1)
    end if


    Sorry, I should have been more clear. I mean I'm still getting the same error as when I originally tried using = 0 and <>0 as I said in my original post:

    I'm guessing that line 34 needs some kind of logical operator for the "If Err.number 0 then" statement. But, I can't figure out what it would be, i.e. <> 0, = 0, etc.

    Just to play around with it I tried both, and still get errors regarding line 35. So, I'm guessing something is really messed up around there.

    However, at least it's a different error this time:

    ERROR: Could not open the BCD system store.

    ***** script completed - exit code: 1 *****

    Any ideas on that one? It seems like it's at least progressing further in the script, but I'm not sure what's causing the error. I appreciate all the help. 

    Wednesday, September 24, 2014 7:57 PM
  • ERROR: Could not open the BCD system store.

    ***** script completed - exit code: 1 *****

    Any ideas on that one? It seems like it's at least progressing further in the script, but I'm not sure what's causing the error. I appreciate all the help.

    Sorry, I have never used WMI to open the BCD system store. I suggest you start googling.
    Wednesday, September 24, 2014 8:32 PM
  • Hi Yabos,

    I think you should use the correct tools for the right job. In this case I recommend BCDEdit, it is a tool bundled in the Windows 8.1 Operating System.

    BCDEdit Command-Line Options

    There is also guidance on this exact issue that you are having.

    Remove Duplicate Firmware Objects in BCD and NVRAM

    /Andrew


    Blog: http://scriptimus.wordpress.com

    Wednesday, September 24, 2014 10:26 PM
    Moderator
  • You should forget VBScript and WMI for this issue. (I've posted above.)

    Blog: http://scriptimus.wordpress.com

    Wednesday, September 24, 2014 10:28 PM
    Moderator
  • Hi Yabos,

    I think you should use the correct tools for the right job. In this case I recommend BCDEdit, it is a tool bundled in the Windows 8.1 Operating System.

    BCDEdit Command-Line Options

    There is also guidance on this exact issue that you are having.

    Remove Duplicate Firmware Objects in BCD and NVRAM

    /Andrew


    Blog: http://scriptimus.wordpress.com

    Sorry, that doesn't help me at all. The reason I want to use VBS and WMI is because we need to do this automatically every single time a machine is imaged using SCCM. Since we are using SCCM to automate our imaging process it would make little sense to manually use BCDedit on every single machine that comes through here. Also, I'm a bit surprised that a moderator for a scripting forum is telling me not to use scripting to automate a lengthy and time consuming process.

    That link you posted is a link I posted in my original post.


    • Edited by Yabos Thursday, September 25, 2014 1:50 PM
    Thursday, September 25, 2014 11:49 AM
  • ERROR: Could not open the BCD system store.

    ***** script completed - exit code: 1 *****

    Any ideas on that one? It seems like it's at least progressing further in the script, but I'm not sure what's causing the error. I appreciate all the help.

    Sorry, I have never used WMI to open the BCD system store. I suggest you start googling.
    I have been Googling, that's why I'm here. In the couple days I've been searching for answers I've only found the two references I made in my original post. Since one of the only two references I found even contains a method for scripting I figured I would bring it here so someone could help me figure out what's wrong with this script. 
    Thursday, September 25, 2014 11:50 AM
  • In general, this forum is for scripting questions, but it's not well-suited for "here's my long script. I don't know what's broken, so somebody needs to debug this and fix this for me." I would start with Andrew Barnes' advice and make sure you're using the right tool for the job. (No need to make things more difficult than they need to be or to reinvent the wheel.)

    If you want to pursue the question, I recommend writing a new script that contains only the absolute minimum amount of code needed to reproduce the problem. In the past, I have found that this process can often reveal the source of the problem. It also makes things much easier for others to digest the specifics of the problem and offer suggestions.

    If you're not well-versed in scripting, this is a great opportunity to learn.


    -- Bill Stewart [Bill_Stewart]

    Thursday, September 25, 2014 2:15 PM
    Moderator
  • In general, this forum is for scripting questions, but it's not well-suited for "here's my long script. I don't know what's broken, so somebody needs to debug this and fix this for me." I would start with Andrew Barnes' advice and make sure you're using the right tool for the job. (No need to make things more difficult than they need to be or to reinvent the wheel.)

    If you want to pursue the question, I recommend writing a new script that contains only the absolute minimum amount of code needed to reproduce the problem. In the past, I have found that this process can often reveal the source of the problem. It also makes things much easier for others to digest the specifics of the problem and offer suggestions.

    If you're not well-versed in scripting, this is a great opportunity to learn.


    -- Bill Stewart [Bill_Stewart]

    Without trying to get this post to devolve into something else, I would like to point out that I was asking for help in the correct direction on fixing this script. I do believe using a script is the correct tool for the job since using BCDedit in the command line would still involve exporting a file, manipulating that file, and then importing it again. Since we continually deploy machines throughout the year I don't believe doing this by hand is the best use of our time, and believe a script to be the best solution.

    I also didn't ask someone to fix the script for me. I'm asking for pointers in the correct direction. I am still trying to take apart the script and understand it, but would appreciate any help as to why I'm getting an error. I figured this would be the correct forum to post this question, and in fact checked the posting guidelines before I posted this question to make sure it would be allowed:

    "Questions like "I can't get this script to work that I've copied below, and here is the error I'm having" are welcome."

    Source: social.technet.microsoft.com/Forums/scriptcenter/en-US/a0def745-4831-4de0-a040-63b63e7be7ae/posting-guidelines?forum=ITCG 

    Additionally, and this is with Technet forums in general, I find that most of the time people responding don't seem to read the original post. In not only my forum posts, but a lot of others I read, people will tend to give answers like "Have you tried X?" when in the original post it CLEARLY states "I have tried X". /rant


    • Edited by Yabos Thursday, September 25, 2014 2:28 PM Grammar
    Thursday, September 25, 2014 2:27 PM
  • 'Questions like "I can't get this script to work that I've copied below, and here is the error I'm having" are welcome.'

    Yes, within reason. Asking others to digest a long script, which presumes we have your entire environment and have the resources to test, is a bit of a tall order. Keep in mind that the help here is free, and we're volunteers.

    Again: My advice is to write a short, self-contained example that contains only the minimum amount of code needed to reproduce the problem. Make it as easy as possible for respondents to have a script that fails for them in exactly the same way it fails for you.


    -- Bill Stewart [Bill_Stewart]

    • Proposed as answer by Bill_StewartModerator Wednesday, October 1, 2014 9:47 PM
    • Unproposed as answer by Yabos Thursday, October 2, 2014 12:27 PM
    Thursday, September 25, 2014 2:33 PM
    Moderator
  • Hi Yabos,

    Perhaps you misunderstood my post. You should defiantly automate this but not by downloading scripts off the internet that you don't understand. I was showing you a tool that you could easily use and understand. From there you could automate the process using bcdedit as the engine in your solution by creating what is called a 'wrapper'. 

    I understand your frustration as you just want the answer and a working coded solution so you can move on. However, we can only give you guidance here.

    My post above is how I would tackle this problem.



    Blog: http://scriptimus.wordpress.com

    Friday, September 26, 2014 10:06 AM
    Moderator