OneDrive with simulated Single Sign-On
Recently we have received numerous requests to implement OneDrive in multi-user environments. This is not an easy task given that Microsoft refuses to release and develop a client-supporting multi-user environment. Citrix and Microsoft give the following recommendations:
- Use OneDrive for Business through the browser.
- Use ShareFile instead of OneDrive for Business.
- Continue using OneDrive for Business but through ShareFile Desktop App or ShareFile Driver Mapper.
You can read more about this here. It is very important to understand these recommendations from Microsoft and Citrix before you continue reading because what I am about to show you is a different approach. An alternative to these recommendations is to use FSLogix with the OneDrive for Business client. You can read more about this here. This means that FSLogix will give you support upon using their software. My approach requires that Microsoft does not change how OneDrive is set up, and as we all know – Office 365 is updated very often.
If you are going to implement OneDrive in a multi-user environment and at the same time give your users a “simulated” single sign-on experience a few things need to be in place. I am referring to this as a “simulated” single sign-on, because this solution is built on top of several different techniques rather than a native single sign-on. I have specified the criteria below. You will need:
- FSLogix licenses
- OneDrive
- Programming skills (AutoIT and PowerShell)
- Extensive knowledge of Group Policy Management and Active Directory
In this blog post, I will take for granted that FSLogix is installed unto your session hosts and every user is successfully receiving a personal VHDX where OneDrive data will be stored. If you need help with this, please refer to FSLogix docs quick start. Basically what we will do is install OneDrive to each user session on login and then launch a packaged app to automatically click through the first sync process.
Let’s get this started. The first thing we must do is install OneDrive on our session hosts. The code below will install OneDrive for your user and also drop ”OneDriveSetup.exe” into ”C:\Program Files (x86)\Microsoft OneDrive”. This will come in handy later on.
change user /install
"%CTXFSROOT%\Media\Application\OneDrive\OneDriveSetup.exe" /machine
change user /execute
When we have the installation files in place you will need to create a program with AutoIT that simulates user input. You do not have to install anything on to the session hosts, but you will need to install AutoIT (AutoIT full installation) and AutoIT script editor (SciTE4AutoIt3) on your local machine. Once you have that installed, fire up the ”AutoIT Script Editor” and create a new file called ”OneDrive.au3”. Paste the code below and then compile it into an executable file (AutoIT_OneDrive.exe). We will use this file to automatically generate mouse clicks through the first sync process to get a “simulated” single sign-on experience.
;"Setup OneDrive
Local $hWnd = WinWait("Microsoft OneDrive", "Set up OneDrive", 180) ; Wait for window with title "Microsoft OneDrive" to appear, times out after 180 sec
Do
$hCtrl = ControlGetHandle($hWnd, "Sign in", "Button1") ; Get the handle to the button 'Sign In'
Sleep(100)
Until $hCtrl <> ""
;MsgBox (0, "Title", "Text0")
ControlClick ($hWnd, "", "Button1") ; Send a mouse left click to the button
; "This is your OneDrive folder"
Local $hWnd = WinWait("Microsoft OneDrive", "This is your OneDrive folder", 180) ; Wait for window with title "Microsoft OneDrive" to appear, times out after 180 sec
Do
$hCtrl = ControlGetHandle($hWnd, "This is your OneDrive folder", "Button1")
Sleep(100)
Until $hCtrl <> ""
;MsgBox (0, "Title", "Text1")
ControlClick ($hWnd, "", "Button1") ; Send a mouse left click to the button
; "Sync your OneDrive files to this PC"
Local $hWnd = WinWait("Microsoft OneDrive", "Sync your OneDrive files to this PC", 180) ; Wait for window with title "Sync your OneDrive files to this PC" to appear, times out after 180 sec
Do
$hCtrl = ControlGetHandle($hWnd, "Next", "Button2") ; Get the handle to the button 'Next'
Sleep(100)
Until $hCtrl <> ""
;MsgBox (0, "Title", "Text2")
ControlClick ($hWnd, "", "Button2") ; Send a mouse left click to the button
; "Your OneDrive is ready for you"
Local $hWnd = WinWait("Microsoft OneDrive", "Your OneDrive is ready for you", 180) ; Wait for window with title "Your OneDrive is ready for you" to appear, times out after 180 sec
Do
$hCtrl = ControlGetHandle($hWnd, "Open my OneDrive - <COMPANY> folder", "Button1") ; Get the handle to the button 'Next'
Sleep(100)
Until $hCtrl <> ""
;MsgBox (0, "Title", "Text3")
ControlClick ($hWnd, "", "Button1") ; Send a mouse left click to the button
Now that we have all the prerequisites in place it is time to implement them. Create a Powershell script and paste the following code. The script will make sure that OneDrive installs successfully for the user and also opens OneDrive prepopulated with the user’s email address.
<#
.Synopsis
This script will install OneDrive.
.DESCRIPTION
This script will install OneDrive.
.NOTES
Name: CTX-XA-U-InstallOneDrive.ps1
Author: Måns Hurtigh, Xenit AB
Date Created: 2017-09-28
Version History:
2017-09-28 - First editor
Initial Creation
Xenit AB
#>
[cmdletbinding()]
Param(
$LocalOneDriveExe = "$env:LOCALAPPDATA\Microsoft\OneDrive\OneDrive.exe"
)
Begin{
if( Test-Path $LocalOneDriveExe -ErrorAction SilentlyContinue ) {
Exit
} else {
Write-Host "Continue..."
}
# Get users mailaddress to pre-populate OneDrive with
$searcher = [adsisearcher]"(samaccountname=$env:USERNAME)"
$UserEmail = $searcher.FindOne().Properties.mail
}
Process{
# Install OneDrive for user and wait for it to finish
& "C:\Program Files (x86)\Microsoft OneDrive\OneDriveSetup.exe" /silent | Out-Null
# Start OneDrive for user and wait for it to finish
& "$env:LOCALAPPDATA\Microsoft\OneDrive\OneDrive.exe" | Out-Null
# Open OneDrive with prepopulated email
#& "C:\Program Files\Internet Explorer\iexplore.exe" odopen://sync?useremail=$UserEmail
start odopen://sync?useremail=$UserEmail
}
End{
}
If you try to log on now you will get a single sign-on with OneDrive. Since all this happens after the user login, FSLogix is not aware that OneDrive is GOING TO BE installed and the data should be redirected to the VHDX. This will cause all OneDrive data to be downloaded to the local disk on the first logon (usually C:\). This means that if several people try to log on for the first time they risk filling up the system drive. For example, if we have 20 users that each have 1 TB of data in their OneDrive all their data will be downloaded to the local disk which requires 20 TB of free disk space on the system drive. I have reported this to FSLogix developers and they are working on a fix for this. However, we came up with two possible workarounds:
- Log out the user automatically when they have successfully logged on and OneDrive is installed
- Create two registry keys when logging in to trick FSLogix into believing that OneDrive already is installed.
In this example, we are going with workaround number two. Create a new PowerShell script and paste the following code:
<#
.Synopsis
Sets keys for FSLogix.
.DESCRIPTION
Sets keys for FSLogix.
.NOTES
Name: CTX-XA-U-FSLogixOneDrive
Author: Måns Hurtigh
Date Created: 2017-10-30
Version History:
2017-10-30 - Måns Hurtigh
Initial Creation
Xenit AB
#>
[cmdletbinding()]
Param(
$VersionInfo = (Get-ChildItem -Path "C:\Program Files (x86)\Microsoft OneDrive\OneDriveSetup.exe").VersionInfo.FileVersion,
$OneDriveKey = "HKCU:\Software\Microsoft\OneDrive",
$OneDriveRegName = "CurrentVersionPath",
$OneDriveRegValue = "C:\Users\$env:USERNAME\AppData\Local\Microsoft\OneDrive\$VersionInfo",
$OneDriveBusiness1Key = "HKCU:\Software\Microsoft\OneDrive\Accounts\Business1",
$OneDriveBusiness1RegName = "UserFolder",
$OneDriveBusiness1RegValue = "C:\Users\$env:USERNAME\OneDrive - <COMPANY>", #Change <COMPANY> to the correct value.
$String = "String",
$LocalOneDriveExe = "$env:LOCALAPPDATA\Microsoft\OneDrive\OneDrive.exe"
)
Begin{
if( Test-Path $LocalOneDriveExe -ErrorAction SilentlyContinue ) {
Exit
} else {
Write-Host "Continue..."
}
}
Process{
If ( Test-Path $OneDriveKey ) {
New-ItemProperty $OneDriveKey -Name $OneDriveRegName -PropertyType $String -Value $OneDriveRegValue -Force | Out-Null
} else {
New-Item $OneDriveKey -Force | New-ItemProperty -Name $OneDriveRegName -PropertyType $String -Value $OneDriveRegValue -Force | Out-Null
}
If ( Test-Path $OneDriveBusiness1Key ) {
New-ItemProperty $OneDriveBusiness1Key -Name $OneDriveBusiness1RegName -PropertyType $String -Value $OneDriveBusiness1RegValue -Force | Out-Null
} else {
New-Item $OneDriveBusiness1Key -Force | New-ItemProperty -Name $OneDriveBusiness1RegName -PropertyType $String -Value $OneDriveBusiness1RegValue -Force | Out-Null
}
}
End{
}
And then finally – add both scripts and the .EXE from AutoIT to start for the user at logon via GPO. The correct order should be like this:
- CTX-XA-U-FSLogixOneDrive.ps1
- AutoIT_OneDrive.exe
- CTX-XA-U-InstallOneDrive.ps1
Good luck with the configuration and feel free to drop a comment or email me if you have any feedback or questions.