Posts RSS Comments RSS 253 Posts and 411 Comments till now

Blog Archives

Find-CitrixIdleUser.ps1 (Citrix Top 10)

This is one of the more useful scripts (at least for me.) It will query the farm and tell you all the user who have exceeded the idle time specified. I also combined another script that logged off users.

Name: Find-CitrixIdleUser.ps1
Purpose: Finds users with idle time greater than value passed and logs them off if -logoff is passed

# Find-CitrixIdleUser.ps1
# Brandon Shell [MVP]
# www.bsonposh.com
# Finds users with idle time greater than value passed
Param($time,[switch]$day,[switch]$hour,[switch]$minute,[switch]$logoff,[switch]$verbose,[switch]$help)
function HelpMe{
    Write-Host
    Write-Host " Find-CitrixIdleUser.ps1:" -fore Green
    Write-Host "   Finds users with idle time greater than value passed"
    Write-Host
    Write-Host " Parameters:" -fore Green
    Write-Host "   -Time                  : Optional. Server to Get Print Info From "
    Write-Host "   -Day                   : Optional. Checks Days of Idle Time "
    Write-Host "   -Hour                  : Optional. Checks Hours of Idle Time (Default)"
    Write-Host "   -Minute                : Optional. Checks Minutes of Idle Time"
    Write-Host "   -Logoff                : Optional. Logs User off if Idle Time exceeds Time"
    Write-Host "   -Verbose               : Optional. Show Verbose Output"
    Write-Host "   -Help                  : Optional. Displays This"
    Write-Host
    Write-Host " Examples:" -fore Green
    Write-Host "   Finds Users who have been idle 2 hours and return AppName, UserName, SessionID, and ClientName" -fore White
    Write-Host "     Find-CitrixIdleUser.ps1 2 -hour | ft AppName,UserName,SessionID,ClientName -auto" -fore Yellow
    Write-Host
    Write-Host "   Finds Users who have been idle 2 hours and Logs them Off" -fore White
    Write-Host "     Find-CitrixIdleUser.ps1 2 -hour -logoff" -fore Yellow
    Write-Host
}
if($verbose){$verbosepreference = "Continue"}
Write-Host
if(!$time -or $help){helpme;Write-Host;Return}

# Get Citrix Farm Object
Write-Verbose " – Creating MFFarm Object"
$farm = new-Object -com "MetaframeCOM.MetaframeFarm"
$farm.Initialize(1)

# Parse Sessions
Write-Verbose " – Parsing Sessions. Total of [$($farm.Sessions.count)] Sessions"
foreach($session in $farm.Sessions)
{
    Write-Verbose "   – Processing Session ID [$($Session.SessionId)]"
    $shouldLogOff = $false

    # Getting Citrix Session Idle Time and Convert to System.DateTime
    Write-Verbose "   – Getting LastInputTime"
    $ctxDate = $session.LastInputTime(1)
    Write-Verbose "   – Checking if idle time is -gt 0"
    if(($ctxDate.HighPart -ne 0) -and ($ctxDate.LowPart -ne 0))
    {
        $date = "{0,4}{1,2:00}{2,2:00}{3,2:00}{4,2:00}" -f $ctxDate.year,$ctxDate.Month,$ctxDate.Day,$ctxDate.Hour,$ctxDate.Minute
        Write-Verbose "   – Converted LastInputTime to [$date]"
        $SessionIdleTime = [system.DateTime]::ParseExact($date,‘yyyyMMddHHmm’,$null)

        # Get Current Time in System.DateTime
        Write-Verbose "   – Getting Current Date"
        $now = Get-Date
        Write-Verbose "   – Current Date is [$now]"

        # Find Difference
        Write-Verbose "   + Getting Time Difference"
        $diff = $now$SessionIdleTime
        Write-Verbose "     – Found Days [$($diff.TotalDays)] Hours [$($diff.Totalhours)] Minutes [$($diff.TotalMinutes)]"

        # Output Sessions that match
        if($day)   {    if($diff.TotalDays    -gt $time)    {$session;$shouldLogOff = $true}  }
        if($hour)  {    if($diff.Totalhours   -gt $time)    {$session;$shouldLogOff = $true}  }
        if($minute){    if($diff.TotalMinutes -gt $time)    {$session;$shouldLogOff = $true}  }

        Write-Verbose "     – Set `$shouldLogOff to [$shouldLogOff]"

        # Logging Off User
        if($logoff -and $shouldLogOff)
        {
            Write-Verbose "   – Logging Off Session ID [$($Session.SessionId)]"
            $session.Logoff($false)
        }
    }
    else
    {
        Write-Verbose "   – Session ID [$($Session.SessionId)] NOT Idle"
    }
    Write-Host
}

