Citrix Receiver to Citrix Workspace App


Citrix Receiver has a large footprint across the enterprise, both on physical and virtual machine. Rightfully so, allowing users access to their virtual machine from a remote location as well as their hosted apps. 

Citrix has two different paths for Receiver release, LTSR (Long Term Service Release) and CR (Current Releases). LTSR is preferred by large organizations since it is more stable and offers the comprehensive updates and bug fixes from CR. 

So, how large is the footprint?! 338,000 roughly…let’s keep that in mind for now.

Towards the end of 2018, Citrix first announced the Citrix Workspace App with new enhanced features not available in Citrix Receiver. The following three things happened during this time frame also:

1. October 2018, Microsoft announced a vulnerability in one of their products. MS11-025. It affects the Visual C++ 2008 SP1 redistributable package which is used by Citrix Receiver. 
2. In response to the vulnerability, Citrix recommended customer to upgrade to the Citrix Workspace App instead.
3. As of this writing, Citrix Workspace App (CWA) does not have a LTSR and CR version of their CWA app like Citrix Receiver. 

With an impact to such a high number of systems, I had to decide on which path to proceed. For a while, it looked like Citrix was going to keep both Citrix Receiver and Citrix Workspace App around. However, from my experience over the years I know that won’t be the case for long. And as suspected, Citrix made the announcement to replace Citrix Receiver with Citrix Workspace App. 

In my next four writeups, I will highlight each of the areas that were impacted by this transition.  

1. Release Cadence: the release cadence of the Citrix Workspace App (CWA).
2. Removing from base app: as the title says.
3. Self Service Enablement: here I will also discuss the auto detection.
4. Cleanup and Compliance revolves around businesses that still requires Citrix Receiver instead.

5 Miler Since 2005


Last time I raced was in 2005 at the Sunflower State Game in Topeka, Ks. It was a 3K race on a track. I still remember, after that first 400 meter turn the heat on my back and thinking to myself, 'Oh boy I am done.'

Since then a lot has happened and I never muster the courage to race again. I'd always find an excuse to put it off. That is until this year. Starting February, I decided to become serious and approach my running in a more scientific method. By April it was clear I needed to set a goal and strive towards it. On a later post, I will describe in grueling detail about my run and training for this year, 2019. But for today, I wanna discuss my experience running my first race after almost a decade.

On October 20, I raced the Rocktober Fest and competed on the 5 miler. At the beginning of the race, I was very cautious and stayed pretty much all the way on the back. Once the race started, I let my body find it's sweet spot, the groove, the rhythm. The first mile I passed was 9.50 and I knew I needed to star pushing more. So, I started picking up the pace.

Around 2 mile, came across a group of runner blaring the Bluetooth speaker attached to the back of one of the runner's hip. After the first few minutes, I am getting annoyed and planning on moving past him. For the next few minutes what seemed like a loooooong time I am trying to shake off the group. That's when I come up to the downhill slope. Instead of charging down the hill though, I decided to focus on my rhythm and posture. I think that paid off. Because by the end of the hill, I had passed the group.

Mile 3 pretty uneventful. Just focusing on my run and enjoying the different view of this awesome city.

Mile 4, came across another runner complaining to all the passers about how terrible whatever is. Put my head down and completely ignored him. Mile 4.38, just passed someone and she decides to catch up and pass me. Instead of sprinting forward and possibly costing my leg I decided to hold my pace steady and focus, Within a minute, I pass the runner for the last time and crossed the finish line soon after.


Crossed the finish line in 45 minutes and 21 second according to my personal time. Official time is a little lower than mine....=)


Everything I am learning on this journey can transcend over to my professional and academic life. And it has been. More on that oat a later post as well.

Along the way, it is important to call on others for support, rely on. Here I am looking for encouragement for my 10 year old.


Smile, Love and Believe...

3.30am Illumination

This happened last night. At 3.30am I woke to dreaming I had a solution to our problem, well the problem that has the potential for escalating quickly at work. Here's the summary of all of that:

