Migrating Ivanti/AppSense profiles to FSLogix Profile Containers

Migrating DesktopNow to FSLogix has always been fiddly. Let’s see how we can do it!

Ivanti User Workspace Manager (or AppSense DesktopNow) has a product called Environment Manager Personalization Server that is used for storing users’ profile information in an SQL database. Whilst a very fine product (I cut my blogging teeth writing about AppSense, so still have a great deal of experience with it and fondness for it), there are a lot of people moving away from it towards the like of FSLogix Profile Containers – mainly purely from a cost perspective. I still think DesktopNow has its place – for fine-grained control of the user environment, you can’t go far wrong – but as I have had to perform migrations for a couple of customers recently, I thought I would write up the process I used to do it.

Introduction

Let’s just start by saying that the migration process isn’t particularly straightforward. If I was someone like Jim Moyle (or one of the many other God-level scripters out there in the EUC community), I would just write a script to pull the information straight out of the SQL database and build a new profile. But unfortunately for you, I’m not. So the process I am using involves a bit more fudging than you may like. However, I have used this in the wild with success on a few occasions now, so I think this should work for you, if you can follow the same process (and you’re always welcome to drop me an email and get me to do it for you, if you have any problems).

Firstly, we need a three-tiered setup to accommodate this. We need our existing Ivanti UWM-managed infrastructure, we need our new FSLogix-managed infrastructure, and we also need an intermediate area which has both Ivanti and FSLogix installed to perform the migration. The reason for this is because most people use Ivanti Personalization Server combined with mandatory profiles, and we can’t migrate data out of mandatory profiles (because they’re utterly non-persistent). If you’re using Ivanti with local profiles, you may be able to skip the need for the intermediate area, but generally in RDSH or VDI environments local profiles are uncommon (unless you’re doing pooled non-persistent).

Also, we have performed the testing and demoing of this on Citrix Virtual Apps, but the principles should work equally well for other setups – whether these be VMware, Parallels, Windows Virtual Desktop, physical machines, cloud-hosted devices, etc.

We are going to use the following acronyms extensively:-

PMO – Present Method of Operation, referring to the existing solution with Ivanti/AppSense being used for profiles

IMO – Intermediate Method of Operation, referring to the intermediate area that users will need to access to trigger the migration

FMO – Future Method of Operation, referring to the new image with FSLogix Profile Containers being used for profiles

Pre-requisites

Ivanti/AppSense version

Unfortunately, more bad news here. This process relies on the ability to move data from one Personalization Group to another within Ivanti/AppSense. If you’re on version 10.x or higher, than all is good – Personalization data is now shared between Personalization Groups (see this article for more information about this – logon required). If you are still on version 8.x – this is a major stumbling block. When the user is moved from the PMO to the IMO group, you will need to manually migrate the Personalization data from the PMO Personalization Group into the IMO Personalization Group. I am reliably informed that Ivanti support may be able to provide a script that can help with this, so if you can get hold of it, this may help you out a bit here. Otherwise – you have to copy the data manually across using Personalization Analysis, and personally, I’d rather just start the users with brand new profiles then spend the time to do that. Update – I’ve had a good long think about version 8, and I now think you could maybe do this with a “big bang” approach instead…see the “Version 8 Considerations” section near the end.

However, if you are on version 10.x – or able to get to version 10.x – then by all means, carry on!

Active Directory Groups

I created three AD groups to go alongside my three slightly different images – PMO_Group, IMO_Group, and FMO_Group.

Citrix Virtual Apps config

I also created three different delivery groups and desktops within Citrix Studio to align with these groups, each of these desktops served by a slightly different image.

Images

The main differences between the images are summarized below:-

PMO – this is the image used currently and has the Ivanti UWM standard agents and configurations installed

