Sometimes the answer is simpl(icity)

I’m a big fan of simple.

Sometimes though, simple isn’t as simple as it seems.

A few months ago, I began working with PowerShell for the first time (with meaningful content). I was creating a script to help my team and our customers with preparing a Windows Server to host Citrix ShareFile’s StorageCenter software. Don’t get me wrong, configuring a server (especially for hosting ShareFile on-prem) isn’t the toughest of jobs – but, man, is it time consuming. I sought out to fix that.

A colleague of mine had built out a script for me to work on – he was (and probably still is) lightyears ahead of me in technical ability, specifically with PowerShell. When I was given the project, we had a script that ran connection tests and strung out a list of Windows features that needed to be installed on the server as a pre-requisite, along with the status of that feature’s installation. I got an email with a long script in the body. My first thought: “What the f*<K is this?!”… followed shortly thereafter by a quick reference to HBO’s Silicon Valley: “Does he tab or space?”

Screen Shot 2017-02-22 at 10.49.22 PM.png

I spent hours upon hours watching PowerShell videos, reading TechNet articles and researching everything I could to learn the art of scripting. I picked up a few tips and tricks, but nothing huge for my first go-round. I wanted to learn the basics – one must crawl before they can walk. I found myself using simple logic (If, this, then that) in a lot of the cmdlets that I was using. I know I can get fancy and use piping, but, again, this was my first crack at a script. I spent three months getting to know PowerShell and expand on this script.

It’s worth noting that ShareFile StorageCenter is supported on Windows Sever 2008 R2 and 2012 R2.. Cmdlets are mostly the same, but roles and features vary ever so slightly in their aliases. I had to rewrite the entire thing to work on both – great. 

Here’s where the ‘simple’ comes into play…

When adding the piece of script that would give the user a prompt asking if they wanted to install the missing, required features, everything worked fine on one server OS, but not the other. That’s because this is where I tried to get fancy with piping.

import-module ServerManager
$features = @()
$features += @("File-Services","FS-FileServer","Web-Server","Web-WebServer","Web-Common-Http","Web-Default-Doc","Web-Dir-Browsing","Web-Http-Errors","Web-Static-Content","Web-Health","Web-Http-Logging","Web-Performance","Web-Stat-Compression","Web-Security","Web-Filtering","Web-Basic-Auth","Web-Windows-Auth","Web-App-Dev","Web-Net-Ext","Web-Asp-Net","Web-ISAPI-Ext","Web-ISAPI-Filter","Web-Mgmt-Tools","Web-Mgmt-Console","Web-Scripting-Tools","Application-Server","AS-NET-Framework","AS-Web-Support","AS-TCP-Port-Sharing","PowerShell-ISE")
$features=Get-WindowsFeature | Where-Object {$features.Installed -eq $False} | Select-Object | Add-WindowsFeature -Name File-Services,FS-FileServer,Web-Server,Web-WebServer,Web-Common-Http,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-Static-Content,Web-Health,Web-Http-Logging,Web-Performance,Web-Stat-Compression,Web-Security,Web-Filtering,Web-Basic-Auth,Web-Windows-Auth,Web-App-Dev,Web-Net-Ext,Web-Asp-Net,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Mgmt-Tools,Web-Mgmt-Console,Web-Scripting-Tools,Application-Server,AS-NET-Framework,AS-Web-Support,AS-TCP-Port-Sharing,PowerShell-ISE

Okay. So we import the module for ServerManager, set the array of features, then pipe out the following: for the features in the array, check to see if they are installed; if they aren’t, select those that are not installed and install them. I know, I know – it’s not perfect. But I was new to this and it worked… or so I thought. Again, 2008 R2 and 2012 R2 don’t share aliases 100%. I tested on 2008 R2 and it worked like a charm. However, on 2012 R2, I couldn’t for the life of me figure out why the script would exit instead of perform the cmdlet.

I looked high and low for a solution with no avail. I asked my colleague who gave me the project to begin with to look at it, I asked my boss, I asked another colleague and another. We couldn’t find a breakthrough. The end of the quarter came around and I still didn’t have an answer for why the hell we weren’t successful on a 2012 R2. I decided to give it a rest for a while and come back to it with fresh eyes in a few weeks…..

I came back to this project a couple of weeks later. I knew a fresh start would help…. or not. I continued the same struggle, right where I left off. For some reason, logic wasn’t winning in this fight. I decided to try something else – remember, I’m new to this. So… Let’s get SIMPLE. I took out the piping – If logic wasn’t going to win, we are going to cut out the logic.

$features = @()
$features += @("FileAndStorage-Services","Storage-Services","Web-Server","Web-WebServer","Web-Common-Http","Web-Default-Doc","Web-Dir-Browsing","Web-Http-Errors","Web-Static-Content","Web-Health","Web-Http-Logging","Web-Performance","Web-Stat-Compression","Web-Security","Web-Filtering","Web-Basic-Auth","Web-Windows-Auth","Web-App-Dev","Web-Net-Ext45","Web-Asp-Net45","Web-ISAPI-Ext","Web-ISAPI-Filter","Web-Mgmt-Tools","Web-Mgmt-Console","Web-Scripting-Tools","NET-Framework-45-Features","NET-Framework-45-Core","NET-Framework-45-ASPNET","NET-WCF-Services45","NET-WCF-TCP-PortSharing45","FS-SMB1","User-Interfaces-Infra","Server-Gui-Mgmt-Infra","Server-Gui-Shell","PowerShellRoot","PowerShell","PowerShell-ISE","WoW64-Support")
$features=Install-WindowsFeature -Name FileAndStorage-Services,Storage-Services,Web-Server,Web-WebServer,Web-Common-Http,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-Static-Content,Web-Health,Web-Http-Logging,Web-Performance,Web-Stat-Compression,Web-Security,Web-Filtering,Web-Basic-Auth,Web-Windows-Auth,Web-App-Dev,Web-Net-Ext45,Web-Asp-Net45,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Mgmt-Tools,Web-Mgmt-Console,Web-Scripting-Tools,NET-Framework-45-Features,NET-Framework-45-Core,NET-Framework-45-ASPNET,NET-WCF-Services45,NET-WCF-TCP-PortSharing45,FS-SMB1,User-Interfaces-Infra,Server-Gui-Mgmt-Infra,Server-Gui-Shell,PowerShellRoot,PowerShell,PowerShell-ISE,WoW64-Support

Lo and behold, it worked. Simplicity worked.

The final product (for now – there are plans to expand the capabilities further) checks for the .NET Framework version and installs the minimum required version (.NET 4.5.2), it will string out the features required for configuration and their install state and it will give the user a menu in which they can choose whether or not to install the missing, required features.


If you’re interested in checking out the script, you can find it posted on the ShareFile GitHub site.

Want to learn more about Citrix ShareFile? Contact me or your local Citrix representative or visit

1 thought on “Sometimes the answer is simpl(icity)”

Leave a Reply

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

You are commenting using your 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