miércoles, 14 de enero de 2015

XenApp 7.6 : How setup Virtual IP Range using a Batch File automatically

Hallo, gutten morgen aus Deutschland !!

Today I have a simple script to setup automatically several Virtual IP ranges in our citrix farm.

According to Citrix KB: http://support.citrix.com/article/CTX137163 to configure virtual ip we need use Microsoft Technologies (RD Configuration). To get this goal, it is necessary modify a few registry keys to setup specific range of Virtual IP in each Citrix Server.

Obviuosly, if you need perform this task in several citrix servers, maybe if you have 50 or 100 servers, to can take a lot off time. Maybe in this case you can run a simple batch file to load these registry keys:

To get this I have made a batch file like this:

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
::  File Name: ConfigureVIP_xa76_v01.cmd
::  Author: citrixpedia@gmail.com
::  Date: 14-01-2015
::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


@echo off

FOR /F "eol=# tokens=1,2,3,4 delims=; " %%i in (vip.ini) do (

REG ADD \\%%i\HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP /v IPPool /t REG_SZ /d %SystemRoot%\system32\TSVIPool.dll /f

REG ADD \\%%i\HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP\IPPool /v Start /t REG_SZ /d %%j /f
REG ADD \\%%i\HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP\IPPool /v End /t REG_SZ /d %%k /f
REG ADD \\%%i\HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP\IPPool /v Subnetmask /t REG_SZ /d %%l /f

)


But you need a input file (*.INI or some TXT planin input file) to get all virtual IP ranges information:

#-----------------------------------------------------------------------------------------------
#
# servername or IP addrees ; starting ip addresses ; ending ip addresses ; subnetmask address
#
#-----------------------------------------------------------------------------------------------

xa7601.ctxlab.local;10.0.0.1;10.0.0.100;255.0.0.0
xa7602.ctxlab.local;10.0.0.101;10.0.0.200;255.0.0.0

Enjoy !!!




lunes, 15 de diciembre de 2014

Where Medevac is Failing ... you can use Perl

Hi to everyone!!!

Citrix Medevac is a fantastic tool but does not work fine with xenapp 6.5.
If you need check your XML Servicers healthy, you can use Perl to launch a script, it is the same used by Netscaler to monitoring the XML service, or very similar.

This script is tested with Perl Strawberry 5.x and works fine.

Only you need publish a app in the XML servers and you must launch the script to the specific servers and asking by this app. You can use a Batch file to run the script to the all brokers servers.
If you have xenapp 5, you can use this script to test all xenapp servers in the farm.

Ok, it is true. you can use third parties monitoring to acomplish this task, but come on....a lot off times this agents are not working. or maybe, if some 'monkey' of monitoring department call you at 3 A.M. you need a simple script to test really the healthy of all entire citrix farm.


If you have a txt file with all XML servers, you can create a batch script like thius to launch the perl script:

FOR /F "eol=; tokens=1 delims=; " %%i in (xmlbroker.txt) do (
CitrixTestXMLService_v02.pl %%i 8080 "notepad-xml-service" %historic_file% %Log_file%
)


And this is the Perl Script:

#!/usr/bin/perl -w
# This script can be run at the command line on a laptop or server
# to verify functionality of the Citrix XML Service
# To invoke this script type:
# perl test_xml_service.pl <ipaddress> <xml_port> [ appname ] #
#!/usr/local/bin/perl

use strict;
use IO::Socket;

my $now_string = localtime;

if ($#ARGV < 1) {
print "\nUsage: perl test_xml_service.pl <ipaddress> <xml_port> [app name]\n";
exit 0;
}
my $ip_address = $ARGV[0];
my $xml_port = $ARGV[1];
my $hostname = `hostname`;
my $app = $ARGV[2] || "notepad";

chop($hostname);

open(LOGFILE, ">>", $ARGV[3]);
open(STDERR, ">>", $ARGV[4]);

