none
bts2013 r2 scom automatic restart of receive location

    Question

  • What I used to have (bts2006r2) and want again...

    If due to some networkerror a receivelocation shuts down, I could like to have it automatically restarted.

    Our old scom(mom) environment was able to get the information of the receivelocation that shutted down from the windows-event  and restarted it (using vbs) as a remedy.

    Now I want our new scom environment to do the same...get the name of the receivelocation from the windowsevent and restart it  (using powershell will be most logic I guess)

    Has anyone already done this?   

    And what I don't want i:  when I disable a receivelocation myself , it shouldn't restart of course.

    (I should say I'm not the one implementing the scom so I have no knowledge here, I just expect something obvious from it :-) )


    Kind regards Isabelledc

    Tuesday, March 7, 2017 1:54 PM

Answers

  • Hi, you can use the following WMI script and have that scheduled in windows scheduler. Under Actions pick : Start a program and in program/script set the path of the WMI script location.

    You can have the scheduler run periodically or tie the trigger of the windows scheduler to the event number which gets generated  in application log when a RL shuts down.

    Option Explicit
    
    MonitorArtifacts
    
    Sub MonitorArtifacts()
    
    	'error handling is done by explicity checking the err object rather than using
    	'the VB ON ERROR construct, so set to resume next on error.
    	on error resume next
    
        const ForReading = 1, ForWriting = 2, ForAppending = 8  
    
    	Dim fso, MyFile, RLInstSet, SPInstSet, OrchInstSet
        Dim Inst, SPInst, OrchInst
    	Dim strQuerySP, strQueryRL, strQueryOrch
    	Dim folderPath, DateInfo
    
        Dim strMessage 
        
        strMessage = ""
    
        DateInfo = DateInfo & Date
        DateInfo = Replace(DateInfo, "/", "")
    
        folderPath = "Path of the folder where you will keep the WMI script"
        folderPath = CheckFolderExists(folderPath)
    
    
    	strQuerySP = "SELECT * FROM MSBTS_SendPort WHERE  Status <> 3"
    	strQueryRL = "SELECT * FROM MSBTS_ReceiveLocation WHERE  IsDisabled = ""True"""
    	strQueryOrch = "SELECT * FROM MSBTS_Orchestration WHERE  OrchestrationStatus <> 4"
    	
    	set RLInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQueryRL)
    	set SPInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQuerySP)
    	set OrchInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQueryOrch)
    	
        Set fso = CreateObject("Scripting.FileSystemObject")
    	Set MyFile = fso.OpenTextFile(folderPath, ForAppending, True)
    
    	'Check for error condition before continuing.
    	If Err <> 0	Then
    		PrintWMIErrorThenExit Err.Description, Err.Number
    	End If
    
    	'Report on number of receive locations found and list each one.
        MyFile.WriteLine "---------------------------------" & Now() & "---------------------------------------"
    	MyFile.WriteLine "A Total of " & RLInstSet.Count & " Receive Locations were disabled."
    	MyFile.WriteLine "A Total of " & SPInstSet.Count & " Send Ports were Stopped."
    	MyFile.WriteLine "A Total of " & OrchInstSet.Count & " Orchestrations were Stopped." 
    	
        If RLInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & RLInstSet.Count & " Receive Locations were disabled." & vbCrLf & vbCrLf
    		For Each Inst In RLInstSet
    			If Inst.IsDisabled = "True" Then
    				MyFile.WriteLine "Receive Location Name  : " & Inst.Name
    				MyFile.WriteLine "  Disabled             : " & Inst.IsDisabled
    				MyFile.WriteLine "  Pipeline Name        : " & Inst.PipelineName
    				MyFile.WriteLine "  Receive Port Name    : " & Inst.ReceivePortName
    				MyFile.WriteLine "  Inbound Transport URL: " & Inst.InboundTransportURL
    				
    				If Inst.Name = "BatchControlMessageRecvLoc" Then
    					MyFile.WriteLine "No Need to enable this receive location" & vbCrLf
    				Else
    					Inst.Enable
    					If Err <> 0	Then
    						PrintWMIErrorThenExit Err.Description, Err.Number
    					End If
    					MyFile.WriteLine "The Receive Location was successfully enabled." & vbCrLf
    					strMessage = strMessage & Inst.Name &" was successfully enabled." & vbCrLf 
    				End If
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If 
    
    	If SPInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & SPInstSet.Count & " Send Ports are stopped." & vbCrLf & vbCrLf
    		For Each SPInst In SPInstSet
    			If SPInst.Status <> 3 Then
    				MyFile.WriteLine "Send Port Name         : " & SPInst.Name
    				MyFile.WriteLine "  Status               : " & SPInst.Status
    				
    				SPInst.Start
    
    				If Err <> 0	Then
    					PrintWMIErrorThenExit Err.Description, Err.Number
    				End If
    
    				MyFile.WriteLine "The Send Port " & SPInst.Name &" was successfully started." & vbCrLf
                    strMessage = strMessage & SPInst.Name &" was successfully enabled." & vbCrLf
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If
    	
    	If OrchInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & OrchInstSet.Count & " Orchestrations are stopped." & vbCrLf & vbCrLf
    		For Each OrchInst In OrchInstSet
    			If OrchInst.OrchestrationStatus <>4 Then
    				MyFile.WriteLine "Orchestration Name     : " & OrchInst.Name
    				MyFile.WriteLine "  Status               : " & OrchInst.OrchestrationStatus
    				
    				Dim strSearch, strSeachString
    				strSearch = "Microsoft.BizTalk.Edi"
    				strSeachString = OrchInst.Name
    				
    				If InStr(1, strSeachString, strSearch) > 0 Then
    					MyFile.WriteLine "The Orchestration " & OrchInst.Name &" is not required to be started." & vbCrLf
    				Else
    					If OrchInst.OrchestrationStatus = 2 Then
    						OrchInst.Enlist
    					End If
    					
    					OrchInst.Start
    					If Err <> 0	Then
    						PrintWMIErrorThenExit Err.Description, Err.Number
    					End If
    					
    					MyFile.WriteLine "The Orchestration " & OrchInst.Name &" was successfully started." & vbCrLf
    					strMessage = strMessage & OrchInst.Name &" was successfully enabled." & vbCrLf
    				End If
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If
    	
        MyFile.WriteLine "----------------------------------- End ---------------------------------------" & vbCrLf
    	MyFile.Close		
    
        
    
    End Sub 
        
    'This subroutine deals with all errors using the WbemScripting object.  Error descriptions
    'are returned to the user by printing to the console.
    Sub	PrintWMIErrorThenExit(strErrDesc, ErrNum)
    	On Error Resume	Next
    	Dim	objWMIError	: Set objWMIError =	CreateObject("WbemScripting.SwbemLastError")
    
    	If ( TypeName(objWMIError) = "Empty" ) Then
    		wscript.echo strErrDesc & " (HRESULT: "	& Hex(ErrNum) & ")."
    	Else
    		wscript.echo objWMIError.Description & "(HRESULT: "	& Hex(ErrNum) & ")."
    		Set objWMIError	= nothing
    	End	If
    	
    	'bail out
    	wscript.quit 0
    End	Sub
    
    Function CheckFolderExists(folderPath)
        On Error Resume	Next
    
        Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
    
        If (fso.FolderExists(folderPath)) Then
            folderPath = folderPath & "\MonitorLogs.txt"
        Else
            fso.CreateFolder(folderPath)
            folderPath = folderPath & "\MonitorLogs.txt"
        End If
    
        CheckFolderExists = folderPath
    
    End Function

    Regards PK: Please mark the reply as answer or vote it up, as deemed fit.




    Tuesday, March 7, 2017 3:14 PM

All replies

  • Hi, you can use the following WMI script and have that scheduled in windows scheduler. Under Actions pick : Start a program and in program/script set the path of the WMI script location.

    You can have the scheduler run periodically or tie the trigger of the windows scheduler to the event number which gets generated  in application log when a RL shuts down.

    Option Explicit
    
    MonitorArtifacts
    
    Sub MonitorArtifacts()
    
    	'error handling is done by explicity checking the err object rather than using
    	'the VB ON ERROR construct, so set to resume next on error.
    	on error resume next
    
        const ForReading = 1, ForWriting = 2, ForAppending = 8  
    
    	Dim fso, MyFile, RLInstSet, SPInstSet, OrchInstSet
        Dim Inst, SPInst, OrchInst
    	Dim strQuerySP, strQueryRL, strQueryOrch
    	Dim folderPath, DateInfo
    
        Dim strMessage 
        
        strMessage = ""
    
        DateInfo = DateInfo & Date
        DateInfo = Replace(DateInfo, "/", "")
    
        folderPath = "Path of the folder where you will keep the WMI script"
        folderPath = CheckFolderExists(folderPath)
    
    
    	strQuerySP = "SELECT * FROM MSBTS_SendPort WHERE  Status <> 3"
    	strQueryRL = "SELECT * FROM MSBTS_ReceiveLocation WHERE  IsDisabled = ""True"""
    	strQueryOrch = "SELECT * FROM MSBTS_Orchestration WHERE  OrchestrationStatus <> 4"
    	
    	set RLInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQueryRL)
    	set SPInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQuerySP)
    	set OrchInstSet = GetObject ("winmgmts:\root\MicrosoftBizTalkServer").ExecQuery(strQueryOrch)
    	
        Set fso = CreateObject("Scripting.FileSystemObject")
    	Set MyFile = fso.OpenTextFile(folderPath, ForAppending, True)
    
    	'Check for error condition before continuing.
    	If Err <> 0	Then
    		PrintWMIErrorThenExit Err.Description, Err.Number
    	End If
    
    	'Report on number of receive locations found and list each one.
        MyFile.WriteLine "---------------------------------" & Now() & "---------------------------------------"
    	MyFile.WriteLine "A Total of " & RLInstSet.Count & " Receive Locations were disabled."
    	MyFile.WriteLine "A Total of " & SPInstSet.Count & " Send Ports were Stopped."
    	MyFile.WriteLine "A Total of " & OrchInstSet.Count & " Orchestrations were Stopped." 
    	
        If RLInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & RLInstSet.Count & " Receive Locations were disabled." & vbCrLf & vbCrLf
    		For Each Inst In RLInstSet
    			If Inst.IsDisabled = "True" Then
    				MyFile.WriteLine "Receive Location Name  : " & Inst.Name
    				MyFile.WriteLine "  Disabled             : " & Inst.IsDisabled
    				MyFile.WriteLine "  Pipeline Name        : " & Inst.PipelineName
    				MyFile.WriteLine "  Receive Port Name    : " & Inst.ReceivePortName
    				MyFile.WriteLine "  Inbound Transport URL: " & Inst.InboundTransportURL
    				
    				If Inst.Name = "BatchControlMessageRecvLoc" Then
    					MyFile.WriteLine "No Need to enable this receive location" & vbCrLf
    				Else
    					Inst.Enable
    					If Err <> 0	Then
    						PrintWMIErrorThenExit Err.Description, Err.Number
    					End If
    					MyFile.WriteLine "The Receive Location was successfully enabled." & vbCrLf
    					strMessage = strMessage & Inst.Name &" was successfully enabled." & vbCrLf 
    				End If
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If 
    
    	If SPInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & SPInstSet.Count & " Send Ports are stopped." & vbCrLf & vbCrLf
    		For Each SPInst In SPInstSet
    			If SPInst.Status <> 3 Then
    				MyFile.WriteLine "Send Port Name         : " & SPInst.Name
    				MyFile.WriteLine "  Status               : " & SPInst.Status
    				
    				SPInst.Start
    
    				If Err <> 0	Then
    					PrintWMIErrorThenExit Err.Description, Err.Number
    				End If
    
    				MyFile.WriteLine "The Send Port " & SPInst.Name &" was successfully started." & vbCrLf
                    strMessage = strMessage & SPInst.Name &" was successfully enabled." & vbCrLf
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If
    	
    	If OrchInstSet.Count > 0 Then
            strMessage = strMessage & "A Total of " & OrchInstSet.Count & " Orchestrations are stopped." & vbCrLf & vbCrLf
    		For Each OrchInst In OrchInstSet
    			If OrchInst.OrchestrationStatus <>4 Then
    				MyFile.WriteLine "Orchestration Name     : " & OrchInst.Name
    				MyFile.WriteLine "  Status               : " & OrchInst.OrchestrationStatus
    				
    				Dim strSearch, strSeachString
    				strSearch = "Microsoft.BizTalk.Edi"
    				strSeachString = OrchInst.Name
    				
    				If InStr(1, strSeachString, strSearch) > 0 Then
    					MyFile.WriteLine "The Orchestration " & OrchInst.Name &" is not required to be started." & vbCrLf
    				Else
    					If OrchInst.OrchestrationStatus = 2 Then
    						OrchInst.Enlist
    					End If
    					
    					OrchInst.Start
    					If Err <> 0	Then
    						PrintWMIErrorThenExit Err.Description, Err.Number
    					End If
    					
    					MyFile.WriteLine "The Orchestration " & OrchInst.Name &" was successfully started." & vbCrLf
    					strMessage = strMessage & OrchInst.Name &" was successfully enabled." & vbCrLf
    				End If
    			End If
    		next
            strMessage = strMessage & vbCrLf 
    	End If
    	
        MyFile.WriteLine "----------------------------------- End ---------------------------------------" & vbCrLf
    	MyFile.Close		
    
        
    
    End Sub 
        
    'This subroutine deals with all errors using the WbemScripting object.  Error descriptions
    'are returned to the user by printing to the console.
    Sub	PrintWMIErrorThenExit(strErrDesc, ErrNum)
    	On Error Resume	Next
    	Dim	objWMIError	: Set objWMIError =	CreateObject("WbemScripting.SwbemLastError")
    
    	If ( TypeName(objWMIError) = "Empty" ) Then
    		wscript.echo strErrDesc & " (HRESULT: "	& Hex(ErrNum) & ")."
    	Else
    		wscript.echo objWMIError.Description & "(HRESULT: "	& Hex(ErrNum) & ")."
    		Set objWMIError	= nothing
    	End	If
    	
    	'bail out
    	wscript.quit 0
    End	Sub
    
    Function CheckFolderExists(folderPath)
        On Error Resume	Next
    
        Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
    
        If (fso.FolderExists(folderPath)) Then
            folderPath = folderPath & "\MonitorLogs.txt"
        Else
            fso.CreateFolder(folderPath)
            folderPath = folderPath & "\MonitorLogs.txt"
        End If
    
        CheckFolderExists = folderPath
    
    End Function

    Regards PK: Please mark the reply as answer or vote it up, as deemed fit.




    Tuesday, March 7, 2017 3:14 PM
  • Hi 

    So you need couple of things here-

    1) Powershell that can parse ReceiveLocation shutdown events (Event ID - 5649). You can use the Get-EventLog cmdlet to do this.

    2) The actual Powershell code that would take the output string(Receive Location name) from (1) and act upon it-

    https://msdn.microsoft.com/en-us/library/aa561437.aspx?f=255&MSPPError=-2147217396

    https://phvbaars.wordpress.com/2015/07/30/powershell-script-to-enabledisable-receive-location/



    Thanks Arindam

    Tuesday, March 7, 2017 3:50 PM
    Moderator
  • Dear Isabelledc,

    I had same problem and I wrote below script and its working perfect.

    When any receive location went down it sends an email and when it brings that receive location up it again sends a confirmation email.

    This script is for SQL server agent:

    # Import external assembly and create a new object
    [void][System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
    $Catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
    #BizTalk Config
    $Catalog.ConnectionString = "SERVER=.;DATABASE=BizTalkMgmtDb;Integrated Security=SSPI"  #connectionstring to the mgmt db
    $hostname = "BizTalkServerApplication" #hostname for the JMS host
    $rcvLocation = "GetNewConfirmReceiveLocation" #receive location
    #Email Config
    $emailFrom = "Bz_admin@XXXX.com.sa"
    $emailTo = "mmasood@XXXX.com.sa"
    $emailSubject  = "Receive Location 'GetNewConfirmReceiveLocation' -Service: 8 on BIZTALK PROD is DOWN"
    $emailSubject2 = "Receive Location 'GetNewConfirmReceiveLocation' -Service: 8 BIZTALK PROD is UP"
    $emailServer ="Mail.XXXX.com.sa"
    #Function to retrieve the status of the specific receive location
    function getStatus(){
    foreach ($receivePort in $catalog.ReceivePorts)
       {
           foreach($receiveLoc in $receivePort.ReceiveLocations  | Where {$_.Name -eq$rcvLocation}){
                return $receiveLoc.Enable

           }

       }
    }
    #Function to enable the receive location
    function enableReceiveLocation(){
         #$location.Enable()
            $recvloc = get-wmiobject MSBTS_ReceiveLocation `
           -namespace 'root\MicrosoftBizTalkServer' `
           -filter "Name='GetNewConfirmReceiveLocation'"
           [void]$recvloc.Enable()
           [void]$Catalog.Refresh()
       }
    #Function to sends an error email
    function sendEmail(){
    $message = "GetNewConfirmReceiveLocation is Down. Trying to restart the host and enabling the receive location"
        $smtp=new-object Net.Mail.SmtpClient($emailServer)
        $smtp.Send($emailFrom$emailTo$emailSubject$message)
     }
    #Function to sends an ok email
    function sendEmailok(){
    $messagee = "GetNewConfirmReceiveLocation is brought up successfully"
    $smtp=new-object Net.Mail.SmtpClient($emailServer)
    $smtp.Send($emailFrom$emailTo$emailSubject2$messagee)
    }
    $keeplooping = $true
    $isok = $false
    $i = 0;
    #check status 5 times
    $isEnabled = getStatus
    if($isEnabled -eq $false){
    while($keeplooping -eq $true){
    $isEnabled = getStatus
    if($isEnabled -eq $false){
    sendEmail
    #Restart host
    Restart-Service -Displayname "BizTalk Service BizTalk Group : ${hostname}"
    #wait a few seconds
    Start-Sleep -s 30  
    #Enable receive location
    enableReceiveLocation
    #Wait 5 minutes
    Start-Sleep -s 30 
    $i++;
            if($i -gt 4){
                $keeplooping = $false
            }
        }else{
            sendEmailok
            $keeplooping = $false
            $isok = $true
        }
    }

    This PowerShell script will check the status of a receive location if receive location is already enabled script will do nothing. If the receive location is disabled then script will first send an error email stating receive location is down\disabled then tries 3 attempts to restart the host instance and enabling the receive location. Once host instance restarted successfully and port enabled successfully it will again send a successfully email stating the receive location XXXXXXXXX is enabled successfully.

    After testing and verification of above script then we may put this under windows scheduler. OR put the code in SQL Agent.

    -Muhammad Masood

    Sunday, March 12, 2017 8:57 AM