Microsoft FSLogix Profile Container

Nach dem Aufkauf von FSLogix hier ein kleines How-To zum Einrichten der FSLogix Profile Container zur Nutzung in einer Microsoft Remotedesktop-Sammlung oder auch in einem Citrix Virtual Apps and Desktop Deployment.

Welche Betriebssysteme werden supported?

  • Desktop: ab Windows 7 (32- / 64-Bit)
  • Server: ab 2008 R2 (32- / 64-Bit)

Wer darf die Profile Container bzw. die FSLogix Suite nutzen?

  • Microsoft 365 E3/E5
  • Microsoft 365 A3/A5/ Student Use Benefits
  • Microsoft 365 F1
  • Microsoft 365 Business
  • Windows 10 Enterprise E3/E5
  • Windows 10 Education A3/A5
  • Windows 10 VDA per user
  • Remote Desktop Services (RDS) Client Access License (CAL)*
  • Remote Desktop Services (RDS) Subscriber Access License (SAL)

* Die RDS (User / Device) CAL dürfte für die On-Prem-Freunde von Interesse sein, um die Container in einer lokal gehosteten (RDSH / CVAD / Horizon) Umgebung zu nutzen.

Wo finde ich die FSLogix Apps? -> https://aka.ms/fslogix_download

Hier noch ein Hinweis: Ich versuche hier so viel wie möglich bzw. das meiste zu automatisieren / zu scripten. Das liegt zum Einen daran, dass ich diesen Task vermutlich des Öfteren wiederholen muss und zum Anderen plane ich ein „kleines“ Deployment-Script. 😉 Für die Freunde der GUI wäre evtl. das folgende Hersteller Video ein Ansatz: http://blog.fslogix.com/deployment-guide-video-for-fslogix-profile-containers-and-office-365-containers

An dieser Stelle fange ich damit an, eine entsprechende Freigabe zur Ablage der späteren Profile Container zu erstellen. Wenn möglich würde ich an dieser Stelle auf das ReFS Dateisystem setzen! Das kann man sich in der GUI zusammenklicken („Benutzer (S-1-5-32-545)“; Nur diesen Ordner; Ändern / „Ersteller Besitzer (S-1-3-0)“; Unterordner und Dateien; Ändern / Optional: „Administratoren (S-1-5-32-544)“; Dieser Ordner, Unterordner und Dateien; Vollzugriff) oder auch flott per PowerShell erledigen:

$FSLogixStore = "D:\FSLogixStore"
$FSLogixShare = "FSLogixStore"
$FslogixHost = "jans-dc01"
$FSLogixSetup = "\\" + $FslogixHost + "\Install\FSLogix_Apps_2.9.7117.27413"
$FSLogixO365Group = "grp_O365_Container"
$FSLogixProfileGroup = "grp_Profile_Container"
$FSLogixPolicy = "C_FSLogix_Config"

$IcaclsPath = "C:\Windows\System32\icacls.exe"

Enable-NetFirewallRule -Name FPS-SMB-In-TCP, FPS-SMB-Out-TCP

if(!(Test-Path $FSLogixStore)){
    New-Item -Path $FSLogixStore -ItemType Directory | Out-Null
} else{
    Write-Host "ACHTUNG: Berechtigungen für ""$FSLogixStore"" wird zurückgesetzt!" -ForegroundColor Red
}
Start-Process -FilePath $IcaclsPath -ArgumentList $($FSLogixStore + " /inheritance:d /T /C /Q") -Wait
Start-Process -FilePath $IcaclsPath -ArgumentList $($FSLogixStore + " /remove:g *S-1-3-0 /remove:g *S-1-5-18 /remove:g *S-1-5-32-545 /grant:r *S-1-5-32-544:(OI)(CI)(F) /grant:r *S-1-5-32-545:(M) /grant:r *S-1-3-0:(OI)(CI)(IO)(M) /T /C /Q") -Wait
if(!(Get-SmbShare | ? Name -eq $FSLogixShare)){
    New-SmbShare -Name $FSLogixShare -Path $FSLogixStore -FullAccess *S-1-5-11 -CachingMode None -Description "FSLogix Profildaten" | Out-Null
} else{
    Write-Host "ACHTUNG: Der Freigabe ""$FSLogixShare"" wird ""Authentifizerte Benutzer - Vollzugriff"" hinzugefügt!" -ForegroundColor Red
    Grant-SmbShareAccess -Name $FSLogixShare -AccountName *S-1-5-11 -AccessRight Full -Confirm:$false
}

Als weitere Vorbereitung ist es hilfreich entsprechende Gruppen und ein Gruppenrichtlinien-Objekt zur Nutzung der Profile Container vorzubereiten. Ebenfalls werden das ADMX / ADML File in den PolicyDefintions Ordner kopiert. Anbei ein PowerShell Script zum Erstellen der, in meinem Fall zwei, benötigten Gruppen („grp_O365_Container“ / „grp_Profile_Container“) sowie dem GPO („C_FSLogix_Config“) samt Konfiguration:

$FSLogixStore = "D:\FSLogixStore"
$FSLogixShare = "FSLogixStore"
$FslogixHost = "jans-dc01"
$FSLogixSetup = "\\" + $FslogixHost + "\Install\FSLogix_Apps_2.9.7117.27413"
$FSLogixO365Group = "grp_O365_Container"
$FSLogixProfileGroup = "grp_Profile_Container"
$FSLogixPolicy = "C_FSLogix_Config"

if(!(Test-Path \\$env:UserDNSDomain\sysvol\$env:UserDNSDomain\Policies\)){
    Copy-Item C:\Windows\PolicyDefinitions \\$env:UserDNSDomain\sysvol\$env:UserDNSDomain\Policies\ -Recurse
}
Copy-Item $($FSLogixSetup + "\fslogix.adml") \\$env:UserDNSDomain\sysvol\$env:UserDNSDomain\Policies\PolicyDefinitions\en-US\
Copy-Item $($FSLogixSetup + "\fslogix.adml") \\$env:UserDNSDomain\sysvol\$env:UserDNSDomain\Policies\PolicyDefinitions\de-DE\
Copy-Item $($FSLogixSetup + "\fslogix.admx") \\$env:UserDNSDomain\sysvol\$env:UserDNSDomain\Policies\PolicyDefinitions\

$GroupOU = Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName | Out-GridView -Title "In welcher OU sollen die beiden Gruppen angelegt werden?" -PassThru
$GroupOU = Get-ADOrganizationalUnit $GroupOU.DistinguishedName
$RDSHOU = Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName | Out-GridView -Title "Wo befinden sich die Session-Hosts / Desktops?" -PassThru
$RDSHOU = Get-ADOrganizationalUnit $RDSHOU.DistinguishedName

New-ADGroup -Name $FSLogixO365Group -DisplayName $FSLogixO365Group -Description "FSLogix Office 365 Container User" -Path $GroupOU.DistinguishedName -GroupCategory Security -GroupScope DomainLocal
New-ADGroup -Name $FSLogixProfileGroup -DisplayName $FSLogixProfileroup -Description "FSLogix Profile Container User" -Path $GroupOU.DistinguishedName -GroupCategory Security -GroupScope DomainLocal

$GPOObject = New-GPO $FSLogixPolicy | New-GPLink -Target $RDSHOU.DistinguishedName -LinkEnabled Yes

# Profile Container
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "Enabled" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "IsDynamic" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "SizeInMBs" -Value 5000 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "RoamSearch" -Value 2 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "VHDLocations" -Value $("\\" + $FslogixHost + "\" + $FSLogixShare) -Type String | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\FSLogix\Profiles" -ValueName "VolumeType" -Value "VHDX" -Type String | Out-Null

# Office Container
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "Enabled" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IsDynamic" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "SizeInMBs" -Value 5000 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeSkype" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeTeams" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOneNote" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOutlook" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOfficeActivation" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOneDrive" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeSharepoint" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOfficeFileCache" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOutlookPersonalization" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "IncludeOneNote_UWP" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "OutlookCachedMode" -Value 1 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "RoamSearch" -Value 2 -Type DWord | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "VHDLocations" -Value $("\\" + $FslogixHost + "\" + $FSLogixShare) -Type String | Out-Null
Set-GPRegistryValue -Name $FSLogixPolicy -Key "HKLM\Software\Policies\FSLogix\ODFC" -ValueName "VolumeType" -Value "VHDX" -Type String | Out-Null

# Group Policy Preferences Gruppen
New-Item $("\\" + $env:USERDNSDOMAIN + "\SYSVOL\" + $env:USERDNSDOMAIN + "\Policies\{" + $GPOObject.GpoId + "}\Machine\Preferences\Groups\Groups.xml") -ItemType File -Force | Out-Null
"<?xml version=""1.0"" encoding=""utf-8""?>" | Out-File $("\\" + $env:USERDNSDOMAIN + "\SYSVOL\" + $env:USERDNSDOMAIN + "\Policies\{" + $GPOObject.GpoId + "}\Machine\Preferences\Groups\Groups.xml") -Encoding utf8
"<Groups clsid=""{3125E937-EB16-4b4c-9934-544FC6D24D26}""><Group clsid=""{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}"" name=""FSLogix ODFC Include List"" image=""2"" changed=""$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")"" uid=""{7D296515-BA25-452D-85A5-B1DB2580B2D5}""><Properties action=""U"" newName="""" description=""Members of this group are on the include list for Outlook Data Folder Containers"" deleteAllUsers=""1"" deleteAllGroups=""1"" removeAccounts=""0"" groupSid="""" groupName=""FSLogix ODFC Include List""><Members><Member name=""%DomainName%\$FSLogixO365Group"" action=""ADD"" sid=""""/></Members></Properties></Group>" | Out-File $("\\" + $env:USERDNSDOMAIN + "\SYSVOL\" + $env:USERDNSDOMAIN + "\Policies\{" + $GPOObject.GpoId + "}\Machine\Preferences\Groups\Groups.xml") -Encoding utf8 -Append
"	<Group clsid=""{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}"" name=""FSLogix Profile Include List"" image=""2"" changed=""$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")"" uid=""{6C2B4A05-A5F4-43E3-8F12-1C80538C2C6A}""><Properties action=""U"" newName="""" description=""Members of this group are on the include list for dynamic profiles"" deleteAllUsers=""1"" deleteAllGroups=""1"" removeAccounts=""0"" groupSid="""" groupName=""FSLogix Profile Include List""><Members><Member name=""%DomainName%\$FSLogixProfileGroup"" action=""ADD"" sid=""""/></Members></Properties></Group>" | Out-File $("\\" + $env:USERDNSDOMAIN + "\SYSVOL\" + $env:USERDNSDOMAIN + "\Policies\{" + $GPOObject.GpoId + "}\Machine\Preferences\Groups\Groups.xml") -Encoding utf8 -Append
"</Groups>" | Out-File $("\\" + $env:USERDNSDOMAIN + "\SYSVOL\" + $env:USERDNSDOMAIN + "\Policies\{" + $GPOObject.GpoId + "}\Machine\Preferences\Groups\Groups.xml") -Encoding utf8 -Append

Kommen wir als nächstes zur Installation der FSLogix Suite auf dem / den Session-Hosts / Desktops bzw. im „Golden-Image“. Erneut bleibt die unspektakuläre Möglichkeit zum Klicken in der GUI (langweilig!) oder per PowerShell Script.

$FSLogixStore = "D:\FSLogixStore"
$FSLogixShare = "FSLogixStore"
$FslogixHost = "jans-dc01"
$FSLogixSetup = "\\" + $FslogixHost + "\Install\FSLogix_Apps_2.9.7117.27413"
$FSLogixO365Group = "grp_O365_Container"
$FSLogixProfileGroup = "grp_Profile_Container"
$FSLogixPolicy = "C_FSLogix_Config"

if(Test-Path $($FSLogixSetup + "\x64\Release\FSLogixAppsSetup.exe")){
    Start-Process -FilePath $($FSLogixSetup + "\x64\Release\FSLogixAppsSetup.exe") -ArgumentList $("/install /quiet /norestart /log " + $FSLogixSetup + "\FSLogix_Log.txt") -Wait
}

Nach einem ggfs. benötigten Reboot finden sich auf dem Host die folgenden Gruppen zur späteren Steuerung der Container wieder:

  • FSLogix ODFC Exclude List
  • FSLogix ODFC Include List (Standardmäßig ist hier „Jeder“ / „Everyone“ bzw. „S-1-1-0“ Mitglied)
  • FSLogix Profile Exclude List
  • FSLogix Profile Include List (Standardmäßig ist hier „Jeder“ / „Everyone“ bzw. „S-1-1-0“ Mitglied)

Sollte die Richtlinie wie oben in meinem Beispiel verwendet worden sein, befindet sich „\Jeder“ nicht mehr in den beiden Gruppen, sondern die, ebenfalls oben erstellten, Gruppen darin. Wenn bis hierher nichts vollkommen daneben gegangen ist, sollte eine Testanmeldung möglich sein. Bei der Anmeldung sollten dann auch die entsprechenden Container erstellt werden – Yay 🙂 !

FSLogix Suite für Jedermann – Update

Da entdeckt man in der Montagmorgen-Lektüre doch glatt, dass nach dem FSLogix Aufkauf von Microsoft absofort jeder (mit RDS-CAL / RDS-SAL / VDA / Windows Virtual Desktop) die komplette Suite nutzen kann.

Update bzw. aktuelles zur Nutzung der FSLogix Suite vom 01.07.2019: https://blog.fslogix.com/fslogix-customer-faq / https://www.microsoft.com/en-us/microsoft-365/blog/2019/07/01/improving-office-app-experience-virtual-environments/

Update II -> Hier ein kleines How-To zur möglichst automatisierten Einrichtung der Profil Container bzw. der Office 365 Container: https://jans.cloud/2019/08/microsoft-fslogix-profile-container/

Hier noch der Link zur Microsoft Dokumentation: https://docs.microsoft.com/en-us/fslogix/

Scott Manchester, Group Manager RDS Microsoft, dazu auf Twitter:

Who will be entitled to #FSLogix? Anyone with an RDS-CAL, RDS-SAL, VDA, or WVD entitlement. Use the full suite for on-prem or in the cloud. #WVD

https://twitter.com/RDS4U/status/1108719908647563270

Die FSLogix Full Suite beinhaltet unter Anderem:

Hier schonmal das Microsoft Doc zur Einrichtung unter der Windows Virtual Desktop Preview: https://docs.microsoft.com/en-us/azure/virtual-desktop/create-host-pools-user-profile

Zu erst am 25.03.2019 veröffentlicht / Update am 02.07.2019 / Update II am 26.08.2019