The Environment/Setup:



So, we have couple monitoring servers that monitors and manages the kiosks out in the field. The IPs for the monitoring servers are hard-coded within the image. Every 30 minutes the kiosk pings the gateways to check if there's any tasks waiting for it. For security. on the router end we also have the IPs setup so when the router sees incoming traffic it will allow it to pass.

The Problem:

Up until recently the monitoring servers had Class C IPs. Life was good. But then the decision was made to migrate the server OS from Windows Server 2003 to 2008 R2 AND move to Class A IPs instead. By this point the kiosk themselves are coming to end of life and we made the decision to retire the whole platform by the end of 2019. Yay!!

With the IP changes on the monitoring server, we had to change the IPs on the kiosk agent themselves. And we were able to accomplish that working hand in hand with the network folks. That particular event went down like this:

1. Week 1: network ACL adds 1 new IP to the list keeping the old ones still in
2. Week 2: migrate that one particular monitoring server that was added on the network ACL and update the agents to replace the Class C IP to Class A for that particular one.

Few months later after verifying all are functioning OK, repeat the same process for other server.

This is great for existing devices. What's not great is any devices that have to be re-imaged or new kiosk installation. Remember I said the kiosk itself is coming to an end.

Oh and the old IPs has been reclaimed. Meaning they are gone. Disappeared.

Finally the Illumination:

Since now there's no way for us to contact the kiosk in order to update the IPs on the agent, I had THE grand idea. Oh BTW, did I mention I designed the whole platform in such a way even if we considered having a tech manually update the agent there's absolutely no way to do it. You can't do "CTRL + ALT + DEL" or "CTRL + Esc"..nada. Without being able to check-in with the monitoring servers these machines are useless.

So, my theory was since we are killing the platform there's only a handful of instances where devices are completely down. How about update the agent on the devices via some type of autorun application that the tech can use? So techs will walk up to the downed device, plug in the stick drive and boom it will update the agent on them and reboot and reseal.

The Solution:

With that in mind, by 4am I am writing the different pieces of the whole solution. Ideally there has to be two instances. a) an AutoRun.inf file and b) the application that will update the agents.

Writing the code for either one are very simple. I was so excited I has having a hard time deciding whether to write the second one in VB, bash, script file among others.

By 5am, I was done with all of the coding and now time to test. I waited anxiously to drop our daughter off at the bus stop and then ran to the lab for testing.

For testing, I devised to only reboot the kiosk. So, if I plug in the USB stick and it reboots correctly then I can enable rest of the code for other changes. I could see the USB sticks gets recognized and but nothing else happens. What gives??!!

Heads down I am working away. Trying to figure out why the autorun.inf is running and nothing else is happening. After some digging I come to find out, MS has disabled the support to run any program automatically from a flash drive for security reasons for Windows 7 and upward. There's one of two ways to handle this:
1. Use some type of Autorun USB Creator
2. If there's a native application in the kiosk that the autorun.inf can call on and then the second application will pass the parameters for the actions.

Now time to take a pause and rethink. I search the company database for any USB creator that is approved and can be used. I am not going to download something from the web that is not approved within the company. When I can't find anything, I decided to hit up two of my colleagues with whom I occasionally discuss life, work and everything in-between. Ironically both are named John.

So, John A. I give him the rundown and my idea. He points out that's about the same as updating the current image and less time consuming than the extra component that I am trying to add on. Even though I am thinking few instances of devices being hard down, eventually he points out this little solution will propagate to all the field techs.

hmmmm...interesting point. Oh and we chatted about getting old and taking more care for our bodies...=)

John B conversation: I give him the run down and let him know I am already leaning on ditching this idea altogether. He reminds me the security protocol we have in place and how unlikely, impossible it would be to get any solution like that to be approved by the security team for release. What if someone decided to swap out the executable and update the .inf file. That means in order to safe guard the flash drive I will have to come up with another solution. Overall a time consuming process that likely won't be approved. AND we talked about our long weekend plans, beach and boat.