my $xml_request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
"<!DOCTYPE NFuseProtocol SYSTEM \"NFuse.dtd\">\n" .
"<NFuseProtocol version=\"4.1\">\n" .
"<RequestAddress>\n" .
"<Flags>no-load-bias</Flags>" .
"<Name>\n" .
"<AppName>$app</AppName>\n" .
"</Name>\n" .
"</RequestAddress>\n" .
"</NFuseProtocol>\n";
my $content_length = length($xml_request);
my $header = "POST /scripts/wpnbr.dll HTTP/1.1\r\n" .
"Content-Type: text/xml\r\n" .
"Content-Length: $content_length\r\n" .
"Host: $hostname\r\n" .
"\r\n";
print "Target Server: $ip_address:$xml_port\n";
print "Header:\n";
print $header;
print "XML Request:\n";
print $xml_request . "\n";
print "-------\n\n";
my $socket1 = IO::Socket::INET->new(PeerAddr => $ip_address,PeerPort => $xml_port,
Proto => 'tcp')  || die $ARGV[0] . ":" . $ARGV[1] . " -> $@ " . $now_string . " ;\n";
print $socket1 $header . $xml_request;
my @output;
while (<$socket1>) {
if (m/\<\/NFuseProtocol\>/) {
close($socket1);
last;
}
else {
push @output, $_;
}
}
push @output, $_;
print @output;
my $output;
foreach $output (@output)
{
if ($output =~ /tickettag/i) {
print LOGFILE $ARGV[0] . " " . $ARGV[1] . " " . " -> exit 0 - " . $now_string . "\n"; 
exit 0;
}
}
@output = "null";
print STDERR $ARGV[0] . ":" . $ARGV[1] . " -> exit 1 " . $now_string . " ;\n"; 
print LOGFILE $ARGV[0] . ":" . $ARGV[1] . " -> exit 1 - " . $now_string . " ;\n"; 
exit 1;

How Get Events of Task Scheduler using Powershell

Hi script guys!

For today I have a simple script to collect events of task scheduler.
It is very easy and I think practice some times, because we can have several tasks scheduled in a system and review if they are working fine it is not funny .... :-(

enjoy it!!!


<# =======================================================================

File Name: GetEventsTaskScheduler_v01.ps1

Author: citrixpedia@gmail.com
Date: 9-dic-2014

Comments: Script to get all events of task scheduler and outpu to text file


======================================================================= #>


#-------------------------------------

# Get Location of script
#-------------------------------------

Get-Location | ForEach-Object { $myPath = $_.Path }


$outputfile= $myPath + "\EventsTaskSchedule.log"


#-------------------------------------

# Get Events
#-------------------------------------

get-winevent -LogName 'Microsoft-Windows-TaskScheduler/Operational' | Where-Object { $_.LevelDisplayName -match "Error" } | fl LevelDisplayName, TimeCreated, OpcodeDisplayName, TaskDisplayName, MachineName, Message | Out-File -Encoding ascii $outputfile


Checking with Powershell if Citrix XenApp 7.6 Services are running

Hi Citrix guys.

This time only I have a simple script to check if all citrix services are runing.
If some service is Stopped, restart again and send an email to report.

Das ist nicht Cool

<# =======================================================================

File Name: CheckCitrixMonitoring_v01.ps1

Author: citrixpedia@gmail.com

Comments: Script developed to check citrix monitoring services. if the services is stopped, it will be started and it will send an email.


======================================================================= #>


$LogFileName="$env:TEMP\CheckCitrixMonitoring.log"

$smtpServer="<smtp_server_fqdn>"
$smtpFrom="<sender_address>"
$smtpAddress="<recipiente_address>"

$eventSource="Citrix Monitoring"

$eventID=7601

#-------------------------------------

# create body message
#-------------------------------------

$header = "The following services were stopped and it has proceeded to start them again.`nPlease, check them: "

$footer= "Please, notify to: $smtpAddress about this message."

#------------------------------

# write event in the system
#------------------------------

New-EventLog -LogName System -Source $eventSource


#-------------------------------------

# Check Citrix Services and if the service is stopped, restart again and send mail to report
#-------------------------------------


$stoppedServices=Get-Service | Where-Object {$_.DisplayName -like "*Citrix*"} | Where-Object {$_.Status -eq "Stopped"} | fl display*,status

$stoppedServices | Out-File -Encoding ASCII $LogFileName

if ($stoppedServices) {

    $readFile=Get-Content -Encoding ASCII $LogFileName
    Get-Service | Where-Object {$_.DisplayName -like "*Citrix*"} | Where-Object {$_.Status -eq "Stopped"}| Start-Service
    Write-EventLog -LogName System -Source $eventSource -EventId $eventID "Warning" –Message "`n$header`n`n$readFile`n`n$footer"

    Send-mailmessage -SmtpServer $smtpServer -from $smtpFrom -to $smtpAddress1 -Subject "Citrix Monitoring Alert -> $env:COMPUTERNAME" -body "`n$header`n`n$readFile`n`n" -Attachments $LogFileName


}




How Dump Citrix XenApp 7.6 User Session Information every hour to AACB database

Hi scripting guys again.

For today I have additional example using powershell with XenApp 7.6
This script get all citrix Site information and dump this user sessions in a Access 2013 database.
If you have installed Office 2013 64bits, you will need install engine DB for 32bits.

Feel you free to contact me to send me some comments or suggestions about this script.



<# =======================================================================

File Name: GetCurrentCitrixSessions_v01.ps1
Author: citrixpedia@gmail.com

Comments: Script to get all sessions active in the Site and dump this info into Access DB (2013).

======================================================================= #>

#-------------------------------------
# Get Location of script
#-------------------------------------

Get-pssnapin -registered | add-pssnapin -passthru | out-null

$myPath = "D:\FarmUsage.DB"

#------------------------------------------------------------------------
# Function to invoke DB
#------------------------------------------------------------------------

Function Invoke-ADOCommand($db, $command) {
$connection = New-Object -ComObject ADODB.Connection
$connection.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$db")
$connection.Execute($command) | Out-Null 
$connection.Close() 
}


#-------------------------------------------------------------------
# Build date string to add to each filename: "dd-mm-yyyy and hh:mm"
#-------------------------------------------------------------------

$myDate = Get-Date -UFormat "%d-%m-%Y"
$myHour = Get-Date -UFormat "%H:%M"
$myDB = $myPath + "\SiteXA76scb.accdb"


#------------------------------------------------------------------------
# Get Current Size of DB and is Greater Than 250MB move to backup folder
# and take the empty file (db structure only)
#------------------------------------------------------------------------

Get-Item $myDB | ForEach-Object { $mySize = $_.Length/1024/1024 }
if ( $mySize -gt 250 ) {
$myTarget = $myPath + "\back_template\SiteXA76scb_BAK_" + $myDate + ".accdb"
$myTemplate = $myPath + "\back_template\Template_Sitexa76scb.accdb"

Move-Item -path $myDB -destination $myTarget
Copy-Item $myTemplate -destination $myDB
}


#--------------------------------------------------------------------------------------------------
# Count Number of sessions (distinct HW ID)
#--------------------------------------------------------------------------------------------------

Get-BrokerSession | where { $_.ConnectionMode -eq "Brokered" -and $_.SessionState -eq "Active" -and $_.SessionType -eq "Application" } | Select HardwareId -unique | Measure | ForEach-Object { $Licenses = $_.Count }

Get-BrokerSession | where { $_.ConnectionMode -eq "Brokered" -and $_.SessionState -eq "Active" -and $_.SessionType -eq "Application" } | ForEach-Object { 
$myAppsArray = $_.ApplicationsInUse
$myApps = ""
ForEach ($app in $myAppsArray) {
if ($app -and $myApps) {$myApps = $myApps + "," + $app}
elseif ($app -and -not $myApps) {$myApps = $app}
}

#--------------------------------------
# Insert into DB Sessions & Licenses
#--------------------------------------

$myString = "Insert into Sessions (Tag, Uhr, AgentVersion, ApplicationsInUse, CatalogName, DesktopGroupName, ClientAddress, ClientName, ClientVersion, ControllerDNSName, StoreFrontHostName, ServerName, Protocol, UserName) VALUES ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}' )" -f $myDate, $myHour, $_.AgentVersion, $myApps, $_.CatalogName, $_.DesktopGroupName, $_.ClientAddress, $_.ClientName, $_.ClientVersion, $_.ControllerDNSName, $_.LaunchedViaHostName, $_.MachineName, $_.Protocol, $_.UserName
Invoke-ADOCommand -db $myDB -command $myString

$myString = "Insert into Licenses (Tag, Uhr, UserConnections) VALUES ('{0}','{1}','{2}')" -f $myDate, $myHour, $Licenses
Invoke-ADOCommand -db $myDB -command $myString
}

How Export all Citrix XenApp 7.6 apps in a CSV file

An option could be get all information about XenApp 7.6 Site and exporting each Delivery Group.
To acomplish this firstly it is necessary get all delivery groups and late, using the attributte UUID, connect to each delivery Group to get all applications inside this group.

If you thinsk you can improove this script, please, send me your improovements to this mail: citrixpedia@gmail.com 

thanks and enjoy it!!

<# =======================================================================

File Name: ExportDeliveryGroupApps_v01.ps1

Author: citrixpedia@gmail.com
Date: 25-nov-2014

Comments: Script developed to get all apps information for each Delivery Group and dump this info in a different csv file.


======================================================================= #>


#-------------------------------------

# Get Location of script
#-------------------------------------

Get-pssnapin -registered | add-pssnapin -passthru


Get-Location | ForEach-Object { $myPath = $_.Path }

$myDate = Get-Date -UFormat "%Y-%m-%d %H%M"

#--------------------------------------------------------------------------------------------------

# Create a "....DeliveryGroups.csv" file with a list of all delivery groups and users permissions
#--------------------------------------------------------------------------------------------------

$myFileName = $myPath + "\" + $myDate + "_DeliveryGroups.csv"

$header = "DeliveryName;UUId;ColorDepth;Enabled;NumPublishedApplications;IncludedUsers"
$header | Out-File $myFileName -encoding ASCII 

Get-BrokerDesktopGroup | Where-Object {$_.Enabled -eq "True"} | ForEach-Object { 

if ($_.Name) { $myDesktopGroupName = $_.Name }
$myString = $_.Name + ";" + $_.UUId + ";" + $_.ColorDepth + ";" + $_.Enabled + ";" + $_.TotalApplications

#--------------------------------------------------------------------------------------------------

#   Get-BrokerAccessPolicyRule -> this CMDLET permits get access permissions
#--------------------------------------------------------------------------------------------------
Get-BrokerAccessPolicyRule | Where-Object { $_.uid -eq "1" -and $_.DesktopGroupName -eq $myDesktopGroupName } | ForEach-Object { 
if ($_.IncludedUsers) { $myIncludedUsers = $_.IncludedUsers }
}
$myUsers = ""
$myIncludedUsers | ForEach-Object {
if ($_.Name -and $myUsers) {$myUsers = $myUsers + "," + $_.Name}
elseif ($_.Name -and -not $myUsers) {$myUsers = $_.Name}
}
$myString + ";" + $myUsers | Add-Content $myFileName
}

#----------------------------------------------------------------------------------------------------------------

# Create a "....<delivery_group_name>_DeliveryGroupApps.csv" file with a list of all apps for each delivery group
# UUID is the attribute to identify and link apps and delivery groups
#----------------------------------------------------------------------------------------------------------------

Get-BrokerDesktopGroup | Where-Object {$_.Enabled -eq "True"} | ForEach-Object { 

$myUUID= $_.UUID
$myFileName = $myPath + "\" + $myDate + "_" + $_.name + "_DeliveryGroupApps.csv"
$myHeader = "AdminFolderName;ApplicationName;ApplicationType;DisplayName;ClientFolder;CommandLineArguments;CommandLineExecutable;AppName;PublishedName;Visible;WaitForPrinterCreation;WorkingDirectory"
$myHeader | Out-File $myFileName -encoding ASCII 

$apps = Get-BrokerApplication -SortBy Name | Where-Object { $_.AssociatedDesktopGroupUUIDs -eq $myUUID }


Foreach ($app in $apps) {
$myString = $app.AdminFolderName + ";" + $app.ApplicationName + ";" + $app.ApplicationType + ";" + $app.BrowserName + ";" + $app.ClientFolder + ";" + $app.CommandLineArguments + ";" + $app.CommandLineExecutable + ";" + $app.Name + ";" + $app.PublishedName + ";" + $app.Visible + ";" + $app.WaitForPrinterCreation + ";" + $app.WorkingDirectory
$myString | Add-Content $myFileName
}
}