Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Use the following code to delete suspended service instances.
' terminate.vbs
' Enter terminate.vbs with no arguments from a command prompt for usage
' This script needs to be run under a user account that is a member of the BizTalk Administrators
' group. This script needs to be run on a machine that is configured with BizTalk administration
' tools.
dim objBtsWmiNS, objMsg, svcinsts, inst, msg, ndx, size, savemessages
Dim aryClassIDs()
Dim aryTypeIDs()
Dim aryInstanceIDs()
Dim aryHostNames()
Dim aryObjQueues()
Dim aryHostBatchSize()
Dim strKey2Instance
Dim strQuery2Msg
maxBatchSize = 200 'Terminate in batches. Max supported batch size is 2K-1 (2047)
On Error Resume Next
Dim objArgs: Set objArgs = WScript.Arguments
If ( objArgs.Count = 0 OR objArgs.Count > 2) Then
PrintUsage()
wscript.quit 0
End If
wmiQuery = ""
'ServiceStatus = 16 - 'Completed With Discarded Messages' in BizTalk Server 2004
'ServiceStatus = 32 - 'Suspended (not resumable)'
'ServiceStatus = 4 - 'Suspended (resumable)'
'ServiceClass = 64 - 'Routing Failure Report'
'ErrorId = "0xC0C01B4C" - is how 'Completed With Discarded Messages' are exposed in BizTalk Server 2009
If (objArgs(0) = "-Z" OR objArgs(0) = "-z") Then
wmiQuery = "select * from MSBTS_serviceinstance where ServiceStatus=16"
End If
If (objArgs(0) = "-A" or objArgs(0) = "-a") Then
wmiQuery = "select * from MSBTS_serviceinstance where ServiceStatus=4 OR ServiceStatus=32 OR ServiceStatus=16 OR ErrorId='0xC0C01B4C' OR ServiceClass=64"
End If
If (objArgs(0) = "-SR" or objArgs(0) = "-sr") Then
wmiQuery = "select * from MSBTS_serviceinstance where ServiceStatus=4"
End If
If (objArgs(0) = "-SNR" or objArgs(0) = "-snr") Then
wmiQuery = "select * from MSBTS_serviceinstance where ServiceStatus=32"
End If
If (objArgs(0) = "-DIS" or objArgs(0) = "-dis") Then
wmiQuery = "select * from MSBTS_serviceinstance where ServiceClass=32 AND ServiceStatus=8"
'ServiceClass = 32 'Isolated Adapter
'ServiceStatus = 8 'Dehydrated
End If
saveMessagesBeforeTermination = True
If ( objArgs.Count > 1) Then
If (objArgs(1) = "-NOSAVE" OR objArgs(1) = "-nosave") Then
saveMessagesBeforeTermination = False
Else
PrintUsage()
wscript.quit 0
End If
End If
If(wmiQuery = "") Then
PrintUsage()
wscript.quit 0
End If
wscript.echo "-->Connecting to BizTalk WMI namespace"
Set objBtsWmiNS = GetObject("WinMgmts:{impersonationLevel=impersonate, (security)}\\.\root\MicrosoftBizTalkServer")
If Err <> 0 Then
CheckWMIError
wscript.quit 0
End If
wscript.echo "-->Getting BizTalk host collection"
Set hosts = objBtsWmiNS.ExecQuery("select * from MSBTS_HostSetting")
If Err <> 0 Then
CheckWMIError
wscript.quit 0
End If
hostCount = hosts.count
ReDim aryHostNames(hostCount - 1)
ReDim aryObjQueues(hostCount - 1)
ReDim aryHostBatchSize(hostCount - 1)
wscript.echo "-->Retrieve BizTalk host names and loading host queues"
ndx = 0
For Each host in hosts
wscript.echo "Found host " & host.Properties_("Name")
aryHostNames(ndx) = host.Properties_("Name")
Set aryObjQueues(ndx) = objBtsWmiNS.Get("MSBTS_HostQueue.HostName=""" & aryHostNames(ndx) & """")
If Err <> 0 Then
CheckWMIError
wscript.quit 0
End If
ndx = ndx + 1
Next
wscript.echo "-->Getting collection of service instances"
Set svcinsts = objBtsWmiNS.ExecQuery(wmiQuery)
ReDim aryClassIDs(hostCount, maxBatchSize-1)
ReDim aryTypeIDs(hostCount, maxBatchSize-1)
ReDim aryInstanceIDs(hostCount, maxBatchSize-1)
'Iterate through instances and save them in host-specific arrays.
'Terminate instances from host-specific array when array gets to a maxBatchSize
wscript.echo "-->Start iterating service instances"
totalCount = 0
saveMessages = saveMessagesBeforeTermination
For Each inst in svcinsts
saveMessagesBeforeTermination = saveMessages
wscript.echo "Found suspended instance """ & inst.Properties_("ServiceName") & """ on host " & inst.Properties_("HostName")
'Resolve host index
For hostIdx = 0 To hostCount-1
If aryHostNames(hostIdx) = inst.Properties_("HostName") Then
Exit For
End If
Next
'16 is an internal service class that cannot be terminated
If 16 = inst.Properties_("ServiceClass") Then
wscript.echo "Skipping BizTalk internal service instances (they cannot be terminated anyway)"
Else
'64 is a routing failure report and doesn't have messages that can be saved
If 64 = inst.Properties_("ServiceClass") Or 16 = inst.Properties_("ServiceClass") Then
saveMessagesBeforeTermination = False
End If
errorCountSavingMessages = 0
If saveMessagesBeforeTermination Then
strQuery2Msg = "select * from MSBTS_MessageInstance where ServiceInstanceID=""" & inst.Properties_("InstanceId") & """"
Set msgInsts = objBtsWmiNS.ExecQuery(strQuery2Msg)
For Each msg in msgInsts
msg.SaveToFile "C:\Temp"
If Err <> 0 Then
CheckWMIError
wscript.echo "Failed to save MSBTS_MessageInstance"
wscript.echo Err.Description & Err.Number
errorCountSavingMessages = errorCountSavingMessages + 1
Else
wscript.echo "Saved message " & msg.Properties_("MessageInstanceID")
End If
Next
End If
If 0 = errorCountSavingMessages Then 'Only terminate when we had no problems saving messages
aryClassIDs(hostIdx, aryHostBatchSize(hostIdx)) = inst.Properties_("ServiceClassId")
aryTypeIDs(hostIdx, aryHostBatchSize(hostIdx)) = inst.Properties_("ServiceTypeId")
aryInstanceIDs(hostIdx, aryHostBatchSize(hostIdx)) = inst.Properties_("InstanceId")
aryHostBatchSize(hostIdx) = aryHostBatchSize(hostIdx) + 1 'Keep track of newly added instace for that host
Else
wscript.echo "Skipping the instance since couldn't save its messages"
End If
totalCount = totalCount + 1
If(aryHostBatchSize(hostIdx) = maxBatchSize) Then
TerminateAccumulatedInstacesForHost hostIdx
End If
End If
Next
' Delete whatever is left
For hostIdx = 0 To hostCount-1
If aryHostBatchSize(hostIdx) > 0 Then
TerminateAccumulatedInstacesForHost hostIdx
End If
Next
wscript.echo "SUCCESS> " & totalCount & " instances were found and attempted to be terminated"
Sub TerminateAccumulatedInstacesForHost(hostIdx)
wscript.echo "Sending termination request for host " & aryHostNames(hostIdx) & " service instances"
Dim aryClassIDs4Host()
Dim aryTypeIDs4Host()
Dim aryInstanceIDs4Host()
ReDim aryClassIDs4Host(aryHostBatchSize(hostIdx)-1)
ReDim aryTypeIDs4Host(aryHostBatchSize(hostIdx)-1)
ReDim aryInstanceIDs4Host(aryHostBatchSize(hostIdx)-1)
For i = 0 to aryHostBatchSize(hostIdx)-1
aryClassIDs4Host(i) = aryClassIDs(hostIdx, i)
aryTypeIDs4Host(i) = aryTypeIDs(hostIdx, i)
aryInstanceIDs4Host(i) = aryInstanceIDs(hostIdx, i)
Next
aryObjQueues(hostIdx).TerminateServiceInstancesByID aryClassIDs4Host, aryTypeIDs4Host, aryInstanceIDs4Host
CheckWMIError
aryHostBatchSize(hostIdx) = 0
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 CheckWMIError()
If Err <> 0 Then
On Error Resume Next
Dim strErrDesc: strErrDesc = Err.Description
Dim ErrNum: ErrNum = Err.Number
Dim WMIError : Set WMIError = CreateObject("WbemScripting.SwbemLastError")
If (TypeName(WMIError) = "Empty" ) Then
wscript.echo strErrDesc & " (HRESULT: " & Hex(ErrNum) & ")."
Else
wscript.echo WMIError.Description & "(HRESULT: " & Hex(ErrNum) & ")."
Set WMIError = nothing
End If
'wscript.quit 0
End If
End Sub
Sub PrintUsage()
wscript.echo "Usage:"
wscript.echo "cscript Terminate.vbs < -Z | -A | -DIS | -SR | -SNR > [-nosave]"
wscript.echo
wscript.echo " -Z terminates all ""Zombie"" instances (e.g. completed with discarded messages)"
wscript.echo " -A terminates all suspended and zombie instances as well as all routing failure reports"
wscript.echo " -SR terminates suspended resumable instances only"
wscript.echo " -SNR terminates suspended non-resumable instances only"
wscript.echo " -DIS terminates all dehydrated 'isolated adapter' instances"
wscript.echo " -nosave terminates instances without saving messages they reference"
wscript.echo " Default action is to save instances to the C:\Temp folder on the local computer"
wscript.echo
wscript.echo " Ensure that the C:\Temp folder exists before running terminate if you want to save instances"
wscript.echo
wscript.echo " Example: cscript Terminate.vbs -z -nosave"
wscript.echo
End Sub