IMO – this image has the Ivanti UWM standard agents and configurations and is the same image, with a few additions

  • FSLogix Apps should be installed, but it should NOT be configured. The GPOs that control FSLogix are NOT applied to these servers (so there will be no value of Enabled in the HKLM\Software\FSLogix\Profiles key).
  • PowerShell Constrained Mode should NOT be turned on. The commands used to migrate the user profile require Full Language Mode. If you have enabled Constrained Language Mode (I recorded a video on it very recently!), then use a filter on the GPO that enables it to stop the policy from applying to the IMO server or servers.
  • The Group Policy Object for “Only allow local profiles” needs to be Enabled, which sits in Computer Config | Admin Templates | System | User Profiles. Ensure that this is turned on, because otherwise the mandatory profile will be purged from the machine and you will be unable to perform the migration.
  • The Ivanti/AppSense configuration applied to this machine should write a local folder called c:\UsersToConvert\%USERNAME% every time a user from the IMO_Group logs on. This will be used as the trigger to migrate their profile after they have logged out. This can be added to the PMO configuration and simply rely on a conditional check for the IMO_Group membership (as below)
  • You should also set the GPO for “Delete user profiles older than a specified number of days on system restart” on this server or group of servers, and set the value to 1. Dependent on how many users you are migrating and how your machines are deployed, you may want to restrict the number of local profiles being saved to the machine. Adding this GPO (which also sits in Computer Config | Admin Templates | System | User Profiles) will keep the number of stored profiles down. You could also delete them manually if required.
  • Finally, you need to set up a Scheduled Task on the IMO image which will trigger a migration script to run when users log off (event id 4647). This can be baked into the image or deployed via GPO or even PowerShell, it is up to you how you do it. The contents of the script and the setup of the Scheduled Task are detailed more later in the article.

FMO – this is the image to be used going forwards, and has the same applications but NO Ivanti agents or configurations, and has the FSLogix Apps agent installed and FULLY configured (enabled with all standard settings and pointing to the file share where the FSLogix profiles are stored)

Personalization Server configuration

Also, you need to make sure you have two Personalization Groups set up within the Ivanti Personalization Server console, with a few slight differences.

They should have exactly the same Application Groups and Windows Settings Groups applied to each.

However the PMO Personalization Group should have its membership rules applying to the PMO_Group from AD

And the IMO Personalization Group should have the same applied to the IMO_Group from AD

Also, the IMO Personalization Group needs to have Profile Migration turned on as below.

Finally, you MUST make sure that the IMO Personalization Group sits above the PMO Personalization Group in the list so that users do not end up in the wrong one.

The process

Hopefully you might be starting to get a feel for how this is supposed to work ๐Ÿ™‚ The diagram below may possibly make the process a bit clearer.

The idea is that users are manually moved into the IMO_Group and removed from the PMO_Group when they are ready for migration. You can do this manually or in an automated fashion and move as few or as many as you wish.

Once they are in the IMO_Group when logging on to Storefront or ADC they are now offered a different desktop, the IMO Desktop. This looks to all intents and purposes the same but as they log on it adds their username into a folder for migration, and then when they log off, a Scheduled Task is triggered that launches a PowerShell script to perform the migration. After migrating, the same script clears their username from the folder, removes their mandatory profile entries, removes them from the IMO_Group and adds them to the FMO_Group.

Once this is done, next time they access Storefront/ADC or refresh it they are now logged on to the FMO Desktop, and this uses FSLogix only with the migrated VHD and should bring across all of their settings.

The migration script

Firstly, you will need to adjust the script slightly, mainly for your FSLogix profile share, your AD group names, whether you want to create VHD or VHDX files, and the parameters for the frx.exe command that will do the migration. The parameters for frx.exe with the copy-profile switch are documented here – you may want to adjust them around such things as maximum VHD size, dynamic assignment, etc.

Secondly, you may notice some severe fudging here (the source for this script is Ryan Gallier’s port of David Ott’s script which I found on CitrixIRC). I had to put a 60-second delay in because the profiles sometimes take a long time to unload (UPM admins will be very familiar with this sort of problem). Also, it isn’t a mistake – yes, I run the frx.exe command twice. Sometimes, halfway through creating the migrated disk, the VHD(x) simply disappears. I have no idea what causes it – but running it again seems to work OK. I said this was a fudge ๐Ÿ™‚

I normally just save this script on the network somewhere and push it down to the IMO server(s) using Group Policy Preferences – again, up to you how to do this. Obviously wherever you put it, you will need to reference it in the Scheduled Task (and I find that storing Scheduled Task action scripts locally always works much better than those on the network). Here’s the PowerShell you will need to edit for your own environment:-

# Migrate local profile into VHD file share at logoff

# Set destination file path here
$destinationprofilepath = "\\UKSLDC003\FileStore\Profiles"

# Set PATH variable
$ENV:PATH=โ€$ENV:PATH;C:\Program Files\fslogix\apps\โ€

# Pull names of users scheduled for migration from c:\UsersToConvert folder. This folder has the usernames added as the users log off from the IMO server
$usernames = gci c:\UsersToConvert | ?{$_.psiscontainer -eq $true} | select -Expand fullname | sort

# Feed user ids from usernames variable into loop

foreach ($user in $usernames) { 
$userid = ($user | split-path -leaf)
$sid = (New-Object System.Security.Principal.NTAccount($userid)).translate([System.Security.Principal.SecurityIdentifier]).Value

$targetpath = join-path $destinationprofilepath ($userid+"_"+$sid)

# If targetpath does not exist, create it and set permissions
if (!(test-path $targetpath)) {New-Item -Path $targetpath -ItemType directory | Out-Null}
& icacls $targetpath /setowner "$env:USERDOMAIN\$userid" /T /C
& icacls $targetpath /grant $env:USERDOMAIN\$userid`:`(OI`)`(CI`)F /T

# Set full VHD path including filename of VHD (use VHD or VHDX file extension here as appropriate to your environment)
$vhdfullpath = Join-Path $targetpath ("Profile_"+$userid+".vhdx")

# Pause for 60 seconds to allow profile to unload before starting to migrate it
start-sleep 60

# Perform profile migration
frx.exe copy-profile -filename $vhdfullpath -sid $sid

# This is not a mistake - we need to run the migration command twice, because sometimes (not sure why) it starts to create the disk and then the disk disappears completely. Have been unable to trap the error, so running twice to make sure
frx.exe copy-profile -filename $vhdfullpath -sid $sid

# Remove from IMO group - EDIT the group name as required here to fit your environment
net group IMO_Group $userid /delete /domain

# Add user to FMO group - EDIT the group name as required here to fit your environment
net group FMO_Group $userid /add /domain

# Remove mandatory profile paths from user object (this section can be removed if not using mandatory profiles)
# The tsprof command will only work if being run from a system which has RDSH installed, but if the target systems are not RDSH, then the RDSH Profile path will not be used anyway
net user $userid /ProfilePath: /domain
tsprof /UPDATE /DOMAIN:$ENV:USERDOMAIN /PROFILE: $userid

# Delete folder that triggers conversion (otherwise it will be constantly trying to re-export the local profile)
remove-item c:\UsersToConvert\$userid -Force
}

The Scheduled Task

Once you’ve gotten the script onto your IMO servers, you now need to deploy a Scheduled Task to invoke it at logoff. I did it manually like this.

Create a new Basic Task in the Task Scheduler

Set the trigger to “When a specific event is logged”

Set the event properties as below (note – this was done on Windows Server 2019, other operating systems may have different properties here)

Select “Start a program” as the Action

Select powershell.exe as the program, and add “-ExecutionPolicy Bypass -File c:\Path\toyourscript.ps1” as the arguments

Select “Open Advanced properties for this task when I click Finish”, then click Finish

Make sure the task is set to run with an administrative account, that it runs whether the user is logged on or not, it runs with highest privileges, and is configured for your OS version. Also, make sure that the account it is running under, as well as having admin privileges, is able to write to the file share where it is going to create the profiles, and can also add and remove users from AD groups and change user object properties (as it does these tasks as part of the cleanup).

Enter the password when prompted and the task should now be ready to run the script when users log off. It will actually run for every user, but unless there are folders in the c:\UsersToConvert folder nothing will be done and it will simply exit.

Version 8 considerations

I know I said doing this from version 8 was ridiculously hard, however, having had time to think, you could do this if you were willing to accept a “big bang” approach. Essentially, because version 8.x doesn’t share Personalization data across the Personalization Groups, your PMO systems would all have to be turned into IMO systems and all of your users migrated in one big bunch. So you’d have to set a date, turn on the profile migration on your personalization group, get FSLogix Apps installed but not configured on your existing servers, set the GPOs for local profiles, do all the AD and Citrix config, update the Ivanti configuration and deploy it, and then set about the migration en masse. This should work OK, as long as you are aware you have little control over the volume of users being migrated. The biggest issue I can see is impact on storage and performance as the user migrations are performed and the potential of jamming up your servers with lots of copies of local profiles as they are left behind. You can easily get around the local profiles issue by adding a delprof2.exe command to the end of the migration script, but the storage impact would have to be assessed. However, if you wanted to migrate version 8 profiles in situ (as long as it is a new enough version that it has the profile migration setting!), this should work OK. You could even use this two-stage big bang approach on 10.x versions if you were brave, but just be aware you are giving up an aspect of control over this.

Time to test!

This is all you need to do (I actually said that with a straight face). Yes, there’s a lot of prep, but once you get it done and working for one user, it should be seamless for the rest.

Given that I seem to have a penchant for video tutorials these days, here’s me trying to run through that for everyone.

Summary

So hopefully this should allow you to perform the migration from Ivanti to FSLogix on a profile level without too much trouble. As I said, thanks to Ryan Gallier and David Ott for their initial work on the migration script – community always rocks for sharing!

If you find this a bit of trouble, I’m always willing to answer emails and comments about it – if you’re really stuck, you can always ask me to come down and visit, but I will demand beer money as recompense ๐Ÿ™‚

Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *