Showing posts with label Technical HowTo. Show all posts
Showing posts with label Technical HowTo. Show all posts

Thursday, July 2, 2009

HP T5545 (Linux) VMWare View and USB Redirection

Well, since I’ve just spent the past 6 hours trying to figure out how the heck to get USB Redirection to work on HP T5545 , I thought I would write up some instructions on how to set it up, and all the gotchas to avoid.

For the record, I only set this device up because I got stuck with 50 of them for one of my schools, and for anyone who doesn’t want headaches, I would recommend they go with XPe (no, not WinCE), I’m pretty sure, the additional premium you will pay for the device itself will be saved in time trying to configure/troubleshoot, and update it. This recommendation is based on my usage with VMWare View (formerly VDI), and where USB Redirection is absolutely needed. For any other purposes (ie: terminal services, ICA, RDP, etc..) , I cannot vouch for it, but I would suspect it would work just fine if you’re on a lower budget.

ok, so now that the complaining about it is over, lets move on to some instructions on how to set this up.

These instructions do assume that you know how to create a VMWare View Desktop Pool, and have an appropriately created template that contains the View Agent in it, etc…  If not, there are some documents out there that describe this process, and you can see my post about Sysprep and VMWare View: the solution as well.

There are a few components that need to be setup correctly for this to work:

1- The HP RDP Multimedia and USB Enhancements (Server Side)

Now, this part, I’m not 100% sure on, but I think it’s only required when using an XPe client. In the case of Linux clients, the redirection is happening somehow within a Samba mount or something similar. If you find the need to install that, you can head over to HP Support site, and download the following file: http://bit.ly/bFKXS

Install this on your View Manager Connection Server, and reboot the server. no further action is required there.

2- Firmware and HP RDP Multimedia and USB Enhancements (Client Side)

This step was by far the most cumbersome, because I had to figure out HP’s way of installing their .hpk files, which are, I believe, essentially a modified .deb (Debian) package. so for this reason – being modified – the dpkg –install  does work on that package.
This is where the confusion starts. If you are running any firmware older than M5ST0019 rev 1 (Oct 6 2008), you will have a command called hpkg to install packages. On that firmware you would need 2 packages to install for the complete View experience.

Unfortunately, all these package are not all available on the “downloads” page of the T5545. (don’t ask me why!). after researching, I ended up finding the new version of the View Client which had the Sound and USB Redirection built into it. Since I can’t seem to find it anymore, I’m making it available through my DropBox. Download it HERE. (this file may disappear at any time, but for now, it’s here) The other file is available on HP’s site, and that is the counterpart of the HP RDP Multimedia USB Enhancements… this time, it’s for the client. you can get it HERE

Even though, if you really want to follow my ideal way, this will not be necessary (see below). but if you really don’t want to flash the firmware of the device, you may be able to get things to work by installing both of the above files.

To install an hpk on the old firmware, you create a new XTerm connection, within the connection manager. On the old firmware you have to create a Custom… connection, then type xterm for the command, and now you should have access to the shell.

change the user to root: su -  (the default password is “root”)
unlock the filesystem: fsunlock
install the package: hpkg –i <filename.hpk>
lock the filesystem: fslock

(In order to get the files to the thin client, you can do it in multiple ways, but I used the FTP method, because it was the simplest). if you know your way around the shell, you can always stick a USB thumb drive and copy the stuff from it. hint: it’ll get mounted on /media