ahhh...it was a great idea putting on the engineering hat at 3.30am. By 11am, this is not a viable solution and all work around it ceased to exist.

Remote Install Software

So, as the component owner for the Citrix Receiver, for a while I had been testing Citrix Receiver 4.9 LTSR CU2 quiet extensively.

Generally once a new version of Receiver comes out, I spend at least a week testing it in every possible version (laptop, desktop, VM, thin clients) before submitting the app for packaging. Once the packaging team is done, they hand over the installer to me for UAT. This is when I spend another week or two of testing the installer that will essentially hit thousands and thousands of computers both virtual and physical. During this time, I will pick several users and systems to pilot the package and gather feedback.

And that's where few PowerShell commands makes it a little bit easier.

There's the antique way of installing the package. Which kinda looks like this: notify user, hand over or share the package out from a shared location. Make sure user has the rights to install the software. Give user instruction on how to copy and run the program. Check back after a week to make sure if the user was able to follow instruction successfully.

With this method as you can see, we are already loosing a week of going back and forth just trying to install the darn package.

Or the other method is:

1. Notify user that they have been selected to pilot the software
2. Notify user in the event of multiple system, which one will be updated
3. Run a PS command to find out if the user already has the app you intend to install. No point reinstalling the same app. Like that never happens.




In the event if it is too small to see here's what the command is:

Invoke-command -computer Computer 1, Computer 2, Computer 3, etc. {Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*  | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
| Where-Object {$_.publisher -eq "Citrix Systems, Inc."} | Format-Table -AutoSize }

The Invoke command basically tells each computer to return the value of all the installed software on those machines. 

The second pipeline is to weed out and select only few of the information I really care about from the returned value above.

The third pipeline is from the whole list again I really want info on certain application. In this case, it is application by Citrix such as Citrix Receiver. 

The fourth and the last pipeline is to make the whole list look more pretty. 

Now Instead of typing in computer1, computer2, etc. I could also say read the names off of a text or csv file but since here my pilot user list is relatively small, I chose to type out the name. Do keep in mind, this does increase the chance of typo. 

4. If the intended app is not installed, copy the installer over to the local drive of the system

In this case, I copied them to the local C:\Temp folder.

5. Use PSExec.exe to install the software remotely from your admin machine.

Psexec.exe \\computer1 c:\temp\Citrix\CitrixSystems_CitrixReceiver_14.9.2000.21.exe

6. Once completed, notify the user that their system has been updated and you will check back with them after a certain time to gather feedback.
7. After the certain time gather feedback.

Few things, I can already think.

1. item no. 5 instead of typing in or arrow upping several time and editing the name of the computer have a command that will install the software in iteration and return value.
2. OR simply write a whole script that will do all these items from 3 to 5 in one run taking in the name of the machines from another source. This way, I simply have to copy the machine names into the source file. The script should read off of it, execute the command. If the software I intend to installed is not on already, copy it and install it and return the success/failure value.

Thoughts?!

Camping at the Table Rock State Park


















Traditionally, we have always went for family camping during memorial weekend and this time was no different. Although in hindsight maybe a beach trip would have been a better choice than camping cuz how it had rained almost every evening.

So, this time knowing the weather ahead of time I decided to spend extra on getting a canopy. And boy, I am so glad I did. It meant we were able to stand in shade, keep our food, silverware dry, cook in shade and made the wife happy....=)

We arrived around 6.30ish that evening at the Table Rock State Park. We had reserved campsite 37 with water and electric hookup. We really lucked out on that site. As we were driving thru the sites to get to ours, wife was groaning about how uneven, steep some of the sites seemed. Honestly, there's some slope but nothing too bad. When we arrived at our site, it hadn't started raining yet. So, both wife and I got to work taking advantage of that. I jumped to setup the small tent first so we can put the kids in there while wife kept them busy in the car. After the small one was setup, put the kids in the tent and then wife and I started setting up the canopy. Once those two were done, we started on the big tent primarily the one for sleeping and everything for next three nights.

