PowerShell: E-mail Server Load and Assigned LE

NOTE: I recently updated this script for XenApp 7.x environments.
Note: I wrote this script for a XenApp 5.0 environment with PowerShell 2.0 and CTP3 XenApp Cmdlets.

Update: I found that the simple ping used with Test-Connection PowerShell cmdlet was not identifying servers that were not available for login. In our environment we occasionally have a server come back from a scheduled reboot and ping, but not allow RDP/ICA connections. I’ve incorporated a Test-Port function from Aaron Wurthmann’s PowerShell Script Connect-RDP.ps1


Citrix has utilized load balancing in XenApp for years. This feature allows you to set parameters in a load evaluator, apply it to a server, and have Citrix manage how users are assigned to servers. Despite the numerous tools available on the market that report on your XenApp farm utilization, Citrix user load balancing remains the easiest to implement (and cheapest). That being said, beyond running the “qfarm /load” command over and over, it’s difficult to report on your farm’s load. Thankfully, with the Citrix PowerShell commands we can regularly report on a server’s load (including the load evaluator rules) and e-mail that information.

The Script

## Title : get-ctxLoadAndLE.ps1
## Description : Gathers server load, assigned LE, and active and disconnected sessions
## Author : Alain Assaf
## Date : 01/11/2012
## Sources : Logging and e-mail sections from Raido
## Sources : http://powershell.com/cs/blogs/ebook/archive/2008/10/23/chapter-4-arrays-and-hashtables.aspx
## Sources : http://technet.microsoft.com/en-us/library/ff730946.aspx
## Sources : http://technet.microsoft.com/en-us/library/ff730936.aspx
## Sources : [test-port function] http://irl33t.com/blog/2011/03/powershell-script-connect-rdp-ps1
## Notes : Assumes Citrix PowerShell cmdlets are installed
#### Changelog ################################################################
# -When - What - Who
# -01/11/2012 -Initial script -Alain Assaf/Chemtura
# -01/18/2012 - Changed way I get user sessions because it was timing out
# -02/20/2012 - Added sendTo variable to add mulitple receipients
# -03/05/2012 - Added lines to include LE Rules
# -04/26/2012 - Added Test-Port function from Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)

