Friday, May 17, 2013

OpenVPN on CentOS Running on Hyper-V Using Windows PKI

I have a knack for titles eh? (Just smile and nod) I've been very impressed by the scalability demonstrated by OpenVPN in applications such as proXPN. Because of this I decided to implement OpenVPN on my favorite Hyper-V friendly distro, CentOS (6.4) and utilize a Windows PKI infrastructure for issuing certificates. Wanna do that? Let's:


Assumptions

  • You're familiar with the basics of PKI and how to process certificate requests. For more information on how to setup Windows PKI, see my article here.
  • You're familiar with the basics of Linux administration including editing config files, etc. 
  • You'll use sudo where applicable. I don't put it on command references to keep them cleaner. 

VM Creation

Create a VM with the following minimal virtual hardware: 
  • 384MB RAM
  • 1 Virtual Proc
  • 10GB HD
  • 2 NICs, (native) one either public/DMZ and one on your internal network (or inside the same DMZ if you desire)
It's possible to setup OpenVPN with 1 NIC, but in most configurations it's less secure and I won't be covering it here.

CentOS Setup

  1. Download from here; minimal is all you'll need.
  2. Insert the ISO to the virtual optical drive on the VM and start it up.
  3. Install CentOS to the VM with desired settings; no special configuration is necessary.
  4. Setup the NICs with static IP addresses. ("/etc/sysconfig/network-scripts/ifcfg-eth0" and "eth1", more instructions here) The following combinations for connectivity are possible: External/Internal, DMZ/Internal, External/DMZ, DMZ/DMZ. While different options have different pros and cons I'm not going to say what you should use because your circumstances will dictate your direction. I am using DMZ/Internal.
  5. Enable ipv4 forwarding by editing "/etc/sysctl.conf" and setting the following value
    net.ipv4.ip_forward = 1
    (It's there and 0 by default)
  6. Enable the EPEL so we can grab OpenVPN from it. Ensure you get the correct version, it was 6.8 as of this writing.
    rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
  7. Make the directory for the keys:(We'll copy keys into this dir before install)
    mkdir /etc/openvpn/keys  
  8. Make sure SSH is installed; if not:
    yum -y install openssh-server
  9. Perform any other tasks you should find applicable to a OpenVPN server such as configuring auto-update (yum install vixie-cron -y needed on CentOS 5 minimal install) or installing any other supporting apps you should want. Just remember that any application you add is a potential security liability.

Create Certificate Templates


I won't be covering the basics of setting up certificate templates; for that see my article.We'll just cover the specifics of this implementation here.

Server Template

  1. Open the certificate template manager for you enterprise PKI, and duplicate the Computer template. 
  2. When prompted, select the "Windows 2003 Server, Enterprise Edition" and hit "OK". (The version of the OS determines the template version) 
  3. Change the template display and name to something sufficiently descriptive such as "Computer (CompanyName OpenVPN Server)"
  4. Up the Validity period should you desire. 
  5. On the "Request Handling" tab set the private key to be exportable. (We're putting this on a Linux server afterall)


  6. On the "Subject Name" tab change the option to "Supply in the request"
  7. On the "Issuance Requirements" tab check that the template requires CA certificate manager approval should you desire. 
  8. Change to the "Extensions" tab, select "Application Policies" and click "Edit". Change it so that the "Server Authentication" is the only listed policy. Do not mark the extension critical. 
  9. Everything else can be left the same unless you should want to change the permissions under security. 

Client Template

Repeat the steps for the Server template except change the name in 3: to a client name and 8: to "Client Authentication".

After creating your templates publish them to your issuing CA. Again, see my article for instructions.

Enroll For Server Certificate

Since this step is virtually the same for the client I'll be redirecting you here for that step as well. There are a few modifications listed to these steps to accommodate that; don't pay any attention to "For Clients:" on the first go-around.

  1. Open the MMC (mmc.exe) and add the certificates snap-in for the local computer.  This can be done on any machine since we'll be exporting it.
  2. Enroll in the server certificate template we created earlier. We need to specify a few options, so click "More information is required to enroll for this certificate.  Click here to configure settings." For Clients: use the client template
  3. On the subject tab under Subject name, set the "common name" to the FQDN of the OpenVPN server. If you're using split DNS, make sure you set this to the external FQDN. For Clients: use your domain FQDN and set the OU to something consistent for all certs so that you can use the tls-verify option down the road should you choose. I use "vpn.company.com ClientCert"


  4. On the "General" tab set the friendly name and the description to whatever you desire. I copy the common name and append "OpenVPN server"
  5. On the "Extensions" tab change "Key Usage" to include only "Key agreement" and "Key encipherment". "Make these key usages critical" can be checked. Based on the template it should already have "Extended Key Usage" set to "Server Authentication". For Clients: Use "Client Authentication" rather than server authentication.


  6. Under "Basic Constraints" click "Enable this extension" and "Make the basic constraints extension critical"
  7. Under the "Private Key" tab select "Allow the private key to be archived" should you desire.
  8. Click "OK" and then "Enroll". After the enrollment finishes you will need to click "Finish"
  9. Go to your CA and complete the enrollment process, then export the public key and import it back on the requesting computer to complete the certificate request process. 

Export and Split the Certificate

Like the section above, this will be used for the client as well. See For Clients: for that.
  1. Using the MMC or command line/powershell, export the newly created certificate WITH the private key to a pkcs12 format. Do not include all certificates in the certification path. Make sure you remember the password.
  2. Use OpenSSL (you'll need to download/install from here) to convert the pfx file to standard text, then cut and split the file into a cert file and a key file. I'd walk you through this, but how about I give you a Powershell script to do it instead. :)  Make sure to set the variables at the top of the file to what suits you. If you don't want to use powershell, just follow the comments and the commands to convert and split the file. For Clients: You may want to change the variable definitions at the top of the file to reference client file names.

#set the output files, working file, and password for the PFX
$inputFile="c:\temp\server.pfx" 
$outputPublicKey="c:\temp\serverCert.cer"
$outputPrivateKey="c:\temp\serverCert.key"
$tempFile="c:\temp\temp.txt"
$password="password"


#Set the location to the Openssl.exe file
$openSSLLoc="C:\Program Files\OpenSSL-Win32\bin"


#Execute OpenSSL to convert the PFX file to standard text
& $openSSLLoc\OpenSSL.exe pkcs12 -in $inputFile -nodes -out $tempFile -passin pass:$password


#Now we need to find where the key and cert start and end. 
#For non-script users the point here is that we chop this one text file into two files,
# one the public key and one the private key. The two of those are denoted by the patterns listed below. 
$beginKey=get-content $tempFile |select-string -Pattern "-----BEGIN PRIVATE KEY-----"
$beginKey=$beginKey.LineNumber
$endKey=get-content $tempFile |select-string -Pattern "-----END PRIVATE KEY-----"
$endKey=$endKey.LineNumber
$beginCert=get-content $tempFile |select-string -Pattern "-----BEGIN CERTIFICATE-----"
$beginCert=$beginCert.LineNumber
$endCert=get-content $tempFile |select-string -Pattern "-----END CERTIFICATE-----"
$endCert=$endCert.LineNumber
$length=Get-Content $tempFile |Measure-Object
$length=$length.Count


$key=Get-Content $tempFile |Select-String "-----BEGIN PRIVATE KEY-----" -Context 0,($endKey-$beginKey)
$cert=Get-Content $tempFile |Select-String "-----BEGIN CERTIFICATE-----" -Context 0,($endCert-$beginCert)


#Write out the files. Make sure they're ASCII encoded!
$key.line| Out-File $outputPrivateKey -Encoding ASCII
$key.Context.DisplayPostContext | Out-File $outputPrivateKey -Encoding ASCII -Append
$cert.line| Out-File $outputPublicKey -Encoding ASCII
$cert.Context.DisplayPostContext | Out-File $outputPublicKey -Encoding ASCII -Append


#Get rid of the temporary working file. Not needed for those not using the script. 
Remove-Item $tempFile -Force

Even if you can't run that hopefully you can decipher what's going on. Let me know if you would like any help.



Export The CA Certs and Copy to Server

For Clients: You can use the CA cert you created earlier for the server on the client as well. Just include it in the keys directory with the other certs. 
  1. Using the MMC or cmdline/powershell, export the root and (if applicable) intermediate certs to base-64 encoded x.509. For specifics, see here.
  2. If using 2 or more tier PKI: You can only specify one CA cert so if you have more than one CA in your chain you need to "stack" them. To do so, pipe both into one file with the simple command from a command prompt: "type RootCA.cer IntermediateCA.cer > CAs.cer" where rootca.cer and intermediateca.cer are the exported certificates. Substitute cat for type if you're doing this on a Linux platform. This will join any listed certs into one chain for use with OpenVPN. 
  3. (For Clients: This step is not necessary.) Generate Diffe-Helman by executing
    openssl genpkey -genparam -algorithm DH -out dh.pem 1024
    This can be done on either the Windows machine you are on or directly on the OpenVPN server. Either way, just make sure you copy the dh.pem to /etc/openvpn/keys/ on the OpenVPN server. (see step below)
  4. Copy the server private key, public key (both created earlier) and (stacked) ca public key to "/etc/openvpn/keys" on the OpenVPN server. These keys will be referred to as server.cer, server.key, and ca.cer in the future. In order to do security correctly, make sure permissions are cranked down on these files as much as possible, especially the server.key file. (private key) On Windows I use pscp.exe which ships with Putty. For Clients: Just copy the certs/keys into a temp directory for now, we'll move them to the final location later.

Install/Configure OpenVPN on Server

  1. Make sure you enabled EPEL above and then execute the following to to install OpenVPN and LZO:
    yum install openvpn lzo -y
  2. Copy the sample configs as a starting point:
    cp /usr/share/doc/openvpn-2.2.2/server.conf /etc/openvpn/
    (Make sure the version number in the /usr/share/doc path hasn't changed since I wrote this) 

  3. Edit /etc/openvpn/server.conf and pay attention to the following lines: 
    1. Set the ipaddress to the address of the NIC you intend to bind to. This should be the NIC closest to the internet, be it an external or DMZ NIC. 
      local 10.1.0.1
    2. Set the port to have OpenVPN listen on. 1194 is default and a firewall rule below assumes that, so be aware if you change it.
      port 1194
    3. Protocol, UDP vs. TCP. UDP is faster and the client machine will already be managing TCP retrans should they be needed. 
      proto UDP
    4. A bit on the the difference between tun and tap: tun is a layer 3 IP routing based solution, whereas tap is a level 2 based solution. Tap can shoot non-routable protocols over the tunnel, so if you're going to play Descent II this is the one you want. The problem (or not) with using tap for standard client connectivity is besides being more complex to setup it also routes broadcast traffic. This won't scale well. Generally tap is used for site-to-site connections. If you want to use tap, you'll need to setup Ethernet bridging. This guide assumes dev tun.
      dev tun
    5. Specify the keys we copied over earlier:
      ca /etc/openvpn/keys/ca.cer
      cert /etc/openvpn/keys/server.cer
      key /etc/openvpn/keys/server.key
    6. Specify Diffe-Helman copied over earlier:
      dh /etc/openvpn/keys/dh.pem
    7. Set the subnet you want to route clients to. This makes that network route through the OpenVPN connection. Note that if your IP range is the same on the close end you'll have problems. Feel free to add multiple lines for multiple subnets.
      push "route 192.168.1.0 255.255.255.0"
    8. Set the internal DNS servers you want to push to the clients to facilitate looking up servers on the other side of the VPN. Add one line for each DNS server you would like in the search order of the client. 
      push "dhcp-option DNS 192.168.1.30"
    9. If you uncomment client-to-client OpenVPN will allow clients to talk to each other. You'll also need to config firewall rules appropriately should you wish to do this.
      client-to-client
    10. Set the maximum number of simultaneous clients.
      max-clients 100
    11. Uncomment the following lines to increase security on 'nix systems by lowering privilege level after program launch.
      user nobody
      group nobody
  4. Set OpenVPN to start on boot:
    chkconfig openvpn on
  5. Configure the IPTables firewall; assuming eth0 is your internal NIC and eth1 is your external NIC. Change the listed NICs in each rule if that assumption is not correct!
    1. Edit the IPTables rule by editing /etc/sysconfig/iptables . There are other ways to accomplish IPTables editing, but since I make few changes I would rather just work directly on the config.
    2. First, change your SSH rule to allow port 22 on the internal NIC only; you should already have a rule listing --dport 22. Find it and change it to:
      -A INPUT -i eth0 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT"
    3. Allow VPN connections on the external interface. If you have changed from the default port make sure to change the port 1194 reference listed here: " -A INPUT -i eth1 -m state --state NEW -m udp -p udp --dport 1194 -j ACCEPT"
    4. Setup forwarding rules for this network:
      -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT"
      -A FORWARD -s 10.8.0.0/24 -j ACCEPT
    5. Make sure the rules from 2 and 3 are listed before the -A INPUT -j REJECT and the rules from 4 are listed before the -A FORWARD -j REJECT default rejection rules or they'll be ignored. 
  6. Reboot the box and ensure that OpenVPN starts successfully. Logs will be written to /var/log/messages. If you have problems and need to troubleshoot you can up the "verb" value in /etc/openvpn/server.conf.
Alternatively, you may see rules listed such as iptables -A INPUT -i tun0 -j ACCEPT and iptables -A FORWARD -i tun0 -j ACCEPT listed elsewhere; these would work in lieu of the 10.8.0.0 rule, but there are security tradeoffs. Feel free to try either if it suits you. For more information about iptables, see this.

Enroll for Client Certificate


For this section you can follow the same instructions as the section "Enroll for Server Ceritificate" with the modifications listed within those points. (Mods in point 2, 3, and 5)


After doing this refer to the Export and Split the Certificate section and use that logic to do the same task to the client cert as well.

Export the CA Certs and Copy to Client

You can use the CA cert you created earlier for the server on the client as well. Just include it in the keys directory with the other certs.

Install/Configure OpenVPN on Windows Clients

  1. Download and install from here
  2. In the install directory, copy the client.ovpn file from the sample-config folder to the config folder for a starting point.
  3. Copy the keys we created earlier to a folder on the client; I use (OpenVPN Install Directory)\Keys.
  4. Edit ".\config\client.ovpn" and pay attention to the following lines: 
    1. Again, we're going to cover tun here. More work will be necessary if you want to do tap. See the server section for an explanation of what these options are. 
      dev tun
    2. Enter the external FQDN and port for your OpenVPN server.
      remote vpn.company.com 1194
    3. List your certs copied over earlier. Make sure you set the directory correctly and protect that directory relative to the fact that a private key resides within it. On windows you need to use double backslashes because "\" is an escape character. 
      ca C:\\InstallDirectory\\Keys\\ca.cer
      cert C:\\InstallDirectory\\Keys\\clientcert.cer
      key C:\\InstallDirectory\\Keys\\clientcert.key
    4. Remark out ns-cert-type server and add remote-cert-tls server in its place. ns-cert-type is deprecated and the template wasn't updated. See here for more info.
      # ns-cert-type server
      remote-cert-tls server
  5. After saving the file, launch OpenVPN GUI as Administrator.


  6. Connect and enjoy!

Closing

Obviously given the scope of this article there is substantially more depth one could go into; if you have any questions please hit me up in the comments. I'm sure you can see the possibilities of this combination as there is much more automation that could be done. Thus far I've been very impressed by the performance of OpenVPN and I look forward to scaling it out in the future.

References/Additional Reading

Saturday, May 4, 2013

Using a Raspberry Pi as a Thin Client for RDP/RemoteFX/VMWare View or Citrix

There is a cool project by Gibbio at blogger that uses Debian Linux as a base turn the Raspberry Pi into a thin client that works with RDP, VMWare View, Citrix, OpenNX, and Spice.  After imaging your SD card you can plug and go. I've tested it with RDP complete with RemoteFX, and it works well with a few caveats which I'll note below.


Requirements

  • Raspberry Pi Rev B with a network connection, monitor, kb, etc.
  • A SD card at least 2GB in size. The faster the better. 

Let's Set it Up

  1. Insert the SD card to a workstation to image it. On that workstation: 
  2. Download the ISO. Links here.
  3. Unpack the ISO to a temporary directory. 
  4. If you're on Linux, skip to step 6. Download DD for windows from here.
  5. Unpack DD to a working directory and make note of where it is; we'll be using it in a moment. 
  6. Insert your SD card and wipe out all partitions on it. I'll assume you know how for Linux; in Windows use Diskpart: Diskpart (Enter), List Disk (Enter), Select Disk X (Enter), List Partition (Enter), Select Partition X (Enter), Delete Partition (Enter). Repeat list, select, delete for each partition on the SD card then Exit (Enter). Make sure you don't execute this sequence on any other drives or you will loose all your data!
  7. Image the drive using DD: dd bs=1M if=c:\temp\RPi-TC_ARMv6j_r1.img od=d: WHERE: c:\temp\RPi... = the image location and od=d: references the location of the SD card. Update: If you have issues with dd, give Roadkill's disk imager a try. 
  8. Remove the SD card (properly) and insert it into the Raspberry Pi
  9. Start it the Pi. 
 

Using RDP


Once the Pi Boots (Note that boot animation) you'll see a bunch of icons on the desktop. To connect to an RDP session, do the following:
  1. Double click on X2Go Client 
  2. Click the "New Session" button in the upper left corner. 
  3. Name the session, enter the host (make sure the host name corresponds to the cert CN)
  4. Enter your login as domain\username
  5. Change "Session Type" to "Connect to Windows terminal server" and check the "Direct RDP Connection"
  6. Click the "Settings" tab and change the Display to the desired resolution. (Fullscreen works) Note that I haven't been able to get xfreerdp to work yet but rdesktop is working. 
  7. Click "OK"
  8. Click the newly created session and then enter in your password. 
  9. Enjoy your RDP session! If you selected Fullscreen, note that the kb combo to go back to a window is CTRL+ALT+ENTER

RDP Notes: 


  • As of now it seems that NLA is not supported, though I'm looking into it. To disable NLA uncheck the box labled "Allow connections only from computers running Remote Desktop with Network Level Authentication" in the "Remote" tab of the advanced system properties dialog of the machine you're connecting to.
  • RemoteFX works, but it is actually slower than standard RDP. I'm looking into this too.
  • Audio redirection, clipboard, multitouch, and USB passthrough don't seem to work. Guess what, I'm looking into that. 

Misc Notes:


  • I haven't tried the other clients yet, though I can report success using the VMWare view client direct from a friend. 
  • The Raspberry Pi has issues with some mice. If your mouse seems unresponsive try a different model. 
  • The newest build uses a tweaked kernel. Though I haven't needed to, you can switch back to the standard Raspberry Pi kernel by changing the line kernel=kernel.img to kernel=kernel-std.img in /boot/config.txt and rebooting. Debian comes with Vi and Nano that you can use to modify it.


Overall this is a interesting project that has been alot of fun to play around with. As always if you have any questions or comments throw them in the comments section!

Update: I'm getting quite a few hits on this one and I just want to underscore before it is proposed in production at your company that it's not quite ready for prime time yet due to the issues listed above. I look forward to helping drive it there though; I intend on updating as I drive towards tweaking RDP to be perform better.

And more importantly, there is a new build posted here! Note Remmina isn't working yet but Gibbio is working on it.

Update 6/27:  Gibbio has posted a new build that looks quite interesting. Among other things he has provided the XFCE desktop environment.

Update 7/1: The newest build works fine with xfreerdp which seems to perform a bit better than rdesktop. To use it, either launch from a terminal or create a shortcut with the following syntax:

xfreerdp /v:server.domain.ext /u:UserName /p:Password /d:DOMAIN /f /cert-ignore

Where: /v: is the target machine, /u: is the username to use, /p:is that user's password, /d:is the domain in which the user resides, /f is for fullscreen mode (if desired) and /cert-ignore is to ignore an untrusted cert, which is likely if you're using the default self-signed certs. For the rest of the options, see the wiki page.

Links: Olivier Muret: French Raspberry Pi RDP Writeup

Thanks for reading!

Thursday, April 18, 2013

What is RemoteFX on Windows 2012 Hyper-V and Deploying a Win 8 Virtual Desktop


Updated 2/3/2017 for Windows Server 2016 and Windows 10!

RemoteFX is Microsoft's advanced desktop RDP solution based on technology acquired from Calista Technologies. It allows for the following functionality above and beyond standard RDP:

This Article Written in RemoteFX. It's... amazing?

Server 2008r2 Based:

  • Virtualized 3d GPU: you can split a single GPU into multiple virtual GPUs for VDI VMs. This allows for 3d accelerated apps to run in the RDP session.
  • RemoteFX Codec: A more advanced version of the RDP compression scheme that allows for more efficient streaming of both video and audio. While it works fine for text, you can always get groceries in a Yugo
  • USB Device redirection: Now you can finally use your USB Scan Toaster on your remote desktop!

Server 2012 Additions: 

  • Multi-Touch: Multi-Touch support through RDP. Needs a compatible client! (RDP 8.0, etc.)
  • Adaptive Graphics: Different compression codecs depending on the content (dynamically on a given screen) among other enhancements. 
  • Media Redirection API: Used primarily to facilitate rendering audio and video of VOIP clients local to the client. (Only Lync right now) 
  • WAN Enhancements: Support UDP; tweaks to lower bandwidth requirements for both remote and WiFi scenarios.  
  • GPU Changes: Support either a software-emulated GPU or a real hardware GPU. DX11 support added. 

Server 2016 Additions: 

  • OpenGL/CL Support: Now supports hardware-accelerated OpenGL (^4.4) and CL (^1.1)... CAD/Lightwave/Photoshop users rejoice!
  • vRAM Assignment Enhancements: Decouple vRAM amount from monitors and resolution, increased dedicated vRAM per host capability to 1GB from 256MB. 
  • Better Performance: More FPS=smoother performance. Noticeable in my case, videos now watchable through RemoteFX without the audio issues that sometimes accompanied the prior version. 
  • Generation 2 VM Support: Allows for use of the new VM platform and all the associated features
  • ... and more, see the reference links at the bottom of this article.

Hardware Requirements:

Full MSFT Article , RDS Blog reqs link
  • The standard HyperV Requirements
  • SLAT Enabled CPU; EPT on Intel, NPT/RVI on AMD
  • DX11 (WDDM 1.2) Compatible GPU; All made for purpose DX11 GPUs from NVIDIA and AMD work, and for testing I've been using a consumer grade NVIDIA 650 in my lab without issue.

Software Requirements:

  • Server: Server 2012/2016 (core preferred, see next section)
  • Client: Windows 8/10 Enterprise, and Enterprise only. Pro won't work. Additionally, I found that re-keying a Win8 Pro to Enterprise install will not work either. While it will report that all is well, and it will install the RemoteFX graphics adapter, when you try to connect it will report "error during licensing protocol" in the final stage of connection negotiation.

Setup

Assumptions

  • You have a fully functional HyperV Host that meets the hardware requirements listed above.
  • You're using server core. You can do this on standard, but you should be using core for performance and patching (or lack thereof) reasons. The commands I relay assume core. 

Prepare the Host

  1. Patch it up; make sure you're fully up to date. 
  2. Install the graphics drivers for your GPU on the host. This may pose some issues on server core, but fortunately I've got a guide for NVIDIA GPUs to help. The procedure is most likely similar for AMD GPUs. Bounce the host after driver install regardless of if it tells you to do so or not. 
  3. Install the Remote Desktop Virtualization Host feature. Either use the server manager remotely to do so, or execute the following directly on the Hyper-V host: "Install-WindowsFeature –name RDS-Virtualization -source j:\sources\sxs" where J: is the DVD-ROM or image with the 2012 install bits. You can use other sources if desired, for more information see this post.
  4. Reboot the server. 
  5. Enable the Adapter for use with the Hyper-V host by opening the Hyper-V management console, right click the server->Hyper-V Settings....
  6. Select "Physical GPUs"
  7. If configured correctly, you should see your adapter listed. Check the "Use this GPU with RemoteFX" box and click "OK". 


Alternatively for steps 5 through 7 you can use the following powershell cmdlets: 

Setup The VM


  1. As noted above, only Win 8 (7 if you want, update + 10) Enterprise will work. Use a template or build from scratch. There are no special needs at build time. 
  2. Enable RDP on the Win8 VM
  3. Install the VM Integration services & shut down the VM
  4. Add a 3D Adapter to the VM by opening the Hyper-V management console, right click the VM->Settings
  5. Under "Add Hardware" select "RemoteFX 3D Video Adapter", click "Add", select the max resolution and # of monitors you plan on using via RDP, and select "OK"
  6. Start up the VM. You now will need to logon via RDP, as the Hyper-V remoting will be locked out. The machine should notify of new hardware being installed that requires a reboot. If it does not, re-install the integration services. Reboot the VM. 
  7. To ensure the VM is operating with the adapter open device manager and look under "Display Adapters". You should see "Microsoft RemoteFX Graphics Device - WDDM"

Alternative Powershell Command:


Configuration

Note that unlike the previous version of RDP, you don't need to select your connection speed on RDS 8.0. So that said, the only configuration you really need in 8.0 can be done via GPO.

Adjust Settings via GPO


Primer: Modifying GPO settings.

Microsoft makes some RemoteFX settings "Tweakable" via GPO. These settings can be found here:

Computer Configuration->Policies->Administrative Templates->Windows Components->Remote Desktop Services->
  Remote Desktop Connection Client->RemoteFX USB Device Redirection
     -Allow RDP redirection of other supported RemoteFX USB devices from this computer
  Remote Desktop Session Host->Remote Session Environment
     -Configure compression for RemoteFX data
     -Configure image quality for RemoteFX Adaptive Graphics
     -Enable RemoteFX encoding for RemoteFX clients designed for WindowServer 2008r2 SP1
     -Configure RemoteFX Adaptive Graphics (Tweak if using only on a LAN)
     RemoteFX for Windows Server 2008 R2
        -Configure RemoteFX (this just allows for disabling RemoteFX via GPO)
        -Optimize visual experience when using RemoteFX (Tweak this one if using only on a LAN)
        -Optimize visual experience for Remote Desktop Service Sessions (Change to "Text" if you setup RemoteFX so Bobby can do his spreadsheets. Why did you setup RemoteFX again?)

Troubleshooting

 

Sound isn't working on the youtubes! : Seems like flash doesn't work correctly with audio redirection. HTML5 works though! Switch to the HTML 5 beta by going here.

Seems Slow: Make sure your color depth is set to 32bit. Based on my testing it seems that the codec favors full 32 bit color.

FAQ (By me of myself @ least, and by frequently I mean once until I answered them)

  • Q: Should I want to, what can I use to benchmark this thing?  A: PassMark works great; I must admit that watching DX11 accelerated 3d benchmarks through an RDP session is kind of cool. :) 
  • Q: Does RemoteFX work through an RDP gateway? What versions? A: Yup, it works through a gateway running on 2008, 2008R2, or 2012.
  • Q: Is GPU performance good enough to run intensive applications or GPU computation tasks? A: In most cases, no. The RemoteFX solution virtualizes the GPU and exposes it as a Microsoft "GPU", essentially translating all requests through a proxy driver. While that solution allows for splitting the GPU across multiple VMs, it also makes for reduced functionality/performance of the card since the OS isn't exposed directly to the native driver. Additionally, framerate is limited by the RDP protocol itself.
  • Q: Does RemoteFX support accelerated OpenGL? A: No, it is done in software.
  • Q: Can RemoteFX do GPU direct passthrough? A: No, only Xenserver Enterprise or higher can do that right now. 
  • Q: How do I know how much memory on my GPU is being used by my VMs? A: You can find the answer on the Hyper-V/Physical GPUs page for each server. The memory stats are listed right under GPU Details->Summary. 
  • Q: Can I deploy RemoteFX in a VDI environment? A: Yeah, though note your max simultaneous RemoteFX sessions will be limited by available GPU memory. (See above post) Fortunately for you, I have a guide on how to setup Hyper-V based VDI!
  • Q: Will this VMWare tweak help up the framerate on Hyper-V/RemoteFX? A: In my testing, it did not. I suspect this is because the HyperV NICs probably don't support interrupt coalescing. It looks like one could enable interrupt coalescing on the host with the following instructions and perhaps that would change the answer depending on how the packets are handled from the RemoteFX machine. 

References

Microsoft: What is RemoteFX?
RDS Blog: RemoteFX Features for Windows 8 and 2012
Technet: Frequently Asked Questions and Troubleshooting Tips
RDS Blog: Your desktop will be a rich DX11-based experience, and your virtual GPU should be too
My Crazy Adventures with RemoteFX, Part 1

2016 Updates

Enterprise Mobility and Security Blog: RemoteFX vGPU Updates in Windows Server Next
Technet: Experience guide for Enabling OpenGL Support for vGPU in Server 2016

Questions/Concerns? Contact me or leave a comment!

Sunday, April 14, 2013

Azure Ate My VM! Or: How to Get Your VM Back

If for any reason your Azure account is suspended (exceeding 90 day compute per month, exceeding monthly spending limit) your IaaS VMs will be deleted. It would appear as if this is normal. Fortunately your disks associated with your VM are not deleted, so we can recover. Hopefully, this is something Microsoft addresses in the near future. For now, let's fix it!

Oh No! Peaches02 is missing!














 

Fix It

  1. First we'll need to reclaim our DNS address. To do so, click on "Cloud Services" and delete the cloud service that is squatting on the name of your old VM you want to recreate.
  2. Now we will recreate the VM using our pre-existing disk. Fortunately, this disk will present itself in the "gallery". Click "New" on the lower left. 
  3. Select "Compute"->"Virtual Machine"->"From Gallery". You'll see your disk in there. Select it.
  4. Set the name to the same as it was before. The size though, can be changed if you like. (For example, I took mine from medium to small)
  5. Set the DNS name to the same as it was before, and select the region as you desire. 
  6. Associate with an availability set if you like and fire it up!


Notes: 


Your RDP port will probably change because of the way MSFT does Natting for the virtual IPs. I was honored to have 3389 on my vm for the first go-around, but when I set it up again MSFT had already given that port back out. It will automatically create a new NAT (endpoint) mapping, so to determine the new port navigate to virtual machines->(VM)->endpoints and take note of the new RemoteDesktop port.

All your endpoints will be deleted. This can be a real pain if you have alot, but fortunately I have a solution for that.

If there are any questions, let me know. Happy clouding!

Monday, April 1, 2013

CentOS ready for Hyper-V 2012 NICs

CentOS 6.4 was released on March 13th, and per the release notes it now ships with the Hyper-V components. Now the native network adapters work right from the base install, even on the minimal distribution. All that need be done is enable the adapters after install. To do so, do the following:


  • Log in as root
  • Navigate to /etc/sysconfig/network-scripts
  • Each NIC config is located in this directory. The configs are named ifcfg-ethX where X is a number starting with 0 and incrementing by 1 for each adapter, i.e. ifcfg-eth0, ifcfg-eth1. Edit each by typing "vi ifcfg-eth0"
  • At the least, you will need to edit the file to change ONBOOT=no to ONBOOT=yes by using the following keys:
    • INSERT
    • (make your modifications)
    • ESC
    • :w
    • :q
  • Reboot
If you want to make further modifications such as static IP, etc, then refer to this guide. Feel free to post questions!

Update 12/8/2013: 

When updating/rebuilding my Hyper-V hosts from 2012 to 2012 r2 the MAC addresses seem to have changed. (Perhaps a good reason to set static MAC addresses on these VMs) You can see if your install exhibits this behavior by examining the following:
  •  cat /var/log/dmesg | grep -I "net"
and looking for:

hv_netvsc vmbus_0_13: Device MAC XX:XX:XX
and
udev: renamed network interface ethX to ethX

To fix it, edit the ifcfg-ethX file as noted above and change the HWADDR entry to match the new MAC, and then remove the /etc/udev/rules.d/70-persistent-net.rules file and reboot.

Tuesday, March 26, 2013

Azure Powershell Setup and IaaS Mass Endpoint Creation

This is a two-purpose article, one general and one specific. Generally, we'll configure powershell to manage your Azure subscription, and then specifically how to configure many endpoints at once.  

When I was working on my article Experiment: Application Server on Windows Azure I noted one peculiar issue. Setting up Windows Azure Endpoints is easy to do one at a time, but doing en masse is seemingly complicated. Fortunately, there is a relatively easy workaround using powershell Azure management.

Setup Powershell to Manipulate Azure

 

Download Azure Powershell

 

You can get the Powershell management plugins from this link. The main link uses the Web Platform Installer and several non-critical items are marked as pre-requsites. If you use WPI it will download and install those as well. Note that despite this assertion, the only thing that is really needed for PowerShell is the stuff that is (by default on a 64 bit OS) installed to "C:\Program Files(x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\*.*" after installing using the WPI. For that reason, I actually put this folder in my Skydrive; the whole thing is only 8.55MB, and you can load it directly without "Installing"(see below).

Setup Powershell Management

  1. Start Powershell as administrator
  2. Ensure you have your execution policy set to RemoteSigned (or unrestricted) with the command "Set-ExecutionPolicy RemoteSigned"
  3. Import the module with the command "Import-Module {Path to Install}\Azure.psd1"
  4. Get your account settings by typing "Get-AzurePublishSettingsFile". This will open up a web browser and download your settings file. You may need to log-in. Note: Ensure you keep this file in a secure location or dispose of it after import.
  5. Import that file by executing "Import-AzurePublishSettingsFile {path to downloaded .publishsettings file}"
You should now be able to manipulate your VMs and other services using powershell. To test this, try something like "Get-AzureVM"

Note: If you have multiple subscriptions in one account you'll need to use the command "Select-AzureSubscription {Subscription Friendly Name}>"

Now you should be good to go. Now let's set up some endpoints!

Mass Endpoint Creation

 

Let's say you want to create TCP port openings from 27000 to 27080 on one or many VMs. (This script will work for both scenarios) Creating them by hand would take quite some time. To accomplish this quickly with powershell, do the following:

If you haven't already, perform steps 1 and 3 above.

Here's the script with line by line discussion below. Note that this could be conflated to fewer lines but I've broken it out to be easier to understand. 



$VMs=Get-AzureVM -ServiceName "VMName"
foreach ($VM in $VMs)
{
    $p=27000
    do
    {
        Get-AzureVM $VM.name|Add-AzureEndpoint -LocalPort $p -PublicPort $p -Name TCP$p -Protocol TCP | Update-AzureVM
        $p+=1
    }
    until ($p -gt 27080)
}

note: PleaseKING below has a great example of how to get this to execute faster by not committing on a per port basis; check it out! 

Discussion:
$VM=Get-AzureVM -ServiceName "VMName" : Get the VM objects. To return all VMs and apply endpoints to all your VMs, just omit the "-ServiceName "VMName" portion.

foreach ($VM in $VMs) : Let's process these ports for each VM. Works with just 1.

$p=27000 : Start port. Change this to the first port you want to forward in.

Get-AzureVM $VM.name|Add-AzureEndpoint -LocalPort $p -PublicPort $p -Name TCP_$p -Protocol TCP | Update-AzureVM : Feed in the VM object | Add endpoint where -localport $p is the port, -Name TCP_$p is the defined port name, feel free to change and -Protocol TCP for TCP. Change to UDP if necessary | Commit changes

$p+=1 : Increment port by 1. Feel free to change the increment if you need to open different port groups

until($p -gt 27080) : The last port in the range to create.

That should do it! Note these will take awhile to setup; the per port provisioning is kinda slow.

Now that you've forwarded the endpoints, you'll need to open the ports on the VM firewall as well. To do this quickly, see Hey Scripting Guy!



Reference time:
If you have any questions or comments please let me know!

Saturday, March 16, 2013

Do You Need Virtual Machine Manager and VMM 2012 SP1 Installation

Do I need VMM?

 

That's a question I've heard many times and while there is alot of data out there I wanted to make a simple list to help those entertaining the same question. Here is the breakdown of what Microsoft offers with VMM above and beyond standard Hyper-V:

  • Centralized management and configuration support for Hyper-V, Xen Server, and VMWare.
  • It contains P2V Migration tools not included with standard Hyper-V.
  • One console for managing multiple hosts. While using standard Hyper-V you can have multiple hosts in one MMC, but you need to switch between them. 
  • Automatic "workload placement" i.e. automatically moving a guest from one host to another based on load. 
  • Tools for environment consolidation. (Identify idle guests, etc.)
  • Much more from a management perspective including tools facilitating hosting multiple clients. "Tenants". 
If any of these features are appealing to your business you should give VMM a try. Everything you need for a trial is available for free. (Win8 AEK, VMM, SQL Express) For licensing costs, see this blog post by the always sharp Scott Lowe and this FAQ published by Microsoft. Now that we covered that,let's install!

Installing VMM

 

Assumptions

  • We're talking 2012 SP1 here, so you'll need Windows Server 2012 
  • Internet Access to D/L the Win8 AEK (link below)
  • Domain and preferably Enterprise Administrator access (You'll see why) 
  • This has a SQL Database; I assume you know where you want to put that. "An intern with Excel" will not suffice.  

Prerequisites

  1.  First you'll need to download and install the Windows 8 Assessment and Deployment Kit on the server on which you intend to install 2012. When installing select "Deployment Tools" and "Windows Preinstallation Environment" only. 
  2. Service Account: This domain-based service account will need only Administrative access to the target server. Lesser access is not possible per Microsoft. For additional security lock the account down to being able to log onto that server only. While it is possible to run VMM with a non-domain account, I won't cover that because doing so loses functionality. If you haven't done a service account before make sure you create at least one dedicated OU and a good prefix or suffix for the account name. I use a prefix of S_.
  3. A container for the Active Directory based crypto keys. By putting these in AD you facilitate moving the server or having a highly available environment. Again, I will not cover the "local" option. There is conflicting information on how to implement this, but through testing I determined that you DO need to pre-create the DKM container. This article is correct on the steps to configure, but here is a short list: 
    1. Pick a location in AD for this container. Use ADSIEdit to create the container by navigating to where you would like it and right clicking target OU->New->Object->Container and name it. (I recommend VMMDKM to correspond with MFST doco) 
    2. (If you're not an "Enterprise Admin", "Domain" not enough) Right click the new CN, select properties, and switch to the "Security" tab, and add the username of the installer to have full control to "this object and all descendant objects". Click OK. 
    3. Make sure you take note of the distinguishedName; this can be copied easily by right clicking->properties->double click distinguishedName->copy to clipboard/paste to notepad or Edlin or vi or Lotus WordPro or WordStar.

 Let's Do This


  1. Insert the DVD (image) and start setup.exe. Hit "Install".
  2. Check "VMM Management server" and "VMM Console" if desired and hit "Next"
  3. Enter your Name, Company, and ProductID. You can do a "evaluation" edition if you don't have a key yet. Hit next, accept the service agreement, and hit next again. 
  4. Choose if you want to participate in the CEIP, and hit "Next". 
  5. Select your install directory and hit "Next". As a rule of thumb I recommend using a drive other than the system drive for  all apps and logs.
  6. Assuming you pass the pre-req check, note any warnings and hit "Next". 
  7. Select your SQL server. As noted above your installer account will need to have sufficient permissions to add a database. If you're setting up a lab and don't have a "real" SQL server available, check out SQL Express. Enter the appropriate info and click "Next".
  8. Now you'll need to enter the service account that we discussed above. Check the "Store my keys in Active Directory" and copy in the DN from earlier. Hit "Next". If you want to use the non-AD based option you can, but eventually your server will self destruct.
  9. On the Port Configuration screen, accept the defaults unless you know you'll conflict with another service on the box and hit "Next".
  10. Specify a location for the VMM Library share. Again, I recommend not putting this on the system drive. Don't worry about space at this time, you can always change this after the install. 
  11. Hit "Install" on the Installation Summary screen. 
  12. Make sure you update the server & VMM from Windows Update and party like it's 1999. 
Now that you've got it installed it's time to see what it can do. I'm not going to tackle that today, but here are a few other resources to get you started:

Have fun & if you have any questions, let me know!

Update 3/31/2013: Troubleshooting
  • Host Performance Counters read 0!  I was having an issue where VMM was missing all or some of the performance counters. Fortunately Kristian Nese published a fix that works well here

Monday, March 11, 2013

New 2012 Powershell CmdLets: Role Focus on NPS (Radius) Server

This will be one in a series of posts highlighting the new Cmdlets available in Windows server 2012 that didn't previously exist. I'll be breaking them down on a role-by-role (or feature) basis for easier reading. The first we'll be focusing on is the NPS server included with Windows Server, which is often used for RADIUS authentication.



Load the module: (on a 2012 Server\Win8 machine with the NPS server role or management tools loaded)

import-module NPS

Get the commands:

get-command -module NPS

CommandType     Name                                  
-----------     ----                                            
Cmdlet          Export-NpsConfiguration
Cmdlet          Get-NpsRadiusClient
Cmdlet          Get-NpsRemediationServer
Cmdlet          Get-NpsRemediationServerGroup
Cmdlet          Get-NpsSharedSecretTemplate
Cmdlet          Import-NpsConfiguration
Cmdlet          New-NpsRadiusClient
Cmdlet          New-NpsRemediationServer
Cmdlet          New-NpsRemediationServerGroup
Cmdlet          Remove-NpsRadiusClient
Cmdlet          Remove-NpsRemediationServer
Cmdlet          Remove-NpsRemediationServerGroup
Cmdlet          Set-NpsRadiusClient


Let's walk through these:

Export-NpsConfiguration: This is great; exports all configuration of the NPS server EXCEPT templates to an XML file for backup or import to a different server. Anything containing template information will be converted to information specific to that configuration item and exported, i.e. if a client profile uses a template shared secret the shared secret will export successfully but it will be an asset of that client configuration rather than having the config linked to the template. This will remain true even if the target server for importing the profile already has the template elements defined by the same name. Also note that if you have a SQL server configured for auditing that information will not be exported either. Security Warning: All information including shared secrets will be stored in clear text. Command example:


Export-NpsConfiguration c:\temp\NPSConfig.xml


Get-NpsRadiusClient,Get-NpsRemediationServer,Get-NpsRemediationServerGroup,Get-NpsSharedSecretTemplate: Enumerates the Radiusclient, RemediationServer(groups), and shared secret templates on the local server. Only the Get-RemediationServer cmdlet requires an argument. The others will show all items on the server and you can use common parameters to parse. Security warning: Get-NpsSharedSecretTemplate will display shared secrets in clear text.

Import-NpsConfiguration: When supplied with an XML configuration file generated by the Export-NpsConfiguration(above) it will import an NPS server configuration. As noted above you cannot import information regarding templates or SQL auditing, but everything else will come over fine. These two commands could be used in a scheduled task if desired to sync configuration from a "master" NPS server to others within the organization. Command example:


Import-NpsConfiguration c:\temp\NPSConfigFromThatOtherServer.xml


New-NpsRadiusClient, New-NpsRemediationServer, New-NpsRemediationServerGroup, Remove-NpsRadiusClient, Remove-NpsRemediationServer,Remove-NpsRemediationServerGroup: Commands to setup and remove NPS/Radius clients, remediation servers, and remediation server groups. Pretty straightforward; here's a New-NpsRadiusClient example:


New-NpsRadiusClient -Name "NameOfMyClientGroup" -Address "10.1.0.0/16" -AuthAttributeRequired 0 -NapCompatible 0 -SharedSecret "SuperSharedSecretxyz" -VendorName "RADIUS Standard"


Set-NpsRadiusClient: All this does is change a value of an existing client specification. This would be useful for doing batch updates of all client profiles. Take, for example, this command which would disable all client profiles:


foreach ($i in Get-NpsRadiusClient){Set-NpsRadiusClient $i.name -Enabled 0}


So here's a fun idea: Automate config changes all your NPS/Radius servers to have a master/slave relationship using a shared storage space, powershell, and task scheduler. It's as easy as 1, 2, 3! (Sheesh, did I just say that?)


  1. Create simple powershell scripts to export the configuration to a shared file space (on "master" NPS server) and import from the shared file space (on "slave" NPS servers)  You may want to version them...
  2. Create Scheduled task on the "master" to export however often you like and one scheduled task on each "slave" NPS to import that config. Make sure the import comes after the export
  3. Profit!
Quick notes: if doing this be aware that changes will flow automatically so if you ruin your master you'll ruin your slaves too. As noted above I'd recommend versioning the configuration files (use the date) so that you have a history of the changes, just make sure you're fully aware of the fact that the shared secret is in the clear. If you wanted to get really fancy to protect that you could use a common service account and EFS, but that's a little deep for this article. :) 

In the mood for some references? Me too!
Technet NPS Migration Guide
Technet NPS Server Migration (different)
Technet NPS Cmdlets (Note the referenced -full and -examples aren't actually in the files)
Technet: Export NPS Config

Any questions? Let me know. Have fun!


Wednesday, February 27, 2013

Azure IaaS (VM) Tip: Use Skydrive to Transfer Files Quickly

While working with Azure hosted VMs, I wanted an easy and secure solution to do one-off file transfers without opening too much up. I found that the web interface for Skydrive works perfectly! Here's a quick howto:

Assumptions:

  • You have an Azure VM you want to get files to. 
  • You have a skydrive account. 

Let's go:

  1. Throw your desired files into a folder in your skydrive. 



  2. Log into your Azure VM via RDP and and click "Configure this local server" in Server Manager



  3. Click "IE Enhanced Security Configuration" 
  4. Set it to "Off" Administrators. (Be careful after this; don't be browsing the web on this thing..) 



  5. Open IE, navigate to skydrive.live.com and login. 
  6. Navigate to the folder you want to copy to the VM; do not drill into it. Hover your mouse over it and check the box in the upper right. 



  7. Click "Download" to download a zip file of the folder structure to the VM! (cool that skydrive makes the zip on the fly) 
Enjoy!

Sunday, February 24, 2013

Experiment: Application Server on Windows Azure IaaS 90 Day Trial

Windows Azure now allows you to demo the IaaS (Infrastructure as a Service) model with a 90 day free trial. This is a welcome change and I thought I'd walk through the setup of something fun as an experiment: A mumble (murmur) server setup. Mumble is an open source voice chat platform that focuses on low latency and high voice quality. It's primary focus is for use when gaming, but my family uses it from time and time to "call" distant places because the low latency makes long distance chat less awkward. That said, this obviously applies to your app of choice, which is what makes this such a powerful option.

IaaS allows you to host full virtual machines in the Azure cloud. (Among other things) Pre-configured options currently include Windows (2012, 2008r2) and Linux. (CentOS, Ubuntu, Suse)

VM Management Dashboard


In this article, I'll walk you through signing up for Windows Azure, provisioning a basic 2012 server, and installing and configuring a serving platform.

Sign up


Navigate to http://www.windowsazure.com/en-us/pricing/free-trial/ and click "Try it now". You'll need to logon with your Microsoft (Live/Passport/etc.) and enter your credit card information to start an account. Note that after the 90 days you will need to cancel the account or you will be billed for anything you have setup.

Setup


After account setup you should be able to immediately log into the Azure management portal. After logging in (and browsing around; they've really done a nice job on this) click "New" in the bottom lefthand corner. To create the 2012 instance, select "Compute->Virtual Machine->Quick Create". You will then need to populate the following fields:
  • DNS Name: This is both the name of the machine and where it will be accessible on the internet. The cloudapp.net suffix will be added on the end of the name. Say, for example, you name it "megawidgetgenerator01". In that case you can find it on the internet by resolving "megawidgetgenerator01.cloudapp.net". Your name will need to be unique among other machines in that DNS zone. (see the green checkbox)
  • Image: What you want the VM to be. I'll be selecting "Windows Server 2012 Datacenter"
  • Size: This select how many cpus and how much memory you would like. After the trial (and perhaps during depending on usage) you will be charged relative to your resource utilization. "Larger" machines cost more per month. I'll be going with "Medium" for my test, which gives me 2 dedicated cores and 3.5GB of RAM. The processors used (as of the writing of this article) are the AMD Opteron 4171 HE, not a stellar performer but excellent in the cores-per-watt department which makes it a smart choice.
  • UserName: Fixed at this time to "Administrator" 
  • Password: for the admin account. Pick something good; this is accessible from anywhere. 
  • Location: Which datacenter do you want it in? Pick the geo closest to your users. 


After filling that out, click "Create Virtual Machine".  Your new VM will be provisioned within a few minutes. You can now connect to your new server by navigating in the Azure management portal to Virtual Machines->Select your new VM-> Connect (on the bottom). This will send you a .rdp file to connect via RDP, but know you can just connect to the hostname you selected at any time; RDP is automatically enabled and unblocked by the default image.


Configuration


After connecting, you probably want to run Windows Update to ensure everything is patched up. After that, do the following:

  • Install your application. (Mumble in my case) 
  • Unblock the ports in Windows Firewall
  • Set the ports up as Endpoints in Azure EDIT: See my article here.

Windows Azure defeats the IPv4 exhaustion issue by NATing VMs. (boy IPv6 will be nice) Because of this, you need to setup enpoints in Azure so they can update their NAT rules to forward ports on the public IP (visible when you click your VM and look under "quick glance") to the private IP associated with your machine. The current limit for endpoints is 150 ports.  This should be more than enough for most applications. To accomplish this: refer to the following:

Overall I'm impressed. I'm very excited to work with Azure in the future. With these capabilities, I feel I've always got another datacenter on tap for any of my clients I can use for load balancing, DR, or as a primary site for whatever they may need.

Friday, February 15, 2013

Server 2012 Hyper-V + RDP + RemoteFX = a Delicious "Sangwich" of Cheap VDI

Oh man. Microsoft has done well on this; VDI/RDP/HyperV/RemoteFX have come together very nicely in 2012. The incremental improvements over the last 4 or so years to RDP, Hyper-V, and RemoteFX have made a great platform for cost effective VDI. This article will outline setting this entire environment up on one Server 2012 Datacenter box, but this could be scaled to as many machines as you need. (Add VMM for management in a large deployment) In this article I'll be walking through a basic setup of a Hyper-V Virtualization Host, Connection Broker, Web Access, a pool, the whole 9.

Assumptions:
  • You have at least one 2012 Hyper-V host setup.
  • You've got at least one 2012 server ready to go as the other roles. This can be a VM. 
  • You've got a sangwich. You'll need one, this is a bit of a lengthy install. 
Starting in seemingly reverse order will make this while thing easier; you'll see why.

Create an Template/Image to use For VDI

BTW, more template info here.
  1. Create a Virtual Desktop template by making a new VM with (generally) default settings. Insert the ISO and install the OS and make sure your product key is applicable to be in a your target VDI environment  (i.e. MAK with a SA or KMS as applicable) 
  2. After installing the OS, execute sysprep or something similar. On windows 8, that will be located under %SystemRoot%\system32\sysprep\sysprep.exe. Make sure you generalize and restore to OOB Experience; select shutdown when complete. 

Install Remote Desktop Services Components

  1. Prior to starting the RDS installation, you need to add all servers involved in your deployment to server manager to enable them as options during deployment. To do so, click "Add Servers To Manage" from the start screen of server manager and add any servers that will be part of the setup. (Hyper-V host, RDS Connection Broker, Session Host, etc.) 
  2. After adding the server(s) in question, start the RDS deployment by clicking "Manage->Add Roles and Features" from within server manager. 
  3. Proceed to the "Installation Type" and select "Remote Desktop Services installation" and click "Next".  
  4. On "Deployment Type" select "Standard deployment" and click "Next". Unless you've been through this before, I don't recommend Quick Start as it skips some things you should know. 
  5. On "Deployment Scenario" we'll be going through "Virtual machine-based desktop deployment". Select it and click "Next". Note that both options here have their uses, we're just covering VDI because it's a newer option. For more information on the differences, see this blog post by Yung Chou. 
  6. Based on our choices, it should notify you that RD Connection Broker, RD Web Access, and RD Virtualization Host will be installed. Review and click "Next". 
  7. You will be prompted to select a machine from your pool to host the RD Connection Broker role. Select the host(s) you would like for this role, move them to the right plane, and then click "Next". The Connection Broker distributes load across multiple hosts (if applicable) and maintains session information to ensure users are directed to the proper session or virtual desktop. For more information, see this TechNet article. This role can be hosted by a virtual machine. 
  8. Now you'll be prompted to select the RD Web Access server. In smaller deployments it is very common to place this on the same server as the RD Connection Broker. In larger environments you'll need to take external connection needs and security into account. Either click "Install the RD Web Access role service on the RD Connection Broker server" or select the server(s) you do want and click "Next". This role can also be hosted by a virtual machine. 
  9. Time to select virtualization host(s). This role cannot be hosted by a virtual machine for obvious reasons. Select the machne(s), move them over, and click "Next". 
  10. You'll be presented with the confirmation screen; review the information and click "Deploy" to create the whole setup. 
  11. The progress of each role installation will be displayed; do not be suprised if this takes some time. 

Setup a VDI Collection

  1. In server manager, click "Remote Desktop Services" and then click "3> Create Virtual Desktop Collections
  2. Click "Next" to bypass the before you begin section and then give your collection an appropriate name and click "Next" again. 
  3. Select the type of collection you want, Pooled virtual desktops or Personal virtual desktops. There is a lot that goes into this decision, but as a rule of thumb you can think of it like this: Pooled virtual desktops = many (users) to one relationship and Personal virtual desktops=one to one relationship. For my lab I'll be doing Personal virtual desktops, so please note that the options listed after this may be slightly different should you want Pooled. Unless you know you want otherwise leave "Automatically create and manage virtual desktops" checked and click "Next".
  4. When prompted with "Virtual Desktop Template" select the template we created in the first step and click "Next". 
  5. (This step unnecessary for pooled desktops) In most cases, you'll want to leave "Enable automatic user assignment" selected because that will give the requesting user access to a newly provisioned VD. If you desire, select "Add the user account to the local administrators group on the virtual desktop" and click "Next". 
  6. For "Virtual Desktop Settings" you should provide your Sysprep answer file; this will contain all the provisioning settings for your company. Since this is a lab setup in my case, I'll be selecting "Provide unattended installation settings". Click "Next".
  7. You need to know where you want to place automatically created VDI objects in Active Directory. After making that determination you'll need to paste in the path to the OU. Then, we'll need to generate a powershell script and execute it on a machine that has the Active Directory management tools installed on it. First things first, navigate to a machine with the Active Directory management tools installed and logon as an account with appropriate domain privs. On that machine:
  8. Open Active Directory Administrative Center and navigate to where you would like the VDI machines go to; create the OU if necessary and double click to go into it. Select the navigation plane (next to the arrow keys on the top) and it will give the DN. Copy and paste this DN to specify in setup. 
  9. Switch back to the RDS server. Set the time zone and then select "Specify the distinguished name of the organizational unit" and paste in our DN from the other server; DO NOT click Next yet. 
  10. After pasting the DN in, click the "Generate script" at the bottom of the window and copy all the contents of the script.
  11. Switch back to the AD server and open notepad. Copy the script into notepad and save it to a temporary location, i.e. C:\temp\Grant-RDSRights.ps1.
  12. (Still on AD server) Open Powershell as an administrator. If needed, execute "Set-ExecutionPolicy unrestricted" to allow script execution. 
  13. (Still on AD server) Execute the script you just saved. If your rights are correct you will get a success message. 
  14. Switch back to the RDS server and click "Next". If it doesn't work you may need to wait for the permissions to replicate. BUG WARNING: Ensure you do not have any "." characters in your DN. (I.E. in you OU names) If you do, this will not work. You will get the message "The RD Connection Broker server does not have access to add the virtual desktops to the Active Directory domain. Configure access by using the Active Directory page of Deployment Properties." despite the fact that permissions are in fact correct. (I wish I could bill someone for time wasted figuring that out) 
  15. Select the Active Directory Group, # of initial virtual desktops, the machine prefix, and the machine suffix. I recommend making one AD group per collection to accurately track who has access to what. As for a machine prefix/suffix, pick something that will work for your organization. I use VDI- for a prefix. Click "Next". 
  16. The "Virtual Desktop Allocation" screen will come up and allow you to distribute your VDI machines across multiple hosts if desired. Distribute accordingly and click "Next". 
  17. For "Virtual Desktop Storage" select what type of storage you would like to utilize for these VDI machines. You have all your standard options here, including Cluster Shared Volumes. For more on CSVs, check this out. Select your desired disk location and hit "Next". 
  18. The confirmation screen will come up; use this to review your settings and click "Create". 
  19. This may take awhile depending on your disk configuration and it may even report to the window that it's not responding. Don't worry, it'll complete eventually. 
That does it! You've now got your stable of virtual machines ready to dole out to deserving employees. If you're particularly astute you will be able to convince management that there is a monthly cost for each desktop payable to your bank account.

Managing Your Collection

Adding a Desktop

  1. Open Server Manager either on the RDS server or a machine with that server registered in its server manager. 
  2. Click "Remote Desktop Services"
  3. Under "Collections", click your collection name. 
  4. Under "Virtual Desktops" on the right, click "Tasks->Add Virtual Desktop"
  5. Specify how many virtual desktops you would like to add. 
  6. Specify on which server you would like to add them.
  7. Click "Create"
  8. You will be notified when the creation request is complete. 

Assigning a Desktop

  1. Open Server Manager either on the RDS server or a machine with that server registered in its server manager. 
  2. Click "Remote Desktop Services"
  3. Under "Collections", click your collection name. 
  4. Right click on the VDI machine you would to assign and select "Assign Virtual Desktop". 
  5. Specify a user to assign to and click "Assign". Note this user must be in the group you specified as the user group for this collection above. 

Configuring Licensing


This is a topic for a whole other article, but for now have a look a this Technet article and this one as well. 

Accessing Your Collection

There is enough here for another article, but to get you started: 

  1. Using IE (preferably) navigate to https://your.rdweb.server/RDWeb 
  2. You'll probably get a cert warning; you can fix that later by installing the proper web cert on your IIS server. 
  3. Log in with your assigned user and double click on the collection you created. 
  4. Enjoy your fresh install of Dos 5.0. (I'm assuming that's what you are using) 
Next up, RemoteFX. Update: RemoteFX Article here.

Monday, February 4, 2013

Installing nVidia Consumer Drivers on Server 2012 Core for RemoteFX


I'm wanting to establish Microsoft RemoteFX in my lab, and to do so, one needs a dedicated 3d accelerator. Obviously, nVidia didn't make the drivers with Server 2012 (now 2016 as well, see below) Core in mind. To accomplish this, we need do the following:

1> Download the newest drivers from nVidia. (Note the later half of these points will probably work on ATI cards as well, you just need to unpack the drivers)
2> Execute the driver setup directly on core server the and select a temporary directory. 
3> Hit "OK"; the installer will crash because it's uncomfortable in the lovely world of server core.
4> Navigate to the display.driver directory underneath the extracted files in the temporary directory you selected earlier. You should find the .inf files in this directory. For nVidia it is nv_disp.if. Update 5/3/2015: the .inf file is now nv_dispi.inf, thanks bearkiter.
5> From cmd.exe, execute "pnputil -i -a nv_disp.inf"
6> The screen will blank! Don't be afraid. After completion, you should see a screen that looks like the shot below. (yes the borders are gone)
7> Assuming it's OK to do so execute "Shutdown /r /t 0" to reboot the machine.

I'm working on another article to cover VDI/RemoteFX. Stay tuned. Update: Article here.



Update 2/3/2017: Confirmed working on Windows 2016! Consumer grade hardware works in the lab as well.