I AM the system administrator. Who do I call?
Windows Admin
ADFS 2.0 in Forest Trust Environment
Oct 11th
I’ve been meaning to get this out there for a while now. I’m not going to go into great detail on ADFS but you can get more background on ADFS and federation in these posts:
Salesforce SSO with ADFS 2.0 – Everything You Need to Know
ADFS 2.0 Choose Your Attributes Wisely
SAML WebSSO Federation Made Easy
My scenario is as follows:
- 2 domains in 2 forests with a one way trust between them.
(For this post I’ll refer to these domains PERIMETER and INTERNAL) - PERIMETER trusts INTERNAL but INTERNAL doesn’t trust PERIMETER
- Both PERIMETER and INTERNAL contain user accounts that need to be authenticated and federated via ADFS
- The ADFS server is joined to the PERIMETER domain
- ADFS and its related IIS services need to run under a service account from the INTERNAL domain
Here are the high level hoops I had to jump through to get this working:
- On a clean Windows 2008 R2 server, obtain and run the ADFS 2.0 setup file AdfsSetup.exe. Select “Federation Server”, This will install everything you need to make ADFS 2.0 work (including pre-requisites). Don’t run through the config wizard – We will do the config from command line later.
- Create a new service account. e.g. INTERNAL\Svc.ADFS. Create a new DNS ‘A’ record and point it to the ADFS server. E.g. federate.internal.com. Set a Kerberos SPN for the DNS record against the service account:
setspn -a HOST/federate.internal.com stjohn\Svc.ADFS
- Load the certificates MMC for local computer account and install a certificate which can be used for the ADFS web site. In the IIS manager configure a new binding on the default website for SSL with the appropriate FQDN and select the cert you just installed.
- Make sure the ADFS server has access to all LDAP servers for all domains. Something to consider if you’ve got a few firewalls here and there.
- Add your service account to the local admins group on the ADFS server and to domain admins group for the domain that the service account belongs to. Don’t panic this will only be temporary! This just allows the service account to create the necessary config for ADFS in the Program Data\ADFS OU. Once created it will have the correct permissions for the service account. I had to do this to get it work, not sure why it’s any different to a normal single forest install.
- Log on to the ADFS server with the service account. Skip this step at your peril!
- Run cmd prompt as admin. cd to:
C:\Program Files\Active Directory Federation Services 2.0\
-
Run the following command to configure and new ADFS 2.0 farm
FSConfig.exe CreateFarm /ServiceAccount "INTERNAL\Svc.ADFS" /ServiceAccountPassword "somebiglongpassword" /AutoCertRolloverEnabled /FederationServiceName "federate.internal.com
-
Remove the service account from local admins and domain admins now.
-
That’s it. Load the ADFS console and configure ADFS as you would in any other scenario
Notes
-
During the install you might get a yellow warning about not being able to set the SPN. That’s cool we already did it above.
- Make sure you can view the federation data for your new server e.g.
https://federate.internal.com/FederationMetadata/2007-06/FederationMetadata.xml - If you get a certificate error from your service provider. E.g. This typical error from SalesForce:Signature or certificate problems
Is the response signed? False
The signature in the assertion is not valid
Is the correct certificate supplied in the keyinfo? False
No valid certificate specified in this response.
Try re-generating your token signing certificate using the following PowerShell commands. Note:This will break any existing trust relationships you have with any service providers. You will have to export the new cert and update your service providers with it.
Add-PSSnapin Microsoft.Adfs.Powershell Set-ADFSProperties -AutoCertificateRollover $true Update-AdfsCertificate -Urgent
This might not be the only way to get this working and I haven’t tested it thoroughly – your mileage may vary! But as always I’m keen to hear how you get on and happy to field questions.
iLO 2 Firmware Images, Cursor Keys and IE8
Apr 20th
A couple of things I came accross with iLO today:
Plain Firmware Image .bin Files
I’ve got DL360 G5 running VMWare ESX 4 and I wanted to update the iLO firmware to the latest version. Even though iLO has a firmware update page where you can upload a new firmware image file. This doesn’t seem to be available for download at the HP iLO2 support page. To get it you need to download the Windows firmware update tool and extract the package using 7-zip.
Remote Console – Cursor Keys Don’t Work with IE8
To get around this, disable protected mode in IE or run it IE as administrator (Windows 7, vista etc).
FindPrivateKey.exe (Pre-Compiled)
Apr 7th
I don’t really like to do this but here’s a compiled copy of FindPrivateKey.exe. It’s a really uesful tool but Microsoft only provide the source code as part of a development sample.
Details about the tool are here: http://msdn.microsoft.com/en-us/library/aa717039.aspx
Hopefully Microsoft will get annoyed with me distributing this here and put up an official binary.
I compiled it my self this afternoon. At least it’s better than downloading it from some dodgy file-sharing site!
Requires .NET 3.5
HP Lefthand / vSphere: “failed on physical path”
Mar 22nd
We recently started having issues with our VMWare / HP Lefthand iSCSI SAN environment. The symptoms were as follows:
- VMs would sometime freeze-up for up to 10 seconds – no ping, nothing! Really nice on a busy SQL server running finance apps! Yeah! The problem affected VMs on both the Lefthand iSCSI and the fibre channel EVA
- Taking snapshots of VMs on the Lefthand storage would almost always fail and in most cases make a mess of disk chaining which would require manual clean up
- Browsing datastores is extremely slow
- General flakiness across the VI environment (Yes, that is a technical term)
I stated out by looking in the vmkernal logs of the ESX hosts and found errors like this occurring fairly regularly.
Mar 10 18:04:02 myesxsvr01 vmkernel: 1:08:22:15.031 cpu1:4514)NMP: nmp_CompleteCommandForPath: Command 0x2a (0x4100040ebc00) to NMP device "naa.6000eb31749025160000000000016019" failed on physical path "vmhba33:C0:T14:L0" H:0x0 D:0x2 P:0x0 Valid sense data: 0x9 0x4 0x2.
These errors were in relation to LUNs on the iSCSI SAN. A quick google of “failed on physical path H:0×0 D:0×2 P:0×0 Valid sense data: 0×9 0×4 0×2 Lefthand” quickly turned up this VMWare KB article which states that this is a LUN locking error caused by having VMFS LUNS presented to a Windows host which has the HP Lefthand DSM (Device Specific Module) for MPIO installed. This immediately rang a bell with me because we had recently installed a new backup server including full iSCSI MPIO support using the HP DSM.
Presenting the LUNs to the backup server allows VMs to be backed-up directly from the LUN as opposed to backing up via one of the ESX hosts. A good idea as long as you read the HP documentation all the way to the end and don’t install the DSM for MPIO!
Great! I thought, I’ve found the problem. It appears the the LUN is being locked by the DSM and is causing the host to “timeout” affecting the entire storage subsystem (iSCSI and Fibre Channel). I went ahead and un-presented the iSCSI VMFS LUNs from the Windows host fully expecting the issues to clear up. Unfortunately this didn’t happen. My next step was to vMotion all the VMs off one host and reboot it. Still no luck, the errors returned to the vmkernal logs within a few minutes of the reboot.
At this point I logged a case with HP who provide our VMWare (and of course Lefthand) support. After they analysed the logs, they felt that the only way to resolve the issue was to do a full shutdown of the all the hosts and all the Lefthand storage! Classic support call – “Have you tried turning it off and back on?” But seriously, the guy at HP was very knowledgeable and helpful. We proved the approach as follows:
- Create a new LUN on Lefthand and present it to all ESX hosts
- Put a VM on the new LUN and prove that there are no issuers associated with the LUN by repeatedly taking snapshots and monitoring the vmkernal log
- Present the LUN to the Windows backup host with the MPIO DSM. – Now the errors start occurring with this new LUN.
- Un-present the LUN from ALL hosts (ESX and Windows)
- Reboot one of the ESX hosts and re-present the new LUN to it. – The errors are no longer occurring with this LUN
It appears that access to a LUN from all hosts must be stopped to clear the locking so we did a fair amount of planning and undertook a full shutdown as follows:
- Uninstall HP Lefthand DSM for MPIO from Windows hosts (We still want to try to present the VMFS LUNs back to the backup server at some stage)
- Shutdown all VMs
- Shutdown all the ESX hosts
- Shutdown Lefthand (Shut down the management group, not the nodes individually)
- Power up the Lefthand and make sure all the nodes are up and volumes are all online
- Power up the ESX hosts and VMs
After doing this all LUN locking errors are gone from the logs. Everything seems very solid, snapshots are working and the flakiness is gone!
Any comments from anyone who has an understanding of the inner workings of iSCSI, lefthand, VMWare SCSI reservations/locking etc who can shed some light on what’s actually happening here would be much appreciated! Or just if you’ve had a similar experience I’d be keen to hear.
Thanks for reading
When to Create a New LUN (The hp way!)
Mar 9th
I know it’s not meant as a definitive technical guide but I had a good laugh when I came across this flow chart in hp’s LeftHand SAN / VMWare vSphere 4 guide.
Or in engineering speak: “Tighten it up ’til it breaks then back it off half a turn!”
Sorry if you dropped by with a legitimate question on LUN management! Actually the question in the chart about snapshots and remote copy is very valid and the very first thing you must consider when designing your LUN layout.
Citrix Web Interface with ISA Single Sign On
Feb 17th
It’s been a long time since my last post! I’ve been so busy working on the house (but nothing really blog-worthy). Anyway today a colleague and I went through and set up the Citrix Web Interface (5.x) with single-sign-on using Microsoft ISA 2006.
The Web Interface and Secure Gateway run on the same server but are configured completely independently of each other, they could just as well be on separate servers if the load warranted it. They both listen on port 443 on separate IP addresses with separate certificates.
On the face of it, it seems quite straight forward – configure the Web Interface for pass-through authentication, create an ISA web publishing rule using our common SSO web listener with forms based authentication and configure an authentication delegation method. This works just fine as far as getting the user logged in with their list of applications.
Next step – configure the CSG to listen on a separate IP address with a separate certificate and configure a NAT rule so the ICA client can connect directly to the CSG. Again fairly straight forward.
Here’s the catch. Using pass-through on the web interface doesn’t work with the CSG. Pass-through mode expects the client to be domain-joined, inside the corporate network and able to authenticate directly with the XenApp Server (as opposed to being pre-authenticated by the XML/STA services). The result with the above configuration is that when the user launches an application they are presented with a Windows login dialog which defeats the purpose of single-sign-on.
The solution – ASP.Net “jump” page on the web interface.
Configure the Web Interface in “Explicit ” mode rather than pass-through. This is the standard method where the user is presented with the Citrix Web Interface login form.
Configure the ISA web publishing rule to delegate “basic” credentials. i.e. clear text user-name/password (secured with SSL of course!).
Create an ASP.NET jump page which extracts the user-name and password from the HTTP request, and creates a form with hidden fields then uses java script to POST the form to the Web Interface login page.
This all happens instantly without the user noticing. Don’t configure the Web Interface as the default IIS page, instead place the jump page in the root of the IIS web site and set the document priority to to serve it up first. Here’s the code: (Download link at the end of the post)
AuthPass.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AuthPass.aspx.cs" Inherits="AuthPass" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> </title> </head> <body onload="submitlogin()"> <div id="FormContainer" runat="server"> </div> </body> </html> <script type="text/javascript" language="javascript"> function submitlogin() { document.CitrixForm.submit(); } </script>
AuthPass.aspx.cs - Note: The domain field needs to be set to your own domain or removed completely depending on how your users login. The form action needs to point to your Web Interface login.aspx page.
using System; using System.Net; using System.Text; using System.Web; public partial class AuthPass: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { FormContainer.InnerHtml = doLogin(Request.ServerVariables["AUTH_USER"],Request.ServerVariables["AUTH_PASSWORD"]); } private String doLogin(String strUser, String strPassword) { StringBuilder strForm = new StringBuilder(); strForm.Append("<form name=\"CitrixForm\" action=\"https://citrix.corp.com/Citrix/XenApp/auth/login.aspx\" method=\"post\">"); strForm.Append("<input type=\"hidden\" name=\"domain\" value=\"MyDomain\">"); strForm.Append("<input type=\"hidden\" name=\"user\" value=\"{0}\">"); strForm.Append("<input type=\"hidden\" name=\"password\" value=\"{1}\">"); strForm.Append("<input type=\"hidden\" name=\"LoginType\" value=\"Explicit\">"); strForm.Append("</form>"); return String.Format(strForm.ToString(), strUser, strPassword); } }
Here are the key points.
ISA 2006
- Web publishing rule with SSO WebListener using forms based Authentication
- “Basic” authentication delegation (SSL end to end!)
- Published logoff URL is set to /Citrix/XenApp/site/logout.aspx
- Simple NAT rule for CSG
Web Interface
- A new XenApp site is created in the Web Interface Management tool with “At Web Interface” configured for the “Where user authentication takes place” setting
- Authentication Method set to Explicit
- AuthPass.aspx[.cs] files are placed in the root of the IIS website to handle auto-login
- XenApp web site is not configured as the default IIS site. AuthPass.aspx is set as the default page on the IIS web site
- Secure access mode is set to “Gateway Direct” but this will depend on your environment
CSG
- This CSG is entirely configure using the CSG Management Console
- A specific certificate for the CSG is selected
- The CSG is set to listen on specific IP address rather than the default of all IPv4 addresses (an additional address must be added to the server’s TCP config).
- “Direct” mode is configured for the Web Interface location
There you have it. Citrix WI/CSG SSO for ISA. I know it’s a bit of a hack but I spent some time trying to find a way to do this natively with Citrix Web Interface configuration and posted in the Citrix support forums without any success. If there is a more official way to do it I’d love to hear about it.
On a side note…
I found a long delay during login which was fixed by disabling NetBIOS over TCP/IP on the web interface server
Citrix Web Interface SSO for MS ISA Updated: 2011-02-17
Download: AuthPass.zip - 1.09 kB
Exchange Resource Mailboxes Schedules – “No Information”
Dec 15th
Here’s a quick one that might save you some time. Even after installing the Exchange auto accept agent and registering your resource mailboxes against it you still don’t get free/busy information when you go to book the resource.
If these are new resource mailboxes which haven’t yet had a booking all you need to do is create a booking and the free/busy information will start working.
Modular vbScript Framework
Dec 14th
Here’s a modular vbscript framework I wrote for deploying software and performing other multi-step tasks across reboots.
I won’t list the whole script in the post because it will get messy with all the wrapping. Instead I’ll just describe the main features and you can download the zip file below. The screenshot will also give you a reasonable idea about how it works. It’s a bit rough and doesn’t have robust error handling – it’s really just to give you some ideas about putting together modular vbscripts.
The main script is a .wsf (Windows script file). I use WSF because you can’t include other script files in a .vbs file. The framework gives us the following benefits:
- Code reuse – We can write core functions that are available across all modules
- Modular development – We can create and maintain modules in isolation
- Extensible – It’s easy to add new functions and modules
- Scripty goodness over unattended reboots/logons
- Log file generation
Here is the file/folder structure of the framework:
\RGFramework.wsf <-Main script logic file \includes\header.vbs <-Header file to declare variables etc \includes\Corefunc.vbs <-Functions which are available across all our modules \Modules\(ModualName)\(ModualName.vbs) <-Module files
Script logic
Here’s an example of typical framework logic:
- Start a continuous loop
- Get the step which we’re up to from the registry. Registry key doesn’t exist yet (Step 0)
- The Select statement executes the code for step 0
- Set the script to run next time windows starts
- Set auto-logon so Windows logs on automatically when it boots up
- Run a module e.g. InstallOffice()
- Call “NextStepReboot()”. The current step is recorded in the registry and the system reboots
- The system has rebooted and logged on automatically and the script starts again
- Get the step which we’re up to from the registry (step 1)
- The Select statement executes the code for step 1
- Run another module .
- If we don’t need a reboot then we’ll just call NextStep() to record the step we’re up to
- The code loops back around to the select statement and we now go to step 2
- Run another module function
- Clear auto-logon
- clear script start-up
- exit
Note*
To start the script from the beginning again or from a specific step ‘the “HKLM\SOFTWARE\RGFramework\Step” registry string must be deleted or manipulated. This string represents the last step that was run so if it is set to 3 then next the script runs it will execute step 4.
Modules
A module is just a file which contains a single function. The function has the same name as the module file. Here is an example of a module which installs an application. (\modules\installMyApp\installMyApp.vbs)
Function installMyApp objShell.run strInstallSource&"\MyApp\myapp.exe /quiet", 1, true End Function
The module is added to the main script logic file with the following directive.
<script language="VBScript" src="\modules\installMyApp\installMyApp.vbs"/>
The module is executed by simply calling the function during one of the steps.
installMyApp()
If you have any questions ask in the comments and let me know if you want more stuff like this
Here’s the zip file which contains the script structure and code.
Cheatsheet: Add HP Lefthand Storage Nodes
Dec 8th
Here are the quick high level steps for adding new storage nodes (P4000, P5400 etc) to your HP Lefthand iSCSI SAN (AKA StorageWorks P4000).
- Install and cable the units
- Check the HP site for firmware updates and apply ONLY the recommended updates
- Configure iLO so you don’t have to spend so much time in the cold room (optional)
- At the console on each unit give the first NIC an IP address. You can leave the other one disabled for now.
- Download and install the latest SAN/iQ Centralized Management Console on your workstation or management server
- In the CMC add the new nodes by going “Find Systems” and entering the IP addresses you assigned to the nodes
- Under “Available devices” go to the TCP/IP settings of each node and create a bond so the two NICs become one and choose a load balancing type.
- Go to http://webware.hp.com/ and generate your license keys. Each unit comes with an entitlement certificate. You’ll need to provide the Feature Key (MAC Address) which can be found in the CMC under “Feature Registration” for each node. When you get the key replace the one that’s in there by default.
- Right click the units and add them to an existing management group (or create a new one)
- Now that You have the units in the management group add them to an existing cluster (or create a new one)
Nodes must be of equal or greater capacity to existing nodes in a cluster. If they are of greater capacity then only the capacity of the smallest node in the cluster will be usable – Maybe time to create a new cluster?
I’ll let you fill in the detail but that’s basically it.
vbScript – Add to Local Group with Alternate Credentials
Dec 7th
This function adds a domain group to a local group but uses alternate credentials than that of the user account running the script.

This is handy when you’re doing automated deployments and you’re using auto admin login for post-install configuration.
Here’s the syntax (Note the forward slash to specify the name of the group you want to add the back slash for the credential). The function returns 0 if all is well.
AddToLocalGroup(LocalGroup, DomainGroup, DomainUser, Password)
e.g.
AddToLocalGroup("Administrators", "domain/groupToAdd","MyCompany\RhysAdmin","secretepassword")
And here’s the function
Function AddToLocalGroup(strLocalGroup,strDomainSlashGroup,strUsername,strPassword) on error resume next Dim strDctrl, strServerName, objDomainGroup, objLocalAdmGroup Const ADS_SECURE_AUTHENTICATION = &H1 Set oLocalAdmGroup = GetObject("WinNT://localhost/"&strLocalGroup&",group") Set objNS = GetObject("WinNT:") Set oDomainGroup = objNS.OpenDSObject("WinNT://" & strDomainSlashGroup & ",group", strUsername, strPassword, ADS_SECURE_AUTHENTICATION) oLocalAdmGroup.Add(oDomainGroup.AdsPath) AddToLocalGroup = Err End Function
Sometimes you just can’t find the exact snippet that you need. That happened to me today so there it is.





