Share via


PowerShell Script To Monitor Biztalk Services Across Multiple Groups

Problem Scenario

One of many duties of a Biztalk Admin is to monitor the status of the Biztalk Services across all the BizTalk Environments. These services are but not limited to :

  • Biztalk Host Instances
  • Biztalk Rule Engine
  • IIS Admin Service
  • World Wide Web Publishing Service
  • SQL Server Service
  • SQL Agent Service
  • Integration Services
  • RuleUpdate Service
  • MSDTC service.

Checking the status of the service on a Single Multi-Server Environment is a manageable task, but what if the number of environments is large, then doing this manually becomes cumbersome and boring and can lead to errors.

Solution

PowerShell is a very powerful tool in the arsenal of an Administrator. Using Power Shell the task becomes automated and can be completed within minutes as compared to an hour or two long task if done manually.

Design

The PowerShell uses a config file which is as shown below.

<Configuration> 
  <Servers> 
    <Server> 
      <Name>LocalHost</Name> 
      <Type>App</Type> 
    </Server> 
    <Server> 
      <Name>LocalHost</Name> 
      <Type>App</Type> 
    </Server> 
    <Server> 
      <Name>LocalHost</Name> 
      <Type>Db</Type> 
    </Server> 
  </Servers> 
 <ServerType> 
    <Type>App</Type> 
    <ServiceName>BTS*</ServiceName> 
    <ServiceName>ENTSSO</ServiceName> 
    <ServiceName>IISADMIN</ServiceName> 
    <ServiceName>W3SVC</ServiceName> 
    <ServiceName>RuleEngineUpdateService</ServiceName> 
    <ServiceName>MSDTC</ServiceName> 
  </ServerType> 
  <ServerType> 
    <Type>Db</Type> 
    <ServiceName>MSDTC</ServiceName> 
    <ServiceName>ClusSvc</ServiceName> 
    <ServiceName>SQLBrowser</ServiceName> 
    <ServiceName>MsDtsServer100</ServiceName> 
    <ServiceName>MsDtsServer120</ServiceName> 
    <ServiceName>MSSQLServerOLAPService</ServiceName> 
    <ServiceName>SQLsafe Backup Service</ServiceName> 
    <ServiceName>MSSQLSERVER</ServiceName> 
    <ServiceName>SQLSERVERAGENT</ServiceName> 
  </ServerType> 
  <ServerType> 
    <Type>Web</Type> 
    <ServiceName>MSDTC</ServiceName> 
    <ServiceName>W3SVC</ServiceName> 
  </ServerType> 
</Configuration> 

Here the servers are segregated based on their type whether they are Application Server(BizTalk Application Server), DB(BizTalk Database Server) or a Web Server. The services are segregated according to the server type so that a properly formatted email can be sent. The config file can be used to include different servers and different services

Code

The PowerShell script for getting the service status across the servers is as below.

