Skip to content

Instantly share code, notes, and snippets.

@PolarbearDK
Last active August 29, 2015 14:01
Show Gist options
  • Save PolarbearDK/ad5d6389907f0668c298 to your computer and use it in GitHub Desktop.
Save PolarbearDK/ad5d6389907f0668c298 to your computer and use it in GitHub Desktop.
param (
[parameter(Mandatory=$false)]
[alias("env")]
[int]$environment,
[parameter(Mandatory=$false, ValueFromPipeline=$true)]
[alias("s")]
[string[]]$service,
[parameter(Mandatory=$false)]
[alias("n")]
[string[]]$node,
[parameter(Mandatory=$false)]
[switch]$start,
[parameter(Mandatory=$false)]
[switch]$stop,
# [parameter(Mandatory=$false)]
# [switch]$stop-MSMQ,
# [parameter(Mandatory=$false)]
# [switch]$stop-DTC,
[parameter(Mandatory=$false)]
[switch]$restart,
[parameter(Mandatory=$false)]
[switch]$purge,
[parameter(Mandatory=$false)]
[switch]$status,
[parameter(Mandatory=$false)]
[alias("qs")]
[switch]$queuestatus,
[parameter(Mandatory=$false)]
[alias("is")]
[switch]$installstatus,
[parameter(Mandatory=$false)]
[alias("h")]
[switch]$help,
[parameter(Mandatory=$false)]
[alias("nf")]
[switch]$noformat,
[parameter(Mandatory=$false)]
[switch]$trace
)
if($help)
{
Write-Output "Usage: TrioUtil [-ENVironment number] [-Service service[,service...]] [-Node node[,node..]] {action...} [-NoFormat] [-Help]"
Write-Output "-Help: Command usage"
Write-Output "-ENVironment: Production environment number: 1=Prod1 2=Prod2 (ignored on test)"
Write-Output "-Service: Service name(s) (Coop.Dai. and Service may be omitted)"
Write-Output "-Node: Only apply for nodes matching this pattern"
Write-Output ""
Write-Output "Actions:"
Write-Output "-START: Start service(s)"
Write-Output "-STOP: Stop service(s)"
Write-Output "-RESTART: Restart service(s)"
Write-Output "-PURGE: Purge storage queues on distributer (implies restart)"
Write-Output "-STATUS: List status for service(s)"
Write-Output "-QueueStatus: List status for queues for service(s)"
Write-Output "-InstallStatus: List installation status for service(s)"
Exit
}
filter Match-Any-Pattern ( [string[]]$patterns ) {
# Check the current item against all patterns.
foreach( $pattern in $patterns ) {
# If one match, return the item.
if($_ -like $pattern -or $_.ToLower().Contains($pattern.ToLower())) {
return $_
}
}
}
function trace {
param($message)
if($trace) { Write-Host $message }
}
############
## BEGIN Cluster functions
############
Import-Module FailoverClusters >$null 2>$null
if((Get-Module -name FailoverClusters)) {
$cluster = $true
$ClusterCache = @{}
}
else
{
$cluster = $false
}
trace "cluster: $cluster"
function is-cluster([string]$srvName)
{
if($cluster)
{
if (-Not ($ClusterCache.ContainsKey($srvName)))
{
if (Get-ClusterResource -Cluster $srvName -Name $srvName >$null 2>$null)
{
$ClusterCache.Add($srvName, $True)
}
else
{
$ClusterCache.Add($srvName, $False)
}
}
$ClusterCache[$srvName]
trace ("is-cluster: $srvName? " + $ClusterCache[$srvName])
}
else
{
$false
}
}
function stop-cluster-service-On {
param($clusterName,$serviceName)
trace "Stop $serviceName on cluster: $clusterName"
Get-ClusterResource -Cluster $clusterName | where { $_.Name -like $serviceName } | %{
if ($_.State -eq 'Online') { Stop-ClusterResource -Name $_.Name -Cluster $clusterName; write-host $_.Name taken offline -ForegroundColor Green; }
else { write-host $clusterName $_.Name is $_.State -ForegroundColor Yellow }
}
}
function start-cluster-service-On {
param($clusterName,$serviceName)
trace "Start $serviceName on cluster: $clusterName"
Get-ClusterResource -Cluster $clusterName | where { $_.Name -like $serviceName } | %{
if ($_.State -eq 'Offline') { Start-ClusterResource -Name $_.Name -Cluster $clusterName; write-host $_.Name taken online -ForegroundColor Green; }
else { write-host $clusterName $_.Name is $_.State -ForegroundColor Yellow }
}
}
function get-cluster-service-status {
param($clusterName,$serviceName)
Get-ClusterResource -Cluster $clusterName | where { $_.Name -like $serviceName } | %{ $_.State }
}
############
## END Cluster functions
############
function simplify-service {
param([string]$name)
if($name.ToLower().StartsWith("coop.dai."))
{
$name = $name.SubString(9)
}
if($name.ToLower().EndsWith("service"))
{
$name = $name.SubString(0, $name.Length-7)
}
$name
}
function simplify-server {
param([string]$name)
if($name.ToUpper().EndsWith($domain))
{
$name.SubString(0, $name.Length - $domain.Length - 1)
}
else
{
$name
}
}
# get service role from service command line
function get-service-role {
param([string]$pathName)
if($pathName.Contains("NServiceBus.Distributor")) { "Distributor" }
elseif ($pathName.Contains("NServiceBus.Worker")) { "Worker" }
elseif ($pathName.Contains("NServiceBus.MSMQDistributor")) { "Distributor" }
elseif ($pathName.Contains("NServiceBus.MSMQWorker")) { "Worker" }
else { "Single" }
}
function purge-queue{
param($queueName)
foreach($distributor in $distributors) {
trace "Distributor $distributor queue $queuename"
foreach($queue in [System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($distributor)) {
if($queue.QueueName -like ("*" + $queuename)) {
$queue.Purge()
$queueName = $queue.QueueName -replace "private\$\\",""
Write-Host $queueName on $distributor has been purged. -ForegroundColor Yellow
}
}
}
}
function purge-distributor-queues {
param($queueName)
purge-queue ($queueName + "*.distributor.storage")
purge-queue ($queueName + "*.distributor.control")
}
function stop-service-on {
param($serverName,$serviceName)
if (is-cluster $serverName) {
stop-cluster-service-on $serverName $serviceName
return
}
trace "Stop $serviceName on $serverName"
Get-Service -ComputerName "$serverName" -include Coop.Dai.* | where {$_.Name -like $serviceName} | %{
if($_.Status -eq 'Running'){ $_.Stop(); Write-Host $_.Name on $serverName stopped -ForegroundColor Green;}
else{ Write-Host $_.Name on $serverName is $_.Status -ForegroundColor Yellow}
}
}
function start-service-on {
param($serverName,$serviceName)
if (is-cluster $serverName) {
start-cluster-service-on $serverName $serviceName
return
}
trace "Start $serviceName on $serverName"
Get-Service -ComputerName "$serverName" -include Coop.Dai.* | where {$_.Name -like $serviceName} | %{
if($_.Status -eq 'Stopped'){ write-host $_.Name on $serverName started; $_.Start();}
else{ Write-Host $_.Name on $serverName is $_.Status -ForegroundColor Yellow}
}
}
function status-service-on {
param($serverName,$serviceName)
trace "Getting services from $serverName matching $serviceName"
Get-WmiObject -ComputerName "$serverName" win32_service | where {$_.name -like $serviceName} | %{
$svcName = $_.Name
trace "Processing $svcName on $serverName"
switch($_.StartMode)
{
"Auto" { $startMode = "Auto" }
default
{
$startMode = " (" + $_ + ")"
if($color -eq "Green") { $color = "Yellow" }
}
}
trace "startMode is: $($startMode)"
trace "Service path $($_.PathName)"
$role = get-service-role $_.PathName
trace "Role is: $role"
if (is-cluster $serverName) {
trace "$serverName is a cluster name"
$serviceStatus = ($_.State)
Get-ClusterResource -Cluster "$serverName" | where {$_.name -like $svcName} | %{
trace "$($_.name), $($_.State)"
New-Object PSObject -Property @{
Service = simplify-service $svcName
Node = simplify-server $serverName
Role = $role
ClusterStatus = ($_.State)
ServiceStatus = $serviceStatus
StartMode = $startMode
isCluster = $true
}
}
}
else {
New-Object PSObject -Property @{
Service = simplify-service($svcName)
Node = simplify-server($serverName)
Role = $role
ServiceStatus = $_.State
StartMode = $startMode
ClusterStatus = ""
isCluster = $false
}
}
}
}
function queuestatus-service-on {
param($serverName,$serviceName)
trace "Getting services from $serverName matching $serviceName"
Get-WmiObject -ComputerName "$serverName" win32_service | where {$_.name -like $serviceName} | %{
$basename = simplify-service($_.Name)
trace "Getting queues from $service for service $basename"
New-Object PSObject -Property @{
Service = $basename
Node = simplify-server($serverName)
Role = get-service-role $_.PathName
Status = $_.State
Queue = [MQEX.MessageQueueExtensions]::GetPrivateQueueCount($serverName, ($basename + "service"))
Storage = [MQEX.MessageQueueExtensions]::GetPrivateQueueCount($serverName, ($basename + "service.distributor.storage"))
Control = [MQEX.MessageQueueExtensions]::GetPrivateQueueCount($serverName, ($basename + "service.distributor.control"))
Timeouts = [MQEX.MessageQueueExtensions]::GetPrivateQueueCount($serverName, ($basename + "service.distributor.timeouts"))
}
}
}
function installstatus-service-on {
param($serverName,$serviceName)
trace "Getting services from $serverName matching $serviceName"
$servicesOnNode = Get-WmiObject -ComputerName "$serverName" win32_service | where {$_.name -like $serviceName}
$files = Get-ChildItem -Path \\$serverName\Trio\Services\Coop.Dai.*\NServiceBus.Host.exe
if($files -eq $null) {
$files = Get-ChildItem -Path \\$serverName\d$\Trio\Services\Coop.Dai.*\NServiceBus.Host.exe
}
$files | % {
$folder = [io.path]::GetFileName($_.DirectoryName)
$serviceOnNode = $servicesOnNode | where {$_.name -eq $folder}
if($folder -Like "Coop.Dai.*") {
$folder = $folder.SubString(9)
}
if($serviceOnNode -eq $null) {
$role = "None"
$status = "Not installed"
}
else {
$role = get-service-role $serviceOnNode.PathName
$status = $serviceOnNode.State
}
New-Object PSObject -Property @{
Service = $folder
Node = simplify-server($serverName)
Role = $role
Status = $status
}
}
}
#main script starts here
$scriptPath = Split-Path $MyInvocation.MyCommand.Path
trace "scriptPath: $scriptPath"
$domain = $env:USERDNSDOMAIN.ToUpper()
switch ($domain)
{
"INTRA.COOP" {
$envbase = ("D:\Environments\PROD" + $environment)
$domain = "BUTIK.COOP"
}
"BUTIK.COOP" { $envbase = ("D:\Environments\PROD" + $environment) }
"TRIOPROD.LOCAL" { $envbase = ("D:\Environments\PROD" + $environment) }
"TRIOSTAGING.LOCAL" { $envbase = ("D:\Environments\PROD" + $environment) }
"COOPDEV.LOCAL" { $envbase = "\\trioconfig.coopdev.local\Environments\TEST" }
default {
Write-Host "Unhandled userdomain $domain"
exit
}
}
$distributors = Get-Content ($envbase + "*_Distributor")
trace "Distributors: $distributors"
$nodes = @();
$nodes += Get-Content ($envbase + "*_Distributor") | sort {$_}
$nodes += Get-Content ($envbase + "*_Gateway") | sort {$_}
$nodes += Get-Content ($envbase + "*_Workernodes") | sort {$_}
$nodes += Get-Content ($envbase + "*_Global") | sort {$_}
trace "Nodes: $nodes"
if($service.length -eq 0) {
$service += "*"
}
if($node.length -gt 0) {
$nodes = $nodes | Match-Any-Pattern $node
}
[Reflection.Assembly]::LoadWithPartialName("System.Messaging") | Out-Null
$assemblyLocation = Join-Path $scriptPath "MQEX.dll"
[Reflection.Assembly]::LoadFrom($assemblyLocation) | Out-Null
foreach($svc in $service) {
if($svc -NotLike "*Service") {
$svc = $svc + "*Service"
}
if($svc -Like "Coop.Dai.*") {
$svc = $svc.SubString(9)
}
$serviceName = "Coop.Dai." + $svc
if($stop -or $restart -or $purge) {
$nodes | %{ stop-service-on $_ $serviceName }
}
if($purge) {
purge-distributor-queues $svc
}
if($start -or $restart -or $purge) {
$nodes | %{ start-service-on $_ $serviceName }
}
if($status) {
$result = $nodes |
%{ status-service-on $_ $serviceName } |
sort-object Service, Node
if($noformat) {
$result
}
else {
$result | format-table Service, Node, Role, ServiceStatus, StartMode, ClusterStatus, isCluster -Autosize
}
}
elseif($queuestatus) {
$result = $nodes |
%{ queuestatus-service-on $_ $serviceName } |
sort-object Service, Node
if($noformat) {
$result
}
else {
$result | format-table Service, Node, Role, Status, Queue, Storage, Control, Timeouts -Autosize
}
} elseif($installstatus) {
$result = $nodes |
%{ installstatus-service-on $_ $serviceName } |
sort-object Service, Node
if($noformat) {
$result
}
else {
$result | format-table Service, Node, Role, Status -Autosize
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment