As always over time scripts get updated and evolve – bring a bit of a powershell novice my scripts could probably do with a great deal of evolution but here’s version 2 of the script I posted previously
I imagine this will only really be interestng to me but I thoguht I’d post it anyway – no ones forcing you to read! (if someone is forcing you to read leave a comment and I’ll contact the authorities – I’m sure it counts as some form of torture).
decisions:
- it seemed their were too many foreach statements in the previous script that essentially did the same thing
- output was a mess
- the customer could need to check servers the farm deeped offline (this to check for another potential issue that I’ll post again once our resolution is tested)
- the code needed tidying up a bit
I would have liked to include powershell modules to call the test-port function but some machines the script ran on only have powershell 1.0 installed. I decided not to load the function as a PS1 script inline as their didnt seem alot of point.
Anyway here it is for those interested:
# ICAScan.ps1
# Script to check XenApp 5 farm for the existence of 3 service effecting issues that exist(ed) with the new XenApp 5 farm
function Test-Port{
[cmdletbinding( 
DefaultParameterSetName = ”, 
ConfirmImpact = ‘low’ 
)] 
Param( 
[Parameter( 
Mandatory = $True, 
Position = 0, 
ParameterSetName = ”, 
ValueFromPipeline = $True)] 
[array]$computer, 
[Parameter( 
Position = 1, 
Mandatory = $True, 
ParameterSetName = ”)] 
[array]$port, 
[Parameter( 
Mandatory = $False, 
ParameterSetName = ”)] 
[int]$TCPtimeout=1000, 
[Parameter( 
Mandatory = $False, 
ParameterSetName = ”)] 
[int]$UDPtimeout=1000, 
[Parameter( 
Mandatory = $False, 
ParameterSetName = ”)] 
[switch]$TCP, 
[Parameter( 
Mandatory = $False, 
ParameterSetName = ”)] 
[switch]$UDP
) 
Begin { 
If (!$tcp -AND !$udp) {$tcp = $True} 
#Typically you never do this, but in this case I felt it was for the benefit of the function 
#as any errors will be noted in the output of the report 
$ErrorActionPreference = “SilentlyContinue” 
$report = @() 
} 
Process { 
ForEach ($c in $computer) { 
ForEach ($p in $port) { 
If ($tcp) { 
#Create temporary holder 
$temp = “” | Select Server, Port, TypePort, Open, Notes 
#Create object for connecting to port on computer 
$tcpobject = new-Object system.Net.Sockets.TcpClient 
#Connect to remote machine’s port 
$connect = $tcpobject.BeginConnect($c,$p,$null,$null) 
#Configure a timeout before quitting 
$wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout,$false) 
#If timeout 
If(!$wait) { 
#Close connection 
$tcpobject.Close() 
Write-Verbose “Connection Timeout” 
#Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “TCP” 
$temp.Open = “False” 
$temp.Notes = “Connection to Port Timed Out” 
} 
Else { 
$error.Clear() 
$tcpobject.EndConnect($connect) | out-Null 
#If error 
If($error[0]){ 
#Begin making error more readable in report 
[string]$string = ($error[0].exception).message 
$message = (($string.split(“:”)[1]).replace(‘”‘,””)).TrimStart() 
$failed = $true 
} 
#Close connection 
$tcpobject.Close() 
#If unable to query port to due failure 
If($failed){ 
#Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “TCP” 
$temp.Open = “False” 
$temp.Notes = “$message” 
} 
#Successfully queried port 
Else{ 
#Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “TCP” 
$temp.Open = “True” 
$temp.Notes = “” 
} 
} 
#Reset failed value 
$failed = $Null 
#Merge temp array with report 
$report += $temp 
} 
If ($udp) { 
#Create temporary holder 
$temp = “” | Select Server, Port, TypePort, Open, Notes 
#Create object for connecting to port on computer 
$udpobject = new-Object system.Net.Sockets.Udpclient($p) 
#Set a timeout on receiving message
$udpobject.client.ReceiveTimeout = $UDPTimeout
#Connect to remote machine’s port 
Write-Verbose “Making UDP connection to remote server”
$udpobject.Connect(“$c”,$p)
#Sends a message to the host to which you have connected.
Write-Verbose “Sending message to remote host”
$a = new-object system.text.asciiencoding
$byte = $a.GetBytes(“$(Get-Date)”)
[void]$udpobject.Send($byte,$byte.length)
#IPEndPoint object will allow us to read datagrams sent from any source. 
Write-Verbose “Creating remote endpoint”
$remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any,0)
Try {
#Blocks until a message returns on this socket from a remote host.
Write-Verbose “Waiting for message return”
$receivebytes = $udpobject.Receive([ref]$remoteendpoint)
[string]$returndata = $a.GetString($receivebytes)
}
Catch {
If ($Error[0].ToString() -match “bRespond after a period of timeb”) {
#Close connection 
$udpobject.Close() 
#Make sure that the host is online and not a false positive that it is open
If (Test-Connection -comp $c -count 1 -quiet) {
Write-Verbose “Connection Open” 
Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “UDP” 
$temp.Open = “True” 
$temp.Notes = “”
}
Else {
<#
It is possible that the host is not online or that the host is online, 
but ICMP is blocked by a firewall and this port is actually open.
#>
Write-Verbose “Host maybe unavailable” 
#Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “UDP” 
$temp.Open = “False” 
$temp.Notes = “Unable to verify if port is open or if host is unavailable.” 
} 
}
ElseIf ($Error[0].ToString() -match “forcibly closed by the remote host” ) {
#Close connection 
$udpobject.Close() 
Write-Verbose “Connection Timeout” 
#Build report 
$temp.Server = $c 
$temp.Port = $p 
$temp.TypePort = “UDP” 
$temp.Open = “False” 
$temp.Notes = “Connection to Port Timed Out” 
}
Else {
$udpobject.close()
}
} 
#Merge temp array with report 
$report += $temp 
} 
} 
} 
} 
End { 
#Generate Report 
$report 
} 
}
#Obtain Servers List from Farm
$farm = new-Object -com “MetaframeCOM.MetaframeFarm”
$farm.Initialize(1)
$All=$farm.servers | select ServerName | %{$_.ServerName} | sort-object
$Online=$farm.zones | %{$_.OnlineServers} |select ServerName | %{$_.ServerName} | sort-object
#Date variables
$date=(get-date (get-date) -uformat %m%d%Y)
#Files to Check for
$FilePath=”c$Program”
#Define Servers to check
write-host “Online – Only checks servers the XenApp farm has marked as online (Default)”
write-host “All – Checks servers the XenApp farm (will result in errors for servers that are powered down)”
$CheckLevel=Read-host “Set Check Level (Online/All):”
if ($Checklevel -match “Online”){$Check=$Online}
elseif ($Checklevel -match “All”){$Check=$All}
else {
$Check=$Online
}
foreach ($server in $Check) 
{ 
$warning=”0″
if (test-port -computer $server -port 1494 | where {$_.open -match “False”})
{$ICA=”DOWN”
$warning=”1″}
else
{$ICA=”UP”}
if (Test-Path -path \$server$FilePath)
{$ProgramRenamed=”yes”
$warning=”1″
rename-item -path \$server$FilePath -newname Temp.$date
}
else
{$ProgramRenamed=”no”}
$wmi=Get-WmiObject -class Win32_OperatingSystem -computer $server
$LBTime=$wmi.ConvertToDateTime($wmi.Lastbootuptime)
[TimeSpan]$uptime=New-TimeSpan $LBTime $(get-date)
if ($uptime.days -lt 1-and $uptime.hours -lt 4){
$Rebooted=”yes”
$warning=”1″}
else
{$Rebooted=”no”}
if ($warning -eq “1”){
write-host -foregroundcolor “red” $Server “| ICA is:” $ICA “| File Renamed:” $ProgramRenamed “| Rebooted in last 4 hours:” $Rebooted
}
else {write-host -foregroundcolor “green” $Server “| ICA is:” $ICA “| File Renamed:” $ProgramRenamed “| Rebooted in last 4 hours:” $Rebooted}
if ($CheckLevel -match “Online”){
write-host “The following servers are marked as Offline:”
write-host $Offline}
}
