-
Notifications
You must be signed in to change notification settings - Fork 1
/
Lockstep - Citrix XenApp Performance.ps1
201 lines (163 loc) · 8.5 KB
/
Lockstep - Citrix XenApp Performance.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
###############################################################################
#
# prtg citrix xenapp monitor (xenapp performance + growth)
# mar 4, 2013
#
###############################################################################
#
# Citrix documentation on this subject
# http://support.citrix.com/article/CTX133540
#
###############################################################################
#
# PRTG configuration:
# ensure the executing security context has the needed permissions
# this likely means "Use Windows credentials of parent device"
# also set "Parameters to "%host" (without the quotes).
#
###############################################################################
# script parameters
Param (
[Parameter(Position=0)]
[string]$ComputerName
)
# parameter options to require this don't send enough info back to prtg. do it manual!
# is there a better way to handle this?
if (!($ComputerName)) {
return @"
<prtg>
<error>1</error>
<text>Required parameter not specified: please provide target hostname (or %host)</text>
</prtg>
"@
}
$TimerStart = Get-Date
###############################################################################
# load the prtgshell module
function Import-MyModule {
Param(
[string]$Name
)
if ( -not (Get-Module -Name $Name) ) {
if ( Get-Module -ListAvailable | Where-Object { $_.Name -eq $Name } ) {
Import-Module -Name $Name
$true # module installed + loaded
} else {
$false # module not installed
}
}
else {
$true # module already loaded
}
}
$ModuleImportSuccess = Import-MyModule PrtgShell
if (!($ModuleImportSuccess)) {
return @"
<prtg>
<error>1</error>
<text>PrtgShell module not loaded: ensure the module is visible for 32-bit PowerShell</text>
</prtg>
"@
}
###############################################################################
# initial wmi connection tests (fail-fast)
function Get-TargetStatus {
Param (
[Parameter(mandatory=$True,Position=0)]
[string]$ComputerName,
[Parameter(Position=1)]
[string]$ServiceName = "SamSs"
)
$wmi = [WMISearcher]""
$wmi.options.timeout = '0:0:5' # 5-second timeout
$wmi.scope.path = "\\$ComputerName\Root\CIMV2"
$wmi.query = 'Select Status from Win32_Service where Name= "' + $ServiceName + '"'
try {
$ServiceStatus = ($wmi.Get() | select Status).Status
} catch {
if ($_.Exception.InnerException) {
return "Error: $($ComputerName): " + $_.Exception.InnerException.Message
} else {
return "Error: $($ComputerName): " + $_.Exception.Message
}
}
if ($ServiceStatus -eq "OK") {
return $true
} else {
return "Error: $($ComputerName): $ServiceName not running."
}
}
$CheckServer = Get-TargetStatus $ComputerName "IMAService"
if ($CheckServer -ne $true) {
return @"
<prtg>
<error>1</error>
<text>$CheckServer</text>
</prtg>
"@
}
###############################################################################
$ReturnText = "OK" # this is the default
###############################################################################
#### queries from citrix documentation: "Operations Guide - Monitoring.pdf"
# XenApp Performance Counters
$wql = "Select ApplicationResolutionTimems,DataStoreConnectionFailure,NumberofbusyXMLthreads,ResolutionWorkItemQueueReadyCount,WorkItemQueueReadyCount,ApplicationResolutionsPersec,ApplicationEnumerationsPersec,FilteredApplicationEnumerationsPersec from Win32_PerfFormattedData_MetaFrameXP_CitrixMetaFramePresentationServer"
$QueryObject = Get-WmiObject -Query $wql -computername $computername
$ApplicationResolutionTimems = $QueryObject.ApplicationResolutionTimems # baseline to determine thresholds
$DataStoreConnectionFailure = $QueryObject.DataStoreConnectionFailure # warning: over one minute
$NumberofbusyXMLthreads = $QueryObject.NumberofbusyXMLthreads # warning at 10; 16 is "full", there's 16 threads
$ResolutionWorkItemQueueReadyCount = $QueryObject.ResolutionWorkItemQueueReadyCount # warn at greater than zero
$WorkItemQueueReadyCount = $QueryObject.WorkItemQueueReadyCount # warn at greater than zero
# XenApp Growth Tracking
$ApplicationResolutionsPersec = $QueryObject.ApplicationResolutionsPersec
$ApplicationEnumerationsPersec = $QueryObject.ApplicationEnumerationsPersec
$FilteredApplicationEnumerationsPersec = $QueryObject.FilteredApplicationEnumerationsPersec
# this is for the script metrics, not xenapp
$TimerInitialExecution = Get-Date
# for growth tracking
$wql = "Select TotalSessions from Win32_TerminalService"
$QueryObject = Get-WmiObject -Query $wql -computername $computername
if ($QueryObject) {
#windows 2008
$TotalSessions = $QueryObject.TotalSessions
} else {
#windows 2003
$wql = "Select TotalSessions from Win32_PerfFormattedData_TermService_TerminalServices"
$QueryObject = Get-WmiObject -Query $wql -computername $computername
$TotalSessions = $QueryObject.TotalSessions
}
$wql = "Select LicenseServerConnectionFailure,LastRecordedLicenseCheckOutResponseTimems,AverageLicenseCheckOutResponseTimems from Win32_PerfFormattedData_CitrixLicensing_CitrixLicensing"
try {
$QueryObject = Get-WmiObject -Query $wql -computername $computername -ErrorAction Stop
$LicenseServerConnectionFailure = $QueryObject.LicenseServerConnectionFailure # warning at greater than 1 minute, failure at 1440 minutes (one day)
$LastRecordedLicenseCheckOutResponseTimems = $QueryObject.LastRecordedLicenseCheckOutResponseTimems # warning at 2000 ms, error at 5000 ms
# XenApp Growth Tracking
$AverageLicenseCheckOutResponseTimems = $QueryObject.AverageLicenseCheckOutResponseTimems
} catch {
# do nothing, just silence the error
}
###############################################################################
$TimerStop = Get-Date
$InitialExecutionTime = $TimerInitialExecution - $TimerStart
$ExecutionTime = $TimerStop - $TimerStart
###############################################################################
# output
$XMLOutput = "<prtg>`n"
$XMLOutput += Set-PrtgResult "Sensor Initial WMI Connection Time" $InitialExecutionTime.TotalMilliseconds "ms"
$XMLOutput += Set-PrtgResult "Sensor Total Execution Time" $ExecutionTime.TotalMilliseconds "ms"
if ($ApplicationResolutionTimems -ne $null) { $XMLOutput += Set-PrtgResult "Application Resolution Time" $ApplicationResolutionTimems "ms" -ShowChart }
if ($DataStoreConnectionFailure -ne $null) { $XMLOutput += Set-PrtgResult "Datastore Connection Failure" $DataStoreConnectionFailure "minutes" -MaxWarn 1 -WarnMsg "Data store disconnected for more than one minute." }
if ($NumberofbusyXMLthreads -ne $null) { $XMLOutput += Set-PrtgResult "Number of busy XML threads" $NumberofbusyXMLthreads "#" -ShowChart -MaxWarn 10 -MaxError 16 -WarnMsg "XML threads queue deep." -ErrorMsg "XML threads queue full." }
if ($ResolutionWorkItemQueueReadyCount -ne $null) { $XMLOutput += Set-PrtgResult "Resolution WorkItem Queue Ready Count" $ResolutionWorkItemQueueReadyCount "#" -ShowChart -MaxWarn 1 -WarnMsg "WorkItem requests queuing." }
if ($WorkItemQueueReadyCount -ne $null) { $XMLOutput += Set-PrtgResult "WorkItem Queue Ready Count" $WorkItemQueueReadyCount "#" -ShowChart -MaxWarn 1 -WarnMsg "WorkItem requests queuing." }
if ($LicenseServerConnectionFailure -ne $null) { $XMLOutput += Set-PrtgResult "Licensing: Server Connection Failure" $LicenseServerConnectionFailure "minutes" -MaxWarn 1 -MaxError 1440 -WarnMsg "Disconnected from Licensing Server (grace period)." -ErrorMsg "Disconnected from Licensing Server." }
if ($LastRecordedLicenseCheckOutResponseTimems -ne $null) { $XMLOutput += Set-PrtgResult "Licensing: Check-Out Response Time" $LastRecordedLicenseCheckOutResponseTimems "ms" -ShowChart -MaxWarn 2000 -MaxError 5000 -WarnMsg "High latency license check-outs from License Server." -ErrorMsg "Extremely high latency license check-outs from License Server." }
if ($ApplicationResolutionsPersec -ne $null) { $XMLOutput += Set-PrtgResult "Growth: Application Resolutions/sec" $ApplicationResolutionsPersec "#" }
if ($ApplicationEnumerationsPersec -ne $null) { $XMLOutput += Set-PrtgResult "Growth: Application Enumerations/sec" $ApplicationEnumerationsPersec "#" }
if ($FilteredApplicationEnumerationsPersec -ne $null) { $XMLOutput += Set-PrtgResult "Growth: Filtered Application Enumerations/sec" $FilteredApplicationEnumerationsPersec "#" }
if ($TotalSessions -ne $null) { $XMLOutput += Set-PrtgResult "Growth: Terminal Services Total Sessions" $TotalSessions "#" }
if ($AverageLicenseCheckOutResponseTimems -ne $null) { $XMLOutput += Set-PrtgResult "Growth: Average License Check-Out Response" $AverageLicenseCheckOutResponseTimems "ms" }
$XMLOutput += " <text>$ReturnText</text>"
$XMLOutput += "</prtg>"
$XMLOutput