5 Replies Latest reply on Nov 6, 2017 6:16 AM by Alessandro Ghezzi

    Script to Unlock BCM Agent Service...

    Eric Christensen
      Share This:

      If any of you are running v12.5 and have taken advantage of the agent service locking feature, you may be in my shoes of running into issues with it. Namely, if you want to restart the agent service with an OpRule, it will fail if the service is still locked.

       

      Unfortunately, there is no out-of-the-box way to quickly unlock the service. You can run the OpRule step to disable the lock, but this requires the computer to be restarted in order for the new setting to take effect (confirmed by support).

       

      Taking a look at the only available means of unlocking the agent (https://localhost:1610/service), I decided to figure out how the web page was unlocking the agent. Ultimately, this is just a RESTful API call, so I figured I would give it a shot to unlock the agent via a script. Since this does work beautifully, I decided to share for anybody else this may help.

       

      This is a single-computer script that prompts for the computer you wish to unlock the agent on, but it could easily be adapted to just unlock the agent on the local computer (strComputer = "."). When configured for the local computer, you could create an OpRule with this script to unlock 1 or thousands of agents at the same time without having to restart the machines.

       

      I hope this is useful for others. Sorry if the formatting does not transfer over well. This editor does not like TABs, so I cleaned it up as best I could. Copy and paste into NP++, clean it up by replacing (Ctrl+H) every four spaces with a tab if you choose, then save as .VBS.

       

      '===============================================================================
      ' Script:    unlockBCMAgent.vbs
      ' Created:    07.01.2016
      ' Updated:    10.21.2016
      ' Author:    Eric.Christensen@*********.com
      ' Purpose:    Proof of concept sample to make RESTful calls to BMC
      '            Client Management Web API
      ' Usage:    Enter username, password, and BCM unlock password below, then
      '            just double-click the VBScript and enter a computer name
      '===============================================================================
      
      '\\ BEST PRACTICE TO REQUIRE DECLARATIONS
      Option Explicit
      
      
      '\\ MAKE SURE WE ARE RUNNING ELEVEATED
      If Not isElevated Then Elevate
      
      
      '\\ GET THE COMPUTER NAME FROM THE USER RUNNING THE SCRIPT
      Dim Valid
      Do Until Valid
          Dim strComputer : strComputer = inputBox( _
              "Please enter the name of the computer to unlock the BMC Agent:", _
              "Enter Computer Name", _
              "ComputerName")
      
          If strComputer = "ComputerName" Then
              msgBox "Please enter a valid computer name.", 0+16, "Invalid"
          ElseIf strComputer = "" Then
              WScript.Quit(1223)
          Else
              Valid = True
          End If
      Loop
      
      
      '\\ ENTER USERNAME AND PASSWORD DETAILS, AND AGENT NAME IF RESTARTING
      Dim userName   : userName   = ""
      Dim passWord   : passWord   = ""
      Dim unlockPass : unlockPass = ""
      Dim svcName    : svcName    = "BMC Client Management Agent"
      
      
      '\\ MAKE SURE THE ABOVE DETAILS ARE NOT BLANK
      If userName = "" or passWord = "" or unlockPass = "" Then
          msgBox _
              "Username, password, and BMC Unlock password cannot be left empty!" & vbCrLf & vbCrLf & _
              "Please edit the script and include the above details and try again.", 0+48, "Details Required!"
          WScript.Quit(1)
      End If
      
      
      '\\ ENTER SERVER DETAILS
      Dim strServer  : strServer  = "https://" & strComputer & ":1611"
      Dim strBaseURI : strBaseURI = strServer & "/ws/1/"
      
      
      '\\ ENTER DETAILS FOR THE REQUEST
      Dim strMethod, strReqURL, strPostBody
      strMethod   = "POST"
      strReqURL   = "app/core/service"
      strPostBody = "{""password"": """ & unlockPass & """, ""action"": ""Unlock""}"
      
      
      '\\ CALL FUNCTION TO SEND REST REQUEST
      Dim objReturn : Set objReturn = callRESTAPI( _
          strMethod, strBaseURI & strReqURL, strPostBody, userName, passWord)
      
      
      '\\ UNCOMMENT THE NEXT LINE IF YOU WOULD LIKE TO RESTART THE AGENT
      'restartSvc strComputer
      
      
      '\\ PARSE THE RETURN AND ECHO ACCORDINGLY
      If objReturn.Status = 200 Then
          If Not LCase(objReturn.ResponseText) = "null" Then
              If inStr(objReturn.ResponseText, """code"":12") Then
                  msgBox "Cannot unlock the agent service due to a bad password or a communication problem with the server.", 0+16, "Service Unlock Failed!"
              ElseIf inStr(objReturn.ResponseText, """code"":13") Then
                  msgBox "The password cannot be empty", 0+16, "Service Unlock Failed!"
              End If
          Else
              msgBox "The BMC Client Management agent service was successfully unlocked on '" & strComputer & "'.", 0+64, "Agent Service Unlocked"
          End If
      Else
          msgBox _
              "The BMC Agent Service unlock request failed. Details:" & vbCrLf & vbCrLf & _
              "Status Code:    " & objReturn.status & " " & objReturn.statusText &  vbCrLf & _
                                  vbCrLf & _
              "Response Text:  " & objReturn.ResponseText, 0+16, "Agent Unlock Request Failed"
      End If
      
      
      
      '====================================================================================================
      '\\ FUNCTION TO MAKE THE REST CALL
      '====================================================================================================
      Function callRESTAPI(strMethod, strURL, strPostBody, userName, passWord)
          '\\ USE CUSTOM ERROR HANDLING HERE
          On Error Resume Next
      
          '\\ CREATE THE MSXML2 OBJECT
          Dim restReq : Set restReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
      
          '\\ SINCE THE BMC CERTIFICATE IS NOT TRUSTED, BYPASS THE TRUST CHECK
          restReq.setOption 2, 13056 'http://msdn.microsoft.com/en-us/library/ms763811(v=VS.85).aspx
      
          '\\ OPEN, SET HEADERS, AND SEND REQUEST
          restReq.open strMethod, strURL, False, userName, passWord
          restReq.setRequestHeader "Accept", "application/json, text/javascript, */*; q=0.01"
          restReq.setRequestHeader "Accept-Encoding", "gzip, deflate"
          restReq.setRequestHeader "Accept-Language", "en-US"
          restReq.setRequestHeader "Authorization", "Basic TlRBTVJcZWFkbWluOkludGVncmExISE="
          restReq.send strPostBody
      
          If err Then
              msgBox err.Description, 0+16, "Error with Request"
              WScript.Quit
          End If
      
          Set callRESTAPI = restReq
          Set restReq = Nothing
      
          '\\ REVERT BACK TO NORMAL ERROR HANDLING
          On Error Goto 0
      End Function
      
      
      '====================================================================================================
      '\\ FUNCTION TO RESTART AGENT SERVICE
      '====================================================================================================
      Function restartSvc(strComputer)
          Dim objWMI, objSVC
          Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
          Set objSvc = objWMI.Get("Win32_Service.Name='" & svcName & "'")
      
          '\\ STOP THEN START THE SERVICE
          Dim objOutParams
          Set objOutParams = objWMI.ExecMethod("Win32_Service.Name='" & svcName & "'", "StopService")
          Set objOutParams = objWMI.ExecMethod("Win32_Service.Name='" & svcName & "'", "StartService")
      End Function
      
      
      '=====================================================================================================
      '\\ CHECKS IF THE SCRIPT IS RUNNING ELEVATED (UAC)
      '=====================================================================================================
      Function isElevated
          Dim objShell, whoami, whoamiOutput
          Dim strWhoamiOutput
          Set objShell = CreateObject("WScript.Shell")
          Set whoami   = objShell.Exec("whoami /groups")
          Set whoamiOutput = whoami.StdOut
          strWhoamiOutput = whoamiOutput.ReadAll
          If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then 
              isElevated = True
          Else
              isElevated = False
          End If
      End Function
      
      
      
      '=====================================================================================================
      '\\ RE-RUNS THE PROCESS PROMPTING FOR PRIV ELEVATION ON RE-RUN
      '=====================================================================================================
      Sub Elevate
          '\\ DECALRE IF NEED TO RUN IN C OR W SCRIPT
          Dim interpreter : interpreter = "wscript.exe"
      
          '\\ START A NEW INSTANCE WITH AN ELEVATION PROMPT FIRST
          Dim shellApp : Set shellApp = CreateObject("Shell.Application")
          shellApp.ShellExecute interpreter, Chr(34) & WScript.ScriptFullName & Chr(34), "", "runas", 0
      
          '\\ END THE NON-ELEVATED INSTANCE
          WScript.Quit
      End Sub