How to Turn Off Reading View for Word 2013 Attachments

Office 2013 has this nasty habit of opening Word, Excel, and other Office email attachments in “Reading View,” which is a stripped-down read-only mode that exists in Office 2013.  Turning it off is simple enough: simply click File > Options and uncheck the setting labeled “Open email attachments and other uneditable files in reading view.”  It’s that simple.

But what if you’ve got a network full of users that need to have this feature disabled?  Well, there’s a registry setting for that.  Using login scripts, group policy, or some other method, set the following registry key to 0:


VDI Woes: Learning From Failure

This article chronicles my experience deploying VDI (Virtual Desktop Infrastructure) at my full-time job at SUN Area Technical Institute.  I’m hoping that sharing my experiences will serve as a cautionary tale to others and help me remember the lessons I ought to take away from this utter failure.

First off: it would come as no surprise to my coworkers if I said that our VDI deployment at SUN Tech bombed from the perspective of both the IT department and our users.

There were parts that people really liked: their newly discovered desktop real-estate where their bulky towers once resided, and they had remote access to their desktops from anywhere on just about any Internet-enabled device.  There was also much to dislike about VDI too:  unreliable thin clients backed by an unreliable company, the cost, the failure to realize time savings in management, the loss of personalization, and the wavering availability of their desktops. As Microsoft’s Joey Snow stated in this video series about VDI, “if it doesn’t work exactly like a physical desktop, users won’t adopt it.”  A truer statement couldn’t be said about VDI, and it’s the point on which I feel we most missed the mark on this project.


vdi1Our VDI journey started as a modest pilot:  10 PanoLogic G2 Zero Clients, a single server running Microsoft Hyper-V and System Center Virtual Machine Manager. At the beginning we only rolled out VDI to a few students who could handle being offline for days at a time. The pilot went well and we began expanding: 20 thin clients, then 30, and soon we started rolling out VDI to our teachers.

Up to this point our experience was very positive.  Our client devices were low-cost and consumed very little power: around $350 for the device, annual maintenance of about $33 per device, and about 6 watts of power consumption. They worked reliably with Hyper-V, but it was Hyper-V that prevented expansion. Because of the limitations in Microsoft’s virtualization technology, we ran out of resources on our Hyper-V server.  At the time Hyper-V virtual machines were resource hogs: virtual machines spawned from a shared template all required their own separate copies of the parent data, even though each virtual machine’s disk was 99.9% identical to the original template.

The boss and I decided that we should explore a more robust and proven virtualization platform and settled on VMWare.  We made some big purchases: two beefy servers from HP to act as ESXi hosts, and licenses for the VMWare Horizon View bundle which provided licenses for the two ESXi hosts, VMWare vCenter, client licenses for 80 virtual machines, ThinApp, and use of VMWare Horizon View for client access through thin clients and remote access.  Of course this was about an $50,000 investment over three years for the servers and the ridiculously priced VMWare licensing.

Read more

Internet Safety, Part 2: There’s No Such Thing as a Free Lunch

(This is part 2 of a series on internet safety? Check out Part 1 to get up to speed.)

In addition to the threats outside of their own control, users face two problems when it comes to internet safety:  a skill-gap, and a sense of entitlement. Both are problems under our control.

Internet Safety Problem #1: The Skill Gap

The Internet is part of our daily lives, but nobody ever actually told us how to use it.

A meme showing an elerly woman believing a scam, which illustrates just difficult Internet safety can be for those who didn't grow up with the technology.

The Internet is basically run by scumbags who hate your Grandma.

Do you know what deism  means? Deism is the belief that God created the universe and then left it to manage itself. The Internet is a lot like a deist universe: in the beginning some geniuses created the Internet. They filled their new digital world with government, military, and university servers. But soon the proud parents turned their creation over to the powers of the free market and the rest is pretty much history. Now you have to navigate a maze of sleaze and scams to do anything constructive. Internet safety is like driving through an unfamiliar city. You need to remain cautious, be aware of where the “bad areas are,” and know what trouble looks like. I’ll try to teach you these skills in the rest of the series.

Internet Safety Problem #2: Entitlement

The second problem of Internet safety is that we have an unrealistic expectation that everything on the Internet ought to be free, and that goes doubly for those of us who grew up suckling at the teats of Napster.

A meme showing a young woman celebrating a life mileston paid for by her parents. Many folks think that they're entitled to everything the Internet has to offer free of charge, an unrealistic expectation that causes real problems when it comes to Internet safety.

I imagine they bought her an iPod full of songs from Limewire too.

The Internet isn’t any different from the real world: there’s no such thing as a free lunch.  One way or another somebody pays for everything, but there are many ways that can happen. The one exception is true Free Open-Source Software, but identifying true open source versus software that’s simply hijacked the term to gain legitimacy is hard work.

“But Brian,” you say, “I found all these neat backgrounds of cute furry kitties, a free download of Elvis’ latest album from beyond the grave, and this free program that makes out with me when I’m alone on a Friday night! How do you explain THAT?”

Keep reading and I’ll explain some of the fun and exciting ways the Internet will try to screw you over.

How Free Services Make Money

My girlfriend wife‘s uncle Bill is fond of saying profit isn’t a dirty word.  I absolutely agree with him, provided that profit doesn’t depend on scamming other people out of their money.  Many will put your Internet safety at risk. Here’s a short list of methods that free services use to make money, ordered from “legitimate and totally safe” to “kill it with fire.”

  • Donation-based services: some services are truly free and won’t ever charge you anything, but they may solicit donations. One example is Wikipedia. Services like these work based on the good-will of their users, and the assumption that honest people will be willing to give what the service is worth to them.  Some of them even hold annual fundraising drives like NPR.
    Internet Safety Rating: Very Safe
  • Crowd-funding: Some services work by soliciting contributions through sites like KickStarter of GoFundMe. The idea is that people will vote with their dollars for services and products that they want to see happen.
    Internet Safety Rating: Very Safe
  • Free software with a paid, premium version. SketchUp is a perfect example. You can download the free version, and if you need more powerful, commercial features you can buy the premium version. The free version is their “loss leader” that makes you want the more expensive product.  It’s sort of like the free samples at the grocery store.
    Internet Safety Rating: Very Safe
  • Pay-With-a-Share: This is another new but relatively save way of providing free services.  A vendor will offer you their software or service either for money or for a “share” on Facebook or Twitter.  Basically you’re deciding if you want to pay for their program or help them reach other people who will.
    Internet Safety Rating: Safe
  • Free trial subscriptions like Spotify Premium. Services with free trials offer their full service for free for a limited time, then either force you to pay or automatically start charging your credit card. Free trials work the same way they work in the real world: they give you a chance to try the full product before you pay for it.  We’ve all received magazine offers that work this way.
    Internet Safety Rating: Safe
  • Ad-Supported Services: Ad-support allow a company to offer their program or service free of charge by selling ad space to other companies. This is one of the most popular revenue options for free services. Most of Google’s services are ad-supported. Heck, even my site and all of my videos are ad-supported because, while I love what I do and I love passing on what I know to other people, I also need to earn a living.  It’s not so different from the ads you might see on public transportation and serve a similar purpose.
    Internet Safety Rating: Safe
  • The Ol’ Bate-and-Switch: sometimes you can’t see this one coming ahead of time. You’ll sign up for a program or service that offers itself completely free of charge, and one day, once the service had become part of your online routine, you’ll be greeted with a Pay Wall requiring you to cough up money to use the service. A recent change at LogMeIn, a top provider of remote access software, recently stopped offering a free package after years of offering a free and paid tier.  The most appropriate real-world example I can think of is the classic drug-deal saying that “the first hit’s always free:” create a need, then use it to hold a person hostage.
    Internet Safety Rating: Safe, but Deceptive
  • Software Bundling: Sometimes the owner of one program gets money to install another program along with their software.  One example is Oracle’s Java. Java is on just about every computer on the planet, yet the program was never been profitable for Oracle or its original creator, Sun Microsystems. In recent years Oracle has tried to lower the loss by packaging browser toolbars along with Java.  Most “legitimate” software that bundles other programs will ask before installing them, giving you the chance to opt-out of stuff you don’t want, but some programs aren’t so kind.
    Internet Safety Rating: Unsafe
  • Adware: To me there’s a distinction between ad-supported software and ad-ware. Software that I consider ad-supported will display ads while you’re using it.  I define ad-ware  as software whose sole reason for existence is displaying ads on your computer whether you’re using the software or not.
    Internet Safety Rating: Unsafe
  • Information Sharing/Theft: Some services might offer you a free download in exchange for your name and your email address.
    Internet Safety Rating: Unsafe
  • Malware: Some free software will bundle things that will harm or slow down your computer.  This sort of software is malware, and sometimes it’s a very fine line between what’s considered malware and ad-ware (or ad-supported software). Some malware will display ads, some change your default search engine and home page, some spies on your internet usage and reports it to marketing agencies, while other malware might use your computer as part of a “botnet” for a larger, more nefarious goal.  And some programs have no function except being a malware vehicle.
    Internet Safety Rating: Very Unsafe
  • Ransomeware: this method of moneymaking is becoming increasingly popular in the last few years.  Ransomeware is software that makes your computer unusable until you pay a fee to fix it. These are some of the biggest threats that home users now face.  There are fake antivirus applications all over the internet which, once installed, reports that viruses have infected your computer and that you need to pay a fee to remove when, in reality, the antivirus program itself is the problem.  And then there’s Cryptolocker: this little gem encrypts your hard drive, then requires you to pay a fee, payable only in BitCoin, to decrypt and access your files.
    Internet Safety Rating: Very Unsafe

The Open Source Exception

The one exception to the rule is open source software.  A program is “open source” if the author has made it’s code available for others to see and change. Open source software is usually quite safe.

Open source exists based on a set of incentives separate from monetary gain.  People write open source software because it solves a particular problem that’s important to them. Some do it to keep their programming skills sharp, or simply for the challenge. Many companies built around open source pay their programmers to contribute to open source projects, and then the company offers a premium, paid product built on top of it, or offers paid support for the open source project itself.

The important thing to remember is that open source is usually free, but free isn’t always open source.If a program is offered for free and isn’t open source, you can bet it’ll try to make money some other way.

Internet Safety Part 1: Introduction
Internet Safety Part 2: There’s No Such Thing as a Free Lunch

How to Use the Internet Safely Part 1: Introduction

On a recent Q&A session I did on Facebook, my friend Tracy asked the following question:

Here’s something that always aggravated me about my HP when I still had a PC. You pretty much can’t avoid malware, spyware, etc. But, there’s a ton of free or open source anti-virus, anti-spyware, anti whatever software out there. I used AVG and Spybot on the recommendations of friends. But I still ended up with things they couldn’t cure. So, I ended up only using the internet by sandboxing. What’s the best way for someone to make the most out of open source protection for their PC?

I didn’t have the time to do that topic justice at the time, but I think it’s important enough to have its own dedicated article and video.  Tracy asked how to use free software to keep her PC clean, but I’m expanding the topic, and calling it “How to Use the Internet Safely,” because none of the tools or knowledge you need to do it cost a dime.

Part 1: Introduction
Part 2: There’s No Such Thing as a Free Lunch

Generate an HTML Report of a User’s Group Memberships with PowerShell

In my last post I shared a PowerShell function which provides a full list of an Active Directory user’s group memberships, including all of those inherited from other groups.

Having a massive list of groups in an array is useful, but you can use and abuse that data and convert into all sorts of interesting formats to simplify IT administration. In my case I can use the list to help me implement Role-Based Access Control.


I’ve been working on transitioning to Role-Based Access Control as described in the book Windows Administration Resource Kit: Productivity Solutions for IT Professionals. Without getting into too many details, the goal of RBAC is to provide single points of management for business roles and IT resources.  I’ve been working on restructuring our Active Directory to implement RBAC by modifying group memberships and naming groups that have similar functions using common prefixes.  For example:

  • Groups that control access to a resource have the format ACL_Resource Name_Permission
  • Groups that control access to a VDI pool have the format VDI_VDI Pool Name
  • Groups that control deployment of a group policy have the format GPO_Policy Name
  • Groups that control deployment of an application have the format APP_Application Name
  • Groups that represent a Role or business logic responsibility have no prefix (such as “Administrative Director“)

As long as I stick to these standards, finding groups and using them to manage capabilities is simple.

The Script

Using a little PowerShell magic, I can generate pretty reports on-the-fly that show me the full story behind a user’s group memberships. My script separates types of groups based on their prefix and displays different information for different types of groups. Here’s an example report that I generated for my user account.

You might not find my script very useful to you as-is, unless of course you use the name naming scheme that I do.  However it should serve as an example of how you can use Active Directory and PowerShell together to generate informative reports about the capabilities of your users.

Note: If you plan to use this script, you’ll also have to download my Get-AdPrincipalGroupMembershipRecursive module and put it at the proper place on PowerShell’s import path.

<# .SYNOPSIS Generates a report in HTML format of all a user's group memberships. .DESCRIPTION Generates a report in HTML format of all a user's group memberships. The groups are separated into categories based on the group's prefix. Groups with no prefix are Role Groups. Groups with the ACL_ prefix are access control groups. Groups with the GPO_ prefix control deployment of Group Policy. Groups with the APP_ prefix control deployment of an application. Groups with the VDI_ prefix control access to a specific virtual desktop pool. .NOTES Author : Brian Reich < .LINK #> # Imports the Get-ADPrincipalGroupMembershipRecursive # See Import-Module GroupManagement\Get-ADPrincipalGroupMembershipRecursive # Ask the user to enter a username $user = Get-ADUser -Identity (Read-Host "Username") # Get the user's group memberships $groups = Get-ADPrincipalGroupMembershipRecursive -dsn $user.DistinguishedName # Split groups based on prefix $acls = $groups | Where-Object { $_.Name -like "ACL_*" } $gpos = $groups | Where-Object { $_.Name -like "GPO_*" } $apps = $groups | Where-Object { $_.Name -like "APP_*" } $vdis = $groups | Where-Object { $_.Name -like "VDI_*" } # Role groups are the groups that didn't fit the other criteria $roles = $groups | Where-Object { $_ -notin $acls -and $_ -notin $gpos -and $_ -notin $apps -and $_ -notin $vdis } <# .SYNOPSIS Returns an HTML fragment listing all of the user's Role Groups. .DESCRIPTION Returns an HTML fragment listing all of the user's Role Groups. Roles Groups are displays with the name of the group and the group's description. .PARAMETER $roles An array of Role Groups .RETURNS Returns a string containing the HTML fragment. #> function Get-RoleHtml( $roles ) { $html = "<h2>Roles</h2>" $html += "<p>Role groups represent the user's job position and " $html += "responsibilities within the organization.</p>" $html += $roles | Select-Object -Property Name,Description | Sort-Object -Property Name | ConvertTo-Html -Fragment return $html } <# .SYNOPSIS Returns an HTML fragment listing all of the user's ACL Groups. .DESCRIPTION Returns an HTML fragment listing all of the user's ACL Groups. ACL Groups are named ACL_Resource Name_Permission. The name of the group is displayed alongside the Resource it controls access to and the permission it provides. .PARAMETER $acls An array of ACL Groups .RETURNS Returns a string containing the HTML fragment. #> function Get-AclHtml( $acls ) { $html = "<h2>Access Control Groups</h2>" $html += "<p>Access Control Groups (groups whose name begins with 'ACL_') are " $html += "groups that control access rights to resources.</p>" $html += $acls | Select-Object -Property ` Name, @{Name="Resource"; Expression = {$_.Name.split("_")[1]}}, @{Name="Permission"; Expression = {$_.Name.split("_")[2]}} | Sort-Object -Property Name | ConvertTo-Html -Fragment return $html } <# .SYNOPSIS Returns an HTML fragment listing all of the user's GPO Groups. .DESCRIPTION Returns an HTML fragment listing all of the user's GPO Groups. GPO Groups are displays with the name of the group and the name of the GPO it controls. .PARAMETER $roles An array of GPO groups. .RETURNS Returns a string containing the HTML fragment. #> function Get-GpoHtml( $gpos ) { $html = "<h2>Group Policy Groups</h2>" $html += "<p>Group Policy Groups (those that start with 'GPO_') are groups " $html += "that control Group Policy assignments.</p>" $html += $gpos | Select-Object -Property ` Name, @{Name="Policy Name"; Expression = {$_.Name.split("_")[1]}} | Sort-Object -Property Name | ConvertTo-Html -Fragment return $html } <# .SYNOPSIS Returns an HTML fragment listing all of the user's App Groups. .DESCRIPTION Returns an HTML fragment listing all of the user's App Groups. App Groups are displays with the name of the group alongside the Application that it controls access to. .PARAMETER $roles An array of App Groups .RETURNS Returns a string containing the HTML fragment. #> function Get-AppHtml( $apps ) { $html = "<h2>Application Groups</h2>" $html += "<p>Application Groups (those that start with 'APP_') are groups " $html += "that control deployment of specific applications. Applications may " $html += "be deployed by Group Policy, ThinApp, or other means.</p>" $html += $apps | Select-Object -Property ` Name, @{Name="Application"; Expression = {$_.Name.split("_")[1]}} | Sort-Object -Property Name | ConvertTo-Html -Fragment return $html } <# .SYNOPSIS Returns an HTML fragment listing all of the user's VDI Groups. .DESCRIPTION Returns an HTML fragment listing all of the user's VDI Groups. VDI Groups are displays with the name of the group alongside the name of the VDI pool they control access to. .PARAMETER $roles An array of VDI Groups .RETURNS Returns a string containing the HTML fragment. #> function Get-VdiHtml( $vdis ) { $html = "<h2>VDI Groups</h2>" $html += "<p>VDI Groups (those that start with 'VDI_') are groups that " $html += "that assign users to virtual desktop pools.</p>" $html += $vdis | Select-Object -Property Name,Description | Sort-Object -Property Name | ConvertTo-Html -Fragment return $html } # Get the account name, which we'll use to name the HTML File. $username = $user.SamAccountName $file = $HOME + $username + "_group_memberships.html" #The following lines generate HTML. We're generating some pretty simple markup #which contains a stylesheet to make the whole thing look decent on-screen. $html = '<html>' $html += "<head><title>RBAC Report for $username</title>" $html += "<style>" $html += " body { width: 800px; margin: 1em auto; font-family: 'Proxima Nova Regular', 'Helvetica Neue', Calibri, 'Droid Sans', Helvetica, Arial, sans-serif; font-size: 16px; font-style: normal; font-weight: normal; } h1, h2, h3, h4, h5, h6, p { border-radius: 5px; padding: 10px 20px; } h1 { background: #333; color: #f0f0f0; } h2 { background: #666; color: #f0f0f0; } p { background: #eee; color: #333 } table th { text-align: left; background: eee }" $html += "</style>" $html += "</head>" $html += '<body>'; $html += "<h1>RBAC Report for $username</h1>" $html += "<p>This report provides a list of all $username's group memberships," $html += "including all of those inherited from other groups. Groups are " $html += "organized based on their prefix. Groups with no prefix are assumed to" $html += "be Role Groups.</p>" $html += Get-RoleHtml $roles $html += Get-AclHtml $acls $html += Get-GpoHtml $gpos $html += Get-AppHtml $apps $html += Get-VdiHtml $vdis # Output the HTML to the file $HOME\$username_group_memberships.html $html | Out-File "$file" # Open the HTML file Invoke-Expression "$file"