Hosted Solutions Panel Discussion – FISPA Atlanta 2014

Last week I had the great opportunity to present at and participate in a panel discussion at FISPA’s Atlanta 2014 conference.  The panel and presentations were focused on the lessons that the presenters and panelists had learned from providing hosted solutions and services to their customers.  This topic suited DataYard very well, as we have been providing hosted services since 1995.  The presentation time was brief, less than five minutes, to allow for questions from the moderator and crowd.  Given the small presentation window, I thought I would elaborate further on some of the points I briefly touched on.

Lesson #1

When I was preparing for this presentation and the corresponding panel discussion, a quote crept into my mind,

The man who promises everything is sure to fulfill nothing, and everyone who promises too much is in danger of using evil means in order to carry out his promises, and is already on the road to perdition.” – Carl Jung

This quote, albeit a bit theatric, catches your attention and makes you start thinking about the first lesson, Focus…

Hosted services, like e-mail, web hosting, etc., are primarily software driven services.  The installation and configuration of them is something many IT professionals can do quite easily and here is where the danger lies.  After, or even during, the initial deployment of a service it is easy to lose focus on the core service it is intended to provide.  Unlike a physical product, features and core functionality can easily be changed with modifications to software configuration.  This can easily lead to a mutation of a hosted service that was originally intended to provide one thing but now does something very different.

A hosted service must be flexible enough to accommodate new customer needs, but must still provide it’s core functionality.  When considering modifications to a hosted service, it is imperative to consider how it adjusts the core functionality of the service.  Does the adjustment add value to the service or take the service in a different direction?  If it takes the service in a different direction, should a new service be created to provide this functionality?  Is there enough demand for this as a new service?

These are difficult questions to answer, but retaining the “Focus” of the service while answering these questions will help guide it in the proper direction. Don’t lose site of the core focus of the hosted service, when dealing with add-ons and service tweaks.

Lesson #2

Building a hosted service can be both an easy and daunting task all at once.  What type of infrastructure should be deployed for this service? Use an open-source project or a white-box solution?  How much more support will this generate?  How will growth be handled? How big should the infrastructure be? 

I have had that conversation many times and there is a two part rule that I have found works best. It does not answer all of the questions but provides a guideline to help build an excellent hosted service.  The first is Build for Quality.  When I bring this up as a guideline for building new hosted services, there are generally two response, “That sounds expensive” and “Doesn’t everyone do that”. 

The answer to the first objection is not really; quality doesn’t always mean drastically increased costs.  Consider the fact that quality will be perceived by the end user of the service.  Good quality of a hosted service may mean providing accurate details and instructions on how to use the service.  Good quality might also mean getting the exact same service every time a customer requests it.  There is the potential for increased expenses if you need to invest in new infrastructure or software, but this isn’t the only way to build for quality.

The second response, the belief that everyone builds hosted services for quality is misguided.  Due to the ease of deployment for hosted services many providers play the “Me Too!” game.  If someone else is providing a hosted service they feel the necessity to “stay competitive” by quickly rolling out the same service.  This can lead to a lower quality service or one the provider may not be equipped to support.  We all know quality products once we use them and quite frequently when they aren’t quality products we like to let everyone else know about it.

Building for quality has several advantages.  First, it allows you to be competitive on the service and not just on the price.  If the service provided is of a higher caliber you can use that to differentiate yourself from the crowd.  Second, a hosted service built for quality will hopefully have a lower support cost.  A hosted service with good documentation, that is always delivered in the same manner and is generally reliable should mean less customer requests.  This can help reduce and potentially make-up the costs you had to invest to build for quality.

The second half to this lesson is Plan for Quantity.

When building a hosted service the initial build scale should be small, but the infrastructure and service should be designed with growth in mind.  It is easy to think that a new hosted service will be the next big thing, but the cost to build infrastructure to support it at scale is probably not practical. However, if the infrastructure is designed with the intention to grow it, when it does become a big hit you can expand it easily.  Then, hopefully costs are less of an issue as revenue is being generated by the service.

 

Wrap Up

These are only a sub-set of lessons that I have learned from providing hosted services, but they provide some foundational guidelines I have found for success.  Of course your approach to hosted services may be very different from mine and if so I would rather enjoy hearing your lessons learned.

Windows Fusion 2.0 – 6/13/2014

DataYard system’s engineers have recently completed a new web cluster based on Server 2012 R2 and IIS 8.5. The cutover from our existing cluster to the new cluster will not require customer interaction and sites should not incur any downtime. We will be changing DNS records for all sites on 6/13/2014 at 5 PM. Please contact us by calling 937-226-6896 or emailing [email protected] if you have any questions or concerns. 

Server Administration with PowerShell 4.0

wright_ps4_powershell_logo

Server Administration with PowerShell 4

TL;DR: PowerShell 4 is awesome, if you are a Windows Technician, Admin, Engineer, Architect, etc. you should be using it.

Intro

In 2007 Microsoft released PowerShell and since then the tool has grown to become one of the most, if not the most, powerful windows administration tool available for Microsoft operating systems and applications. Not only has Microsoft embraced PowerShell as the primary administration tool, but they have opened the door for vendors to develop modules to manage their own software and products. For example, we use Cisco PowerTool for managing their Unified Computing System (UCS) Platform and we utilize VMware PowerCLI for managing ESXi, vSphere, vCloud Director, and several other services and applications. PowerShell isn’t only for administrative purposes but also for personal use, you can even download a module for managing your Facebook account.

PowerShell provides cmdlets rather than command line executables. Cmdlets are instances of .NET framework classes that can perform CRUD actions on .NET framework objects. PowerShell’s runtime environment allows us to pipe results of cmdlets (.NET objects) to other cmdlets, providing a fluid way of administrating Microsoft Windows and applications. This post will focus on cmdlets that will streamline the administration of your server infrastructure.

Server Administration Cmdlets

Let’s geek out a little bit on some new cmdlets that have changed the way I work in regards to administrating a local server.

Add and Remove Windows Features

In legacy versions of windows, administrator’s hands were forced to use Server Manager or Control Panel to see what was installed or to install/uninstall window’s components. Starting with Server 2008 R2 the ServerManager module was introduced and it has never been easier to see what is installed, install additional features, uninstall features, and optionally remove them permanently.

Get-WindowsFeature – Gets information about Windows Server roles, role services, and features that are available for installation and/or are installed on a specified server. A few of the properties that we can filter these features by are DisplayName, InstallState, and Name. For example, in the following command we see what DHCP components are installed:

Get-WindowsFeature | Where Displayname -Match dhcp

            

Display Name                  Name      Install State

————                  —-      ————-

[ ] DHCP Server               DHCP          Available

        [X] DHCP Server Tools RSAT-DHCP     Installed

        

Install-WindowsFeature – This cmdlet installs one or more Windows Server roles, role services, or features on either the local or a specified remote server that is running Windows Server 2012 R2. This cmdlet replaces Add-WindowsFeature in previous versions. Here is how we can install all web server components on the local server:

Get-WindowsFeature Web* | Install-WindowsFeature

Success Restart Needed Exit Code      Feature Result

——- ————– ———      ————–