ok, so now that I ranted on the old way, let me point you to the new way, and seemed to have been much less cumbersome. There are 3 ways you can do this, on a CD (you would have to connect an external optical drive to the thin client), a USB thumb drive (that’s how I did it), and for deployment … (haven’t figured out how to use this one, but I’m pretty sure, it’s meant to work with Altiris deployment packages.

What we’re going to do here is flash the firmware to the latest version. Don’t be fooled, as of this writing, HP did not have the latest firmware on their website, so I had to fish for it with Dr. Google’s assistance. I finally found it HERE. When you download this, you will need a flash drive that’s bigger than 512Mb (1Gb should be ideal). just run the file, and choose the “USB” option when it pops up. note: you will lose all data on your flash drive when you do this. The drive will be loaded with the new firmware. once this is done, stick the USB thumb drive in your thin client, and reboot. You don’t have to change boot order, as USB is already enabled as the first boot device.  It’ll ask you if you really want to flash it, Answer “Y” , and wait about 5 minutes, the Thin Client will reboot and comes back up with the new firmware.

Now, your VDM client will be named View client, and will have more options on it. When you create a session, under “Options” there will be an additional setting called “ Sound Redirection” , and another one called “ Device Mapping”, which allows for mapping the USB Storage, Serial port and Printer mapping. for USB Storage, you can also select what drive you want the USB storage to map to. Enable whichever ones you want.

Prior to this firmware, the USB redirection hpk would’ve done what this one does natively. Though I never got the first solution to work fully, it looked to me like the HP RDP Multimedia USB Enhancements had way more options than the new View client. But I had no need for the other ones, and I couldn’t figure out how to install an hpk package on the new firmware, since the hpkg command no longer existed in the new firmware. Anyone that may have any insight on this, please share in the commends.

 

3- Your Virtual Machine template.

You may be thinking.. duh ! that’s simple. Well, that was one of the components that threw off for a loop, at least in regards to USB Redirection. You see, for USB redirection to function correctly, you need to have an actual virtual USB controller connected to the VM. you can install all plugins and add-ons all over the place, but without the controller, nothing will work.

Capture 9   Capture 10

When all is well with the USB controller, your VM should be showing all the items in the blue in addition to the items in the red box. Without the USB controller, and provided you had installed all the required add-ons on your thin client, you will see only the items in the red box.

4- Your Group Policies in Active Directory

This was a tricky one, and mostly due to the fact that USB Redirection on the Linux Thin Client does not work in the same as you would expect any USB redirect (at least I don’t think so) . What the redirect is doing, is really mounting the USB device to the Linux OS, and then the mechanism of the firmware (when USB redirection is enabled) somehow shares that drive as an SMB share, and makes it available to the connected View client. So this is where the drive letter comes into play. Of course, not knowing this, I had GPOs in AD that locked down printer redirection, COM ports, LPT ports, and most importantly for my purposes drive redirection. this was a no no, and was causing the whole system not work. So, what have we learned here? make sure you either choose NOT CONFIGURED or DISABLED on that option if you would like to stay sane.

 

When you have all this enabled, don’t expect a whole lot with USB redirection. For very novice users, it’s still going to be very confusing. The drive will get mapped by the volume name of the USB drive, or sometime by the Linux path, and does not get deleted when you remove the drive, though the user can actually delete the “ghost” folder, it’s still very confusing.

Also, it’s not instantaneous, when you plug in a USB device, especially if it’s a large capacity device with some data on it, the Linux OS has to scan it, mount it, and share it out, before the Windows OS can even figure out that it’s there. Bottom line, Windows does not see the USB device as a USB device, but rather, a SAMBA share.

I have not tested how that type of redirection will be affected by disabled USB access from VDI manager policies. That is something that is still up for testing. If I find something interesting there, I’ll make sure to post that.

 

Well there you have it, T5545 Thin Client USB Redirection, finally working. 

Sunday, June 21, 2009

Rowmote Pro for iPhone: Review and Demo

If you’re like me, and you have done away with your cable subscription, and transformed your whole media center to Boxee, or Plex, then this review is for you. In fact, even if you don’t use Boxee or Plex, but have a computer connected to your TV that you’d like to control. This is also for you.

Since I got rid of my cable, I setup an iMac to take care of all my media. It was a nice setup, except I didn’t have full access to the computer, unless I had my laptop, and connected to it via LogMeIn or TeamViewer, or, for much less control, using the native Boxee remote for the iPhone, or even the Rowmote free application.

These were all fine and dandy, but I really wanted full access to the machine without having my laptop or another computer around. Before finding out about Rowmote Pro, or even before it ever existed, and I went and bought the Adesso Wirelsss Slimtyouch Mini-Mac, which I paid $80 for, and turned out to be a total waste of money, in short, very short range, and battery life lasts 2 days at best.

 

Enter Rowmote world. If you have an iPhone, you’re going to be blown away by what this app does! It’s only $4.99 – well, $4.99 + $199 or $299 at best if you don’t have an iPhone yet :) You may be familiar with the regular interface of Rowmote which looks something like this:

IMG_0362

