Posts RSS Comments RSS 127 Posts and 199 Comments till now

Get-CitrixServer (Playing Around Series)

This is a quick run through a MFCOm Citrix Server Object

Best Viewed Full Screen
Get the Flash Player to see this player.

Demo File

#
# We start by creating a Server Object
#
$mfsrv = New-Object -ComObject MetaFrameCOM.MetaFrameServer
#
# Initializing Server
#
$mfsrv.Initialize(6,$ENV:ComputerName)
#
# Now we have are server… Lets see what we have to play with
#
$mfsrv | Get-Member -type Properties
#
# Lets start by looking at the current sessions on the server
#
$mfsrv.Sessions | ft SessionID,AppName,ClientAddress,ClientHRes,ClientVRes -auto
#
# What about what Zone it is in?
#
$mfsrv.ZoneName
#
# Printers?
#
$mfsrv.Printers
#
# Lets see what Processes are running
#
$mfsrv.Processes | ft SessionID,ProcessID,UserName,ProcessState -auto
#
# A common task is Server Load
#
$mfsrv.WinServerObject.ServerLoad
#
# Last (and perhaps most important) What applications?
#
$mfsrv.Applications | ft BrowserName,ParentFolderDN

Citrix and Powershell Webinar

For those of you that use Citrix Presentation Server you will want to watch this. I maybe a little bias, but I loved it :)
http://community.citrix.com/display/~vishalg/2008/04/30/PowerShell+and+Citrix+MFCOM+recorded+Webinar+and+Powerpoint+slide+deck

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

Citrix functions Updated!

I didn’t have time last post to additional “Farm” functionality to some the functions. The following are updated to work against multiple farms.

Updated Server functions

  • Publish-CitrixApplication
  • UnPublish-CitrixServer
  • Remove-CitrixApplication
  • Updated Application functions

  • Get-CitrixApp
  • Get-CitrixAppUsers
  • Get-CitrixAppServers
  • Find-CitrixUser
  • Citrix Server Functions

    ##########################################
    ####     Citrix Server Functions      ####
    ##########################################

    ## Publish Application to Server(s)
    ## -app: Name of Application to remove. This is required
    ## -Server: Name of Server
    ## PIPED: It will take Servers via Pipe. It expects a list or Citrix Server Object
    ## NOTE: App Name must include subfolders of the app.
    ##       If the app in in Applications\Test then app would be Test\MyApp
    ##       Example: Publish-CitrixApplication -server myserver -app Test\MyApp
    function Publish-CitrixApplication{
        Param([string]$server,[string]$app)
        Begin{
            Write-Host
            function gcs{
                Param($srv)
                $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeServer",$Server)
                $mfServer = [system.Activator]::CreateInstance($type)
                $mfServer.Initialize(6,$Server)
                $mfServer
            }
            function gca{
                Param($srv,$ma)
                $type = [System.Type]::GetTypeFromProgID("MetaFrameCOM.MetaFrameApplication",$Server)
                $mfApp = [system.Activator]::CreateInstance($type)
                $mfApp.Initialize(3,"Applications\$ma")
                $mfApp.LoadData($true)
                $mfApp
            }
            function cPublish {
                Param([string]$Srv,[string]$myapp)
                $Srv = $Srv.toUpper()
                $mfSrv = gcs $srv
                $mfApp = gca $srv $myapp
                $mfAppBinding = New-Object -ComObject MetaFrameCOM.MetaFrameAppSrvBinding
                $mfAppBinding.Initialize(6,$Srv,"Applications\$app")
                if($mfAppBinding)
                {
                    Write-Host "Publishing App[$myapp] on Server [$Srv]" -ForegroundColor Green
                    $mfApp.AddServer($mfAppBinding)
                    $mfApp.SaveData()
                }
                else
                {
                    Write-Host "Unable To Create App Binding" -ForegroundColor Red
                }
            }
            $process = @()
        }
        Process{
            if($_){
                if($_.ServerName){
                    $process += $_.ServerName
                }
                else{
                    $process += $_
                }
            }
        }
        End{
            if($Server){$Process += $Server}
            foreach($s in $process){
                cPublish -srv $s -myapp $app
                Write-Host
            }
        }
    }

    ## UnPublishes ALL Application from Server(s)
    ## -Server: Name of Server
    ## PIPED: It will take Servers via Pipe. It expects a list or Citrix Server Object
    function UnPublish-CitrixServer{
        Param([string]$server)
        Begin{
            function gcs{
                Param($srv)
                $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeServer",$Server)
                $mfServer = [system.Activator]::CreateInstance($type)
                $mfServer.Initialize(6,$Server)
                $mfServer
            }
            function cUnPublish {
                Param([string]$Srv)
                $Srv = $Srv.toUpper()
                $mfSrv = gcs $srv
                If($mfSrv.Applications.Count -gt 0)
                {
                    Write-Host "Removing All Published Applications from $Srv" -ForegroundColor Red
                    Write-Host "===================================================" -ForegroundColor Green
                    ForEach($a in $mfSrv.Applications)
                    {
                        $myApp = $a.AppName
                        Write-Host "Removing App [$myApp] from Server [$Srv]" -ForegroundColor White
                        $a.RemoveServer($Srv)
                        $a.SaveData()
                    }
                }
                else
                {
                    Write-Host "No Published Applications for $Srv" -ForegroundColor Red
                }
            }
            Write-Host
            $process = @()
        }
        Process{
            if($_){
                if($_.ServerName)
                {
                    $process += $_.ServerName
                }
                else
                {
                    $process += $_
                }
            }
        }
        End{
            if($Server){$Process += $Server}
            foreach($s in $process){
                cUnPublish $s
                Write-Host
            }
        }
    }

    ## Remove Specific Application from Server(s)
    ## -app: Name of Application to remove. This is required
    ## -Server: Name Server.
    ## PIPED: It will take Servers via Pipe. It expects a list or Citrix Server Object
    function Remove-CitrixApplication {
        Param([string]$server,[string]$app)
        Begin{
            function gcs{
                Param($srv)
                $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeServer",$Server)
                $mfServer = [system.Activator]::CreateInstance($type)
                $mfServer.Initialize(6,$Server)
                $mfServer
            }
            function RemoveApp {
                Param([string]$Srv,[string]$myapp)
                $AppRemoved = $false
                $Srv = $Srv.toUpper()
                $mfSrv = gcs $srv
                If($mfSrv.Applications.Count -gt 0)
                {
                    ForEach($a in $mfSrv.Applications)
                    {
                        If(($a.AppName -eq "$myapp") -or ($a.BrowserName -eq "$myapp"))
                        {
                            Write-Host "Removing App [$myApp] from Server [$Srv]" -ForegroundColor Green
                            $a.RemoveServer($Srv)
                            $a.SaveData()
                            $AppRemoved = $true
                        }
                    }
                }
                else
                {
                    Write-Host "No Applications Published for $Srv" -ForegroundColor Red
                    $AppRemoved = $true
                }
                If($AppRemoved -eq $false)
                {
                    Write-Host "This Application not Published for $Srv" -ForegroundColor Red
                }
            }
            Write-Host
            $process = @()
        }
        Process{
            if($_)
            {
                if($_.ServerName){

                    $process += $_.ServerName
                }
                else
                {
                    $process += $_
                }
            }
        }
        End{
            if($Server){$Process += $Server}
            if($process.Length -eq 0){$Process += get-content env:COMPUTERNAME}
            foreach($s in $process)
            {
                RemoveApp -Srv $s -myapp $app
                Write-Host
            }
        }
    }

    Citrix App Functions

    #########################################
    ####     Citrix App Functions        ####
    #########################################
    ## Returns Citrix Application for Farm
    ## -Server: Name of Farm Server. This is required
    ## -App: Name of Application to remove. This is required
    function Get-CitrixApp{
        Param($Server =$(throw ‘$Server is Required’),$App= $(throw ‘$FarmServer is Required’))
        $type = [System.Type]::GetTypeFromProgID("MetaFrameCOM.MetaFrameApplication",$Server)
        $mfApp = [system.Activator]::CreateInstance($type)
        $mfApp.Initialize(3,"Applications\$myapp")
        $mfApp.LoadData($true)
        $mfApp
    }

    ## Returns Users currently using APP
    ## -app: Name of Application. This is required
    ## -Server: Name of Farm Server. Defaults to local if not passed
    ## -count: Switch… if set just returns count of servers
    function Get-CitrixAppUsers {
        Param($app = $(throw ‘$app is required’),$server,[switch]$count)
        function gcf{
            param($srv)
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$Server)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        $ErrorActionPreference = "SilentlyContinue"
        Write-host
        if($server){$mfm = gcf $server}
        else{$mfm = New-Object -com MetaFrameCOM.MetaFrameFarm;$mfm.Initialize(1)}
        $users = $mfm.Applications | ?{($_.AppName -eq $app) -or ($_.BrowserName -eq $app)}
        $Users = $users.Sessions | sort -Property UserName
        if($count){
            Write-Host "Found [$($Users.Count)] Users for Application [$app]" -ForegroundColor White
            Write-Host
        }
        else{
            Write-Host ""
            Write-Host "Found [$($Users.Count)] Users for Application [$app]" -ForegroundColor White
            Write-Host "—————————————————–" -ForegroundColor gray
            foreach($user in $Users){
                If($User.SessionState -eq 1){
                    Write-Host ($User.UserName).PadRight(10) -ForegroundColor Green -NoNewline
                }
                else{
                    Write-Host ($User.UserName).PadRight(10) -ForegroundColor yellow -NoNewline
                }
            }
            Write-Host
            Write-Host "—————————————————–" -ForegroundColor gray
            Write-Host "Found [$($Users.Count)] Users for Application [$app]" -ForegroundColor White
            Write-Host
        }
    }

    ## Returns Servers currently published APP
    ## -app: Name of Application. This is required
    ## -Server: Name of Farm Server. Defaults to local if not passed
    ## -count: Switch… if set just returns count of servers
    function Get-CitrixAppServers {
        Param($app = $(throw ‘$app is required’),$Server,[switch]$count)
        function gcf{
            param($srv)
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$Server)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        if($server){$mfm = gcf $server}
        else{$mfm = New-Object -com MetaFrameCOM.MetaFrameFarm;$mfm.Initialize(1)}
        $Apps = $mfm.Applications | ?{($_.AppName -eq $app) -or ($_.BrowserName -eq $app)}
        # for XP farms
        $servers = $apps | %{$_.Servers} | sort -Property ServerName | Select-Object ServerName
        if(!$servers){
            # for 40/45 farms
            $servers = $Apps.Sessions | Select-Object ServerName | Sort-Object -unique ServerName
        }
        if($count)
        {
            Write-Host
            Write-Host "Found [$($Servers.Count)] Servers for Application [$app]" -ForegroundColor White
            Write-Host
        }
        else
        {
            Write-Host ""
            Write-Host "Found [$($Servers.Count)] Servers for Application [$app]" -ForegroundColor White
            Write-Host "———————————————–" -ForegroundColor gray
            foreach($server in $servers){Write-Host "$($server.ServerName)" -ForegroundColor Green}
            Write-Host "———————————————–" -ForegroundColor gray
            Write-Host "Found [$($Servers.Count)] Servers for Application [$app]" -ForegroundColor White
            Write-Host ""
        }
    }

    ## Returns Server(s) user is logged into via Citrix
    ## -LoginName: Login Name of user (Domain\User). This is Required
    ## -Server: Name of Farm Server. Defaults to local if not passed
    ## -Verbose: Details about User
    function Find-CitrixUser {
        Param([string]$LoginName,$Server,[switch]$verbose)
        $user = $LoginName.Split("\")[1]
        $Domain = $LoginName.Split("\")[0]
        if($server)
        {
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeUser",$Server)
            $mfuser = [system.Activator]::CreateInstance($type)
            $mfuser.Initialize(1,$Domain,1,$user)
        }
        else
        {
            $mfuser = New-Object -ComObject MetaframeCOM.MetaframeUser
            $mfuser.Initialize(1,$Domain,1,$user)
        }
        Write-Host
        Write-Host "User: $($mfuser.UserName) found on the Following:"
        foreach ($s in $mfuser.Sessions)
        {
            if($verbose)
            {
                Write-Host
                Write-Host "$($s.ServerName)"
                Write-Host "-=-=-=-=-=-"
                Write-Host "AppName          : $($s.AppName)" -foregroundcolor yellow
                Write-Host "SessionName      : $($s.SessionName)" -foregroundcolor yellow
                Write-Host "SessionID        : $($s.SessionID)" -foregroundcolor yellow
                Write-Host "ClientAddress    : $($s.ClientAddress)" -foregroundcolor yellow
                Write-Host "ClientEncryption : $($s.ClientEncryption)" -foregroundcolor yellow
                Write-Host
                Write-Host "Processes"
                Write-Host "========="
                foreach ($proc in $s.Processes)
                {
                    Write-Host $proc.ProcessName -foregroundcolor Green
                }
                Write-host
            }
            else
            {
                write-Host "   -> $($s.ServerName)"
            }
        }
    }

    Citrix, Citrix, and more Citrix!

    It has been a while since I dove into the MFCom pool. Most of the Citrix functions I wrote where at the very beggining of my Powershell Adventure. I decided to go through and rewrite some of them and post the others.

    So… here you go.

    I broke these down into three sections
    - Citrix Farm Functions
    - Citrix App Functions
    - Citrix Server Functions

    If you get a chance to use these let me know if you run into any troubles… I did test them thoroughly.. but you never know.

    Other than Publish/Unpublish/Remove they shouldn’t change anything.

    UPDATED: I added information about functions before each section. And a list at the bottom!

    Farm functions
    ————–
    # Returns Farm Object.
    # -Server: Any PS should do.. I recommend ZDC though) !!REQ!!
    Get-CitrixFarm

    # Returns a collection of Server Objects
    # -zone= This will be the zone name (normally the subnet i.e. 10.1.1.0) !!REQ!!
    Get-CitrixOnline

    # Returns Load Evaluators Information
    # -Server: Any PS should do.. I recommend ZDC though) !!REQ!!
    Get-CitrixLE

    # Returns Printer Drivers install in Farm
    # -Server: Any PS should do.. I recommend ZDC though) !!REQ!!
    # This can take a REAL long time
    Get-CitrixPrintDrivers

    # Returns Polices in the Farm
    # -Server !!REQ!! (any PS should do.. I recommend ZDC though)
    Get-CitrixPolicies

    #########################################
    ####     Citrix Farm Functions       ####
    #########################################
    # Get Citrix Farm
    function Get-CitrixFarm{
        param($Server)
        $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$Server)
        $mfarm = [system.Activator]::CreateInstance($type)
        $mfarm.Initialize(1)
        return $mFarm
    }

    # Get Online Servers by Zone
    function Get-CitrixOnline {
        Param($zone)
        $mfzone = New-Object -ComObject MetaFrameCOM.MetaFrameZone
        $mfzone.Initialize($zone)
        $servers = $mfzone.OnlineServers
        $servers
    }

    # Get Citrix Load Evaluators (only 4.0/4.5)
    function Get-CitrixLE{
        Param($server=$(throw "Server is Required"))
        function Load-Farm{
            param($srv)
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$srv)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        $Farm = load-farm $server
        if($Farm.LoadEvaluators){
            foreach($eval in $Farm.LoadEvaluators)
            {
                $eval.loadData(1)
                "+ Load Evaluator: {0}" -f $eval.LEName
                $servers = $eval.AttachedServers(1)
                if($servers.count -ne 0)
                {
                    "  + Servers"
                    $servers | %{"    - {0}" -f $_.ServerName}
                }
                $rules = $eval.rules | Select-Object RuleType,HWM,LWM,Schedules
                if($rules.count -ne 0)
                {
                    "  + Rules"
                    foreach($rule in $rules)
                    {
                        "    - {0}" -f $rule
                    }
                }
            }
        }
    }

    # Gets the Citrix Printer Drivers for the Farm (Can be REAL slow)
    function Get-CitrixPrintDrivers{
        Param($server=$(throw "Server is Required"))
        function Load-Farm{
            param($srv)
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$srv)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        $farm = Load-Farm $Server
        $farm.Drivers
    }

    # Gets Citrix Policies
    function Get-CitrixPolicies{
        param($Server)
        function Load-Farm{
            param($srv)
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$srv)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        $farm = Load-Farm $server
        $type = [System.Type]::GetTypeFromProgID("MetaFrameCOM.MetaFrameUserPolicy")
        foreach($pol in $Farm.policies($type))
        {
            $pol.loadData(1)
            "+ Name: {0}" -f $pol.Name
            "  - Description: {0}" -f $pol.Description
            "  - Enabled: {0}" -f $pol.Enabled
            if($pol.AllowedAccounts)
            {
                "  + AllowedAccounts"
                foreach($aa in $pol.AllowedAccounts)
                {
                    "    - {0}" -f $aa.AccountName
                }
            }
            if($pol.UserPolicy2)
            {
                "  + UserPolicy"
                $props = $pol.UserPolicy2 | Get-Member -membertype Property | %{$_.Name} | Sort-Object Name
                foreach($prop in $props)
                {
                    if(($pol.UserPolicy2.$prop -match "\d") -and ($pol.UserPolicy2.$prop -ne 0))
                    {
                        "     - {0}:{1}" -f $prop,$pol.UserPolicy2.$prop
                    }
                }
            }
            write-Output " "
        }
    }

    App functions
    ————–
    # Returns User Count for an App or All Apps
    # -FarmServer !!REQ!! (any PS should do.. I recommend ZDC though)
    # -app: Name of Application
    # This loops CTRL+C to break
    Get-ApplicationUserCount

    # Returns Server(s) user is logged into via Citrix
    # -LoginName: Login Name of user (Domain\User) !!REQ!!
    # -Verbose: Details about User
    Find-CitrixUser

    # Returns Servers published for Application or just Count
    # -app: Name of Application !!REQ!!
    # -count: Switch… if set just returns count of servers
    Get-CitrixServers

    # Returns Users currently using APP
    # -app: !!REQ!!
    # -count: Switch… if set just returns count of servers
    Get-CitrixAppUsers

    #########################################
    ####     Citrix App Functions        ####
    #########################################
    # Outputs the number of Users using a Citrix App or Apps
    function Get-ApplicationUserCount {
        Param([string]$app,[string]$farmServer = $(throw ‘$FarmServer is Required’))
        function List-AllCitrixApps{
            Param($mFarm)
            ForEach($app in $mFarm.Applications)
            {
                $name = $app.BrowserName.PadRight(25)
                $count = "$($app.Sessions.Count)"
                $count = $count.PadRight(10)
                Write-Host "$name $count"
            }
        }
        function List-App{
            param($mApp,$mfFarm)
            ForEach($app in $mfFarm.Applications)
            {
                if($app.BrowserName -eq "$mApp")
                {
                    $name = $app.BrowserName.PadRight(25)
                    $count = "$(($app.Sessions | ?{$_.SessionState -eq 1}).Count)"
                    $count = $count.PadRight(10)
                    Write-Host "$name $count"
                }
            }
        }
        function Load-Farm{
            $type = [System.Type]::GetTypeFromProgID("MetaframeCOM.MetaframeFarm",$srv)
            $mfarm = [system.Activator]::CreateInstance($type)
            $mfarm.Initialize(1)
            return $mFarm
        }
        Write-Host
        $title1 = "Application".PadRight(25)
        $title2 = "===========".PadRight(25)
        Write-Host "$title1 User Count" -ForegroundColor White
        Write-Host "$title2 ==========" -ForegroundColor Red
        $mf = Load-Farm $farmServer
        While($true)
        {
            $oldpos = $host.UI.RawUI.CursorPosition
            If($app)
            {
                List-App $app $mf
            }
            else
            {
                List-AllCitrixApps $mf
            }
            sleep(5)
            $host.UI.RawUI.CursorPosition = $oldpos
        }
        Write-Host ""
    }

    # Finds what Server a User is on
    function Find-CitrixUser {
        Param([string]$LoginName,[switch]$verbose)
        $user = $LoginName.Split("\")[1]
        $Domain = $LoginName.Split("\")[0]
        $mfuser = New-Object -ComObject MetaframeCOM.MetaframeUser
        $mfuser.Initialize(1,$Domain,1,$user)
        Write-Host
        Write-Host "User: $($mfuser.UserName) found on the Following:"
        foreach ($s in $mfuser.Sessions)
        {
            if($verbose)
            {
                Write-Host
                Write-Host "$($s.ServerName)"
                Write-Host "-=-=-=-=-=-"
                Write-Host "AppName          : $($s.AppName)" -foregroundcolor yellow