In almost all XenApp and XenDesktop environments I build, I solve user virtualization with AppSense Personalization and local profiles.
AppSense Personalization allows you to virtualize and personalize the user desktop without the need of a roaming profile, and by using AppSense Personalization together with local profiles you get some big advantages over roaming and mandatory profiles:
- Fast logon and logoff times (no profile has to be loaded over the network)
- No profile corruption
- No manual mandatory profile creation
- No “hung” profiles
The only drawback of using local profiles is that they are not automatically deleted from the server or desktop when the user logs off, but this is where spoofing the state of the local profile with PowerShell comes in.
If you would make your users member of the local guest group, the problem would be solved: Windows automatically deletes local profiles of guest users at logoff.
Unfortunately it’s not that simple because being a guest user on a system has some limitations, for example not being able to use and manage certificates.
The trick is to make windows believe you are a guest user only at logoff so the local profile will be deleted automatically.
You can achieve this by spoofing the local profile state with a PowerShell script:
# Spoof Profile State Script # Created by Michel Stevelmans - http://www.michelstevelmans.com # Get SID of the current user $SID = ([Security.Principal.WindowsIdentity]::GetCurrent()).User.Value # Set the state of the local profile to guest Set-ItemProperty -path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\$SID\" -name State -value 128
Because the script requires the user to change the value of a local machine key, you must give the user permissions on HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList.
Ofcourse you can change these permissions locally or in your vDisk, but I prefer to use group policy:

To run the script when a user logs off, use a logoff execute action in AppSense Environment Manager:
Notice the following parameter for powershell.exe: -ExecutionPolicy Bypass.
By setting this parameter you completely bypass the PowerShell execution policy, which eliminates the need for changing the default restricted execution policy (with the Set-ExecutionPolicy command).
Hopefully soon AppSense will let us use PowerShell as a custom action like they already do with VBScript and JScript (If you are reading AppSense: this is a feature request!), but for now stick with the execute action.
When a user logs off now, all settings are saved in AppSense Personalization and the local profile will be deleted from the server or desktop… Great!
Update 20 November 2011:
AppSense released Environment Manager 8.2 last week, which includes native PowerShell support (thanks for listening to my feature request guys
).
You don’t have to make a custom action which calls my PowerShell script anymore. Instead just copy and paste my PowerShell script into a PowerShell custom action like this:
Apparently the PowerShell custom action bypasses your system’s execution policy which means Environment Manager can run scripts without you having to lower your system’s execution policy, great!


Hi there
Interesting article here, im currently deploying Appsense within a Vmware View environment but using mandatory profiles instead.
We do still have some “remote workers” who will require laptops. I was looking at the best way to handle the prrofiles on this medium as they will be working mostly offline (sometimes with direct VPN).
Would you reccomend configuring the default profile on the Base Image before deploying it with WDS to end clients?
Hi Usman,
I personally don’t like mandatory profiles because they require configuration/administration and they can cause “you’re profile could not be loaded” errors.
I actually never “configure” the local profile at all.
When a user logs on, he receives a copy of the default user profile automatically when you don’t configure any profile. I then use AppSense Environment Manager to build the user’s start menu, import current user registry settings etc.
So the same would go for a WDS client image. Just make sure the clients can contact the AppSense Management Server every once in a while to receive your configurations.
Hi Michel,
Thanks for the info above. I just therefore need to make sure that when configuring my base WDS image that i remove any Start Menu / Program Items that i dont want to show up when the user logs in for the first time. Then use EM to add the Start Menu Items as required.
So far mandatory profiles in the VDI Environmnet ar working fine, albiet a few teething issues with Crypto API and Lync which ive now resolved by profile spoofing. This is fine for 90% of our users who use regular office based apps and dont require much management.
But i think Local profiles may be a better way to go for the Fat Clients and with your script is ushould be able to keep things nice and tidy.
Good to see there is also other people out there with similar issues apart from me
Many thanks for taking the time to write your blog and findings as it has been a great help
Hi,
Just a heads up that with the new version of EM (8.2.125.0 released 15th November 2011) you can now use PowerShell as a native custom action or condition.
I will be uploading an EM Snippet on my blog soon that will take into account whether PowerShell is installed. If it isn’t then it will fallback to other methods to retrieve the users SID. The snippet also makes use of the newly introduced If…Then…Else conditions.
Hi,
Ive tried your technique here on EM 8.2 but it does not appear to work.
I have given users FULL CONTROL to the Profile list and key and run the script as a logoff action.
But the C:\users\xxxx is still there and a entry for the user in profile list key.
Any ideas ?
I also wanted to ask what you run the PS script as, the user, System or select a Admin user ?
thanks
David
Hi David,
The script should run as the user. I you would run it as any other user, it would check for the SID of that particular user.
A couple of things you could check why the script isn’t functioning:
- Does the script change the state value to 128 for your user if you execute it manually ?
- Does the script work if you use the “pre 8.2″ method which I describe in the blogpost ?
- Does AppSense actually run the script/custom action at logoff ? (you could let the PS script create a temporary file in the user home directory, so you know for sure the script has run)
- Does windows delete the local profile when you manually change the state to 128 of a user in the registry ?
Hi Dave,
Long time no speak/see. Have you tried using the snippet from my blog?
As per Michel’s reply, which bit doesn’t appear to work? The snippet I have has been tested on WinXP, Win7 and Server 200 R2 with XenApp 6 installed.
I’m on site on Monday and in and out of meetings on Tuesday, but feel free to mail over the config and I’ll take a look when I can.
Sorry boys it was the obvious in the end. Execution Policy was not set correctly.
Hey Mike, I am beginning to deploy xenapp 6.5 to replace our existing 4.5 infrastructure and recently configured citrix user profile manager along side folder redirection to handle the user profiles. Our environment does not use roaming profiles. Is this a good configuration to use for profile management? Would you recommend appsense? The profile virturalization seems to have its perks…. Thanks for listening
Tommy
Hi Tommy,
In almost all cases I use AppSense Personalization, so I can’t really comment on the Citrix Profile Management solution.
AppSense Personalization is an entirely different product though, which comes as part of AppSense Environment Manager and the AppSense Management suite with which you can do so much more then just profile management. Try it out for yourself and see if you like it!
Hi,
Good work, I’ve also been using local/temp profiles (a script wrote by James S), unless I have to I prefer to avoid mandatory now.
Have you had much trouble with the new if/else statement in 8.2? I found only the first item in ‘else’ runs, after speaking to appsense they told me it is a bug, so for now step each item down from the first. Additionally to this, I’ve found that odd things can happen in the main IF, like certain elements from other underlying conditions -> actions (or just part of) execute….
I’ve got to raise with appsense so will post if I find out any more.
Hi Phil,
No, haven’t seen any issues with the if/else state.
Submitting your issue to AppSense should get it solved. Let me know if it turns out to be a bug!
I tried doing this manually, setting the key to 128, and that doesn’t delete the profile at logoff on a Server 2008 R2 machine with XA 6.5 installed. Any ideas?
Hi Joey,
Maybe an obvious question, but you are sure you are changing the State value in the SID of your user ?
Also, make sure the value is hexadecimal and that your R2 server is member of a domain.
If you are still unsure about the correct registry key, just create a new user with local guest privileges and compare the registry key to that user.
128 did not work for me either, so I created a local guest user and logged in as that user and looked at the state value. It was set to 0×00000284 (644)
So, I logged in as a domain user, changed the value to 0×00000284 (644) and logged out and the profile was deleted.
Just an addition to this article if you do this in a VMware environment with Win 7 thick clients you need to modify the registry so that it will be able to delete the folder otherwise VMware tools prevents the folder from being deleted.
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1317
Hello Michel, Thanks for sharing your experiance here. We have an issue here where I work. The issue is that we are standing up an XenApp Server 2008 r2 farm. That farm is setup with Mandatory Profiles via gpo. Our Help desk is located in Canada and we allow them to used remote assistance to assist customers. Long Story short Remote Assistance wont work unless we set the profile to roaming. We also have AppSense. Do you think using your spoof profile powershell script might help? If we use it I am not sure how to set the “State” value so that windows thinks the logged in user is Roaming? Any advise you can provide would be extremely appreciated! Thanks……….
Hi Steve,
I didn’t know mandatory profile conflict with remote assistance, thanks for sharing that.
Mandatory profiles also don’t allow a user to have a certificate store and there are a few other drawbacks, that’s why I switched to local profiles a few years back.
I’d strongly recommend looking into that.
But on spoofing your current mandatory profile…
If you have AppSense, do you also use AppSense Personalization ?
If so, on the properties tab of your Personalization group there is a setting called “Manage Certificates”.
This setting should spoof your mandatory profile into a roaming profile (because of the mandatory profiles and certificates issue I mentioned earlier), which allows AppSense Personalization to “personalize” the users’ certificates into the database.
If you would like to use my script to spoof the mandatory into a roaming, just create a user with a roaming profile and check the “state” value of that users’ SID in the registry on the server to which he is logged in and put that value into my script.
I use the above succesfully, did any of you tried the SpoofProfileforWholeSession key that Appsense claims to have created for this…. does not do it for me, maybe regarding the types of certificates I’m importing. Let me know and thanx !
Registry Key: HKLM\Software\AppSense\Environment Manager HKCU\Software\AppSense\Environment Manager
Value Name: SpoofProfileForWholeSession
Value Type: REG_DWORD
Value Data: 1 to enable / 0 to disable (Default)
Hi,
Whats the deal of wanting your local profile get wiped when logging off?
First off all, logon gets slowed down due the “First run” (Active Setup) process.
And what if you are in a scenario where users are able to install software by themselves?
U cant whitelist that software (because u dont know its there) and no personal settings are held because youre whiping your local profile at logoff.
Im very curious whats your opinion in this.
Greets,
Marc
Hi Marc,
Well, I could go on for hours on this subject because I have done a lot of testing with this, but I’ll stick to your questions:
I’ve been disabling active setup for years now (with an action in AppSense Environment manager), so I don’t drag my users through this proces in not a single XenApp or XenDesktop implementation I do.
I’m not loading a mandatory or roaming profile, so logon times are very fast.
When the user is gone, I want the local profile to be gone as well… This is AppSense Personalization: I’m not using the profile to persist settings so why leave the mess on the server when the user is gone ?
About users installing software…
We are talking XenApp here, so I don’t think you want to let your users install software.
XenDesktop has a use-case for users that need to install software and indeed: Without proper whitelisting, the application settings do not persist.
In fact, I don’t even just whitelist the executable: I whitelist the application (or application group) and then apply proper folder and registry inclusions/exclusions so only what is really necessary get’s personalized.
Hi Michel, I’ve really found your blog useful, thanks!
I’ve encountered the slooooowness of the active setup kicking the bum of any new profile that logs in. I have one user who I (using your powershell snippet, thanks!) delete the local profile for on logoff.
I was wondering if you could link me to information/script to disable the active setup action that you mention please?
Thanks again
Gary
Hi Gary,
You can disable active setup by clearing the value for “StubPath” for each component under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Active Setup\Installed Components\ and HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\
When all stubpath values are cleared, active setup will not bother your users anymore.
Thanks very much! Really appreciated
keep up the awesome work!
Hi Michel, i suc6 full implement your solution a while back. Today i worked on a case where personal certificates could not be stored in the profile for some users. Strange, first thing i checked whas the type of profile the user got and it showed me it was Mandatory!?. After investigate the issue i found that the user got a local profile (normal ntuser.dat) but the state of the profile was set to mandatory. Strange problem, the group policy settings to force “Only allow local profiles” is working and in place.
When i changed the key [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\SID] “State” from 205 to 204 the problem was solved instantly. I spend a while finding out how and why Windows sets the “state” differently but i clould not find much information about this. Yes Microsoft profides al list with “State” values but not how the values are caclulated and set.
The values i found in my envoirement (HEX /Dec);
Mandatory ;
10205 / 66053
205 / 517
Local ;
10204 / 66052
304 / 772 (domain Administrator)
204 / 516
100 / 256
Because i did not had more time to investigate i decided to used the same Powershell script to set the “State” value but now upon login.
Problem is solved but it doe-sent feel good. So if you, or some of your readers, can explain how the state value is set i am very interested.
[...] Startup: Spoof Profile State – Building on Michel Stevelmans’ blog, this is a PowerShell script that will modify the security permissions on the ProfileList key to [...]
Hi Michel Stevelmans
Its very good article on local profile. I have few users whose NTUSER.dat files are to large.
would you have any thoughts. much appreciated thanks
Cheers
Micky