However, you may not know this interface: IMG_0364  IMG_0363

IMG_0367IMG_0366Yup .. you’re getting a sweet interface to control your mouse and keyboard straight from the Rowmote application. In its original interface, Rowmote now supports over 17 applications, and obviously, anything you can do on the PC outside of the native Rowmote controls. 

 

Check out the video below for a live demonstration of Rowmote Pro. It’s definitely worth the $4.99.

 

 

 

 

 

 

Rowmote Pro Demonstration

Friday, June 19, 2009

VMWare View (VDI) client for HP T5540 (WinCE)

So, here I am sitting at my office trying to get VMWare View to work on an HP T5540 thin client. Had no idea where to get the client for. the 11Mb file that you get from VMWare is entirely too big to be intalled on that client. This is a Win CE operating system, which is so horrible to deal with anyway.

Google searches failed me left and right, everywhere I looked. People said that the T5540 can only be used in a remote desktop environment, which, of course, will lose out on the capability of VDI, dynamic provisioning, multiple desktop availability, Multimedia, and USB. Essentially, all the advantages of VDI would’ve gone down the drain. so that was not an option for me.

Some mentioned JRE version for Win CE, on which the VDI client will run. I had 2 problems with this one:

  1. I couldn’t easily find a free JRE client for WinCE
  2. For the life of me, I could not figure out how to get VDI Manager to use JRE.

So, I went ahead with my research, until I stumbled upon something called the VDI Broker Add-On for Microsoft Windows CE.  That can be found here: http://bit.ly/16M38p

If you look closely at the description of this download, however, you will find that it says this:

"This is an Altiris package that contains the VDM Broker Agent for the supported thin client models running a supported operating system.”

Hmm.. I thought I’d try it anyway. Downloading the file wasn’t a problem. Running the file, however, was. It just plain wouldn’t run from the T5540.

So poking around some more, I finally got the solution. Unzip the EXE that is supposedly designed for Altiris, and you will find a little file (145Kb)  called VDMClient.cab, which will do the trick. Now, copy this to your T5540, and run it, and you shall have your VDI client available.

This took me about an hour of research to figure out, since there is absolutely no documentation I could find about it anywhere!. 

Hopefully this will help someone that may be having the same problem.

Sysprep and VMWare View: the solution

I’m in the process of implementing VMWare vSphere 4.0 at work, with an add-on for VMWare View.

I had been working with ESXi for a while, so the switch to ESX 4 wasn’t too hard. On the View side, the learning curve was quite easy as well. There’s little that needs to be done in VDI Manager, and the rest is managed just like it would be managed on a physical machine deployed.

For those techies reading this that haven’t dealt with sysprep yet, it’s a Microsoft utility, which you can install, and it ends up residing in C:\Windows\System32\deploy.cab , unzipping this cab will reveal a set of files required to sysprep a machine.

Essentially, sysprep is used when mass deploying desktops on the same network, this could be problematic, because each computer has a SID which is a long number that identifies the computer on the network. By imaging a hard drive without sysprep at all, there will be conflicts, especially if this machine is part of a domain. Part of sysprep’s job is to strip out these SIDs and regenerate them when the machine is re-imaged.  Other things sysprep can do is unattended installations, by automating entering the Windows license key, joining to the domain (which is the main point of this article), setting time zones, IPs, etc …  (If there is any interest in speaking in more detail about sysprep, post it in the comments, and I can write up an article dedicated to that.)

For those who ARE very familiar with sysprep, you would know that it’s not the most reliable tool to join the machine to the domain when a workstation is booted up with the mini-setup.

Let’s skip ahead and get into VMWare View world. For VDI Manager to work correctly and create desktop pools, the process of creating machines and provisioning them for users has to be flawless, otherwise, the purpose of VDI manager is in vain. The fact that sysprep wasn’t working, meant that the machines weren’t joined to the domain. One failing step is enough to fail everything.

So I decided to create a solution that will allow me to do so much more than sysprep because it creates a framework of setting up a machine through a script that can be expanded as needed. All this while keeping the number of my templates to a minimum. In my case, for a basic user template, a total of ONE!

Keep in mind, in my environment, I have 3 domains, (forest root, and 2 child domains), Machines that are in the VDI Manager desktop pools have to go to their corresponding locations in Active Directory, and even more broadly, to the correct domain.