# Test-Port function to test RDP availability
# Written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)
function Test-Port{
 $ErrorActionPreference = "SilentlyContinue"
 $tcpclient = new-Object system.Net.Sockets.TcpClient
 $iar = $tcpclient.BeginConnect($srv,$port,$null,$null)
 $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
 Return $false
 $tcpclient.EndConnect($iar) | out-Null
 Return $true
#Assign e-mail(s) to $sendto variable and SMTP server to $SMTPsrv
$SMTPsrv =

#Initialize array
$finalout = @()

#add XenApp Cmdlets
Add-PSSnapin -name *citrix* -erroraction silentlycontinue

#Get server list
$ctxservers = get-xaserver | select -Property servername | sort -Property servername

#Get user sessions
$ctxsrvSessions = Get-XASession | select -property SessionID,ServerName,AccountName,Protocol,State| where {($_.State -eq 'Active' -or $_.State -eq 'Disconnected') -and $_.Protocol -eq 'Ica'}

#Create a new object array with all the data we need
foreach ($srv in $ctxservers) {
 $ctxsrv = $srv.servername
 if (test-port $ctxsrv) {
  $srvload = get-xaserverload -servername $ctxsrv | select -Property ServerName,LoadEvaluatorName,Load,Rules
  $srvactive = @($ctxsrvSessions | where {$_.Servername -eq $ctxsrv -and $_.State -eq 'Active'}).count
  $srvdisconn = @($ctxsrvSessions | where {$_.Servername -eq $ctxsrv -and $_.State -eq 'Disconnected'}).count
  $objctxsrv = new-object System.Object
  $objctxsrv | Add-Member -type NoteProperty -name ServerName -value $srvload.servername
  $objctxsrv | Add-Member -type NoteProperty -name LEName -value $srvload.LoadEvaluatorName
  $objctxsrv | Add-Member -type NoteProperty -name Load -value $srvload.Load
  $objctxsrv | Add-Member -type NoteProperty -name Active -value $srvactive
  $objctxsrv | Add-Member -type NoteProperty -name Disconnected -value $srvdisconn
  $objctxsrv | Add-Member -type NoteProperty -name 'Server User Load' -value $srvload.Rules[0].Load.ToString()
  $objctxsrv | Add-Member -type NoteProperty -name 'Load Throttling' -value $srvload.Rules[1].Load.ToString()
  $objctxsrv | Add-Member -type NoteProperty -name 'Memory Usage' -value $srvload.Rules[2].Load.ToString()
  $objctxsrv | Add-Member -type NoteProperty -name 'CPU Usage' -value $srvload.Rules[3].Load.ToString()
  $finalout += $objctxsrv
 } else {
  $objctxsrv = new-object System.Object
  $objctxsrv | Add-Member -type NoteProperty -name ServerName -value $ctxsrv
  $objctxsrv | Add-Member -type NoteProperty -name LEName -value "OFFLINE"
  #$objctxsrv | Add-Member -type NoteProperty -name Load -value "0"
  #$objctxsrv | Add-Member -type NoteProperty -name Active -value "0"
  #$objctxsrv | Add-Member -type NoteProperty -name Disconnected -value "0"
  $finalout += $objctxsrv

#Create HTML Header
$head = '<style>
META{http-equiv:refresh content:30;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{font-size:12px; border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:Aquamarine}
TD{font-size:12px; border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:GhostWhite}
<script type="text/javascript">
var linhas = $("table tr");
var Valor = $(this).find("td:first").html();
if(Valor == "OFFLINE"){
}else if(Valor == "Running"){
#$header = "<H5>XenApp DASHBOARD</H5>"
$title = "XenApp DASHBOARD"
#$body = $finalout | ConvertTo-Html -head $head -body $header -title $title
#$body = $finalout | ConvertTo-Html -head $head -title $title

#Create mail parameters
$messageParameters = @{
 Subject = "Report: Server Load and Assigned LE for XenApp Farm"
 Body = $finalout | ConvertTo-Html -head $head -title $title | out-string
 From = "Admin-Citrixtask@chemtura.com"
 To = $sendto
 SmtpServer = "$SMTPsrv"

#Send e-mail with Server load data
Send-MailMessage @messageParameters -BodyAsHtml

#Uncomment to output the results in an HTA file to view in a browser
#$finalout | ConvertTo-Html -head $head -title $title | out-file $env:temp\report.hta
#ii $env:temp\report.hta

Example e-mail

Currently the script records the following:

  • Server Name
  • Assigned Load Evaluator
  • Server Load
  • Active Sessions
  • Disconnected Sessions
  • Load Evaluator Rules (you will have to modify the above script depending on which LE rules are using)
    • User Load
    • Load Throttling
    • Memory Usage
    • CPU Usage
click on image to make it larger

I created a repeating scheduled task on a XenApp server in the farm I wanted to report on. Now my team gets an hourly report of the farm load.

Explore more

Load Manager Values Explained

Load Manager Rules Explained

Performance Monitor Counters Used by Load Manager

Troubleshooting Load Balancing Issues

How to Enable the Load Manager Log for Load Balancing Issues


Please try it out and let me know how it works for you. As you can see above, I borrowed a javascript that was supposed to color the cells for an OFFLINE server red, but have not been able to get it to work. If anyone has a solution, I will be happy to update this post and spotlight you, your blog, or twitter account.

As always, I welcome all comments and questions.


33 thoughts on “PowerShell: E-mail Server Load and Assigned LE”

    1. Lance,

      None yet. Have you reviewed the comments for this post. I believe someone has made it work for XenApp 6.5.

      Thanks for reading,

      1. Since it seems to be a common question about how to get it to work with version ‘x’, it might help some others to know what i had to do to make it work, because there was some other factors that needed to be addressed other than syntax in the script: (your experience may vary)

        We have a Very complex environment that we use this script for.
        14 seperate farms, 12 domains spanning several several geographical regions which is currently a mix of 4.5, 6.0, 6.5 (slow process of migrating to 6.5) – a total of 127 citrix/xenapp servers.

        Things i had to do:
        – ensure that all xenapp/citrix farms have the following baseline:
        – Latest version of powershell availible to the operating system
        – Latest Citrix / XenApp powershell cmdlets installed for the specific version of Citrix/Xenapp (4.5, 6.0, 6.5)
        – Powershell restriction policy set to allow the running of the script as a task.
        – Ensure that RPC ports were opened on the firewalls to allow communication between the servers in the farm ( we also allowed 445, 137-139, 5985)

        in my environment i set the script to run as a scheduled task on one server on each farm to retrieve the report. We use a service account specific to the domain The service account we used has the following characteristics:

        1. logon as batch rights,
        2. logon as service rights.
        3. part of the Citrix Farm Administrators group (would not return certian criteria otherwise e.g. load evaluator info)
        4. part of the local administrators group (would not return certian criteria otherwise e.g. last reboot information)

        Again, Big thanks to Alain to getting this started.

  1. I got this working on Citrix 6.5 complete with load evaluator name and Load evaluator rule values for each server. It does not require any customization for different load evaluators with different rules either. The downside is it is not pure pure Powershell and has a dependency on an external exe from Citrix called queryds.exe.

      1. I did try Michael Woodward’s script but its missing the load evaluator rules. On XenApp 6.0 the only way to get those figures is with queryds, but requires converting from hex to decimal

      2. I will try to find a way to make my modifications to this script available. At this point it works on 4.5 and 6.5 maybe others and reports the Load Evaluator rule values. The one downside is it does require DSQuery.exe. I have added a host of other enhancements like there is no need to customize the script to work with different load evaluators as well as additional features, for instance, I currently run this script via a scheduled job every 15 minutes if the clock minutes value is less than 15 it will send an email otherwise it just appends to a running log file. The result is I get a report emailed every hour AND I can get a running history for every server in my environment that shows load every 15 minutes with why the load is what it is. Plus more but i don’t have the script in front of me right now to list it all.

      3. “I am not sure what you mean by ‘missing the load evaluator rules’. With the line: $srvle = Get-XALoadEvaluator -ServerName $ctxsrv | select -Property LoadEvaluatorName I am setting the $srvle variable to be the name of the Load Evaluator currently applied to the server being evaluated ($ctxsrv). As long as all of the farms (4.5, 6.0, 6.5) have the most recent version of citrix/xenapp powershell cmdlets applied, this has always been returned in readable text.

  2. Does not work with 6.5 due to differences in output from get-xaserverload. Only server and load are returned. Neither the LE Name nor the rule values are returned.

    1. to return what Load Evaluators are in use from 4.5, 6.0 and 6.5 i made sure all had the most current citrix cmdlets for their respective environments. then i used the following line under the foreach statement:

      $srvle = Get-XALoadEvaluator -ServerName $ctxsrv | select -Property LoadEvaluatorName

      for the body i used:

      $objctxsrv | Add-Memeber -MemberType NoteProperty -Name “Load Evaluator” -Value $srvle.LoadEvaluatorName

      I have one script for all farm versions and it is working pretty well returning all the names. In fact i have just recently added listing of workgroups (if 4.5 it just states ‘No Workgroups’) which is also returning if a server is a member of mulitple workgroups.

      Thanks Alan for getting the ground work laid.

      1. Michael,

        That is sweet. Do you have a link or blog post detailing what you did? I’d love to share it here.


  3. Love this script!

    I made a fiew changes myself to add more functionality. I added:

    1. Changed so sending to multiple email addresses is possible
    [string[]] $sendto = “em1@company.com”,”em2@company.com”,”em3@company.com”

    2. Logons enabled change found in responses here – Thanks very cool idea!

    3. CSV Output with Date/time as the first column because I wanted to use this to illustrate load trends using CSV output that appends to a CSV file indefinitely.

    $objctxsrv = New-Object System.Object
    $objctxsrv | Add-Member -type NoteProperty -name ‘Date’ -value (get-date).ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘Server’ -value $srvload.servername


    #Create mail parameters
    $finalout | ConvertTo-Html -head $head -title $title >c:\temp\metrics.html

    #Create or append to CSV output
    $ServerStats = $finalout | ConvertTo-Csv -NoTypeInformation

    $Result = Test-Path -path C:\CitrixAccess\Logs\CitrixLoad.csv
    if ($Result -eq $False) {
    $ServerStats | Add-Content -Path “C:\CitrixAccess\Logs\CitrixLoad.csv”
    } else {
    $ServerStats[1..($ServerStats.count – 1)] | Add-Content -Path “C:\CitrixAccess\Logs\CitrixLoad.csv”

    4. A condition to send the email based on time. This way I can run the script every 15 minutes to get trending data in the CSV file but it will only send an email with the current runs data in the body once every hour.

    #Usage: dir c:\demo\files\*.* -Recurse | add-Zip c:\demo\myzip.zip
    #Source: http://blogs.msdn.com/b/daiken/archive/2007/02/12/compress-files-with-windows-powershell-then-package-a-windows-vista-sidebar-gadget.aspx
    function Add-Zip {

    if(-not (test-path($zipfilename))) {
    set-content $zipfilename (“PK” + [char]5 + [char]6 + (“$([char]0)” * 18))
    (dir $zipfilename).IsReadOnly = $false

    $shellApplication = new-object -com shell.application
    $zipPackage = $shellApplication.NameSpace($zipfilename)

    foreach($file in $input) {
    $zipPackage.CopyHere($file.FullName, 0x10)
    Start-sleep -milliseconds 500

    $Date = Get-Date
    if ($Date.Minute -lt 15) {
    #Create Zip File with Server Load Data
    dir “c:\CitrixAccess\Logs\CitrixLoad.csv” | add-Zip “c:\CitrixAccess\Logs\CitrixLoad.zip”

    $messageParameters = @{
    Subject = $Subject
    Body = $finalout | ConvertTo-Html -head $head -title $title | Out-String
    From = $From
    To = $sendto
    SmtpServer = “$SMTPsrv”
    Attachments = “c:\CitrixAccess\Logs\CitrixLoad.zip”
    #Send e-mail with Server load data
    Write-Host “Sending e-mail with Server load data…” -ForegroundColor Yellow
    Send-MailMessage @messageParameters -BodyAsHtml

    5. Zipping and attaching the csv data file to the email as an attachment. This way the email shows me what load looks like right now but I can also open the zipped CSV file and see how usage has been trending in 15 minute increments, or however often I choose to run it, for the duration of the CSV file by loading it into Excel and sorting first by server name then by date/time columns.

    See above code^

    6. The lines below seem to depend on how the load evaluator and the rules there-in:

    $objctxsrv | Add-Member -type NoteProperty -name ‘Server User Load’ -value $srvload.Rules[0].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘Load Throttling’ -value $srvload.Rules[1].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘Memory Usage’ -value $srvload.Rules[2].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘CPU Usage’ -value $srvload.Rules[3].Load.ToString()

    So I changed them. Adding conditions that would accomodate different load evaluators:

    if ($srvload.LoadEvaluatorName -match “Default” ) {
    $objctxsrv | Add-Member -type NoteProperty -name ‘% Committed Bytes In Use’ -value “N/A”
    $objctxsrv | Add-Member -type NoteProperty -name ‘% Processor Time’ -value “N/A”
    $objctxsrv | Add-Member -type NoteProperty -name ‘Load Throttling’ -value “N/A”
    } else {
    #$objctxsrv | Add-Member -type NoteProperty -name ‘Server User Load’ -value $srvload.Rules[0].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘% Committed Bytes In Use’ -value $srvload.Rules[0].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘% Processor Time’ -value $srvload.Rules[2].Load.ToString()
    $objctxsrv | Add-Member -type NoteProperty -name ‘Load Throttling’ -value $srvload.Rules[1].Load.ToString()

  4. Alain, i really like this, i did some modifications for our purposes. as far as the javascript you had at the beginning i was able to find a way around it. it involved having to ‘hardcode’ what i wanted then fixing the replacements that would occur when the Convert-toHTML got a hold of it.

    One of the modifications i made was to determine if the system had logons disabled (something you don’t get from QFARM /load) and to show up red when they were disabled.

    so here is what i did for that:

    foreach ($srv in $ctxservers)
    $ctxsrv = $srv.servername
    $LIEnabled = Get-XAServer $ctxsrv
    if ($LIEnabled.LogOnsEnabled -ne “False”){$LES = “False“} else {$LES = $LIEnabled.LogOnsEnabled}

    $objctxsrv | Add-Member -MemberType NoteProperty -Name “Logons Enabled ” -Value $LES

    #Send e-mail with Server load data
    Send-MailMessage -SmtpServer $SMTPsrv -Body ($finalout | ConvertTo-Html | foreach {$_.replace(“<“,””)} | Out-String) -BodyAsHtml -Subject $mailsubject -To $sendto -From $sentfrom

    couple of caveats:

    1. i ended up removing the $head $Title, i could not get the .replace to work correctly with it.
    2. when i attempted to pipe this to a file i was not able to eliminate the < and > but it worked for the e-mail.

    I have not tried this with any of the other options but it might work.

    1. ok. the $LES = “False” had HTML <font code in it that got converted when it posted. but inside the " " it was standard html code to turn it bold and color to = red. then word False and closing the html brackets.

  5. Do you have the same Powershell script for Xeanpp 6.0. If I try the the script to run on the existing Farm:
    Get-XAServerLoad : Invalid argument
    At C:\test.ps1:37 char:30
    + $srvload = get-xaserverload <<<< -servername $ctxsrv | select -Property ServerName,LoadEvaluatorName,Load,Rules
    + CategoryInfo : NotSpecified: (:) [Get-XAServerLoad], IMAException
    + FullyQualifiedErrorId : Citrix.IMA.IMAException,Citrix.XenApp.Commands.GetServerLoadCmdlet

    Cannot index into a null array.
    At C:\test.ps1:46 char:93
    + $objctxsrv | Add-Member -type NoteProperty -name 'Server User Load' -value $srvload.Rules[ <<<< 0].Load.ToString()
    + CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    And to the end…

    If Use the send message stuff should I put the cassarray from Exchange 2010 server. I get also the error for that.

    If somebody have a solution I will wait for your help.

    E-mail: deliyurek007@msn.com

      1. Hi Alain,

        Were you able to test this on XA 6.5? I have the same issue on XA 6.5. Let me know if you find a solution for this.

    1. it looks like you are using the wrong commands for the version: I am running a version of this on 4.5, 6.0, 6.5 with no modifications for either farm version:

      try this:

      Get-XAServerLoad -ServerName $ctxsrv | select -Property ServerName,Load

      then, another for LE

      Get-XALoadEvaluator -ServerName $ctxsrv | select -Property LoadEvaluatorName

      if it doesn’t work check to see if you have the current version of the Citrix SDK for the cmdlets on all versions you want to run this against.

      1. I am able to run the first command, however the Get-XALoadEvaluator fails with the Cannot validate argument on parameter ‘Servername. I have downloaded all the SDK’s. Any suggestions would be appreciated. I’m in a 6.5 environment.

      2. Kalif, in the line: ‘Get-XALoadEvaluator -ServerName $ctxsrv | select -Property LoadEvaluatorName’ the variable $ctxsrv needs to be populated with a server name. iThere are a couple of lines that generate that information for that variable, because it has been a long time since i have looked at the original code and there could have been a lot of modifications since then, i am going to go with the basics to get assist with an answer:

        – first you have to get a list of the servers, that is in the variable $ctxservers. You can get that with the line: $ctxservers = Get-XAServer | select -Property servername
        – next there is a ‘for each’ loop that looks at all the items that are in the $ctxservers and sets the value for $ctxsrv it will look similar to this

        foreach ($srv in $ctxservers)
        $ctxsrv = $srv.servername
        Get-XALoadEvaluator -ServerName $ctxsrv | select -Property LoadEvaluatorName

        That is basically how it should build to populate the variable. But if you just need to test that specific line to see if there is a problem. you can run the line by itself with just:

        ‘Get-XALoadEvaluator -ServerName | select -Property LoadEvaluatorName’

        That should work (without the quotation marks) on both 6.0 and 6.5.

  6. Hi Alain,

    Really like the report you have here, however ive been having some problems with it…

    When i run it from one of my servers i get the following error several times – i get the report through email, but its missing several fields. A friend said its something wrong in the $srvload.Rules array.

    Cannot index into a null array.
    At D:\admin\get-ctxloadandle.ps1:71 char:93
    + $objctxsrv | Add-Member -type NoteProperty -name ‘Server User Load’ -value $srvload.Rules[ <<<< 0].Load.ToString()
    + CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At D:\admin\get-ctxloadandle.ps1:72 char:92
    + $objctxsrv | Add-Member -type NoteProperty -name 'Load Throttling' -value $srvload.Rules[ <<<< 1].Load.ToString()
    + CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At D:\admin\get-ctxloadandle.ps1:73 char:89
    + $objctxsrv | Add-Member -type NoteProperty -name 'Memory Usage' -value $srvload.Rules[ <<<< 2].Load.ToString()
    + CategoryInfo : InvalidOperation: (2:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At D:\admin\get-ctxloadandle.ps1:74 char:86
    + $objctxsrv | Add-Member -type NoteProperty -name 'CPU Usage' -value $srvload.Rules[ <<<< 3].Load.ToString()
    + CategoryInfo : InvalidOperation: (3:Int32) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    1. Cody,

      What version of XenApp and PowerShell are installed on your servers? This script runs from a zone data collector running XenApp 5.0 on W2K8 and powershell 2.0. I’ve got version CTP3 of the XenApp Cmdlets installed which are still considered (by Citrix) a technical preview. Also, what are your LE rules?

      Thanks for reading,

      1. Ah! Well that might explain it then. I (not sure why…) just assumed this was for XenApp 6.5. Were running 6.5 and Powershell 2.0.

        My LE Rules are pretty basic at the moment; the production one im using was just the user limit one; however i loaded up a more detailed LE that tracked CPU Usage, Memory, etc to see if that was the issue and it still threw that error.

        Doing a bit of google work, the CTP3 Cmdlets appear to be more geared towards 5.0; while the Powershell SDK CmdLets are what im using in 6.5.

  7. Is there a way to have the active sessions remove duplicates? We’d like a count of users per citrix server(For example, user 12345 might have 12 sessions open, but we want to report that there are 12 users with 24 sessions open, instead of just 24 sessions open)

    1. Mitch,

      The purpose of the script to to show load/utilization per server, so removing duplicates would get you a user count per server, but not show the session load. You have all the sessions in the $ctxsrvSessions array, so you could run a further command to find the users with multiple sessions in that array.
      1. Use a select item statement with the -unique parameter (this could be done when you create the $ctxsrvSessions array)
      2. Use the get-unique cmdlet but you would have to sort the array first.

      I’m curious why a user would have so many multiple sessions open. Do you have a lot of server silos in your environment?


      1. I’ve tried to sort the array like that, but received mixed results. I’ll try it again today at work and report back. Thanks. The reason why we have so many sessions is because we don’t host a full desktop, and instead just host separate applications. When a user logs into the web interface and launches an application(Like explorer, for example), he can launch it as many times as he wants, and each one of those counts as a session in the script. At first we thought it was doing unique users, but saw that one of the servers was reporting 37 active sessions. It turned out that one user was (for reasons unknown to us) using 14 explorer windows. When looking at the Active Sessions list for the 20 servers in our environment all of them had about 20 active sessions with the exception of this one server reporting nearly twice as much- some people looking at the report were concerned there was something wrong with the server.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.