Manage Citrix Tags with PowerShell

In this post, we are going to cover how to manage Citrix tags with PowerShell. Citrix Studio is a great tool, but it can be very time consuming especially if you have to do bulk tag actions. Citrix tags can be used in several methods, but this post is focused on desktop tagging. This post will cover the following scenarios:

  • List all current Citrix tags
  • List the members of a specific Citrix tag
  • Creation of a new Citrix tag
  • Removing a Citrix tag from a list of desktop names
  • Adding a Citrix tag from a list of desktop names
  • Deleting a Citrix tag while removing it from all members

Code

GitHub

Let’s begin by getting things prepared to run Citrix PowerShell commands. The PowerShell snap-ins that are needed to manage tags are installed automatically when you install a Delivery Controller or Studio. Ensure that you are running your scripts from a machine that is either a Delivery Controller or has Studio installed.

The first thing we need to do is add the Citrix PowerShell snapins.

try{
    ### Adding Citrix powershell snapins
    Add-PsSnapin *Citrix* -ErrorAction Stop
}
Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
    Write-host "Citrix Powershell snapins are not present, install the snapins and try again. Script is exiting..." -BackgroundColor Red -ForegroundColor White
    Return
}

Here we are going to set a variable to the server fully qualified domain name (FQDN) of a Delivery Controller. There are better ways to do this, but for this example we are going to keep it simple.

$Citrix_DC = "dc_server.domain.local"
List all current Citrix tags

This will return all current Citrix tags that are present and send the output to screen via Out-GridView.

Get-BrokerTag -AdminAddress $Citrix_DC  | Select Name, Description | Out-GridView -Title "All Active Citrix Tags"
List the members of a specific Citrix tag

The below code will return all the members of a selected tag by utilizing Out-GridView. Out-GridView is a very clean method to present data and accept user input. You can read more on that in my previous post. This is a way to report on what desktops are assigned to a given tag.

### Out-gridview for user to select the citrix tag they want to find which members (Desktops) are tagged
$Tag_to_Search = Get-BrokerTag -AdminAddress $Citrix_DC | Select Name, Description | Out-GridView -Title "Select the Citrix Tag you want to grab members for" -OutputMode Single
### Grabbing all the members (Desktops) that are tagged with the selected tag
$Members_of_Tag = Get-BrokerDesktop -AdminAddress $Citrix_DC -Tag $Tag_to_Search.Name -MaxRecordCount 100000 | Select HostedMachineName, AssociatedUserFullNames, AssociatedUserNames, Tags, IPAddress 
### If there are no members of the tag it will send output to console otherwise it will send an out-gridview
If ($null -eq $Members_of_Tag){
    Write-Host "No members of the selected TAG" -BackgroundColor Red -ForegroundColor White
}
Else{
    $Members_of_Tag | Out-GridView -Title "Members of selected Tag"
}
Creation of a new Citrix tag

Now we will take a look at how to create a new tag. I have used Read-Host here to allow the user to input the pertinent data, but other methods could be used. I am using a try / catch to ensure that we capture any errors that might arise from creating a new tag.

$New_Tag_Name = Read-Host "Enter the NEW Tag Name (ie: Finance)"
$New_Tag_Description = Read-Host "Enter the NEW Tag Description (ie: Finance Department)"

try{
    ### The creation of the new citrix tag
    New-BrokerTag -AdminAddress $Citrix_DC -Description $New_Tag_Description -Name $New_Tag_Name
    Write-Host "Process Complete" -BackgroundColor Green -ForegroundColor White
}
Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
    $errormessage = $_.Exception.Message
    Write-host $errormessage -BackgroundColor Red -ForegroundColor White
}
Removing a Citrix tag from a list of desktop names

In this example, I am using the GUI text box that I wrote about in a previous post. I am using the text box as one method you could use to accept a list of desktop names. The script will pull all the possible tags that could be removed and present them via Out-GridView. Once a tag is selected, the script continues with the removal.