By the time, we started on the big tent it started raining on us. In a rush and with some confusion, we were able to get it setup albeit some mistakes as clear on the pic above. In the middle of that night, I had to get up and readjust our sons' side of the tent cuz it was leaking. Next morning we realized water had got in on our daughters' side as well.

Where the park is located, there's no restaurant or grocery store within a short distance. There's one restaurant but it closes by about 8/9pm I believe. By the time, we were done setting up tents, it was almost 9pm. Kids were hungry, but more tired than anything. We had to drive 20 minutes into town to pickup pizza.

Next day, we took advantage of many of the activities the park has to offer. There's a play area, it is big and in a pretty decent shape. Because of the continuous rain, the playground appeared somewhat dirty but I believe it actually is kept well. Kids enjoyed burning off steam playing at the playground, watching ducks, visiting the nature center.


And it rained on us that night again. However, this night was a little more festive. I had downloaded few movies on our iPad from Netflix. So, this night during dinner wife and I setup the movie in our small tent and they were thrilled. They loved the whole atmosphere of eating their favorite dish while watching a movie inside a tent.

Next morning, I woke up quite early as usual. Realizing I won't be able to get back to sleep, I decided to take advantage of everyone else sleeping and go for a hike. I would've loved to do the Pinnacle Mountain Trail which takes you all the way to the summit, however I knew I wouldn't have enough time for that hike. It is 4.2 miles one way and very strenuous. Instead I decided to hike the simple Carrick Creek trail.


This trail is a simple 2 miles loop trail starting from the nature center. Earlier we had planned to hike this trail as a whole family. However, part of me wanted to assess what the trail holds for hiking with kids, since I didn't have our trusty Kelty child carrier with us. And boy I am glad I did the hike by myself. Without the child carries, it would've been quiet challenging with a 3 year old. Trying to get up on some parts of the trail, crossing the streams would've been a challenge. And that is always a recipe for disaster and make everyone miserable.

I had an awesome time exploring the trail by myself alone in the morning. Towards the end, I ran into two people on the trail. During this whole time, I was taken by the sound of nature, noise from the waterfalls, and on occasion cars and trucks driving by in distance.




Hiking with Kids

This past Sunday, we went hiking with the kids. I would like to think it is just the beginning of the season and be able to keep up during the summer.

So, first about the hike itself. Gave wife two options, either a) Crowders Mountain which is about 40 minutes from our house or b) Latta Plantation, 5 minutes distance. She wanted something far and challenging. So Crowders it is.

For this hike, I focused on getting the kids moving. While the wife focused on snacks. Unfortunately, that meant I didn't pay attention to amount of snacks and water she packed. She had packed more than necessary amounts of snacks just for the four of us with only one water bottle. We hiked the Backside trail which is a strenuous hike, albeit .90 miles. By the time we made it half way through, wife herself had pretty much finished up all the water.

I was also hoping that I had remembered to bring my towel or bandanna. Carrying the little one on by back going up, I was sweating profusely.

Ian on my back in our trusted Kelty Kids

Hiking up with the kids, as an avid hiker myself I focused on few things. 
1. Made sure the wife is going to be OK to go up herself since her pace is slower compared to mine
2. Get the kids moving at THEIR pace
3. Be silly, have fun.

If I was hiking by myself I would have focused on either speed and length or the natural surrounding itself or both. But here since kids are involved, I decided to trek along at a good pace that our daughter set and just keep moving. While making it fun, pointing at trees, dogs, singing silly songs.



Once we made it to the top, I made it very clear to both kids that since we are all the way to the top they must stay with me all the time. And then let Ian out, and let both of them explore a little. Wife joined us shortly. Took a small break. Sucked to put the backpack back on with a sweaty back. 

Going back down was rather simple but had its own challenge. Since now I have an added wait on my back, top of the waist lets just say I wasn't excited about looking down at the stairs the whole time. 