I decided to leverage the information in the customization wizard in vCenter to provide the information needed for the script to know what domain to add the machine to, and what OU to place it in.

The customization specification manager looks something like this:

Capture 3

In the settings one of these templates, 2 key screens that need to be setup correctly:

Capture 4

This first screen will tell the virtual machine to call itself by the same name as the VDI pool naming scheme is setup as. So if the VDI pool is setup to name the machine as labmachine- with an increasing sequence, my machines will start to automatically pop up with the names: labmachine-1 , labmachine-2, labmachine-3 , for as many machines that I allow in the pool.

The second screen is very simple, and often overlooked:

Capture 7

The second part in this screen is the one that doesn’t work. The part I want to direct your attention to is the “Workgroup” field. In this screenshot, the workgroup is set to “WORKGROUP” for our purposes, I’m changing this workgroup to the NetBios name of the 3 domains I have. I know this will not join the machines to the domain, but this will be leveraged by the script that will get that name and perform the appropriate actions.

Now that this environment is ready. I create a script with Kixtart (which very much like VB, only more geared towards login scripts).

 

   1: ;region Script Settings
   2: ;<ScriptSettings xmlns="http://tempuri.org/ScriptSettings.xsd">
   3: ;  <ScriptPackager>
   4: ;    <process>kix32.exe</process>
   5: ;    <arguments />
   6: ;    <extractdir>%TEMP%</extractdir>
   7: ;    <files />
   8: ;    <usedefaulticon>true</usedefaulticon>
   9: ;    <showinsystray>false</showinsystray>
  10: ;    <altcreds>false</altcreds>
  11: ;    <efs>true</efs>
  12: ;    <ntfs>true</ntfs>
  13: ;    <local>false</local>
  14: ;    <abortonfail>true</abortonfail>
  15: ;    <product>VDI Workstation Joiner</product>
  16: ;    <internalname>VDIWKJoin</internalname>
  17: ;    <version>1.0.0.1</version>
  18: ;    <versionstring>1.0.0.1</versionstring>
  19: ;    <description>Script to run at the startup of a machine after being sysprepped that will join it to the domain, and install LANDesk on it. </description>
  20: ;    <comments />
  21: ;    <company>Chino Valley Unified School District</company>
  22: ;    <includeinterpreter>false</includeinterpreter>
  23: ;    <forcecomregistration>false</forcecomregistration>
  24: ;    <consolemode>false</consolemode>
  25: ;    <EnableChangelog>false</EnableChangelog>
  26: ;    <AutoBackup>false</AutoBackup>
  27: ;    <snapinforce>false</snapinforce>
  28: ;    <snapinshowprogress>false</snapinshowprogress>
  29: ;    <snapinautoadd>0</snapinautoadd>
  30: ;    <snapinpermanentpath />
  31: ;  </ScriptPackager>
  32: ;</ScriptSettings>
  33: ;endregion
  34:  
  35: ;
  36: ; Script Packager Template
  37: ; Creates variables For dynamic use by packaged executables and normally executed scripts
  38: ;
  39: ; (C) 2004-06 iTripoli, Inc.
  40: ; 
  41:  
  42:  
  43: If %ISEXE% = "1"
  44:     $HKCU = %ASEHKCU%        
  45:     $CURDIR = %ASEEXEPATH%            
  46:     $SCRIPTARGS = %ASEEXEARGS%    
  47:     $FullID = %ASEUSERID%    
  48:     $UserID = Right($FullID, ( Len($FullID) - (InStr($FullID, "\")) ))
  49: Else
  50:     $HKCU = "HKEY_CURRENT_USER"
  51:     $CURDIR = @CURDIR
  52:     $SCRIPTARGS = "n/a" ; KiX lets you specify variable values, but not open strings
  53:     $FullID = @DOMAIN + "\" + @USERID
  54:     $UserID = @USERID
  55: EndIf
  56:  
  57: Break ON
  58: Global $DEBUG $DEBUG = 0
  59: $ = SetOption("WrapAtEol","ON")
  60:  
  61: If Exist("C:\Windows\system32\stage1.dat") 
  62:     Use Z: /DEL
  63:     Use Z: "\\do-ld-core\wwwAgent\Windows_Agents" /USER:CVUSD\username /Password:*****
  64:     Shell '%COMSPEC% /c xcopy "z:\Windows_Agent_and_Antivirus_with_status.exe" "C:\"'
  65:     Use Z: /DEL 
  66:     Shell '%COMSPEC% /c start /wait /d"c:\" Windows_Agent_and_Antivirus_with_status.exe'
  67:     Shell '%COMSPEC% /c echo "Ready" > c:\windows\system32\ready.dat'
  68:     Del "C:\Windows_Agent_and_Antivirus_with_status.exe"
  69:     Shutdown("", "Computer shutting down - Ready", 5, 1, 1)
  70:     
  71:     Exit 0
  72: EndIf
  73:  
  74: ; Get Workstation name, and school number
  75: Global $ComputerName $ComputerName = @WKSTA
  76: Global $Prefix $Prefix = (Trim(Left($ComputerName, ( InStr($ComputerName, "-") - 1 ))))
  77:  
  78: ; Get WORKGROUP NAME
  79: Global $WORKGROUP
  80: $wmiColl = GetObject("WinMgmts:root/cimv2").ExecQuery("Select * FROM Win32_ComputerSystem ")
  81: For Each $wmiObj in $wmiColl
  82:     $WORKGROUP = $wmiObj.Domain
  83:     If $DEBUG = 1
  84:         ? "DEBUG: WORKGROUP: " + $WORKGROUP
  85:     EndIf    
  86: Next
  87:  
  88: ; Check to make sure that the combination of the Computer name and the Site match. A machine name starting with "DO" can only be in the CVUSD domain. 
  89: If ($Prefix = "do" And Not $WORKGROUP = "cvusd")
  90:     $ = MessageBox("Machine name indicate that it needs to reside in the CVUSD domain. A different domain has been specified." + Chr(13) + Chr(10) + "Domain name specified: $WORKGROUP" + Chr(13) + Chr(10) + "Machine name specified: $ComputerName", "Domain and machine name do not match. ", 16)
  91:     Exit 1
  92: EndIf
  93:     
  94: Select
  95:     Case InStr($Prefix, "do") 
  96:         Global $NetDomCmd$NetDomCmd = $Prefix
  97:     Case isNumeric($Prefix) = 0
  98:         $SchoolNumber = $Prefix
  99:         If $DEBUG = 1 
 100:             ? "DEBUG: School number detected, running SQL Query"
 101:             ? "DEBUG: School number: " + $SchoolNumber + " - Prefix: " + $Prefix
 102:         EndIf
 103:         
 104:         
 105:         ; Get School OU for adding in Active Directory correct OU
 106:         $cnstring = 'Provider=SQLOLEDB.1;Password=*****;Persist Security Info=True;User ID=username;Initial Catalog=UserNameStore;Data Source=do-mgtweb;'
 107:         $cmdtext = 'SELECT TOP 1 OUName, SchoolNumber FROM AssetInfo WHERE (SchoolNumber=' + $SchoolNumber + ')'
 108:         $cn = CreateObject("adodb.connection") 
 109:         $cmd = CreateObject("adodb.command") 
 110:         $cn.connectionstring = $cnstring 
 111:         $cn.Open 
 112:         $cmd.activeconnection = $cn 
 113:         $cmd.commandtext = $cmdtext 
 114:         $rs = CreateObject("adodb.recordset") 
 115:         $rs.cursortype = 3 
 116:         $rs.locktype = 3 
 117:         $rs.Open($cmd)
 118:         
 119:         While Not $rs.EOF And Not $rs.BOF
 120:             Global $OUName $OUName =  $rs.Fields.Item("OUName").Value
 121:             Global $SchoolNumber $SchoolNumber = $rs.Fields.Item("SchoolNumber").Value
 122:             $rs.MoveNext
 123:         Loop
 124:                         
 125:         If $DEBUG = 1 
 126:             ? "DEBUG: OU Name: " + $OUName ? "DEBUG: SchoolNumber: " + $SchoolNumber
 127:         EndIf
 128:         
 129:         $rs.Close
 130:         $cn.Close
 131:     Case 1
 132:         $ = MessageBox("Unrecognized machine format - Cannot continue. Machine name needs to start with DO or the School Number. " + Chr(13) + Chr(10) + "i.e: do-machinename or 309-machinename", "Unrecognized machine format", 16)
 133:         Exit 1
 134: EndSelect
 135:  
 136:  
 137:  
 138: Select 
 139:     Case $WORKGROUP = "CVUSD"
 140:         Global $OU $OU = $OUName
 141:         Global $Domain $Domain = "CVUSD\do-dc2.chino.k12.ca.us"
 142:         Global $DomainAdmin $DomainAdmin = "CVUSD\username"
 143:         Global $DomainPassword $DomainPassword = "*****"
 144:         If $DEBUG = 1
 145:             ? "DEBUG: OU: " + $OU ? "DEBUG: Domain: " + $Domain ? "DEBUG: Domain Admin: " + $DomainAdmin ? "DEBUG: Domain Password: " + $DomainPassword
 146:         EndIf
 147:         domainjoin($Domain, $DomainAdmin, $DomainPassword,, "Do")
 148:         Shutdown("", "Computer shutting down - Stage 1 Complete",5, 1, 1)
 149:     Case $WORKGROUP = "STUDENT"
 150:         ;? "IN STUDENT"
 151:         Global $OU $OU = 'ou=workstations,ou='+ $OUName + ',ou=Schools,dc=student,dc=chino,dc=k12,dc=ca,dc=us' 
 152:         Global $Domain $Domain = "STUDENT\do-studc.student.chino.k12.ca.us"
 153:         Global $DomainAdmin $DomainAdmin = "STUDENT\username"
 154:         Global $DomainPassword $DomainPassword = "*****"
 155:         If $DEBUG = 1
 156:             ? "DEBUG: OU: " + $OU ? "DEBUG: Domain: " + $Domain ? "DEBUG: Domain Admin: " + $DomainAdmin ? "DEBUG: Domain Password: " + $DomainPassword
 157:         EndIf
 158:         domainjoin($Domain, $DomainAdmin, $DomainPassword, $OU, $SchoolNumber)
 159:         Shutdown("", "Computer shutting down - Stage 1 Complete",5, 1, 1)
 160:     Case $WORKGROUP = "STUDENT2"
 161:         Global $OU $OU = 'ou=workstations,ou=' + $OUName + ',ou=Schools,dc=student2,dc=chino,dc=k12,dc=ca,dc=us'
 162:         Global $Domain $Domain = "STUDENT2\do-studc2.student2.chino.k12.ca.us"
 163:         Global $DomainAdmin $DomainAdmin = "STUDENT2\username"
 164:         Global $DomainPassword $DomainPassword = "*****"
 165:         If $DEBUG = 1
 166:             ? "DEBUG: OU: " + $OU ? "DEBUG: Domain: " + $Domain ? "DEBUG: Domain Admin: " + $DomainAdmin ? "DEBUG: Domain Password: " + $DomainPassword
 167:         EndIf
 168:         domainjoin($Domain, $DomainAdmin, $DomainPassword, $OU, $SchoolNumber)
 169:         Shutdown("", "Computer shutting down - Stage 1 Complete",5, 1, 1)
 170:     Case 1
 171:         $ = MessageBox("Unrecognized domain - Cannot continue. Domain is not recognized. This should have been specified in the Customization Specification in vCenter" + Chr(13) + Chr(10) + "Valid domain names: CVUSD, STUDENT, STUDENT2", "Unrecognized Domain", 16)
 172:         Exit 1
 173: EndSelect
 174:  
 175: ; FUNCTIONS
 176:  
 177: Function domainjoin($Domain, $DomainAdmin, $DomainPassword, OPTIONAL $OU, $Location)
 178:     If $DEBUG = 1 
 179:         If $WORKGROUP = "CVUSD"
 180:             $OU = "CN=Computers,DC=chino,DC=k12,DC=us"
 181:         EndIf
 182:         ? "Fn DEBUG: OU: " + $OU 
 183:         ? "Fn DEBUG: Location: " + $Location                    
 184: EndIf
 185:     
 186:     Select
 187:         Case $Location = "do"
 188:             Shell '%COMSPEC% /c c:\windows\netdom.exe join ' + @WKSTA + ' /d:' + $Domain + ' /UserD:"' + $DomainAdmin + '" /PasswordD:' + $DomainPassword
 189:                 If $DEBUG = 1
 190:                     ? ? 'DEBUG: Shell "%COMSPEC% /c c:\windows\netdom.exe join ' + @WKSTA + ' /d:' + $Domain + ' /UserD:"' + $DomainAdmin + '" /PasswordD:' + $DomainPassword
 191:                 EndIf
 192:             Shell '%COMSPEC% /c echo "Stage 1" > c:\windows\system32\stage1.dat'    
 193:         Case isNumeric($Location) = 0
 194:             Shell '%COMSPEC% /c c:\windows\netdom.exe join ' + @WKSTA + ' /d:' + $Domain + ' /UserD:"' + $DomainAdmin + '" /PasswordD:' + $DomainPassword + ' /ou:"' + $OU + '"'
 195:                 If $DEBUG = 1
 196:                     ? ? 'DEBUG: Shell "%COMSPEC% /c c:\windows\netdom.exe join ' + @WKSTA + ' /d:' + $Domain + ' /UserD:"' + $DomainAdmin + '" /PasswordD:' + $DomainPassword + ' /ou:"' + $OU + '"'
 197:                 EndIf
 198:             Shell '%COMSPEC% /c echo "Stage 1" > c:\windows\system32\stage1.dat'
 199:         Case 1    
 200:             $ = MessageBox("The location passed to function is not recognized. " + Chr(13) + Chr(10) + "value passed need to be - do - or a school number. ", "Function error", 16)
 201:             Exit 1
 202:     EndSelect
 203: EndFunction
 204:     
 205: Function isNumeric($var)
 206:     If $DEBUG = 1
 207:         ? "Fn DEBUG: Reached iNumeric Function"
 208:     $IsNumeric = Not IIf($var = 0.0 + $var, 1, 0)
 209: EndFunction
 210:  
 211:  
 212:  
 213:  
 214:  
 215:  
 216:  

What this script does is run on the first login after the Virtual Machine has been deployed by VDI Manager and will do the following:

  • It will check to see if the machine name starts with a prefix acceptable, in my case, it was either DO for the district office, or a 3 digit number for any of the schools. This means that any of the provisioned VMs have to match this naming convention or an error will be thrown upon login.
  • If the machine starts with “do”, then it’s a valid workstation name, next, the script will check for the WORKGROUP that we specified in the customization specification manager, by doing a WMI call to root/cimv2 database, and get the computer workgroup name. This workgroup returned,  will correspond to one of the 3 domains. Anything else will fail.
  • In the case of DO, not much is required, all machines are dumped into one OU. In the case of the schools, it’s more complicated: in my case, computers sit in different OUs, so  in the case of a computer name that starts with a number (corresponding to a school), a database (that I created)  query is made that will get me the corresponding OU for the school in question.
  • Now that all the information is gathered, the script will continue on to run the Netdom command to join the machine to the domain.
  • After this is done, the script will raise a flag  to create a file to let the system know that it’s been already setup.

This script is very flexible because it’s being run independently from sysprep. I trigger it from the Programs/All Users/startup.bat, which calls another batch file:

 

 

   1: @echo off
   2:  
   3: IF EXIST "c:\windows\system32\ready.dat" GOTO DELETEWSSETUP
   4: IF EXIST "c:\windows\system32\wssetup.exe" GOTO SETUP
   5: GOTO END
   6:  
   7: :DELETEWSSETUP
   8: DEL C:\Windows\system32\wssetup.exe
   9: GOTO EXIT
  10:  
  11: :SETUP
  12: c:\windows\system32\wssetup.exe
  13: GOTO EXIT
  14:  
  15: :END
  16: GOTO EXIT
  17:  
  18: :EXIT
  19:  

This script will trigger the main vbscript which is represented as wssetup.exe. I encoded it in an exe, to hide any sensitive information in the script. i.e: database and domain passwords.

The rest of it just monitors the environment to make sure that everything has been ran. Once it has, and it finds the flag specified by the original script. It deletes that original script leaving no trace behind it. At this point the machine is ready to go.

This setup is very flexible, because it allows the adding of any number of functions to run at the setup of the machines prior to the users even touching them. Think, install applications, anti-virus software, customization, etc…