Function GetServiceStatusesAcrossRemoteServers 
{ 
 param 
    ( 
                         #This variable point to the path where the config file is stored.
        $strConfigFilePath 
    ) 
    $PathValidator 
    $ConnectionValidator 
    if(test-path $strConfigFilePath) 
    { 
        [xml] $Config= Get-Content "$strConfigFilePath\Config.xml" 
        $Fetchingdata="Hi Team,<b><br/></b><br/>Following is the server wise list of BizTalk Related Services <br/><br/>" 
        $MailBody= $MailBody+$Fetchingdata 
        $AppServices= @() 
        $DbServices=@() 
        $WebServices=@() 
        foreach($Configuration in $Config.Configuration) 
        { 
            foreach( $ServerType in $Configuration.ServerType) 
            { 
                if($ServerType.Type.ToUpper() -eq "APP") 
                { 
                    #Read the list of the application server related services from the config File 
                    foreach($ServiceName in $ServerType.ServiceName) 
                    { 
                        $AppServices += $ServiceName.ToString() 
                    } 
                } 
                if($ServerType.Type.ToUpper() -eq "WEB") 
                { 
                    #Read the list of the web server related services from the config File 
                    foreach($ServiceName in $ServerType.ServiceName) 
                    { 
                        $WebServices += $ServiceName.ToString() 
                    } 
                } 
                if($ServerType.Type.ToUpper() -eq "DB") 
                { 
                    #Read the list of the Database server related services from the config File 
                    foreach($ServiceName in $ServerType.ServiceName) 
                    { 
                        $DbServices += $ServiceName.ToString() 
                    } 
  
                } 
  
                  
            } 
  
  
  
            foreach($Servers in $Configuration.Servers) 
            { 
                foreach($Server in $Servers.Server) 
                { 
                  
                    #Check if The server can be connected to. 
                    if(Test-Connection $Server.Name) 
                    { 
                        $ServerName= $Server.Name 
                        $MailBody= $MailBody+ "Server Name:<b>"+ $ServerName +"</b>:"+$Server.Type.ToUpper()+" Server <br/><br/>" 
                        $style="<style>BODY{background-color:white;}TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; }TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#4d79ff }TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:white}</style>" 
                        $head= "<head>$style</head>" 
                        $tableBOdy= "<body><p style='font-size:25px;family:calibri;color:#ff9100'>$style<table><colgroup><col/><col/><col/><col/></colgroup><tr><th>ServiceName</th><th>DisplayName</th><th>ServiceStartType</th><th>ServiceStatus</th></tr>" 
                          
  
  
                        # Check the server type 
                                   #If the Service is not found on the server, the powershell script will continue silently
                                   #Ignoring the service.
                            
                        if($Server.Type.ToUpper() -eq "APP") 
                        { 
                              
                            foreach($AppService in $AppServices) 
                            { 
                                  
  
                                $Services= Get-WmiObject -Class Win32_Service  -filter "Name like '%$AppService%'"  -ComputerName $ServerName 
                                if($Services.Count -gt 1) 
                                { 
                                  foreach($Service in $Services)   
                                  { 
                                        $ServiceName=$Service.Name 
                                       $DisplayName=$Service.DisplayName 
                                       $ServiceStatus= $Service.State 
                                       $ServiceStartType=$Service.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($Service -ne $null) 
                                    { 
                                          
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                  } 
                                } 
                                else 
                                { 
                                     $ServiceName=$Services.Name 
                                       $DisplayName=$Services.DisplayName 
                                       $ServiceStatus= $Services.State 
                                       $ServiceStartType=$Services.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($Services -ne $null) 
                                    { 
                                           
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                } 
  
  
                            } 
                                $tableBOdy= $tableBOdy+ "</table></body>" 
                                $html="<html>$head$tableBOdy</html>" 
                          
                                $MailBody=$MailBody+ $html+"<br/><br/>" 
  
                        } 
                        if($Server.Type.ToUpper() -eq "DB") 
                        { 
                              
                            foreach($DbService in $DbServices) 
                            { 
                                  
                                $DataServices= Get-WmiObject  -Class Win32_Service  -filter "Name like '%$DbService%'"  -ComputerName $ServerName 
                                if($DataServices.Count -gt 1) 
                                { 
                                  foreach($DataService in $DataServices)   
                                  { 
                                        $ServiceName=$DataService.Name 
                                       $DisplayName=$DataService.DisplayName 
                                       $ServiceStatus= $DataService.State 
                                       $ServiceStartType=$DataService.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($DataService -ne $null) 
                                    { 
                                           
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                  } 
                                } 
                                else 
                                { 
                                     $ServiceName=$DataServices.Name 
                                       $DisplayName=$DataServices.DisplayName 
                                       $ServiceStatus= $DataServices.State 
                                       $ServiceStartType=$DataServices.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($DataServices -ne $null) 
                                    { 
                                           
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                } 
  
                            } 
                            $tableBOdy= $tableBOdy+ "</table></body>" 
                            $html="<html>$head$tableBOdy</html>" 
                          
                            $MailBody=$MailBody+ $html+"<br/><br/>" 
                              
                        } 
                        if($Server.Type.ToUpper() -eq "WEB") 
                        { 
                            foreach($WebService in $WebServices) 
                            { 
                                  
                                $WbServices= Get-WmiObject  -Class Win32_Service  -filter "Name like '%$WebService%'"  -ComputerName $ServerName 
                                if($WbServices.Count -gt 1) 
                                { 
                                  foreach($WbService in $WbServices)   
                                  { 
                                        $ServiceName=$WbService.Name 
                                       $DisplayName=$WbService.DisplayName 
                                       $ServiceStatus= $WbService.State 
                                       $ServiceStartType=$WbService.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($WbService -ne $null) 
                                    { 
                                           
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                  } 
                                } 
                                else 
                                { 
                                     $ServiceName=$WbServices.Name 
                                       $DisplayName=$WbServices.DisplayName 
                                       $ServiceStatus= $WbServices.State 
                                       $ServiceStartType=$WbServices.StartMode 
                                    if($ServiceStatus -eq "Stopped") 
                                    { 
                                        $ServiceStatus="<font color='Red'>Stopped</font>" 
                                     } 
                             
                                    if($WbServices -ne $null) 
                                    { 
                                           
                                    $tableBOdy= $tableBOdy + "<tr><td>$ServiceName</td><td>$DisplayName</td><td>$ServiceStartType</td><td>$ServiceStatus</td></tr>" 
                                    } 
                                      
                                } 
  
                            } 
                            $tableBOdy= $tableBOdy+ "</table></body>" 
                                $html="<html>$head$tableBOdy</html>" 
                          
                                $MailBody=$MailBody+ $html+"<br/><br/>" 
                              
                        } 
  
  
                    } 
                    else 
                    { 
                        write-Host "Connection to the server"+ $ServerName.Name + "failed" 
                        $ConnectionValidator="Connection to the server:<b>"+$Server.Name+"</b>failed." 
  
                    } 
                } 
            } 
        } 
  
    } 
    else 
    { 
        $PathValidator="Provided Path is invalid." 
    } 
  
    [string]$MailBodyMsg=$PathValidator+$ConnectionValidator+$MailBody+"<br/><br/>Regards,<br/>BizAdmin Team <br/><br/>----------------------------------------------------------------------<br/>This is an autogenerated mail. Please do not reply to it.<br/>" 
      
      
    $Subject= "Service Status Notification on"+(get-date)        
    [string[]]$users = "xyz@pqr.com" 
    [string]$fromemail = "xyz@pqr.com"  
    [string]$server = "SMTP Server Ip or name"    
    send-mailmessage -from $fromemail -to $users -subject $Subject -BodyAsHTML $MailBodyMsg -priority High -smtpServer $server  
    Write-Host "Mail Sent successfully...!!!" 
  
      
} 

The only thing that needs to be taken care of is that the user with which the PowerShell script is being executed has right to execute the script on the remote system.

Sample

A sample report for the test is shown below.

Conclusion

PowerShell can be used to automate the task of checking the status of the service instances across multiple BizTalk Environment and the report can be sent via mail to multiple parties of Interest.

Download

The PowerShell Script can be downloaded from the Technet Gallery at below link.

See Also

Another important place to find a huge amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki