Unattended ISA Server 2006 installation with rdesktop and powershell

In the last post I explained how to use rdesktop to script Windows.
In this post, I will show you how to install ISA Server 2006 Enterprise Edition using rdesktop completely automated. Or as they say, an unattended installation.

I have the advantage of hindsight, but I will explain it without the lessons learned so you may learn why I do some things the way I do them now :)

It's worth noting that I performed this installation on a virtual machine in VMWare. I created a snapshot right before I started the installation, so it was easy to redo the whole thing without having to reinstall Windows.

One of the advantages of Enterprise Edition (EE) over the Standard Edition (SE), is that EE used a centralised configuration server called CSS (Configuration Storage Server). Using SE with 5 ISA servers, you would have to configure each of them separately. In EE, you only need to point all the ISA servers to a CSS, and they will fetch the configuration.

So, I will first setup the CSS on one of the ISA servers (It's normally setup on a different machine, but I don't have one handy right now), then I will install ISA server on ISA1, and then ISA2 (We have 2 ISA servers in loadbalancing)

The second Windows Server 2003 installation CD was required during installation of the CSS. To avoid having to swap CDs all the time (that wouldn't be very unattended), I loaded it into the virtual CD-drive and took a snapshot after that.

ISA Server 2006 Enterprise Edition Installation Guide

Installing the CSS on ISA1

The unattended installation of any ISA component depends on 2 things: a configuration file with the values you want filled into the textboxes, and invoking the setup.exe program with the correct parameters.

Let's start with the latter.


setup.exe /v" /qb FULLPATHANSWERFILE=\"X:\INIFiles\InstallNewManagementServer.ini\""


This is how to invoke the setup.exe program in my case. I trimmed a bit of the front, setup.exe is actually located in C:\software\isa-server-enterprise\FPC\
Instead of passing this entire commandline to rdesktop, I chose to put it in a batch script called "install_css.bat". To be correct, the name should be "install_css_and_mgmt.bat" because it will also install an ISA Firewall Management Client, but that's not important.

There are 3 flags in the command line above. The "/v" option is the only one passed to setup.exe, and I presume that its parameter will just be passed to some .msi installer at a later stage. But to be honest, I have no idea what it does.
The "/qb" option specifies how verbose the installation should be and it is explained in Appendix C of the Microsoft site I linked to above.
Finally, "FULLPATHANSWERFILE" specifies where the INI file with the answers is located. In my case, it's (of course) located in the INIFils directory on the X: drive which is actually a directory on my client computer.

The INI-file contains the following:

[Setup Property Assignment]

ADDLOCAL=Storage_Server,MSFirewall_Management
ENTERPRISE_MODE=New
ENTERPRISE_NAME="Katholieke Universiteit Leuven"
PIDKEY=...


Sadly for you, I stripped out the product key (PIDKEY) ;)

The INI-file above is edited from an example INI file that can be found on the ISA installation CD under \FPC\Unattended_Setup_Sample\Enterprise_Edition\

As shown in the INI, the unattended installation will install a CSS and management client, and create a new enterprise.

I use the following rdesktop line (more or less) to install it:


rdesktop -r disk:local="/home/deepstar/" isa.example.com -u p0036393 -d PAD -s "cmd.exe /K net use x: \\\\tsclient\local & x:\install_css.bat & logoff"


Installing the ISA server itself on ISA1 and creating a new array

After this installation, it's time to setup ISA itself on ISA1. All we need to do, is use another INI file for this and start the installation the same way. I created a batch script called "install_isa_new_array.bat" with this content:


setup.exe /v" /qb FULLPATHANSWERFILE=\"X:\INIFiles\InstallNewArrayAndServer.ini\""


InstallNewArrayAndServer.ini contains this:

[Setup Property Assignment]
ADDLOCAL=MSFirewall_Services,MSFirewall_Management,MSDE
ARRAY_MODE=New
ARRAY_NAME=Verteron
ARRAY_INTERNALNET=1 10.32.6.0-10.32.6.255
STORAGESERVER_COMPUTERNAME=ISA.example.com
PIDKEY=...


This INI file instructs the installer to create a new array (an ISA loadbalancing term) called "Verteron". And the array will use the IP-range 10.32.6.0/24 on its internal interface. The 1 in front of the "ARRAY_INTERNALNET" value indicates the amount of ranges to follow.

[In case you are wondering where "Verteron" comes from, the Active Directory domain in which the Microsoft Exchange environment will be setup is called LUNA]

ISA1 will be pointed to the CSS on ISA.example.com for its configuration.

As expected, the installation will do its thing. But after some time you'll see that the RDP session no longer responds. (Even worse, currently, my entire desktop stops working and I have to kill rdesktop to get my desktop back).
The cause of this is ISA. After the ISA installation, the ISA firewall is running. This firewall blocks RDP to the ISA. It appears that my client computer is added to the group "Remote Management Computers", but with the wrong IP. ISA registers an 192.168.x.x address, but because I'm behind a NAT, the ISA server sees another IP and drops it. This is very annoying! It appears that rdesktop passes the local IP address to ISA. It would have made more sense if ISA added the IP that it saw on its side, instead of relying on the IP rdesktop sends.

In any case, you will no longer be able to login to the ISA.

Solution ? Yes, there is one, but it works only a bit. The trick is to add your IP address to the group "Enterprise Remote Management Computers" after the CSS is installed, but before the ISA is installed.

Of course, configuring this by hand is totally out of the question. Remember that I'm lazy in that way. Nature provided me with 10 fingers so I could use a keyboard. Using a mouse is inefficient, unless I could use 2 mice with 5 buttons each.

Time to get scripting. This time we won't get away with some funky batch script because ISA doesn't offer any interface towards it. What ISA does provide though, is a way to access it through PowerShell.

Here is the script to add the IP address 12.34.56.78 (with name "My NAT Gateway") to the group "Enterprise Remote Management Computers":


$root = new-object -comobject "FPC.Root" -strict

$remotemgmt = $root.Enterprise.RuleElements.ComputerSets | where-object { $_.name -eq "Enterprise Remote Management Computers" }

$remotemgmt.Computers.add("My NAT Gateway", "12.34.56.78")
$remotemgmt.Computers.save()


The first line in the script gets the root of the FPC tree. [There is no explanation of FPC on wikipedia. Maybe some kind soul should provide one]
Next, we look at the computersets in our enterprise, and filter out the one called "Enterprise Remote Management Computers". We add our NAT Gateway to it and save.

That's all.

There is more information on the ISA Server Administration Object Model on Microsoft MSDN.

So, how can we execute this script on Windows ? The first step is to download and install PowerShell v1.0.
Then, 2 hurdles remain before things will be allright.

First, PowerShell scripts execution is disabled by default.
Demonstration:


C:\Documents and Settings\p0036393>c:\WINDOWS\system32\windowspowershell\v1.0\po
wershell.exe x:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1
File X:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1 cannot be loaded because
the execution of scripts is disabled on this system. Please see "get-help abou
t_signing" for more details.
At line:1 char:49
+ x:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1 <<<<

C:\Documents and Settings\p0036393>


A way to enable the execution of scripts is the following:

c:\windows\system32\windowspowershell\v1.0\powershell -command "set-executionpolicy unrestricted"


This sets the execution policy to "unrestricted".

I placed this command inside a script called "enable_powershell.bat". Hurdle 1 is behind us.

Next problem: PowerShell requires you to sign your scripts and whatnot, which is a really gay policy.


C:\Documents and Settings\p0036393>c:\WINDOWS\system32\windowspowershell\v1.0\po
wershell.exe x:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1

Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful,
this script can potentially harm your computer. Do you want to run
X:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"):


The reason why I can't execute this script, is because it is located on the X: drive and that's a network drive. So to get around that, I copy the script to C:, execute it and then remove it.
Problem solved.

This is a batch script to automate the execution of powershell scripts located somewhere where pwoershell doesn't like it:


@copy %1 c:\temp.ps1

@echo Executing %1 ...

@c:\windows\system32\windowspowershell\v1.0\powershell.exe c:\temp.ps1

@del c:\temp.ps1


I called it "execute_ps1.bat"

Now the stage is set. To add the gateway IP address to the correct group on the ISA, we execute a powershell script with the following rdesktop line:


rdesktop -r disk:local="/home/deepstar/" isa.example.com -s "cmd.exe /K net use x: \\\\tsclient\local & x:\enable_powershell.bat & x:\execute_ps1.bat x:\PowerShellScripts\allow_RDP_from_kulnetnat.ps1 & logoff"