Get-CitrixSessionUser.ps1 (Citrix Top 10)

One of the script I was asked to convert was a script to output all the Users and the Client IP.

This is what I came up with

Name: Get-CitrixSessionUser.ps1
Purpose: List ClientAddress and UserName for each Session

# Get-CitrixSessionUser.ps1
# Brandon Shell [MVP]
# www.bsonposh.com
# List ClientAddress and UserName for each Session

$farm = new-Object -com "MetaframeCOM.MetaframeFarm"
$farm.Initialize(1)
$farm.Sessions | Format-Table UserName,ClientAddress

After I did this… I stopped and actually thought about what I was doing. What is the point? What would someone use this for? It seemed to me that a simpler script that was more flexible would not only meet the original goal, but expand it significantly. It comes back to the object nature of Powershell. I needed to stop thinking strings and start thinking objects. Using the following script not only accomplishes the same goal to get UserName and ClientAddress, but also expands it to add the following:

AAName
AAType
AccessSessionGuid
Applications
AppliedPolicy
AppName
AverageLatency
BandwidthCap
BytesRcvdPostExpansion
BytesRcvdPreExpansion
BytesSentPostCompression
BytesSentPreCompression
ClientAddress
ClientAddrFamily
ClientBuffers
ClientBuild
ClientCacheDisk
ClientCacheLowMem
ClientCacheTiny
ClientCacheXms
ClientColorDepth
ClientDimBitmapMin
ClientDimCacheSize
ClientDimVersion
ClientDirectory
ClientEncryption
ClientHardwareID
ClientHRes
ClientID
ClientLicense
ClientModemName
ClientModules
ClientName
ClientProductID
ClientProductIDValue
ClientVRes
DeviceID
ICABufLen
InputSpeed
LastLatency
LatencyDeviation
OutputSpeed
Processes
ProtocolType
ServerBuffers
ServerName
SessionID
SessionName
SessionState
SmartAccessFilters
UserName
VIPAddress
VirtualChannels

# Get-CitrixSession.ps1
# Brandon Shell [MVP]
# www.bsonposh.com
# Gets all the Sessions for a Farm

$farm = new-Object -com "MetaframeCOM.MetaframeFarm"
$farm.Initialize(1)
$farm.Sessions

Set-CitrixPSVersion.ps1 (Citrix Top 10)

I am constantly looking for content for my blog and tasks that can be automated. I believe this helps me learn and helps other with their needs.

In this search I was directed to convert/write Powershell examples for scripts located here http://community.citrix.com/display/cdn/Script+Exchange

Here is the first of those scripts.

Name: Set-CitrixPSVersion.ps1
Purpose: Sets PS Version on a Server, List of Servers, or all Servers in the Farm