But finally we made it down. Once we made it all the to the bottom, instead of jumping in the car and taking off we decided to have a little picnic and enjoy the weather and watch other people and dogs. After that, change out my sweaty t-shirt, takes the hiking shoes off and put on a sandal (ah.....) and then drive back home. 

For next time, I will be sure to followup on the items below.

1. Snacks
2. Water and/or energy drink
3. Towel
4. Sandals for everyone.

Recently I came across this awesome blog all about hiking. I will try to follow her and thought others might enjoy it too.

http://homemadewanderlust.com/

Disabling TLS 1.0

Recently I had to deal with an issue where the f5 load balancer had turned off any incoming and outgoing TLS 1.0 traffic which caused a system wide outage for a set of identical machines across the company.

We were in a time crunch since the change has already been implemented and had to be rolled back. We were given 2 weeks to determine the root cause, come up with a solution and apply the fix before mgmt will be forced to decide whether to move on with the TLS 1.0 traffic denial to meet the deadline or hold off.

At first logically, we thought maybe the TLS and SSL settings within the systems are to be blamed. But that wasn't the case, the settings for the most part was the default IE 11 settings.




















While troubleshooting, we discovered the issue only happened when logged in with a particular service account. When logged in as an admin, the issue on the same machine doesn't appear to be happening. (I think you can already see where this is going).

https://technet.microsoft.com/en-us/library/dn786418(v=ws.11).aspx#BKMK_SchannelTR_TLS11

The link above discusses how to enable/disable TLS/SSL settings on a machine via system registry. NOTE: even if you made changes in a system via the IE Properties, those changes will not show up in the registry.

So, from the article above I thought Ok, we will simply disable TLS 1.0 in the system and that will resolve the issue. To disable TLS 1.0 do the following:

1. Open registry.
2. Local Machine\SYSTEM\CurrentControlSet\Control\SecurityProvider\SCHANNEL\Protocols
3. Create a subkey Client.
4. Create the DWORD entry Enabled and set the value to 0. BTW, to disable it is 0 and to enable set it to 1.

Crossed my finger hoping this will force the system to using anything other than TLS 1.0. Nope!
It didn't work. Issue still persist with the below error screen:


So, the search continues. Thanks Google!

BTW, we were able to determine via a packet capture (thanks Wireshark) that for each web request the system would start with TLS 1.0 request first. It's suppose to be the other way around. The request always start top down, from TLS 1.2 and down.

Then I stumbled across this article below from MS:

https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1.1-and-tls-1.2-as-a-default-secure-protocols-in

Basically this article describes how you can force a system to use either TLS 1.2 or 1.1 via registry. Below are the steps to do just that:

1. Open registry
2. Local Machine\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHTTP
3. Here add the subkey DefaultSecureProtocols and enter the desired value.

If you want the option to use both TLS 1.2 and 1.1, you can just add 0x00000A00.

Within the same article, there's also the option to Download the fix and apply it to the system. However, I didn't like this particular solution.

I didn't like the solution because it is forcing a system to use a specific protocols for each request which means, I will have to have that documented and that piece of info will have to be passed on for anyone other than me in future responsible with this particular platform. Also if any changes were decided upon in future with TLS settings like this time, we will be revisiting the issue again.

So the search continues. And that's when I noticed the Note section right below the Download button within the same article.



Hmmm, interesting.

I immediately had a feeling that the particular User(Service) account that's having the issue has an entry for that subkey. I took the below steps:

1. Open registry.
2. Load the user hive.
3. Browse out to: Software\Microsoft\Windows\CurrentVersion\Internet Settings
4. And lo, behold! There it is. There's an entry for SecureProtocols.
5. I deleted the entry and voila, we are up and running like nothing ever happened.

Bottom line: instead of disabling the TLS 1.0 in the system and create a subkey DefaultSecureProtocols which would force the system to use either TLS 1.2/1.1, I simply deleted the SecureProtocols entry within the user account where the issue was.