### Launch GUI textbox to accept input from user
$Desktops = GUI_TextBox "Desktop Name(s):" ### This function was introduced in previous blog post
$Desktop_Count = $Desktops | Measure-Object | % {$_.Count}
If ($Desktop_Count -eq 0){ ### If nothing was inputed, the script will not continue
    Write-Host "Nothing was inputed, script is exiting..." -BackgroundColor Red -ForegroundColor White
    Return
}
Else{   
    ### Gathering all the available tags that could be removed
    $Tag_to_Remove_From_Desktops = Get-BrokerTag -AdminAddress $Citrix_DC | Select Name, Description | Out-GridView -Title "Select the Citrix Tag you want to REMOVE for the list of imported Desktop Names" -OutputMode Single

    Write-host "Number of Desktop Names to remove from $($Tag_to_Remove_From_Desktops.Name) : $Desktop_Count" -BackgroundColor Cyan -ForegroundColor Black
    $Remove_Tag_Confirm = Read-Host "Do you want to continue? (Y/N)"

    If ($Remove_Tag_Confirm.ToUpper() -eq "Y"){
        Foreach ($Desktop in $Desktops){ ### Going through each inputted Desktop name and removing the tag
            try{
                ### In order to remove a tag, we need to gather the uid of the Desktop
                $Uid = Get-BrokerDesktop -HostedMachineName $Desktop -AdminAddress $Citrix_DC | % {$_.Uid}
                ### Removal of the tag
                Remove-BrokerTag $Tag_to_Remove_From_Desktops.Name -Desktop $Uid
                Write-Host "Process Complete" -BackgroundColor Green -ForegroundColor White
            }
            Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
                $errormessage = $_.Exception.Message
                Write-host $errormessage -BackgroundColor Red -ForegroundColor White
            }
        }
    }
    Else{
        Write-Host "User Canceled Script" -BackgroundColor Red -ForegroundColor White
    }
}
Adding a Citrix tag from a list of desktop names

This bit of code is almost identical to the removing of a tag, so I am not going to go into great detail here. Obviously the command to add a tag vs remove a tag will change, but that’s about it.

### Launch GUI textbox to accept input from user
$Desktops = GUI_TextBox "Desktop Name(s):" ### This function was introduced in previous blog post
$Desktop_Count = $Desktops | Measure-Object | % {$_.Count}
If ($Desktop_Count -eq 0){ ### If nothing was inputed, the script will not continue
    Write-Host "Nothing was inputed, script is exiting..." -BackgroundColor Red -ForegroundColor White
    Return
}
Else{  
    ### Grabbing all the possible citrix tags
    $Tag_to_Add_to_Desktops = Get-BrokerTag -AdminAddress $Citrix_DC | Select Name, Description | Out-GridView -Title "Select the Citrix Tag you want to ADD to Desktop Names" -OutputMode Single

    Write-host "Number of Desktop Names to add to $($Tag_to_Add_to_Desktops.Name) : $HD_Count" -BackgroundColor Cyan -ForegroundColor Black
    $Add_Tag_Confirm = Read-Host "Do you want to continue? (Y/N)"

    If ($Add_Tag_Confirm.ToUpper() -eq "Y"){

        Foreach ($Desktop in $Desktops){ ### Going through each inputted Desktop name and adding the tag
            try{
                ### In order to add a tag, we need to gather the uid of the Desktop
                $Uid = Get-BrokerDesktop -HostedMachineName $Desktop -AdminAddress $Citrix_DC | % {$_.Uid}
                ### Adding of the tag
                Add-BrokerTag -Name $Tag_to_Add_to_Desktops.Name -Desktop $Uid -AdminAddress $Citrix_DC
                Write-Host "Process Complete" -BackgroundColor Green -ForegroundColor White
            }
            Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
                $errormessage = $_.Exception.Message
                Write-host $errormessage -BackgroundColor Red -ForegroundColor White
            }
        }
    }
    Else{
        Write-Host "User Canceled Script" -BackgroundColor Red -ForegroundColor White
    }
}
Deleting a Citrix tag while removing it from all members

Here we are completely deleting all traces of a tag. In order to delete a tag, we have to ensure that there are no members. Once the tag is free from all members, it can be successfully deleted.

### Grabbing all available citrix tags available to delete
$Tag_to_Delete = Get-BrokerTag -AdminAddress $Citrix_DC | Select Name, Description | Out-GridView -Title "Select the Citrix Tag you want to DELETE" -OutputMode Single
### Pulling all of the members of the selected tag to delete
$Members_of_Tag_to_Delete = Get-BrokerDesktop -AdminAddress $Citrix_DC -Tag $Tag_to_Delete.Name -MaxRecordCount 100000 | Select HostedMachineName, AssociatedUserFullNames, Tags 

