676 lines
24 KiB
PowerShell
676 lines
24 KiB
PowerShell
<#
|
||
BizTalk Status Tool – Extended Version
|
||
Includes:
|
||
- Applications Snapshot (RL/SP/ORCH)
|
||
- Host Instances Snapshot
|
||
- JSON / CSV / HTML / Console
|
||
- Compare (Before / After)
|
||
- HostInstance Diff (New / Removed / Changed)
|
||
#>
|
||
|
||
# ======================================================
|
||
# PARAMETERS
|
||
# ======================================================
|
||
param(
|
||
[switch]$Before,
|
||
[switch]$After,
|
||
[switch]$Compare,
|
||
[switch]$Diag,
|
||
[string]$Server,
|
||
[string]$MgmtDbServer,
|
||
[string]$MgmtDbName,
|
||
[string]$OutDir
|
||
)
|
||
|
||
if (-not $Server) { $Server = $env:COMPUTERNAME }
|
||
if (-not $OutDir) { $OutDir = "." }
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
$Global:LogFile = Join-Path (Get-Location) "BizTalkStatusTool.log"
|
||
|
||
# ======================================================
|
||
# LOG
|
||
# ======================================================
|
||
function Write-Log {
|
||
param([string]$Message,[ValidateSet('INFO','WARN','ERROR','DEBUG')]$Level='INFO')
|
||
|
||
$ts = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
|
||
$line = "[$ts][$Level] $Message"
|
||
$fg = switch ($Level) {
|
||
INFO {"Gray"} WARN {"Yellow"} ERROR {"Red"} DEBUG {"DarkCyan"}
|
||
}
|
||
Write-Host $line -ForegroundColor $fg
|
||
Add-Content -Path $Global:LogFile -Value $line
|
||
}
|
||
|
||
# ======================================================
|
||
# STATUS MAPPING
|
||
# ======================================================
|
||
function Format-Status {
|
||
param([string]$ArtifactType, $Value)
|
||
|
||
$r = [ordered]@{
|
||
Text = ""
|
||
Class = "neutral"
|
||
ConsoleColor = "Yellow"
|
||
}
|
||
|
||
switch ($ArtifactType) {
|
||
|
||
"ReceiveLocation" {
|
||
if ($Value -eq $true) {
|
||
$r.Text="Enabled"; $r.Class="ok"; $r.ConsoleColor="Green"
|
||
}
|
||
elseif ($Value -eq $false) {
|
||
$r.Text="Disabled"; $r.Class="bad"; $r.ConsoleColor="Red"
|
||
}
|
||
}
|
||
|
||
"SendPort" {
|
||
switch ([int]$Value) {
|
||
3 { $r.Text="Started"; $r.Class="ok"; $r.ConsoleColor="Green" }
|
||
2 { $r.Text="Stopped"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
1 { $r.Text="Bound"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
default { $r.Text="Unknown"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
}
|
||
}
|
||
|
||
"Orchestration" {
|
||
switch ([int]$Value) {
|
||
4 { $r.Text="Started"; $r.Class="ok"; $r.ConsoleColor="Green" }
|
||
3 { $r.Text="Stopped"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
2 { $r.Text="Bound"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
default { $r.Text="Unknown"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
}
|
||
}
|
||
|
||
"HostInstance" {
|
||
switch ([int]$Value) {
|
||
4 { $r.Text="Started"; $r.Class="ok"; $r.ConsoleColor="Green" }
|
||
2 { $r.Text="StartPending"; $r.Class="warn"; $r.ConsoleColor="Yellow" }
|
||
3 { $r.Text="StopPending"; $r.Class="warn"; $r.ConsoleColor="Yellow" }
|
||
1 { $r.Text="Stopped"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
default { $r.Text="Unknown"; $r.Class="bad"; $r.ConsoleColor="Red" }
|
||
}
|
||
}
|
||
}
|
||
|
||
return [pscustomobject]$r
|
||
}
|
||
|
||
# ======================================================
|
||
# MGMT DB
|
||
# ======================================================
|
||
function Get-BizTalkMgmtDbInfo {
|
||
param([string]$MgmtDbServer,[string]$MgmtDbName)
|
||
|
||
$reg = "HKLM:\SOFTWARE\Microsoft\BizTalk Server\3.0\Administration"
|
||
|
||
try {
|
||
$p = Get-ItemProperty $reg
|
||
if (-not $MgmtDbServer) { $MgmtDbServer = $p.MgmtDBServer }
|
||
if (-not $MgmtDbName) { $MgmtDbName = $p.MgmtDBName }
|
||
}
|
||
catch {
|
||
if (-not $MgmtDbServer) { $MgmtDbServer = "localhost" }
|
||
if (-not $MgmtDbName) { $MgmtDbName = "BizTalkMgmtDb" }
|
||
}
|
||
|
||
return @{ Server=$MgmtDbServer; Name=$MgmtDbName }
|
||
}
|
||
|
||
# ======================================================
|
||
# HOST INSTANCES
|
||
# ======================================================
|
||
function Get-BizTalkHostInstances {
|
||
param([string]$Server)
|
||
|
||
$wmi = @{
|
||
Namespace = "root\MicrosoftBizTalkServer"
|
||
ComputerName = $Server
|
||
ErrorAction = 'Stop'
|
||
}
|
||
|
||
$list = Get-WmiObject MSBTS_HostInstance @wmi
|
||
|
||
$result = foreach ($hi in $list) {
|
||
$st = Format-Status -ArtifactType "HostInstance" -Value $hi.ServiceState
|
||
[pscustomobject]@{
|
||
InstanceName = $hi.InstanceName
|
||
HostName = $hi.HostName
|
||
Server = $hi.RunningServer
|
||
RawState = $hi.ServiceState
|
||
StateText = $st.Text
|
||
StateClass = $st.Class
|
||
ConsoleColor = $st.ConsoleColor
|
||
}
|
||
}
|
||
|
||
return $result
|
||
}
|
||
|
||
function Show-HostInstancesConsole {
|
||
param($HostInstances)
|
||
Write-Host "`n=== Host Instances ===" -ForegroundColor Yellow
|
||
foreach ($hi in $HostInstances) {
|
||
Write-Host ("{0,-35} {1,-20} {2,-10}" -f $hi.InstanceName,$hi.HostName,$hi.StateText) `
|
||
-ForegroundColor $hi.ConsoleColor
|
||
}
|
||
}
|
||
|
||
function Export-HostInstancesHtml {
|
||
param($HostInstances)
|
||
|
||
$html = @()
|
||
$html += "<h3>Host Instances</h3>"
|
||
$html += "<table>"
|
||
$html += "<tr><th>Instance</th><th>Host</th><th>Server</th><th>Status</th></tr>"
|
||
|
||
foreach ($hi in $HostInstances) {
|
||
$html += "<tr>
|
||
<td>$($hi.InstanceName)</td>
|
||
<td>$($hi.HostName)</td>
|
||
<td>$($hi.Server)</td>
|
||
<td class='$($hi.StateClass)'>$($hi.StateText)</td>
|
||
</tr>"
|
||
}
|
||
|
||
$html += "</table>"
|
||
return ($html -join "`n")
|
||
}
|
||
|
||
function Export-HostInstancesCsv {
|
||
param($HostInstances, [string]$CsvFile)
|
||
$HostInstances |
|
||
Select InstanceName,HostName,Server,StateText |
|
||
Export-Csv -NoTypeInformation -Encoding UTF8 -Path $CsvFile
|
||
}
|
||
|
||
# ======================================================
|
||
# SNAPSHOT
|
||
# ======================================================
|
||
function Get-BizTalkSnapshot {
|
||
param(
|
||
[string]$OutputFile,
|
||
[string]$Server,
|
||
[string]$MgmtDbServer,
|
||
[string]$MgmtDbName
|
||
)
|
||
|
||
Write-Log "Snapshot: Server=$Server File=$OutputFile"
|
||
|
||
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
|
||
$db = Get-BizTalkMgmtDbInfo -MgmtDbServer $MgmtDbServer -MgmtDbName $MgmtDbName
|
||
|
||
$cat = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
|
||
$cat.ConnectionString = "Server={0};Database={1};Integrated Security=SSPI" -f $db.Server,$db.Name
|
||
|
||
$apps = $cat.Applications
|
||
|
||
# WMI lookup tables
|
||
$wmi = @{ Namespace='root\MicrosoftBizTalkServer'; ComputerName=$Server; ErrorAction='Stop' }
|
||
|
||
$rlW = Get-WmiObject MSBTS_ReceiveLocation @wmi |
|
||
Select Name, @{n='Enabled';e={-not $_.IsDisabled}}, AdapterName, @{n='Address';e={$_.InboundTransportURL}}
|
||
|
||
$spW = Get-WmiObject MSBTS_SendPort @wmi |
|
||
Select Name, @{n='Status';e={$_.Status}}, @{n='PrimaryTransportType';e={$_.PTTransportType}},
|
||
@{n='PrimaryTransportAddress';e={$_.PTAddress}}
|
||
|
||
$orW = Get-WmiObject MSBTS_Orchestration @wmi |
|
||
Select Name, @{n='OrchestrationStatus';e={$_.OrchestrationStatus}}
|
||
|
||
$mapRL=@{}; foreach($i in $rlW){$mapRL[$i.Name]=$i}
|
||
$mapSP=@{}; foreach($i in $spW){$mapSP[$i.Name]=$i}
|
||
$mapOR=@{}; foreach($i in $orW){$mapOR[$i.Name]=$i}
|
||
|
||
$snapshot=@()
|
||
|
||
foreach ($app in $apps) {
|
||
|
||
$rlItems=@()
|
||
foreach ($rp in $app.ReceivePorts) {
|
||
foreach ($rl in $rp.ReceiveLocations) {
|
||
if ($mapRL.ContainsKey($rl.Name)) {
|
||
$w = $mapRL[$rl.Name]
|
||
$rlItems += [pscustomobject]@{
|
||
Name=$rl.Name
|
||
Enabled=$w.Enabled
|
||
AdapterName=$w.AdapterName
|
||
Address=$w.Address
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$spItems=@()
|
||
foreach ($sp in $app.SendPorts) {
|
||
if ($mapSP.ContainsKey($sp.Name)) {
|
||
$w = $mapSP[$sp.Name]
|
||
$spItems += [pscustomobject]@{
|
||
Name=$sp.Name
|
||
Status=$w.Status
|
||
PrimaryTransportType=$w.PrimaryTransportType
|
||
PrimaryTransportAddress=$w.PrimaryTransportAddress
|
||
}
|
||
}
|
||
}
|
||
|
||
$orItems=@()
|
||
foreach ($o in $app.Orchestrations) {
|
||
$key = if ($mapOR.ContainsKey($o.FullName)) { $o.FullName } else { $o.Name }
|
||
if ($mapOR.ContainsKey($key)) {
|
||
$w = $mapOR[$key]
|
||
$orItems += [pscustomobject]@{
|
||
Name=$o.FullName
|
||
OrchestrationStatus=$w.OrchestrationStatus
|
||
}
|
||
}
|
||
}
|
||
|
||
$snapshot += [pscustomobject]@{
|
||
Application=$app.Name
|
||
ReceiveLocations=$rlItems
|
||
SendPorts=$spItems
|
||
Orchestrations=$orItems
|
||
}
|
||
}
|
||
|
||
# Host Instances
|
||
$hostInstances = Get-BizTalkHostInstances -Server $Server
|
||
|
||
# Export JSON (Applications + HostInstances)
|
||
$full = [pscustomobject]@{
|
||
Applications = $snapshot
|
||
HostInstances = $hostInstances
|
||
}
|
||
|
||
$full | ConvertTo-Json -Depth 8 | Out-File $OutputFile -Encoding UTF8
|
||
|
||
# Export CSV
|
||
$csvArtifact = foreach ($app in $snapshot) {
|
||
foreach ($rl in $app.ReceiveLocations) {
|
||
$st = Format-Status -ArtifactType "ReceiveLocation" -Value $rl.Enabled
|
||
[pscustomobject]@{
|
||
Application=$app.Application
|
||
Type="ReceiveLocation"
|
||
Name=$rl.Name
|
||
Status=$st.Text
|
||
}
|
||
}
|
||
foreach ($sp in $app.SendPorts) {
|
||
$st = Format-Status -ArtifactType "SendPort" -Value $sp.Status
|
||
[pscustomobject]@{
|
||
Application=$app.Application
|
||
Type="SendPort"
|
||
Name=$sp.Name
|
||
Status=$st.Text
|
||
}
|
||
}
|
||
foreach ($o in $app.Orchestrations) {
|
||
$st = Format-Status -ArtifactType "Orchestration" -Value $o.OrchestrationStatus
|
||
[pscustomobject]@{
|
||
Application=$app.Application
|
||
Type="Orchestration"
|
||
Name=$o.Name
|
||
Status=$st.Text
|
||
}
|
||
}
|
||
}
|
||
|
||
$csvArtifact |
|
||
Export-Csv -Encoding UTF8 -NoTypeInformation -Path ($OutputFile + ".csv")
|
||
|
||
Export-HostInstancesCsv -HostInstances $hostInstances -CsvFile ($OutputFile + ".hosts.csv")
|
||
|
||
# HTML
|
||
$html=@()
|
||
$html+="<html><head><style>
|
||
table{border-collapse:collapse;margin-bottom:20px;}
|
||
td,th{border:1px solid #999;padding:4px 8px;}
|
||
.ok{color:green;font-weight:bold;}
|
||
.bad{color:red;font-weight:bold;}
|
||
.warn{color:orange;font-weight:bold;}
|
||
</style></head><body>"
|
||
$html+="<h2>BizTalk Snapshot</h2>"
|
||
|
||
foreach ($app in $snapshot) {
|
||
$html+="<h3>Application: $($app.Application)</h3>"
|
||
|
||
if ($app.ReceiveLocations.Count -gt 0) {
|
||
$html+="<h4>Receive Locations</h4><table><tr><th>Name</th><th>Status</th></tr>"
|
||
foreach ($rl in $app.ReceiveLocations) {
|
||
$st = Format-Status -ArtifactType "ReceiveLocation" -Value $rl.Enabled
|
||
$html+="<tr><td>$($rl.Name)</td><td class='$($st.Class)'>$($st.Text)</td></tr>"
|
||
}
|
||
$html+="</table>"
|
||
}
|
||
|
||
if ($app.SendPorts.Count -gt 0) {
|
||
$html+="<h4>Send Ports</h4><table><tr><th>Name</th><th>Status</th></tr>"
|
||
foreach ($sp in $app.SendPorts) {
|
||
$st = Format-Status -ArtifactType "SendPort" -Value $sp.Status
|
||
$html+="<tr><td>$($sp.Name)</td><td class='$($st.Class)'>$($st.Text)</td></tr>"
|
||
}
|
||
$html+="</table>"
|
||
}
|
||
|
||
if ($app.Orchestrations.Count -gt 0) {
|
||
$html+="<h4>Orchestrations</h4><table><tr><th>Name</th><th>Status</th></tr>"
|
||
foreach ($o in $app.Orchestrations) {
|
||
$st = Format-Status -ArtifactType "Orchestration" -Value $o.OrchestrationStatus
|
||
$html+="<tr><td>$($o.Name)</td><td class='$($st.Class)'>$($st.Text)</td></tr>"
|
||
}
|
||
$html+="</table>"
|
||
}
|
||
}
|
||
|
||
# Add Host Instances
|
||
$html += Export-HostInstancesHtml -HostInstances $hostInstances
|
||
|
||
$html+="</body></html>"
|
||
$html -join "`n" | Out-File ($OutputFile + ".html") -Encoding UTF8
|
||
|
||
# Console Output
|
||
Write-Host "`n===== Snapshot =====" -ForegroundColor Yellow
|
||
foreach ($app in $snapshot) {
|
||
Write-Host "`nApplication: $($app.Application)" -ForegroundColor Cyan
|
||
|
||
foreach ($rl in $app.ReceiveLocations) {
|
||
$st = Format-Status -ArtifactType "ReceiveLocation" -Value $rl.Enabled
|
||
Write-Host (" RL {0,-60} {1}" -f $rl.Name,$st.Text) -ForegroundColor $st.ConsoleColor
|
||
}
|
||
|
||
foreach ($sp in $app.SendPorts) {
|
||
$st = Format-Status -ArtifactType "SendPort" -Value $sp.Status
|
||
Write-Host (" SP {0,-60} {1}" -f $sp.Name,$st.Text) -ForegroundColor $st.ConsoleColor
|
||
}
|
||
|
||
foreach ($o in $app.Orchestrations) {
|
||
$st = Format-Status -ArtifactType "Orchestration" -Value $o.OrchestrationStatus
|
||
Write-Host (" OR {0,-60} {1}" -f $o.Name,$st.Text) -ForegroundColor $st.ConsoleColor
|
||
}
|
||
}
|
||
|
||
Show-HostInstancesConsole -HostInstances $hostInstances
|
||
|
||
Write-Host "Snapshot erstellt: $(Resolve-Path $OutputFile)" -ForegroundColor Green
|
||
}
|
||
|
||
# ======================================================
|
||
# COMPARE (Before/After)
|
||
# ======================================================
|
||
function Compare-BizTalkSnapshots {
|
||
param(
|
||
[string]$Before,
|
||
[string]$After,
|
||
[string]$HtmlReport = "BizTalkDiff.html"
|
||
)
|
||
|
||
$b = Get-Content $Before | ConvertFrom-Json
|
||
$a = Get-Content $After | ConvertFrom-Json
|
||
|
||
$diff = @()
|
||
|
||
function AddDiff {
|
||
param($app,$type,$name,$before,$after)
|
||
|
||
$bf = Format-Status -ArtifactType $type -Value $before
|
||
$af = Format-Status -ArtifactType $type -Value $after
|
||
|
||
$script:diff += [pscustomobject]@{
|
||
Application = $app
|
||
ArtifactType= $type
|
||
Name = $name
|
||
BeforeText = $bf.Text
|
||
BeforeClass = $bf.Class
|
||
AfterText = $af.Text
|
||
AfterClass = $af.Class
|
||
}
|
||
}
|
||
|
||
foreach ($appAfter in $a.Applications) {
|
||
$appBefore = $b.Applications | Where-Object {$_.Application -eq $appAfter.Application}
|
||
|
||
# RECEIVE LOCATIONS
|
||
foreach ($x in $appAfter.ReceiveLocations) {
|
||
$old = $appBefore.ReceiveLocations | Where-Object {$_.Name -eq $x.Name}
|
||
if (-not $old) { AddDiff $appAfter.Application "ReceiveLocation" $x.Name $null $x.Enabled; continue }
|
||
if ($old.Enabled -ne $x.Enabled) { AddDiff $appAfter.Application "ReceiveLocation" $x.Name $old.Enabled $x.Enabled }
|
||
}
|
||
foreach ($x in $appBefore.ReceiveLocations) {
|
||
if (-not ($appAfter.ReceiveLocations | Where-Object {$_.Name -eq $x.Name})) {
|
||
AddDiff $appBefore.Application "ReceiveLocation" $x.Name $x.Enabled $null
|
||
}
|
||
}
|
||
|
||
# SEND PORTS
|
||
foreach ($x in $appAfter.SendPorts) {
|
||
$old = $appBefore.SendPorts | Where-Object {$_.Name -eq $x.Name}
|
||
if (-not $old) { AddDiff $appAfter.Application "SendPort" $x.Name $null $x.Status; continue }
|
||
if ($old.Status -ne $x.Status) { AddDiff $appAfter.Application "SendPort" $x.Name $old.Status $x.Status }
|
||
}
|
||
foreach ($x in $appBefore.SendPorts) {
|
||
if (-not ($appAfter.SendPorts | Where-Object {$_.Name -eq $x.Name})) {
|
||
AddDiff $appBefore.Application "SendPort" $x.Name $x.Status $null
|
||
}
|
||
}
|
||
|
||
# ORCHESTRATIONS
|
||
foreach ($x in $appAfter.Orchestrations) {
|
||
$old = $appBefore.Orchestrations | Where-Object {$_.Name -eq $x.Name}
|
||
if (-not $old) { AddDiff $appAfter.Application "Orchestration" $x.Name $null $x.OrchestrationStatus; continue }
|
||
if ($old.OrchestrationStatus -ne $x.OrchestrationStatus) {
|
||
AddDiff $appAfter.Application "Orchestration" $x.Name $old.OrchestrationStatus $x.OrchestrationStatus
|
||
}
|
||
}
|
||
foreach ($x in $appBefore.Orchestrations) {
|
||
if (-not ($appAfter.Orchestrations | Where-Object {$_.Name -eq $x.Name})) {
|
||
AddDiff $appBefore.Application "Orchestration" $x.Name $x.OrchestrationStatus $null
|
||
}
|
||
}
|
||
}
|
||
|
||
# ======================================================
|
||
# HOST INSTANCE DIFF (Option H-DIFF2)
|
||
# ======================================================
|
||
|
||
$beforeHI = $b.HostInstances
|
||
$afterHI = $a.HostInstances
|
||
|
||
$hiDiff_New=@()
|
||
$hiDiff_Removed=@()
|
||
$hiDiff_Changed=@()
|
||
|
||
# New
|
||
foreach ($hi in $afterHI) {
|
||
if (-not ($beforeHI | Where-Object {$_.InstanceName -eq $hi.InstanceName})) {
|
||
$hiDiff_New += $hi
|
||
}
|
||
}
|
||
|
||
# Removed
|
||
foreach ($hi in $beforeHI) {
|
||
if (-not ($afterHI | Where-Object {$_.InstanceName -eq $hi.InstanceName})) {
|
||
$hiDiff_Removed += $hi
|
||
}
|
||
}
|
||
|
||
# Changed
|
||
foreach ($hiAfter in $afterHI) {
|
||
$hiBefore = $beforeHI | Where-Object {$_.InstanceName -eq $hiAfter.InstanceName}
|
||
if ($hiBefore) {
|
||
if ($hiBefore.StateText -ne $hiAfter.StateText) {
|
||
$hiDiff_Changed += [pscustomobject]@{
|
||
Instance = $hiAfter.InstanceName
|
||
Before = $hiBefore.StateText
|
||
After = $hiAfter.StateText
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
# ======================================================
|
||
# JSON DIFF EXPORT
|
||
# ======================================================
|
||
$jsonDiff = [pscustomobject]@{
|
||
ArtifactsDiff = $diff
|
||
HostInstances = [pscustomobject]@{
|
||
New = $hiDiff_New
|
||
Removed = $hiDiff_Removed
|
||
Changed = $hiDiff_Changed
|
||
}
|
||
}
|
||
|
||
$jsonDiff | ConvertTo-Json -Depth 8 | Out-File "diff.json" -Encoding UTF8
|
||
|
||
# ======================================================
|
||
# CSV DIFF EXPORT
|
||
# ======================================================
|
||
$diff | Export-Csv -Path "diff.csv" -NoTypeInformation -Encoding UTF8
|
||
|
||
# ======================================================
|
||
# HTML DIFF EXPORT
|
||
# ======================================================
|
||
$html=@()
|
||
$html+="<html><head><style>
|
||
table{border-collapse:collapse;margin-bottom:20px;}
|
||
td,th{border:1px solid #999;padding:4px 8px;}
|
||
.ok{color:green;font-weight:bold;}
|
||
.bad{color:red;font-weight:bold;}
|
||
.warn{color:orange;font-weight:bold;}
|
||
</style></head><body>"
|
||
$html+="<h2>BizTalk Differences</h2>"
|
||
|
||
# Artifacts
|
||
$html+="<h3>Artifact Differences</h3>"
|
||
$html+="<table><tr><th>Application</th><th>Type</th><th>Name</th><th>Before</th><th>After</th></tr>"
|
||
foreach ($d in $diff) {
|
||
$html+="<tr>
|
||
<td>$($d.Application)</td>
|
||
<td>$($d.ArtifactType)</td>
|
||
<td>$($d.Name)</td>
|
||
<td class='$($d.BeforeClass)'>$($d.BeforeText)</td>
|
||
<td class='$($d.AfterClass)'>$($d.AfterText)</td>
|
||
</tr>"
|
||
}
|
||
$html+="</table>"
|
||
|
||
# HostInstance DIFF
|
||
$html+="<h3>Host Instance Changes</h3>"
|
||
|
||
# NEW
|
||
$html+="<h4>New</h4><table><tr><th>Instance</th><th>Host</th><th>Server</th><th>Status</th></tr>"
|
||
foreach ($hi in $hiDiff_New) {
|
||
$html+="<tr>
|
||
<td>$($hi.InstanceName)</td>
|
||
<td>$($hi.HostName)</td>
|
||
<td>$($hi.Server)</td>
|
||
<td class='$($hi.StateClass)'>$($hi.StateText)</td>
|
||
</tr>"
|
||
}
|
||
$html+="</table>"
|
||
|
||
# REMOVED
|
||
$html+="<h4>Removed</h4><table><tr><th>Instance</th><th>Host</th><th>Server</th><th>Status</th></tr>"
|
||
foreach ($hi in $hiDiff_Removed) {
|
||
$html+="<tr>
|
||
<td>$($hi.InstanceName)</td>
|
||
<td>$($hi.HostName)</td>
|
||
<td>$($hi.Server)</td>
|
||
<td class='bad'>$($hi.StateText)</td>
|
||
</tr>"
|
||
}
|
||
$html+="</table>"
|
||
|
||
# CHANGED
|
||
$html+="<h4>Changed</h4><table><tr><th>Instance</th><th>Before</th><th>After</th></tr>"
|
||
foreach ($hi in $hiDiff_Changed) {
|
||
$before = Format-Status -ArtifactType "HostInstance" -Value $hi.Before
|
||
$after = Format-Status -ArtifactType "HostInstance" -Value $hi.After
|
||
$html+="<tr>
|
||
<td>$($hi.Instance)</td>
|
||
<td class='$($before.Class)'>$($hi.Before)</td>
|
||
<td class='$($after.Class)'>$($hi.After)</td>
|
||
</tr>"
|
||
}
|
||
$html+="</table>"
|
||
|
||
$html+="</body></html>"
|
||
$html -join "`n" | Out-File $HtmlReport -Encoding UTF8
|
||
|
||
# ======================================================
|
||
# CONSOLE OUTPUT
|
||
# ======================================================
|
||
Write-Host "`n===== BizTalk DIFF =====" -ForegroundColor Yellow
|
||
|
||
if ($diff.Count -eq 0 -and
|
||
$hiDiff_New.Count -eq 0 -and
|
||
$hiDiff_Removed.Count -eq 0 -and
|
||
$hiDiff_Changed.Count -eq 0)
|
||
{
|
||
Write-Host "Keine Unterschiede." -ForegroundColor Green
|
||
}
|
||
else {
|
||
Write-Host "`n--- Artifacts ---" -ForegroundColor Cyan
|
||
foreach ($d in $diff) {
|
||
Write-Host "`nApplication: $($d.Application)" -ForegroundColor Cyan
|
||
Write-Host "Artifact: $($d.ArtifactType)"
|
||
Write-Host "Name: $($d.Name)"
|
||
Write-Host ("Before: {0}" -f $d.BeforeText) -ForegroundColor $(
|
||
if ($d.BeforeClass -eq "ok") {"Green"} elseif ($d.BeforeClass -eq "warn") {"Yellow"} else {"Red"})
|
||
Write-Host ("After: {0}" -f $d.AfterText) -ForegroundColor $(
|
||
if ($d.AfterClass -eq "ok") {"Green"} elseif ($d.AfterClass -eq "warn") {"Yellow"} else {"Red"})
|
||
}
|
||
|
||
Write-Host "`n--- Host Instances (New) ---" -ForegroundColor Cyan
|
||
foreach ($hi in $hiDiff_New) {
|
||
Write-Host ("NEW: {0} {1}" -f $hi.InstanceName,$hi.StateText) -ForegroundColor $hi.ConsoleColor
|
||
}
|
||
|
||
Write-Host "`n--- Host Instances (Removed) ---" -ForegroundColor Cyan
|
||
foreach ($hi in $hiDiff_Removed) {
|
||
Write-Host ("REMOVED: {0} {1}" -f $hi.InstanceName,$hi.StateText) -ForegroundColor Red
|
||
}
|
||
|
||
Write-Host "`n--- Host Instances (Changed) ---" -ForegroundColor Cyan
|
||
foreach ($hi in $hiDiff_Changed) {
|
||
Write-Host ("CHANGED: {0} {1} -> {2}" -f $hi.Instance,$hi.Before,$hi.After) -ForegroundColor Yellow
|
||
}
|
||
}
|
||
|
||
Write-Host "HTML Diff exportiert: $HtmlReport" -ForegroundColor Green
|
||
}
|
||
|
||
# ======================================================
|
||
# DISPATCH
|
||
# ======================================================
|
||
if (-not (Test-Path $OutDir)) {
|
||
New-Item -ItemType Directory -Path $OutDir | Out-Null
|
||
}
|
||
Set-Location $OutDir
|
||
Write-Log "Working dir: $(Get-Location)"
|
||
|
||
if ($Diag) {
|
||
Write-Host "DIAG → Server: $Server" -ForegroundColor Yellow
|
||
try {
|
||
$sp = Get-WmiObject MSBTS_SendPort -Namespace root\MicrosoftBizTalkServer -ComputerName $Server |
|
||
Select -First 3 Name,Status
|
||
Write-Host "WMI OK:" -ForegroundColor Green
|
||
$sp | Format-Table
|
||
}
|
||
catch {
|
||
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
||
}
|
||
exit
|
||
}
|
||
|
||
if ($Before) { Get-BizTalkSnapshot -OutputFile "before.json" -Server $Server -MgmtDbServer $MgmtDbServer -MgmtDbName $MgmtDbName; exit }
|
||
if ($After) { Get-BizTalkSnapshot -OutputFile "after.json" -Server $Server -MgmtDbServer $MgmtDbServer -MgmtDbName $MgmtDbName; exit }
|
||
if ($Compare){ Compare-BizTalkSnapshots -Before "before.json" -After "after.json"; exit }
|
||
|
||
Write-Host "Usage:"
|
||
Write-Host " .\BizTalkStatusTool.ps1 -Before"
|
||
Write-Host " .\BizTalkStatusTool.ps1 -After"
|
||
Write-Host " .\BizTalkStatusTool.ps1 -Compare"
|
||
Write-Host " .\BizTalkStatusTool.ps1 -Diag" |