Symbolic Links with ShareFile Sync

Alright; so, this is pretty cool. A few months ago, Citrix ShareFile (somewhat silently) released support for symbolic links with its Sync for Windows client.

When we heard about this, there was a lot of excitement from our team… excitement that seemed to quickly fizzle out.

I didn’t understand it – why weren’t people talking about this? Not only this a ‘cool’ feature (#TalkNerdyToMe), but it’s quite practical and useful.The full knowledge base article on this feature can be found here, but to sum it up: users that are running ShareFile Sync for Windows can now create symbolic links to sync folders from their local machine to a ShareFile repository.

“Wait. Isn’t that the point of a sync client?”

Why, yes; Yes, it is.

However, traditionally, sync clients (both from ShareFile and most other vendors) allow users to sync down data from their respective service to the end-user machine, saving it to the specified location as designed with the sync application.

Now, users can leave their data where it is and continue to interact with it (share, edit, etc.) on their local machine, all while syncing the end result to ShareFile – be it for a backup or just to keep your data up to date across devices.

The Backstory

This small feature may have been my favorite feature release from ShareFile in the past year.

I couldn’t wait to show off the symbolic links feature to my clients and extended team members as a tool for striking up conversations around use cases. In my mind, I could see it used for a multitude of reasons; all while helping to address the conflict between security and IT oversight vs end-user’s perception of usability.

From that perspective, it had to be deployable to end-users – so, I had the idea of building this feature into a logon script for an administrator to deploy broadly.

I noodled on it for a few days… a few days turned into a week… a week turned into a few weeks… I still hadn’t started working on this. I had the concept down, but never executed.

Finally, I get a little free time and sit down to work on building out my script. I don’t get far, but it’s a start – and that’s all that I needed for the moment.

Lucky for me, I had a client who came to us with a perfect-fit use case for this feature… and they wanted to test it. *Fire lights* I now have to have a deliverable to my client, preferably within the week.

Thus, I get back to work on this script and think of a few different ways to write it out. It had been a while since I had dabbled with PowerShell, so it takes a minute for me to get my bearings back.

I keep running into an error message stating that resources exist when I know they don’t… what to do, what to do.

Aha! It hits me: keep it simple… it’s funny how we don’t always take our own advice (I had written about keeping it simple in an earlier post about my first PowerShell experience).

I heed my own words and skinny-down my script.

The Real Meat

 Let’s get back to the “why” of all of this.

Why is it a cool feature? Well, in my opinion, giving your users the freedom to store their data in any location on a company-issued machine ensures their productivity levels don’t slip and eliminates the need to train them on a new system/application/process, regardless of how minute the change may be – i once had a client explain to me that adding two clicks into a folder structure can cost them up to $10,000 a minute when looking at the time lost from being on a production line.

While maintaining the levels of productivity, you’re also ensuring your data is safe (and backed up). Remember that client I mentioned that lit the fire under my @$$? Well, turns out, they have users who continuously lose company issued devices, have them stolen or destroyed. For them, this was reassurance that their data would be safe should they lose another resource/asset. For them, they would deploy the script to ensure syncing of users’ data. For others, it could be a user-driven choice (assuming it was okay with the company, of course!).

Because of the dual-use here, I decided to write two separate scripts, derived from the same concept/base. The first of which can be used as a logon script and added/applied via Group Policy as a run-once script; and the second, which can be run by an end-user, and delivers a menu for them to select from pre-defined source folders to sync up to ShareFile. Check them out below!

Once these are deployed, you’ll see the green check marks to signify that the files have, in fact, synced to ShareFile – you’ll also see the folders populate within ShareFile.

Untitled

 The Finished Product(s)

After a few hours of sheer focus, I arrive at the final; well, one of the final products – the second would come a short time after the first was completed. Here they are:

A few things to note when looking through these:

  1. Obviously, the disclaimer: The sample scripts are provided AS IS without warranty of any kind. Citrix further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Citrix, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Citrix has been advised of the possibility of such damages.
  2. Running this script requires administrator permission within PowerShell on the target device.
  3. The target folders are created when running this script – you do not need to create the target folder within ShareFile prior to running it.
  4. ShareFile Sync for Windows installs with a default location of the user profile, hence the paths in the scripts – these paths can be changed.
  5. Likewise, with the local paths or destination paths – they do not have to be user profile source folders or the user’s Personal Folders within ShareFile (you can point to Shared Folders).
  6. The formatting below may not be the best, feel free to contact me for the actual scripts themselves.

Version 1 – Administrator Deployment

</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">&lt;##</span></pre>
<pre><span style="color:#dedede;">Title: Symbolic Link Creator</span></pre>
<pre><span style="color:#dedede;">Description: This script will give administrators the ability to sync local folders within a user's User Profile to sync data back to ShareFile as a backup - allowing users to maintain current open/save workflows</span></pre>
<pre><span style="color:#dedede;">with local resources, while backing up data to a ShareFile repository.</span></pre>
<pre><span style="color:#dedede;">Creator: Michael Dombroski</span></pre>
<pre><span style="color:#dedede;">Company: Citrix Systems, Inc.</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">Please note: This script requires administrative access to create folders on the targeted machine.</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">Disclaimer...</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">The sample scripts are provided AS IS without warranty of any kind. Citrix further disclaims all implied warranties including,</span></pre>
<pre><span style="color:#dedede;">without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation</span></pre>
<pre><span style="color:#dedede;">remains with you. In no event shall Citrix, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages</span></pre>
<pre><span style="color:#dedede;">whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability</span></pre>
<pre><span style="color:#dedede;">to use the sample scripts or documentation, even if Citrix has been advised of the possibility of such damages.</span></pre>
<pre><span style="color:#dedede;">##&gt;</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## Specify the source folders from the user's machine</span></pre>
<pre><span style="color:#dedede;">$Desktop = $env:USERPROFILE + '\Desktop'</span></pre>
<pre><span style="color:#dedede;">$Documents = $env:USERPROFILE + '\Documents'</span></pre>
<pre><span style="color:#dedede;">$Downloads = $env:USERPROFILE + '\Downloads'</span></pre>
<pre><span style="color:#dedede;">$Pictures = $env:USERPROFILE + '\Pictures'</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## Specify the ShareFile folders to be targeted for links</span></pre>
<pre><span style="color:#dedede;">$SFDesktop = $env:USERPROFILE + '\ShareFile\Personal Folders\Desktop'</span></pre>
<pre><span style="color:#dedede;">$SFDocuments = $env:USERPROFILE + '\ShareFile\Personal Folders\Documents'</span></pre>
<pre><span style="color:#dedede;">$SFDownloads = $env:USERPROFILE + '\ShareFile\Personal Folders\Downloads'</span></pre>
<pre><span style="color:#dedede;">$SFPictures = $env:USERPROFILE + '\ShareFile\Personal Folders\Pictures'</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## If a "Desktop" folder does not exist for the user in ShareFile, then create a "Desktop" folder within a user's personal folders and create a symbolic link to the current "Desktop" folder from the machine to ShareFile</span></pre>
<pre><span style="color:#dedede;">If (test-path -path "$env:userprofile\sharefile\personal folders\desktop")</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">Write-Host "Desktop folder already exists for $env:username in this location: $sfdesktop"</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;">Else</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">new-item -path $SFDesktop -itemtype symboliclink -value $Desktop</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## If a "Documents" folder does not exist for the user in ShareFile, then create a "Documents" folder within a user's personal folders and create a symbolic link to the current "Documents" folder from the machine to ShareFile</span></pre>
<pre><span style="color:#dedede;">If (test-path -path "$env:userprofile\sharefile\personal folders\documents")</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">Write-Host "Documents folder already exists for $env:username in this location: $sfdocuments"</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;">Else</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">new-item -path $SFDocuments -itemtype symboliclink -value $Documents</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">&amp;nbsp;</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## If a "Downloads" folder does not exist for the user in ShareFile, then create a "Downloads" folder within a user's personal folders and create a symbolic link to the current "Downloads" folder from the machine to ShareFile</span></pre>
<pre><span style="color:#dedede;">If (test-path -path "$env:userprofile\sharefile\personal folders\downloads")</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">Write-Host "Downloads folder already exists for $env:username in this location: $sfdownloads"</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;">Else</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">new-item -path $SFDownloads -itemtype symboliclink -value $Downloads</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">&amp;nbsp;</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">## If a "Pictures" folder does not exist for the user in ShareFile, then create a "Pictures" folder within a user's personal folders and create a symbolic link to the current "Pictures" folder from the machine to ShareFile</span></pre>
<pre><span style="color:#dedede;">If (test-path -path "$env:userprofile\sharefile\personal folders\pictures")</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">Write-Host "Pictures folder already exists for $env:username in this location: $sfpictures"</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;">Else</span></pre>
<pre><span style="color:#dedede;">{</span></pre>
<pre><span style="color:#dedede;">new-item -path $SFPictures -itemtype symboliclink -value $Pictures</span></pre>
<pre><span style="color:#dedede;">}</span></pre>
<pre><span style="color:#dedede;"></span></pre>
<pre><span style="color:#dedede;">

Version 2 – User-Initiated Sync


<##Title: Symbolic Link Creator - User InitiatedDescription: This script will give users the option to select local folders within the User Profile to sync data back to ShareFile as a backup - allowing users to maintain current open/save workflows with local resources, while backing up data to a ShareFile repository.Creator: Michael DombroskiCompany: Citrix Systems, Inc.
Please note: This script requires administrative access to create folders on the targeted machine.
Disclaimer...
The sample scripts are provided AS IS without warranty of any kind. Citrix further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Citrix, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Citrix has been advised of the possibility of such damages.##>
## Specify the source folders from the user's machine$Desktop = $env:USERPROFILE + '\Desktop'$Documents = $env:USERPROFILE + '\Documents'$Downloads = $env:USERPROFILE + '\Downloads'$Pictures = $env:USERPROFILE + '\Pictures'
## Specify the ShareFile Destination folders to be created and linked$SFDesktop = $env:USERPROFILE + '\ShareFile\Personal Folders\Desktop'$SFDocuments = $env:USERPROFILE + '\ShareFile\Personal Folders\Documents'$SFDownloads = $env:USERPROFILE + '\ShareFile\Personal Folders\Downloads'$SFPictures = $env:USERPROFILE + '\ShareFile\Personal Folders\Pictures'

function Show-Menu{     param (           [string]$Title = 'Which folders would you like to sync to ShareFile?'     )      Write-Host "$title"          Write-Host "1: Press '1' to sync Desktop."     Write-Host "2: Press '2' to sync Documents."     Write-Host "3: Press '3' to sync Downloads."     Write-Host "4: Press '4' to sync Pictures."     Write-Host "Q: Press 'Q' to quit."
}do{     Show-Menu     $input = (Read-Host "Please make a selection - To sync multiple destinations, please separate by comma.").split(',')          switch ($input)     {             '1' { If (test-path -path $SFDesktop)                    {                    Write-Host "Desktop folder already eixist for $env:username in this location: $sfdesktop"                    }                    Else                    {                    new-item -path $SFDesktop -itemtype symboliclink -value $Desktop                    }                  } '2' { If (test-path -path $SFDocuments)                    {                    Write-Host "Documents folder already eixist for $env:username in this location: $sfdocuments"                    }                    Else                    {                    new-item -path $SFDocuments -itemtype symboliclink -value $Documents                    }                           } '3' { If (test-path -path $SFDownloads)                    {                    Write-Host "Downloads folder already eixist for $env:username in this location: $sfdownloads"                    }                    Else                    {                    new-item -path $SFDownloads -itemtype symboliclink -value $Downloads                    }                         } '4' { If (test-path -path $SFPictures)                    {                    Write-Host "Pictures folder already exists for $env:username in this location: $sfpictures"                    }                    Else                    {                    new-item -path $SFPictures -itemtype symboliclink -value $Pictures                    }
} 'Q' { return }     }     pause}until (test-path $SFDesktop,$SFDocuments,$SFDownloads,$SFPictures)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s