Publishing Remote Desktop Gateway with Azure App Proxy – The Easy Way

After reading that Azure can support Application Proxy, I began to think of ways I could use this to expand the configuration of my lab. My lab is hosted in my closet and brought to the Internet via AT&T fiber. So I only have a single IP which limits what I can do/publish externally. So my remote access (via Remote Desktop Gateway) was using the sole IP address.

What I have now is depicted below:

The key items to note here:

  • Single Server – hosting ALL RDS Roles(Gateway Role, WebApp Role, Session Host, Connection Broker)
  • RDS Server ALSO hosts Application Proxy Connector
  • DNS name pointing to Azure (not using “xxxx.cloudapp.net”)
  • Need TWO Published Applications
    • One for RDWEB (webapp page)
    • One for RPC (for RDP or HTTPS)

Step-by-step:

On Prem-

  1. Install Windows Server 2016
  2. Add RDS – I used “Quick Start”….give collection and external name
    “rds.yourdomain.com”
  3. Import certificate and configure RDS

Azure

  1. Create new application – select Azure AD/Enterprise Applications/ + New Application/All/On-Premise Application

    Configure like below (note the ending of url “/rdweb/”):

  1. Create new application (again) – select Azure AD/Enterprise Applications/ + New Application/All/On-Premise Application

    Configure like below (note the ending of url “/rpc/”):

Other items to note:

  • You’ll need at least ONE user with an Azure Active Directory Basic license to publish an application ($1 per month)

Shift is the key/fix for the crazy image resizing in Office 365

I write a lot of documents for the customers I work with.  And often I end up creating documents with screenshots.  Lately I’ve notice a CRAZY behavior with resizing images within Word (and I assume other Office apps would do the same).

When I resize the image (usually to make it smaller to fit better on the page) Word ends up flipping it upside down! This was driving my crazy (maybe you too).

What is now working for me is to press the SHIFT key while doing the resizing and Word adjusts to the desired size and nothing funky happens.

Maybe you found another solution?  Let me know.

Thanks,

D

Nano – drivers and drive setup

@Foxdeploy and I were chatting about my Nano/Lab setup and he asked me if I had any driver issues with my setup and Nano. The short answer is no…not with this build. But earlier builds (TP1 I think) I did have issues. Here’s how I dealt with that:

I dual boot (as stated in my previous post) to a FULL version of Windows Server 2016 – I consider that my “get out of jail” card just in case things don’t go as planned (as they sometimes do). With a full OS installed I can then use the Device Manager to clearly see what driver is not working properly. With my first build of Nano in the lab I had a NIC driver (ugh). In the early builds of Nano you had to use full OS and Device Manager to get the driver’s inf and other data to import the driver via dism:

dism\dism /Add-Driver /image:.\mountdir /driver: C:\Windows\System32\DriverStore\FileRepository\nic.inf_amd64_23224432324

Luckily that is not needed any longer 🙂 . To add “custom drivers” to a Nano build simply add the option “DriversPath” to the New-NanoServerImage command and point the option to the appropriate folder for the driver(s) you needed add.

As for setting up a dual boot – here’s the method I used:

I booted my system with Windows install media and at the “Windows Setup” screen press Shift+F10

Type diskpart and use the commands listed below
List disk ….and verify which disk you intend to install the OS onto (usually “0”…in the example below I only have a single disk)
  • Select disk 0
  • clean
  • create partition primary
  • format quick fs=ntfs label=boot
  • create vdisk file=c:\Win2016.vhd maximum=50000 type=expandable
  • attach vdisk
  • exit (to exit diskpart) then exit (to exit command prompt)
  • Now continue with Windows Setup and when prompted select “Custom: Install Windows only (advanced)”
  • The drive (vdisk) previously created is displayed – Click Next to install
  • Complete the install as normal

Now that the GUI OS is installed, the Nano VHDX can be added to the boot configuration:

  • Mount the Windows Server 2016 ISO and note the drive letter (in my case it was F:)
  • From an elevated PowerShell console run the following commands
    Import-Module f:\NanoServer\NanoServerImageGenerator -Verbose
    
    New-NanoServerImage -Edition Standard -DeploymentType Host -MediaPath f:\ -BasePath D:\temp -TargetPath D:\Temp\Nano.vhd -ComputerName Nano -OEMDrivers -Compute
    #Create an djoin file:
    djoin.exe /provision /domain thenewtonlab.com /machine "Nano" /savefile c:\temp\objBlob
    

    The above command will prompt for an administrator password to assign to the new VHDx image

    • Copy the VHDX over to the server and place on the “Boot” partition created earlier
    • From an elevated command prompt create a new boot entry via BCDEDIT (the last command set the new entry as the default boot entry):

Bcdedit /copy {current}

Copy the GUID that is returned

bcdedit /set {GUID} device vhd=[c:]\NanoServer.vhd

bcdedit /set {GUID} osdevice vhd=[c:]\NanoServer.vhd

bcdedit /set {GUID} path \windows\system32\boot\winload.exe

bcdedit /default {GUID}

Next step in the process is to finalize the Nano configuration:

Logon as Administrator with the password assigned during the New-NanoServerImage command.

Configure the IP and firewall:

Enter administrator for user and the appropriate password:

Press Select Networking and press Enter

Press Enter to configure the NIC

Select F11 and then F4 to toggle DHCP off and then enter a static IP

Press Enter to save the configuration and then ESC back to the main menu

Next the server needs to added to the domain – within PowerShell run the following:

$ip = "192.168.1.200"
Set-Item WSMan:\localhost\Client\TrustedHosts $ip
$user = “thenewtonlab\dan”
Enter-PSSession -ComputerName $ip -Credential $user
netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=yes
$ifa = Get-NetAdapter -Name Ethernet
netsh interface ipv4 add dnsserver "Ethernet" address=192.168.1.20 index=1

Copy the djoin blob file:

#map drive
net use z: \\192.168.1.200\c$
copy c:\temp\objBlob z:\temp\objBlob
#reboot the server
shutdown /r /t 5

We now have a dual boot system that is ready to host Hyper-v guests.  While the overall process might seem tedious, it is a process the is done very seldom (gratefully). I hope you find this information helpful.  Do you have a test lab?  How do you like to setup your lab?  I’d love to hear how others are working these issues out.

Regards and happy labbing,

D

The Newton Lab – How it’s built

I’ve used my lab for years.  Many have heard me say how this lab has saved me so much time over the years…it’s paid for itself several times 🙂

Often times I need to test a migration or other configuration for a client (or just test some new software).  This lab is made up of a single server (desktop case) here’s the basic specs (it’s all on the cheap):

thenewtonlab-blog

After many rebuilds over the years between running full installs of Windows 2012 and Windows Hyper-V Server , I’ve finally settled on installing all host OSs to boot from VHD.  This makes sure the drive letters stay consistent across the OSs (I previously would dual boot between Windows Server 2012 direct on the boot disk and a boot from VHD Windows Hyper-V Server).

With the host done I built a VM to run as a Remote Desktop Gateway.  I use the “Quick Session Collection”.  To gain access remotely I use a free (yes free) cert from StartSSL.com.  All you need is a registered domain and you can get a free cert (you need to validate that you own the domain via confirmation email).  So let’s say you own newton.com (I wish I did Apple…’cause you’re not using it right now).  You can then request a server cert for remote.newton.com and install that on your internal RD Gateway.  Then you’ll need to add a host name in the newton.com zone that points to the public IP of your home router…and you should be good to go.  Many ISPs today will not keep your IP the same overtime and so you’ll need to update the A record you created.  For that I use a free service from DNSExit.  Just transfer your DNS  zone and you can use client software that will monitor the external IP and update it as needed.

A couple of other notes….  I now only publish the “Server Manager” app and then launch Hyper-V Manger from there (it’s good to keep things simple)…in previous builds I would publish all the management tools separately.

Windows Server 2016 has changed things up for Hyper-V – one of which is the configuration files.  I was running the Tech Preview 5 for quite awhile and then earlier this week decided to move to the RTM build and plan to use a script my good friend @foxdeploy wrote that would simply export the XML files for each VM.  I then would take those files to import back to Hyper-V (the VHDs are not changing location)…but this didn’t work with Windows Server 2016 which now uses VMCX files. So I decided to create my own script to export the VM configs to a file and then re-import.

function Export-VMs {
 [CmdletBinding()]
 param(
 [Parameter(Position=0)][string]$VMHost,
 [Parameter()][string]$Output = "vm-export-cfg.csv")

 $vms = get-vm -ComputerName $VMHost
 foreach($vm in $vms){

 $properties =[ordered] @{'VMName'=$vm.name;
 'VMDisk1'= Get-VMHardDiskDrive -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty path -first 1;
 'VMDisk2'= Get-VMHardDiskDrive -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty path -last 1;
 'VMSwitch1'=Get-VMNetworkAdapter -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty Switchname -first 1;
 'VMSwitch2'=Get-VMNetworkAdapter -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty Switchname -last 1;
 'VMDynRAM' = Get-VMMemory -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty DynamicMemoryEnabled;
 'VMRAMMin' = Get-VMMemory -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty Minimum;
 'VMRAMStartup' = Get-VMMemory -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty Startup;
 'VMRAMMax' = Get-VMMemory -ComputerName $VMHost -VMName $vm.name|select -ExpandProperty Maximum;
 'VMGen' = $vm.Generation}
 $object = New-Object –TypeName PSObject –Prop $properties
 Write-Output $object|export-csv $output -NoTypeInformation -Append
 }#end foreach $vm
}#end function 

function Import-VMs {
 [CmdletBinding()]
 param(
 [Parameter(Position=0)][string]$VMHost,
 [Parameter()][string]$input = "vm-export-cfg.csv")

$vmconfigs = import-csv $input
 foreach($vm in $vmconfigs){
 #create VM
 new-vm -ComputerName $VMHost -Name $vm.VMname -MemoryStartupBytes $vm.VMRAMStartup -VHDPath $vm.VMDisk1 -Generation $vm.VMGen -SwitchName $VM.VMSwitch1
 #Enable Dynamic Memory
 if($vm.VMDynRAM -eq $true){
 Get-VM -Computername $VMHost -Name $vm.VMName|Set-VMMemory -DynamicMemoryEnabled $True
 }

 #add second disk if needed
 if($vm.VMDisk1 -ne $vm.VMDisk2){ #need to add second disk
 Get-VM -ComputerName $VMHost -Name $vm.VMName|Add-VMHardDiskDrive -Path $vm.VMDisk2
 }
 #add second Nic if needed
 if($vm.VMSwitch1 -ne $vm.VMSwitch2){
 Get-VM -ComputerName $VMHost -Name $vm.VMName|Add-VMNetworkAdapter -SwitchName $vm.VMSwitch2
 }
 }#end foreach $vm
}#end function

I take the export file and save it off the host server and then rebuild the server as a new Hyper-V host and then run the import and boom all the VMs are there (man i love PowerShell).

 

Anyway I hope someone finds this helpful in their lab building.  In a future post I’ll cover how a setup my multi-boot configuration and built the fresh new Nano server.

Happy building.