# Set-CitrixPSVersion.ps1
# Brandon Shell [MVP]
# www.bsonposh.com
# Sets PS Version on a Server, List of Servers, or all Servers in the Farm
Param($file,$server,$PSVer,[switch]$help,[switch]$all,[switch]$whatif,[switch]$show,[switch]$verbose)
function HelpMe{
    Write-Host
    Write-Host " Set-CitrixPSVersion.ps1:" -fore Green
    Write-Host "   Sets PS Version on a Server, List of Servers, or all Servers in the Farm"
    Write-Host
    Write-Host " Parameters:" -fore Green
    Write-Host "   -File <fileName>       : Optional. Name of the File of Servers"
    Write-Host "   -Server <serverName>   : Optional. Name of the Server to Change"
    Write-Host "   -Verbose               : Optional. Enables Verbose Output"
    Write-Host "   -All                   : Optional. Sets Version on all Servers [Requires -Server]"
    Write-Host "   -Show                  : Optional. Displays the Version for Server(s)"
    Write-Host "   -Help                  : Optional. Displays This"
    Write-Host "   -Whatif                : Optional. Will not Commit Info just Display what would change"
    Write-Host
    Write-Host " Examples:" -fore Green
    Write-Host "   Set PS Version on Server1 to STD" -fore White
    Write-Host "     .\Set-CitrixPSVersion.ps1 -Server Server1 -psver STD " -fore Yellow
    Write-Host
    Write-Host "   Set PS Version on Servers in a File" -fore White
    Write-Host "     .\Set-CitrixPSVersion.ps1 -file c:\Mylist.txt -psver STD " -fore Yellow
    Write-Host
    Write-Host "   Get PS Version from ALL server" -fore White
    Write-Host "     .\Set-CitrixPSVersion.ps1 -all -Server myzdcserver" -fore Yellow
    Write-Host
    Write-Host " Product Edition Options" -fore Green
    Write-Host "   STD = Citrix Presentation Server Standard Edition" -fore White
    Write-Host "   ADV = Citrix Presentation Server Advanced Edition" -fore White
    Write-Host "   ENT = Citrix Presentation Server Enterprise Edition" -fore White
    Write-Host "   PLT = Citrix Presentation Server Platinum Edition" -fore White
    Write-Host
}
function Ping-Server {
    Param($srv)
    $pingresult = Get-WmiObject win32_pingstatus -f "address=’$srv’"
    if($pingresult.statuscode -eq 0) {$true} else {$false}
}
function Set-PSVer{
    Param($srv)
    Write-Verbose "  Getting Citrix Server Object"
    $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeServer",$srv)
    $mfsrv = [system.Activator]::CreateInstance($type)
    $mfsrv.Initialize(6,$srv)
    if(!$?){Write-Host "   – Server [$srv] threw and Error" -fore red;return}

    if($show) # Check for $Show and will display only
    {
        Write-Host "   – PS Version for [$srv]: $($mfsrv.WinServerObject.mpsedition)"
        return
    }
    else
    {
        if($whatif) # Check for $Whatif
        {
            Write-Host "  What if: Performing operation `"Set PS Version [$PSVer]`" on Target `"$srv`"."
        }
        else
        {
            Write-Verbose "   – Setting PSVer to [$PSVer] on [$srv]"
            $mfsrv.WinServerObject.mpsedition = $PSVer
            Write-Host "   – PS Version for [$srv]: $($mfsrv.WinServerObject.mpsedition)"
        }
    }
}
function Set-PSALL{
    $mfarm = new-Object -com "MetaframeCOM.MetaframeFarm"
    $mfarm.Initialize(1)
    foreach($mfsrv in $mfarm.Servers)
    {
        if($show){Write-Host "   – PS Version for [$($mfsrv.ServerName)]: $($mfsrv.WinServerObject.MPSEdition)";continue}
        if($whatif){Write-Host "  What if: Performing operation `"Set PS Version [$PSVer]`" on Target `"$($mfsrv.ServerName)`"."}
        else
        {
            Write-Verbose "   – Setting PSVer to [$PSVer] on [$($mfsrv.ServerName)]"
            $mfsrv.WinServerObject.mpsedition = $PSVer
            Write-Host "   – PS Version for [$($mfsrv.ServerName)]: $($mfsrv.WinServerObject.MPSEdition)"
        }
    }
}

# Script Setup. Checking Parameters
Write-Host

## Checing Verbose flag
if($verbose){$verbosepreference = "Continue"}else{$erroractionpreference = "SilentlyContinue"}

## Verifying that File/Server was passed. If not or -help I Call HelpMe and close.
if(!$file -and !$server -and !$all -or $help){HelpMe;Return}

## Verify Valid Edition was Passed
if(!$show -and ($PSVer -notmatch "STD|ADV|ENT|PLT"))
{
    Write-Host " PS Edition [$PSVER] is NOT Valid. Please use STD, ADV, ENT, or PLT" -fore RED
    Write-Host
    Return
}

# If $Server and we can ping it we run Set-PSVer against Server
if($server -and (ping-server $server))
{
    Set-PSVer $server
    Write-host
}

# Check for -File and Verify the file is valid
if($File -and (test-Path $file))
{
    Write-Verbose " – Processing File [$file]"
    # Process each Server checking for blanks
    foreach($Server in (get-Content $file | where{$_ -match "^\S"}))
    {
        Write-Host " + Processing Server [$Server]"
        if(ping-Server $server){Set-PSVer $Server}else{Write-Host "   – Ping Failed to [$Server]" -fore Red}
        Write-host
    }
}

if($all){Set-PSALL}

Write-Host

« Prev