True    No             Success        {Remote Access, Application Initialization…

        

Uninstall-WindowsFeature – Uninstalls and optionally removes specified roles, role services, and features. We can use this cmdlet to actually get space back from the storage footprint of an installation of Windows. This cmdlet replaces Remove-WindowsFeature in previous versions. Let’s say we know we are never going to use SNMP, and you don’t want the additional installation files taking up space on your disk partition, you can remove it from the operating system to reclaim space:

Get-WindowsFeature *SNMP* | Uninstall-WindowsFeature -Remove -Confirm:$False

Success Restart Needed Exit Code      Feature Result

——- ————– ———      ————–

True    Yes            SuccessRest… {SNMP Tools, SNMP Service, SNMP WMI Provider}

WARNING: You must restart this server to finish the removal process.

        

Firewall Rules Administration

PowerShell 4, limited to Server 2012 or newer, introduces some game changers for managing host firewalls. The legacy command netsh advfirewall firewall was not only hard to remember, but very hard to automate firewall configuration. Let’s take a look at how we used to show all rules:

netsh advfirewall firewall show rule name=all

Once the rule name was found, we could modify it using even more complex syntax. Here is an example of how to change the remote addresses for WMI:

netsh advfirewall firewall set rule name=”Windows Management Instrumentation (WMI-In)” `

dir=in new remoteip=”192.168.1.0/24″

Remembering the syntax was difficult and if you wanted to do this from an object oriented perspective, you would need to use COM objects. This is how you could get a rule through COM:

$Rule = ((New-Object -ComObject HNetCfg.FwPolicy2).Rules) | `

Where-Object { $_.Name -eq “Windows Management Instrumentation (WMI-In)” }

This is how to change the remote IPs using COM:

$Rule.RemoteAddresses = “10.0.0.0/24”

This was easier, but remembering New-Object -ComObject HNetCfg.FwPolicy2 was still too complicated unless your primary job was firewall administration. To be honest, this resulted in me using the graphical Windows Firewall with Advanced Security Console the majority of the time. The only time I used PowerShell to adjust host firewalls was when I was forced to for scripting purposes. Starting with Server 2012 we have new cmdlets for host firewall administration which are included in the NetSecurity module:

Get-NetFirewallRule – Retrieves firewall rules from the target computer or server. This cmdlet allows the retrieval of all firewall rules or filtering by common things such as DisplayName, DisplayGroup, Enabled, and Action. The following snippet obtains information for WMI firewall rules, by grabbing all rules in the group:

Get-NetFirewallRule | Where DisplayGroup -Match “Windows Management Instrumentation” | `

select DisplayName,Name,Enabled,Action | Format-Table -AutoSize

DisplayName                                   Name                Enabled Action

———–                                   —-                ——- ——

Windows Management Instrumentation (DCOM-In)  WMI-RPCSS-In-TCP      False  Allow

Windows Management Instrumentation (WMI-In)   WMI-WINMGMT-In-TCP    False  Allow

Windows Management Instrumentation (WMI-Out)  WMI-WINMGMT-Out-TCP   False  Allow

Windows Management Instrumentation (ASync-In) WMI-ASYNC-In-TCP      False  Allow

Enable-NetFirewallRule – enables a previously disabled firewall rule to be enabled. Common parameters used by this cmdlet are a DisplayName, DisplayGroup, and Direction. These can be explicitly defined as a parameter of the cmdlet. This is how to enable a single rule:

Enable-NetFirewallRule -DisplayName “File and Printer Sharing (SMB-In)”

However, very often it is necessary to open up firewalls for purposes rather than single rules, for example enabling all WMI rules:

Enable-NetFirewallRule -DisplayGroup “Windows Management Instrumentation (WMI)” -PassThru | `

Select DisplayName,Enabled | ft -auto

DisplayName                                   Enabled

———–                                   ——-

Windows Management Instrumentation (WMI-In)      True

Windows Management Instrumentation (WMI-Out)     True

Windows Management Instrumentation (DCOM-In)     True

Windows Management Instrumentation (ASync-In)    True

The counteraction of this cmdlet is Disable-NetFirewallRule, which disables a previously enabled firewall rule.

Set-NetFirewallRule – modifies existing firewall rule properties. Common parameters used by this cmdlet are DisplayName and DisplayGroup. This is how to set the remote IP range able to access your host for File and Printer Sharing purposes:

Set-NetFirewallRule -DisplayGroup “File and Printer Sharing” -RemoteAddress 192.168.1.0/24

Get-NetFirewallRule -DisplayGroup “File and Printer Sharing” | `

Get-NetFirewallAddressFilter | Select RemoteAddress

RemoteAddress

————-

192.168.1.0/255.255.255.0

192.168.1.0/255.255.255.0

192.168.1.0/255.255.255.0

New-NetFirewallRule – Creates a new firewall rule. Common parameters used by this cmdlet are a DisplayName, Direction, Action, Protocol, and LocalPort. This is how to create a new firewall rule that requires a specific port to be open on the host:

New-NetFirewallRule -DisplayName “My Application” -Direction Inbound `

-Action Allow -EdgeTraversalPolicy Allow -Protocol TCP -LocalPort 28002 -RemoteAddress 192.168.1.0/24

Name                  : {487aedbf-0a0b-4965-baee-ec5a09024c73}

DisplayName           : My Application

Description           :

DisplayGroup          :

Group                 :

Enabled               : True

Profile               : Any

Platform              : {}

Direction             : Inbound

Action                : Allow

EdgeTraversalPolicy   : Allow

LooseSourceMapping    : False

LocalOnlyMapping      : False

Owner                 :

PrimaryStatus         : OK

Status                : The rule was parsed successfully from the store. (65536)

EnforcementStatus     : NotApplicable

PolicyStoreSource     : PersistentStore

PolicyStoreSourceType : Local

The counteraction of this cmdlet is Remove-NetFirewallRule.

Testing Network Connectivity

Troubleshooting network connectivity is a common task for administrators that is often more difficult than it has to be due to the poor tools available. Have you ever tried scripting out ping responses, telnet connections, or net view commands? Scripting out results of legacy tools was extremely hard and unreliable. Starting in Server 2012 R2 and Windows 8.1 there is a new cmdlet available that combines troubleshooting TCP connections, tracert, and ping and this cmdlet is part of the NetTCPIP module:

Test-NetConnection – cmdlet for testing network connectivity and common parameters include Port, Traceroute, and InformationLevel. Here is a very simple way to document which Active Directory computers have SMB enabled:

$smb = @{}

ForEach ($computer in Get-ADComputer -Filter *){

$test = Test-NetConnection -Computername $computer.DNSHostName -Port 445

$smb.Add($computer.DNSHostName, $test.TcpTestSucceeded)

}

$smb.count

30

Testing Web Sites and Web Requests

In PowerShell’s infancy, Windows admins had the hardest time trying to mimic common web tools such as wget on the Linux side. In the past I’ve scripted out starting IE through a COM object and attempting to script web requests. There are new cmdlets that save us significant amounts of time when we have to test HTTP responses from a variety of systems:

Invoke-WebRequest – sends HTTP and HTTPS requests to a web page or web service. It parses the response and returns collections of forms, links, images, and other significant HTML elements. Here’s a quick example of how we can test all of our sites using a CSV file as a data source, and store the results in a hash table:

$status = @{}

$sites = Import-Csv .\Hosted_Sites.csv

ForEach ($site in $sites){

    try {

        $result = (Invoke-WebRequest -Uri $site.Site).StatusCode

    }

    catch {

        $result = $_.ToString()

    }

    $status.Add($site.Site, $result)

}

Invoke-RestMethod – sends HTTP and HTTPS requests to Representational State Transfer (REST) web services that returns richly structured data. Windows PowerShell formats the response based to the data type. For an RSS or ATOM feed, Windows PowerShell returns the Item or Entry XML nodes. For JavaScript Object Notation (JSON) or XML, Windows PowerShell converts (or deserializes) the content into objects. With REST being a common web standard, this cmdlet expands the possibilities of PowerShell. We use Invoke-RestMethod to test our service APIs, but here is a quick example of using it to pull some map data from google map APIs:

Invoke-RestMethod -Uri “http://maps.googleapis.com/maps/api/geocode/xml?address=130+W+2nd+St+45402&sensor=false” -Method GET

Scheduled Jobs

PowerShell 4 introduces some improvements to some commands that have existed in previous versions. A great example of this is working with Scheduled Jobs (Scheduled Tasks). The legacy command line utility schtasks.exe was next to impossible to script and automate your work. Here is how we used to create a scheduled task:

schtasks /create /tn Update-File /tr ‘cmd /c ipconfig > c:\ip.txt’ /sc minute

A major problem is that you always have to identify a program that you want to run. Getting PowerShell to run as the program and execute a script was more difficult than it should have been. Now, we have PowerShell Scheduled Jobs, allowing us to utilize the .NET framework cmdlets to create and manage jobs:

Register-ScheduledJob – cmdlet for managing scheduled jobs on the local computer. A “scheduled job” is a Windows PowerShell background job that can be started automatically on a one-time or recurring schedule. Scheduled jobs are stored on disk and registered in Task Scheduler, so they can be managed in Task Scheduler or PowerShell. Here is an example of how to create a scheduled job to send an email every minute:

$minute = New-TimeSpan -Minute 1

$trigger = New-JobTrigger -Once -At 12am -RepetitionInterval $minute `

-RepeatIndefinitely

Register-ScheduledJob -Name “Send Email” -Trigger $Trigger -ScriptBlock {

    Send-MailMessage -SmtpServer localhost -To [email protected] -From [email protected] `

    -Subject “Minute Notice” -Body “Testing every minute emails!”

}

 

Conclusion

In 2009 I wrote the following in a blog post, “For those Windows Admins that haven’t tampered with Windows PowerShell I recommend you start… I am finding the more I dive in the less I want to come up for air.” The same holds true today and 3 PowerShell versions later. PowerShell is only becoming more powerful as time goes on, and DataYard is taking advantage on the ability to automate administrative tasks and make our jobs easier. Here are some quick PowerShell resources that will help you, no matter your familiarity with PowerShell:

Stay tuned for future posts about PowerShell!