If ($null -eq $Members_of_Tag_to_Delete){ ### If there are NO members of the selected tag then it will just delete the tag
    Write-Host "No members of the selected TAG" -BackgroundColor Cyan -ForegroundColor Black
    Remove-BrokerTag $Tag_to_Delete.Name -AdminAddress $Citrix_DC
    Write-Host "Process Complete" -BackgroundColor Green -ForegroundColor White
}
Else{ ### If there are members of the selected tag then it will confirm that you really want to delete the tag
    $Member_Count_To_Delete = $Members_of_Tag_to_Delete | Measure-Object | % {$_.Count} ### Counting the members of the tag to delete

    Write-host "Number of Desktop Names to remove from $($Tag_to_Delete.Name) : $Member_Count_To_Delete" -BackgroundColor Cyan -ForegroundColor Black
    $Remove_Tag_Confirm = Read-Host "Do you want to continue? (Y/N)"

    If ($Remove_Tag_Confirm.ToUpper() -eq "Y"){
        try{
            ### Doing a loop on all the members in the given tag and removing that tag
            Foreach ($Member in $Members_of_Tag_to_Delete.HostedMachineName){
                ### In order to remove a tag, we need to gather the uid of the Desktop
                $Uid = Get-BrokerDesktop -HostedMachineName $Member -AdminAddress $Citrix_DC | % {$_.Uid}
                ### Removal of the tag
                Remove-BrokerTag $Tag_to_Delete.Name -Desktop $Uid
            }
            ### After the tag has been removed from all of the members its time to delete the tag
            Remove-BrokerTag $Tag_to_Delete.Name -AdminAddress $Citrix_DC
            Write-Host "Process Complete" -BackgroundColor Green -ForegroundColor White
        }
        Catch [Exception]{ ### If the command inside the try statement fails the error will be outputted
            $errormessage = $_.Exception.Message
            Write-host $errormessage -BackgroundColor Red -ForegroundColor White
        }
    }
    Else{
        Write-Host "User Canceled Script" -BackgroundColor Red -ForegroundColor White
    }
}

That’s it for now, thanks for reading!


Check out my other blog posts:

Media Sync: Organize Your Photos and Videos with PowerShell

Do you have photos and videos that you have taken over the years that are scattered all over the place? Do you want to have all your photos and videos organized? Do you want all your photos and videos to have a standardized naming scheme? If you answered YES to these questions, then this is…

NetNeighbor Watch: The PowerShell Alternative To Arpwatch

In this post, we are going to setup NetNeighbor Watch on a Raspberry Pi. NetNeighbor Watch can keep an eye on your network and send you an email when a new host is discovered. NetNeighbor Watch is done completely in PowerShell. The results are very similar to those of arpwatch. NetNeighbor Watch is for anyone…

Generate a Citrix Desktop Report Based on Active Directory Users

In this post, we are going to merge data from two different sources to generate a report that can provide insight into your Citrix environment. I will show you how to combine Active Directory data for the users in your domain with Citrix data. This report will provide you with the following knowledge: Users that…

Creating a PowerShell Module to Improve Your Code

Do you have PowerShell code that you reuse in your scripts over and over? Do you have server names hard coded in variables? Are you using a text file or CSV file to import server names? Do you find yourself only utilizing one server out of a cluster of servers to make your PowerShell commands?…

Generate a DHCP Report Via PowerShell

Today we are going to look at how to generate a DHCP scope statistics HTML report by using PowerShell. This report will give you one location to see all of your DHCP scope statistics across all of your Windows DHCP servers. It will dynamically pull the DHCP servers and associated DHCP scopes within your Active…

Increase VMware VM Disk Size with PowerShell

In this post, I will cover how to use PowerShell to increase the disk size of a Windows 10 VM running in a VMware vCenter environment. Automating simple but time consuming tasks like this can save precious time for your support staff or yourself. There are two parts to accomplishing this task; first we need…

Create a Text Box to Accept User Input for PowerShell GUI

Do you have a PowerShell GUI that needs to accept text input? Maybe you want to be able to copy and paste a list of computers, ip addresses, user names or some other data. I will show you how to add a text box into your PowerShell GUI to handle that input. If you haven’t…

Utilizing PowerShell Out-GridView as a GUI Alternative

In my previous post, I showed how you can build a simple menu driven PowerShell GUI; check it out here. To further improve upon that simple GUI, we will go over how to use Out-GridView. Out-GridView is a built-in powershell cmdlet that sends the output from a given command to an interactive window. This post…

How to Create a Simple PowerShell GUI

Have you ever wanted to create a menu driven PowerShell GUI to conduct a series of automated tasks? You are in luck, because that is exactly what we are going to cover in this post. This very simple PowerShell GUI will help you easily distribute your code to other team members or maybe you just…

2 thoughts on “Manage Citrix Tags with PowerShell

Leave a comment