<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.brianmadden.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Ron Oglesby</title><subtitle type="html">Ron Oglesby is the Director of Virtualization and Architectural Services at GlassHouse Technologies, and was formerly Director of Technical Architecture for RapidApp. He has been published in several industry magazines and is the co-author of several books including CCA Study Guide for MetaFrame XP, Terminal Services for Microsoft Windows Server 2003, and VMware ESX Server: Advanced Technical Design Guide. Ron is a Microsoft Terminal Server MVP.</subtitle><id>http://www.brianmadden.com/blogs/ronoglesby/atom.aspx</id><link rel="alternate" type="text/html" href="http://www.brianmadden.com/blogs/ronoglesby/default.aspx" /><link rel="self" type="application/atom+xml" href="http://www.brianmadden.com/blogs/ronoglesby/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.30929.2835">Community Server</generator><updated>2004-04-07T00:45:00Z</updated><entry><title>Where is all this virtualization going?</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2006/08/27/where-is-all-this-virtualization-going.aspx" /><id>/blogs/ronoglesby/archive/2006/08/27/where-is-all-this-virtualization-going.aspx</id><published>2006-08-28T02:00:00Z</published><updated>2006-08-28T02:00:00Z</updated><content type="html">&lt;p&gt;I sat down with a client the other day and was asked some pretty simple questions that couldn&amp;rsquo;t easily be answered. Those questions were, &amp;ldquo;So where is virtualization going anyway? Not in the next 12 months, but in the next 2-3 years? What should we know about virtualization that&amp;rsquo;s going to mean big changes like the first implementation we put in of our virtualization platform?&amp;rdquo;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This drove an interesting discussion with some follow up on my part in both research and some long thought over numerous cold beers and a whiteboard. Once I figured out where I thought it was going, I started putting my ideas into Word and figured more people than just me would be interested in where this is all going and why it&amp;rsquo;s important. Of course I have no crystal ball--this is just one guy&amp;rsquo;s opinion of where things are and where they will be going. (Feel free to comment with your thoughts.) &lt;/p&gt;
&lt;p&gt;Right now you can talk to any company paying lip service virtualization or that considers themselves virtualization experts and they will begin to talk about the &amp;ldquo;future&amp;rdquo; of virtualization.&amp;nbsp; Inevitably they all say some (or all) of the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Virtualization will expand beyond just servers and into the desktop realm. (Mostly people are talking about &lt;a href="http://www.brianmadden.com/subject.asp?ID=39"&gt;VDI&lt;/a&gt; here, and of course about five different packages for VDI have been released this year alone.) &lt;/li&gt;
  &lt;li&gt;Virtualization will take the next step into the enterprise expanding beyond server consolidation.&lt;/li&gt;
  &lt;li&gt;Virtualization technology&amp;rsquo;s next step is to get better performance from VMs to assist the move deeper into the enterprise.&lt;/li&gt;
  &lt;li&gt;Virtualization may act as a conduit for software vendors to deliver application appliances to you preconfigured and ready to go, You just modify some settings for your environment and you are up and running.&lt;/li&gt;
  &lt;li&gt;Built-in virtualization technology at the hardware level will take it to the next step. (Here we&amp;rsquo;re talking about processors that are moving system calls for VMs out of Ring 0 and into &amp;ldquo;Ring 1,&amp;rdquo; or Network adapters and HBAs that have built-in hardware hypervisors to allow for better control and resource allocation at that level.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyway, if you read this the way I do, I don&amp;rsquo;t see anything huge here. I mean when ESX really started making an impact in IT a couple of years ago it did so because it changed the landscape of IT infrastructure as we know it. It changed the way servers were provisioned and spec&amp;rsquo;d out, how they were purchased, and the number purchased. It changed every calculation we had been making from the cost of the servers to amount of HVAC, floor space, UPS capacity, power, network requirements, and storage we needed. It changed the mindset of architects and engineers when designing solutions and gave them options they never dreamed of. It allowed the businesses to drive down costs while still providing the same levels of service on a lot of applications all the while decreasing recovery time for individual applications both locally and during DR. &lt;/p&gt;
&lt;p&gt;Do &lt;em&gt;any&lt;/em&gt; of the &amp;ldquo;future of virtualization&amp;rdquo; statements above come anywhere near to having this kind of impact? Or does it really just extend the existing benefits a little bit without changing our mindset and the way we&amp;rsquo;re already doing things with our virtualization technology of choice?&lt;br /&gt;
  In a drive-by world where everything is &amp;ldquo;what can you do for me today,&amp;rdquo; most people aren&amp;rsquo;t looking at the reality of this technology&amp;rsquo;s future. The reality is that sooner or later it&amp;rsquo;s going to be a commodity just like hardware. Face it, virtualization is just another way to supply hardware to an operating system and its applications. The future of virtualization isn&amp;rsquo;t in the stuff listed above. These items (for sure the hardware) will have an impact on &lt;em&gt;how&lt;/em&gt; virtualization is done, but software that virtualizes hardware (in a couple of years) will be a commodity just like the hardware it runs on. When you select that software you will do so just like you purchase hardware. Right now I believe that the real race going on in the virtualization space isn&amp;rsquo;t about who can Vmotion or support four processor VMs, etc. The real race is about who has the first lightweight fully integrated hypervisor that is OEM&amp;rsquo;ed on servers and desktops. (That&amp;rsquo;s right, I said &amp;ldquo;desktops,&amp;rdquo; but we&amp;rsquo;ll get back to that in a minute)&lt;/p&gt;
&lt;p&gt;When people talk about a hardware hypervisor (Microsoft, a hardware vendor, VMware, anyone), most people listening assume this is built right into the hardware and then you will install the OS&amp;rsquo;es right into this. Let&amp;rsquo;s be realistic. Even when it&amp;rsquo;s &amp;ldquo;built right into the hardware,&amp;rdquo; it&amp;rsquo;s still software. The line between hardware and software has blurred over the years with on-board BIOS&amp;rsquo;s for hardware components that are fully configurable and upgradeable. The only thing keeping them from being their own OS is that they can&amp;rsquo;t manage other hardware components and you can&amp;rsquo;t install an app to it.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s picture a world where you buy an HP server, with OEM&amp;rsquo;ed Qlogic HBAs, Intel or OEM&amp;rsquo;ed Intel nics, memory from HP or Crucial, or (insert favorite vendor here), processors from AMD or Intel, drives from... you get the picture. Even if the processors, NICs, and HBAs all had hardware hypervisors built-in to them, what controls those hypervisors and connects VMs to them? What connects a virtual machine to each of these components? Right now the closest thing to bare metal is ESX. And improvements to the hardware will make ESX&amp;rsquo;s performance even closer to raw hardware performance. But what is the future? The Future is a thin layer that is OEM&amp;rsquo;ed that can work with and control all these devices. It will not be as bulky as any Windows or Linux OS you have ever seen and will more closely resemble a glorified piece of firmware that boots and starts dividing up resources to whatever number of VMs you have running on the machine. Of course it will still have some type of interface while the server and its VMs are running, but it will be extremely lightweight and self-sustaining. This will come with every x86 server and desktop. What you will buy is not the hypervisor but the management tools that wrap around it. That is the key and this is where we bleed into desktops a bit.&lt;/p&gt;
&lt;p&gt;Right now on a desktop you have a single OS. (Let&amp;rsquo;s not talk VMware workstation of Virtual PC for this article) with applications installed, Anti-Virus, Spy/Malware detection and removal software, an Internet browser, etc. What if your machine didn&amp;rsquo;t look like this? What if your machine looked like the image below?&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.brianmadden.com/library/content/futurevmdesktop.jpg" width="400" height="300" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;In this example all four VMs would load at boot time. The network and security VM would be the first one up after the hypervisor loads. This VM will scan all traffic in and out almost like a network virus wall or a SMTP gateway server. It could be a one-stop shop for traffic scanning, IDS, IPS and even traffic scanning between VMs. This security VM may even be a VM that comes OEM&amp;rsquo;ed along with the hypervisor. &lt;/p&gt;
&lt;p&gt;Next is your trusted desktop. This is where you work normally on your corporate LAN and interacted with trusted machines/networks. What machines and networks are trusted is configured in the security VM and is possibly centrally controlled by an administrator. The cool thing is that if this is a personal laptop or computer you may be able &amp;ldquo;outsource&amp;rdquo; your security by buying a subscription to &amp;ldquo;Symantec&amp;rsquo;s Security VM Package.&amp;rdquo; (I know, it&amp;rsquo;s a lame name, but it&amp;rsquo;s all I could come up with.) Anyway, the package may be purchased and delivered to the user to replace an existing one shipped by the hardware vendor (back to application distribution by VM appliance). They can then offer you a service where they update the VM (like getting new virus definitions) but in this case it&amp;rsquo;s virus, malware, spyware, firewall, etc., and it&amp;rsquo;s not tattooed in the trusted OS and can be hardened in ways that the trusted OS can&amp;rsquo;t while still remaining functional.&lt;/p&gt;
&lt;p&gt;The trusted desktop is now behind a line of security that will protect it from the outside and from other VMs. Then you have a default non-trusted application VM. Maybe this VM runs applications like an Internet browser, media player, etc. This VM (or more likely its applications) is invoked whenever the user makes a call outside its trusted area or uses an application specifically configured for high security. This application is then presented to the trusted desktop (kind of like an ICA seamless window) but is actually running in another VM. The non-trusted application VM might not even have an entire OS like we know it. Instead this VM may be another VM Appliance that has a small OS that loads just enough to support that browser app and a few multi-media type apps and presents the screen (like ICA or RDP) into a window in the Trusted VM.&lt;/p&gt;
&lt;p&gt;Finally, you&amp;rsquo;ll have the ability to add other VMs as needed. Maybe you&amp;rsquo;re contractor like I am and need a specific build with a specific virus package and hotfixes to connect to a client site. This hypervisor&amp;rsquo;s configuration would allow for that to be added, and may even have a rule base setup in the hypervisor that says, &amp;ldquo;When Contract A VM is turned on the trusted VM isn&amp;rsquo;t able to connect to the network.&amp;rdquo; Then when I am at the client site I invoke their VM (maybe by booting it, or maybe by simply using a hotkey sequence almost like an Alt-Tab) and I am ready. Their security team could even have these VMs preconfigured for delivery to contractors or even new employees. (There I go again with Virtual Appliances, only in this case it&amp;rsquo;s a home grown one.)&lt;/p&gt;
&lt;p&gt;As you can see the concept laid out above &lt;em&gt;would&lt;/em&gt; solve a number of issues and change the way we do desktops. It would increase security, allow for isolated work environments that are independent of each other and allow for minute control of the desktops at a level we don&amp;rsquo;t have now. In addition it would allow vendors numerous options, like delivering security packages in whole to a desktop and not worrying about &amp;ldquo;what rev of windows do they have, this doesn&amp;rsquo;t run on XP SP2&amp;rdquo; yet, etc. Hell the firewall VM may even be able to allow you to shut down network connectivity from that machine after so many days without an update. Wouldn&amp;rsquo;t that be cool!&lt;/p&gt;
&lt;p&gt;Anyway, with the impact this could have on the desktop and the complexity that it would introduce from a management standpoint, I think you can see where I am going by now. Imagine the following environment at the server level:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A security VM independent of the hypervisor that can does IDS and IPS for all the VMs on the host along with acting as a network virus wall.&lt;/li&gt;
  &lt;li&gt;A configuration VM that manages the hypervisor on that box that is independent of the security VM but relies on it.&lt;/li&gt;
  &lt;li&gt;A VM appliance supplied by your backup vendor that you put on each server that acts as a backup job manager for each VM This would manage backup resources of VMs on that host ensuring that not all the bandwidth or processing resources were being hogged by doing a large number of VMs at once. It just detects the VMs running right now on that host and (based on configurations from the centralized management server) schedules and moves jobs accordingly.&lt;/li&gt;
  &lt;li&gt;A central management tool to handle the configuration of the hardware hypervisor, the management and interaction with the hardware, and the startup sequence of the appliance VMs that will support the application VMs you&amp;rsquo;ve installed. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Really, the numbers of things that can be done on the server side are endless, and I&amp;rsquo;ve just touched on a few. But the bottom line is that in the future the hypervisor &lt;em&gt;will&lt;/em&gt; be a commodity. The future of virtualization is a lightweight hypervisor that will &lt;em&gt;manage&lt;/em&gt; the hardware and its extended capabilities being built into NICs, HBAs, disks, processors, etc., to support numerous OSes/VMs on a single server. No hardware fix will show up to make Intel, Broadcom, AMD, QLogic, Emulex, all be managed the same way by some piece of firmware on the motherboard. Nope. It will be software and it will be installed on every server that roles out of HP or Dell or IBM. You may still choose to use only one OS but you don&amp;rsquo;t have to. &lt;/p&gt;
&lt;p&gt;Now you may ask, &amp;ldquo;Who will provide it?&amp;rdquo; Who knows? My bet is VMware gets there first. They just have too much of a lead in second quarter of the game. Whoever does it will more than likely provide the hypervisor for little cost to the OEMs with each server coming with a limited single host management tool. Then you would be able to purchase the additional tools to provide management to large numbers of hosts, their VMs, and the appliances being installed. This of course is all in addition to the things that tools like VirtualCenter already do (Vmotion, resource balancing, VM provisioning, automated host recovery, etc.).&lt;/p&gt;
&lt;p&gt;My guess is you will pick the hypervisor like you pick hardware vendors. You go into a shop with all HP servers and they basically run HP because they like the support, the tools available, the response they get from sales etc. You could say the same thing for an IBM or Dell shop. You will find the vendor that fits your needs and then buy in bulk. But the key will be the tools and mgmt options. You don&amp;rsquo;t find organizations buy 2 Dells this week, 4 HPs next week, 3 IBMs the following week. They purchase a standard and stick with it for they have found the vendor of a commodity that fills their needs. (I mean really is there &lt;em&gt;that&lt;/em&gt; much difference between a dual proc box from any of the vendors?) The reasons for purchasing hardware will be stated for the hypervisor use in the future. It&amp;rsquo;s just going to be an extension of the server. The other things are what&amp;rsquo;s really important.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=10574" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Server Virtualization" scheme="http://www.brianmadden.com/tags/Server+Virtualization/default.aspx" /><category term="VDI" scheme="http://www.brianmadden.com/tags/VDI/default.aspx" /><category term="Editorials" scheme="http://www.brianmadden.com/tags/Editorials/default.aspx" /></entry><entry><title>Citrix plans to enter VDI space: An analysis of their solution</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2006/08/03/citrix-plans-to-enter-vdi-space-an-analysis-of-their-solution.aspx" /><id>/blogs/ronoglesby/archive/2006/08/03/citrix-plans-to-enter-vdi-space-an-analysis-of-their-solution.aspx</id><published>2006-08-03T08:45:00Z</published><updated>2006-08-03T08:45:00Z</updated><content type="html">&lt;p&gt;Since my &lt;a href="http://www.brianmadden.com/content/content.asp?id=608"&gt;last article on the Virtual Desktop Infrastructure (VDI)&lt;/a&gt; topic, I have received a number of e-mails. Some show interesting tips, some are just angry at life (and me specifically at the time of their writing), and some point out some interesting solutions that are trying to fill the &amp;lsquo;pie in the sky&amp;rsquo; VDI solution I discussed last time. &lt;/p&gt;
&lt;p&gt;Now personally, I haven&amp;rsquo;t seen a solution that makes me jump up and down saying &amp;ldquo;this is the end all be all for VDI!&amp;rdquo; However, I have seen some interesting takes on the problems I pointed out previously. Because of the e-mails and calls I received, I&amp;rsquo;ve decided to do a series of articles on the different VDI solutions available today. In this article I&amp;rsquo;ll discuss a solution (forthcoming) from Citrix for VDI implementations, and in future articles I&amp;rsquo;ll look at packages from &lt;a href="http://www.leostream.com/" target="_blank"&gt;Leostream&lt;/a&gt;, &lt;a href="http://www.propero.com/" target="_blank"&gt;Propero&lt;/a&gt;, and any others I can get my hands on.&lt;/p&gt;
&lt;p&gt;Before I get into the Citrix solution I need to qualify it some. First of all, the Citrix solution is not on the street yet (while the ones from Propero and Leostream are). Second, the Citrix solution I&amp;rsquo;m going to describe is a &amp;ldquo;stopgap&amp;rdquo; solution. Citrix is working on a full featured solution for release at some point in the future and is targeting a solution that covers most of what I described in the first article. The solution they are going to release now is a stopgap to help their existing customers with the VDI issues they face and is not meant as the end-game.&lt;/p&gt;
&lt;p&gt;Okay, with the qualifications out of the way let&amp;rsquo;s talk about Citrix&amp;rsquo;s stopgap solution they&amp;rsquo;re calling the &amp;ldquo;Remote Desktop Broker&amp;rdquo; (or RDB). The concept with RDB is pretty simple; it&amp;rsquo;s an application that can feed parameters into the RDP client and provide you a way to manage connections and create resource pools of desktops (VMs, blades, etc.). The RDB application is installed on a Citrix Presentation Server and then published as an application. Users execute the application which then connects them to the type of desktop they (or the app) is configured for.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll get into more detail on HOW it works in a second, but for now understand that it&amp;rsquo;s an application, not a server, and because of this is it uses a double-hop scenario with ICA connecting to the Presentation Server and then RDP connecting from the Presentation Server to the virtual desktop. &lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.brianmadden.com/library/content/citrixrdb1.jpg" width="621" height="311" alt="" /&gt;&lt;/p&gt;
&lt;p&gt; If you imagine an exiting Citrix environment (shown above) using an ICA client to connect to a Presentation Server, you&amp;rsquo;ll note that you have some of the items you need to provide a really solid VDI solution. You have a web interface that will allow for &amp;ldquo;publishing of the desktop,&amp;rdquo; you have the inherent SSL connectivity for remote users that Citrix already provides, and you have some session management and some tools to show connections and their status. So what&amp;rsquo;s missing? A way to pool desktop resources, handle peripherals, etc. Citrix&amp;rsquo;s RDB will handle some of this for you.&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.brianmadden.com/library/content/citrixrdb2.jpg" width="595" height="323" alt="" /&gt;&lt;/p&gt;
&lt;p&gt; Citrix&amp;rsquo;s RDB will sit on top of your existing Citrix infrastructure. The concept is that the desktop broker application will be installed on your Presentation Servers. This application will communicate with an RDB database that will contain connection information for different pooled desktops. As pooled resources are used, they will be noted in this database so that the desktop is noted as &amp;ldquo;in use&amp;rdquo; and the next user will be routed to an unused desktop. If you look at the image above you&amp;rsquo;ll see that a connection will look something like this:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;User connects to a&amp;nbsp; Citrix Web Interface server (or uses some other Citrix      client)&lt;/li&gt;
  &lt;li&gt;Based on the credentials, a published application is made available for that user (in this case the RDB application).&lt;/li&gt;
  &lt;li&gt;The user launches the RDB application and is connected to the Presentation Server via ICA&lt;/li&gt;
  &lt;li&gt;Once the application loads, the user is routed to virtual desktop based on information in the RDB application. This is basically passing parameters to the Microsoft RDP client on the Presentation Server to tell it what end desktop to connect to. &lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;During execution RDB is going to check its database to determine which desktop is available from the pool the user is connecting to. &lt;/li&gt;
    &lt;li&gt;This information is passed to the RDB application which in-turn uses it to establish an RDP session to the Windows XP VM or blade.&lt;/li&gt;
    &lt;li&gt;When the application is closed the desktop is released.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;In looking at this you&amp;rsquo;ll notice right off that be that this is a &amp;ldquo;one session for the price of two sessions&amp;rdquo; deal. It&amp;rsquo;s a double hop. While it gets you to the desktop, its obviously not the most optimal configuration around. Citrix knows this, and this isn&amp;rsquo;t their long term design, but with this should come some cautions.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Speed screen latency reduction&lt;/em&gt; features will not help here. Most functionality/assistance you get with speed screen latency reduction features focus on making the users think that latency is not effecting their ICA session. Basically it works by detecting the font and size and color of the text being typed in the Citrix session then instead of waiting for that text to appear on the client it shows it on the client before the round trip communication ever happens. In this case the RDP client is essentially an image or movie like application and typing within it is an image change, NOT text within a field or form on the Citrix server. (Check out &lt;a href="http://www.brianmadden.com/content/content.asp?ID=234"&gt;this article&lt;/a&gt; for more details.) &lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Not all features available in Citrix will be available in the RDP session.&lt;/em&gt; There will be some features (noted later in this article) that you are used to with Citrix, but since it is not ICA to the XP Pro, it will not be full featured.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could put a third point here about it being a double hop, and the cost of a Citrix license without getting full features, etc., but I think that&amp;rsquo;s implied with these two other cautions.&lt;/p&gt;
&lt;p&gt;In caution number two I noted that you won&amp;rsquo;t get all of the features (Speed screen, good printer redirects, driver replication, pure session mgmt in the XP pro desktop etc), but you will get some. Citrix plans to offer the following:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;em&gt;Client Drives&lt;/em&gt;&lt;/a&gt;&lt;em&gt; Access.&lt;/em&gt; Users can share drive mappings between their hosted desktop and server drives. I must note I had mixed results with Client drives mapped to the Citrix session then mapped to the XP Pro session, but server drives did show up in my XP Pro desktop.&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;USB &lt;/em&gt;&lt;em&gt;Key Drives.&lt;/em&gt; Users can access USB devices through their hosted desktops; however, the key must be connected prior to session startup.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Audio&lt;/em&gt;. Users launching a hosted desktop the user can hear audio (for example,  using Microsoft Media Player), though this may require some ICA channel reconfiguration if you use RDB on an existing application host.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Single Sign On&lt;/em&gt;. When the user logs into the Citrix Web Interface and connects to the published hosted desktop, they can be      automatically logged into their virtual desktop using Citrix Password Manager. This one was kind of a pain for me as I do NOT use password      manager and I was required to sign into the Web Interface and then Sign in again to the Virtual Desktop. (Suggestion: Password Manager for free would      be nice!) &lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Printing&lt;/em&gt;. Users can print to locally installed printers as well as network printers. I had a couple of interesting issues with this that I believe are more related to the XP Pro desktop than the Citrix session. Again it leads back to not having a control agent with the XP Pro desktop and needing to do some manual configuration on the images used by the users. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The long and short of this solution is that it is a stop-gap. Basically it&amp;rsquo;s an application that will allow you to create pools of VMs or XP blades for your users, and use your Citrix servers as a proxy mechanism. Citrix is hoping that it can help its existing customers get over the big hurdles here by delivering a brokering mechanism and allowing them to leverage the existing Citrix tools to solve the other issues I&amp;rsquo;ve previously mentioned (secure remote access, web-based authentication, etc.). &lt;/p&gt;
&lt;p&gt;The disappointment to me is that Citrix wasn&amp;rsquo;t out in front of this a long time ago. Last year at VMworld people were all over themselves talking about Citrix servers on VMs or about running VM workstation instances on Citrix (which, by the way, is a ridiculously stupid idea) instead of focusing on creating real VDI tools and solutions. Hopefully the time-to-market on this won&amp;rsquo;t be too long and the follow-on product that will solve most of this product&amp;rsquo;s issues will not be to long of a wait. &lt;/p&gt;
&lt;p&gt;In my next article in the series I will take a look at Propero&amp;rsquo;s VDI solution.&amp;nbsp; I was going to use Leostream&amp;rsquo;s solution first but had a slight issue with it during configuration that I will have to discuss during the article. As always, e-mail or post comments, I look forward to most of them. J &lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=10388" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Technical Articles" scheme="http://www.brianmadden.com/tags/Technical+Articles/default.aspx" /><category term="VDI" scheme="http://www.brianmadden.com/tags/VDI/default.aspx" /></entry><entry><title>Virtual Desktop Infrastructures (VDI): What's real today, what's not, and what's needed</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2006/07/20/virtual-desktop-infrastructures-vdi-what-s-real-today-what-s-not-and-what-s-needed.aspx" /><id>/blogs/ronoglesby/archive/2006/07/20/virtual-desktop-infrastructures-vdi-what-s-real-today-what-s-not-and-what-s-needed.aspx</id><published>2006-07-20T11:00:00Z</published><updated>2006-07-20T11:00:00Z</updated><content type="html">&lt;p&gt;Over the last several months, the concept of a Virtual Desktop Infrastructure (VDI) has become the buzzword in a lot of IT shops. Organizations are using (or looking to use) VDI to solve a number of issues they are facing. Of course, for the last year I&amp;rsquo;ve been talking about what VDI is missing in order to make it a real solution and why it can&amp;rsquo;t beat Terminal Server in a lot of cases. Well, maybe I have seen the light. I mean for some problems, VDI is a perfect fit. For others it&amp;rsquo;s not so perfect but is still being crammed in nonetheless because someone hates Citrix or TS (or just loves VMware).&lt;/p&gt;
&lt;p&gt;In this article, we&amp;rsquo;ll quickly go through an example use case that a VDI solution will fit almost perfectly and the types of use cases where it doesn&amp;rsquo;t fit. (When VDI doesn&amp;rsquo;t fit it&amp;rsquo;s generally for cost reasons. I mean it would be great to have multi-node clusters for every server on the network but we don&amp;rsquo;t do it because of cost.) Once we look at the history of SBC and when to use VDI, I&amp;rsquo;ll then draw a &amp;ldquo;pie in the sky&amp;rdquo; VDI solution from the bottom level (the VMs) all the way to the top level (the management tools). I&amp;rsquo;ll note the components of the solution that are already available and, more importantly, describe in detail the components do not exist yet that are being looked at by numerous vendors.&lt;/p&gt;
&lt;p&gt;Before we get started, I want to point out that a number of organizations are implementing or have already implemented VDI solutions. For the most part, these solutions have been cobbled together with scripts, snips of custom code, hacking of existing products, and of course good old duct tape. This article describes a theoretical solution that could be implemented by a single vendor or two with a couple of core technologies, I am NOT saying that the items I say don&amp;rsquo;t exist can not be accomplished with hacks and tricks&amp;mdash;it&amp;rsquo;s just that no solution on the street has been developed as a package to address specific VDI shortcomings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is VDI?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First let&amp;rsquo;s describe VDI from a high level and compare it to more traditional server-based computing models. &lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.brianmadden.com/library/content/vdi1.jpg" width="433" height="173" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The image on the right shows a traditional SBC model. The users all have access to a desktop GUI via an individual session on the terminal server. This server has a single OS installed; an instance of Terminal Services to provide the sessions and session management, and a set of applications that can be used by all the users on the server. &lt;/p&gt;
&lt;p&gt;In the VDI model on the left, a single server is used again, but a hardware virtualization layer is added to this server in place of a more traditional OS like Windows Server. The Virtualization layer provides numerous Virtual Machines that are each supplied with an operating system, applications, and a unique GUI / desktop environment for each user. &lt;/p&gt;
&lt;p&gt;As you can tell by the image, a VDI solution provides the same basic functionality of a traditional SBC solution. This functionality is (primarily) to provide a centralized desktop via a protocol like RDP or ICA. Besides the Virtualization layer and numerous OSes, the two solutions look almost identical. (The key word is &amp;rsquo;almost&amp;rsquo;.)&lt;/p&gt;
&lt;p&gt;With VDI you gain a couple of benefits that you cannot achieve in a SBC environment, including things like:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The ability to provide a unique      environment for each and every user.&lt;/li&gt;
  &lt;li&gt;Each of these environments can      be completely customized with different apps and settings without      impacting other users. &lt;/li&gt;
  &lt;li&gt;Users can be granted more      control of their own &amp;ldquo;virtual&amp;rdquo; desktop to allow them to install and modify      applications if needed.&lt;/li&gt;
  &lt;li&gt;Applications that were not      multi-user friendly (i.e. &amp;ldquo;we cant get this to run on Citrix&amp;rdquo;) can be run      in this environment since each instance is just like installing the app on      a new desktop.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problems start when you think about the solution from its very basic components. Let&amp;rsquo;s say your boss decides that you need to provide 100 desktops to developer users in India. Each developer needs local admin rights, the ability to reboot the machine, install apps, etc. Basically every one of them must have their own machine. A few years ago the only way to do this would be to buy 100 desktops, stack them in a room or in the datacenter, load up PC Anywhere, Dameware or some other remote control solution, and tell them to go to town. Of course right now you&amp;rsquo;re frowning at the thought of this, but really is a VDI solution that much different? You still have the same number of OSes, you still have the same number of application installs, you still have to use some type of third party software to get your users connected to the machines, remote printing is going to be an issue and so are peripherals, etc... Starting to sound kind of lame, huh?&lt;/p&gt;
&lt;p&gt;The truth is it&amp;rsquo;s not that lame. Virtualization has allowed you not to have to buy a hundred new boxes and instead get maybe 4, 5 or 6 servers and create the target machines as virtual machines. This, of course, could drop the solution cost pretty significantly. &lt;/p&gt;
&lt;p&gt;This leaves you with several issues that need to be solved, including the connectivity, application installations, application upgrades, OS management, VM provisioning, load management, and of course performance monitoring/management and maybe even a number of peripheral issues. Also (with today&amp;rsquo;s virtualization technologies) you need to put those VMs (encapsulated in files) onto a SAN if you want redundancy. If not the loss of a single server can create the loss of a large number of VMs and their customizations from the users.&lt;/p&gt;
&lt;p&gt;As you can see the basic infrastructure is available to provide the platform. The connectivity and management and other surrounding pieces are missing in order to make this a really competitive solution.&lt;/p&gt;
&lt;p&gt;&amp;lt;Preachy Rant&amp;gt;&lt;br /&gt;
  Before I get too far I should note that I believe that VDI is NOT a Citrix replacement in 95% of the use cases, but instead is a solution that fits specific needs and most likely will run side-by-side with terminal servers to fill these needs. VDI is a powerful/useful technology for UNIQUE desktops or apps that will not run on Citrix or on Citrix via an application virtualization software like Softgrid or Citrix&amp;rsquo;s AIE technology. If you want to host a call center and all the machines/desktops should be identical with little to no modifications possible, buy a terminal server, have it set up correctly, and save the money by using VDI for unique PC deployments or those &amp;ldquo;no way it runs on Citrix&amp;rdquo; applications.&lt;br /&gt;
  &amp;nbsp;&amp;lt;/Preachy Rant&amp;gt;&lt;/p&gt;
&lt;p&gt;Okay, so you&amp;rsquo;ve decided that you need to get these 100 desktops done, but PCAnywhere is so 1999 that you just have to jump on the VDI bandwagon. What issues / needs are you going to have to address, and where can the software come from to address these needs?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with a &amp;ldquo;pie in the sky&amp;rdquo; view of a perfect VDI solution:&lt;/p&gt;
&lt;p align="center"&gt;&amp;nbsp;&lt;img src="http://www.brianmadden.com/library/content/vdi2.jpg" width="433" height="342" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;In the perfect VDI solution, you would see an easily managed (one or two tools) environment. If you use Citrix and Terminal Server as your starting point then it&amp;rsquo;s easy to see what you need. The Perfect VDI solution would have or support the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Session load balancing of &amp;ldquo;pooled&amp;rdquo; VMs that are identical.&lt;/li&gt;
  &lt;li&gt;Capabilities to have unique VMs for specific users and still allow them to connect to pooled VMs if needed.&lt;/li&gt;
  &lt;li&gt;A secure way to access these desktops remotely.&lt;/li&gt;
  &lt;li&gt;A management tool that would allow you to see/manage the following:&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Locate users (which pooled VM are they connected to)&lt;/li&gt;
    &lt;li&gt;Show connection information (where are they coming from how long have they been connected)&lt;/li&gt;
    &lt;li&gt;Timeouts for session active and disconnected times&lt;/li&gt;
    &lt;li&gt;Ability to reset or remotely reboot a VM&lt;/li&gt;
    &lt;li&gt;Ability to pull a VM out of the pool for maintenance or troubleshooting&lt;/li&gt;
    &lt;li&gt;Centralized way of publishing and establishing security for the VDI connectivity&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;A connection method that allowed for the &amp;ldquo;easily&amp;rdquo; supported printing and peripheral environment. &lt;/li&gt;
  &lt;li&gt;Ability to add to the pooled VMs resources as load increases WITHOUT having numerous VMs sitting around idle and eating resources. This is akin to dynamic VM creation&lt;/li&gt;
  &lt;li&gt;A way to centrally patch and maintain the pooled VMs that is easier than managing a bunch of unique desktops.&lt;/li&gt;
  &lt;li&gt;Better peripheral support, specifically, printer mapping and management. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you begin to look at the ideal VDI environment you begin to see it is almost IDENTICAL to a current Citrix or Terminal Server deployment except for the fact the VDI environment has an OS and app instance per VM. This is where the solution begins to loose some of its coolness. You now need to install an OS and its apps, and manage, update, and patch the OS, and the apps for each VM. There may be some ways to simplify that, but before we go there lets look at some of the key features that are needed in a perfect VDI solution, how they are being done today, and how they should be done.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Session load balancing of &amp;ldquo;pooled&amp;rdquo; VMs &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In most VDI deployments this is not being done (or at least not being done well). In some cases administrators are manually mapping users to VMs by giving the user an IP address or computer name and having them connect via the RDP client. The connection method varies. Some use an RDP file deployed to the user&amp;rsquo;s existing desktop, some use thin client configured to use a CE based RDP to connect to the desktop, and some companies are hacking/faking out software used for load balancing TS sessions to load balance XP desktop sessions. &lt;/p&gt;
&lt;p&gt;What we are talking about is a management tool that allows you to add a list of computer names into a central tool. You would assign that pool a name and then assign permissions to that pool to groups of users. Pie in the Sky would be to even select specific or users or groups of users and allow them to connect to the pool and give them the OPTION to save their VM for later use or not. This would give certain power users the ability to spawn a unique VM from the pool for later use where task-based workers may not receive the option at all. This could also be useful if you have a base image that all users would use (unique and pool users). In another case you could assign multiple groups of users to the pooled resources. Then have the option to allow a submit (unknown to them) to automatically be spun off into a unique VM where session settings and changes are saved. In this case each VM starts with the same base image but only groups or users that are assigned get to &amp;ldquo;keep&amp;rdquo; their VM from the pool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ability to have unique VMs for specific users and still allow them to connect to pooled VMs if needed&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This may sound silly, but the concept of running multiple desktops (or applications) is nothing new.&amp;nbsp; I mean let&amp;rsquo;s assume your environment grows a bit and you use VDI for some type of custom application that conflicts with everything including notepad. Now you have a user with a thin client (or fat) that connects to their custom desktop that they&amp;rsquo;ve been using for a month or two, they&amp;rsquo;ll also need access to the customer application and thus its pooled desktop. This needs to be done easily, meaning that you need an easy connection method, maybe a web interface that allows the user to select a desktop from the ones they are authorized to use or the ability to directly launch the second desktop from within the first (and still support any peripherals needed). &lt;/p&gt;
&lt;p&gt;Right now people are using the RDP client to connect to an XP Pro VM. Then they are either establishing another connection with RDP client from their desktop or not doing it all. This will not work in the long run. (I once had to change about 500 users Program Neighborhoods over to published apps and NFuse because these multiple connections where a nightmare.) As VDI expands, this too will become a problem if there is no centralized brokering mechanism.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A secure way to access these desktops remotely&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s face it, a lot of the VDI solutions being implemented are for outsourced developers. Not all mind you, but enough that remote access (or should I say secure remote access) is an issue. The basic idea is that the end user needs a simple yet secure way of accessing the desktop that won&amp;rsquo;t require the hosting company to drop a bunch of software on the remote client. This screams clientless SSL VPN, or possibly SSL encryption built into the VDI desktop client. In addition it means a software package that is Internet facing that could (or should) integrate with some different types of backend directories (e-dir, AD, maybe throw in SecureID). &lt;/p&gt;
&lt;p&gt;How are people doing it now? &amp;ldquo;Hopping&amp;rdquo; is the only way to describe it. In some situations companies are publishing the RDP client in Citrix. Users then come into a Web Interface server, login, run the RDP client published app, get routed through a Citrix Secure Gateway into a Citrix session running the MS-RDP client, and use it to launch the RDP session to the XP Pro machine. This is essentially a double hop. It works, but it causes overhead, requires a Citrix license just to run the RDP client, and is basically one session for the price of two.&amp;nbsp; In other cases, companies are creating firewall rules and VPN connections to allow users to open TCP 3389 from their PC to the XP Pro box. When doing this it&amp;rsquo;s often a multi-step process for the end user (we know how that works out) or requires you drop a package on their desktop and support it. &lt;/p&gt;
&lt;p&gt;What would be ideal? A single hop that integrates both the session brokering and session connectivity without a middleman. (Think of a secure connection to the XP Pro box that looks like an ICA session to a Citrix Presentation Server.)&lt;/p&gt;
&lt;p&gt;I know, I know, I&amp;rsquo;m comparing a bunch of this stuff to Presentation Server. But hey, if something works, model after it, don&amp;rsquo;t re-invent the wheel. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A complete management tool for the environment&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the funnier things I see in the VDI realm is that the Non-TS guys kind of have to re-invent all the hacks that Citrix and Terminal Server guys had to do in NT 4.0 and the early days of Server Based Computing. For you old timers, you&amp;rsquo;ll remember changing the &amp;ldquo;My &amp;ldquo; icon on the session desktop to %username% on %computername%. Well I&amp;rsquo;ve seen them doing these in XP Pro VMs. Why? There is no management tool to easily tell you which user is connected to which VM, how long have they been connected, or what is the state of their session is.&lt;/p&gt;
&lt;p&gt;These are simple things taken for granted in Citrix and TS since the tools have been there forever. A huge step in VDI would be a tool that looks like TSAdmin.exe or MFadmin.exe but is geared towards the VDI market. (Of course I just had to geek out and make a mock up one that you can see below).&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.brianmadden.com/library/content/vdi3.jpg" width="432" height="230" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Yeah, I know it looks like a TS admin tool, and it&amp;rsquo;s supposed to. The same concepts you&amp;rsquo;re familiar with in TS also apply here. The difference is that this tool would need to show the resource groups available, the individual virtual machines available, and of course the users connected to them. In addition I think such a tool (with the rest of the required infrastructure) should be able to:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Locate users (which pooled VM are they connected to)&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Very important for troubleshooting and security reasons&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Show connection information&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Right now this is not being done or being done by login scripts that note the login time and username in a central access DB for logon and logoff times.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Should allow session shadowing&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;this could somewhat be done today with Dameware on the machine and the end user connecting via RDP&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Timeouts for session active and disconnected times&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Some would say you could use domain timeouts (and I already got an e-mail, thanks) but we are really talking about a session open for 29 hours by a single user. How do you know when that happens?&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Ability to reset or remotely reboot a VM&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Absolute must. I would say you need hooks from this tool to reboot the VM maybe suspend, obviously take it out of the pool of resources, and possibly to log the user off the VM cleanly. Right now people do this by accessing another tool (like with Vmware&amp;rsquo;s Virtual Center or VS 2005&amp;rsquo;s web interface, but I would want the application to be able to call the APIs and from this console handle the shutdowns and restarts)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Ability to pull a VM out of the pool for maintenance and or troubleshooting&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Noted above but is a must. &lt;/li&gt;
  &lt;/ul&gt;
  &lt;li&gt;Centralized way of publishing and establishing security for the VDI connectivity&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Today people are basically doing a one-to-one ratio (VM:User) or hacking together load balancing from other tools. That&amp;rsquo;s great until you have a centralized way of getting at the desktops and need to restrict Suzie in accounting from seeing the comptrollers desktop remotely. I mean how many of you actually set the local logon rights on desktops? It would be a pain to manage on lots of images.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;A connection method that allowed for the &amp;ldquo;easily&amp;rdquo; supported printing and peripheral environment. &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yeah. VDI is great until someone prints. Sure there are some ways to get network printers working easily, but then there is the guy in India with a brand new MFC made by some no name company in China, connecting to a desktop in London. Send his support call to Timbuktu because you&amp;rsquo;re not going to get that printer to work easily. &lt;/p&gt;
&lt;p&gt;I would begin to look seriously at some third party companies like ThinPrint for solutions, because I just feel this is going to be a huge issue.&lt;/p&gt;
&lt;p&gt;In addition to making printing at least meet the standards of today&amp;rsquo;s Terminal Server and Citrix environments, you&amp;rsquo;ll be looking for peripheral support so Suzie in accounting can sync her &amp;ldquo;CrackBerry&amp;rdquo; with her desktop. Don&amp;rsquo;t laugh! If you get VDI running, people will begin to ask for that stuff.&lt;br /&gt;
  &amp;nbsp; &lt;br /&gt;
  &lt;strong&gt;Ability to add to the pooled VMs resources as load increases WITHOUT having numerous VMs sitting around idle and eating resources&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is akin to dynamic VM creation. One thing that has always bugged me about VDI is that it FEELS like WinFrame. Basically if you need to support 30 Concurrent sessions you have to have 30 VMs sitting there whether all 30 are being used or only 2 are being used. Right now this is how most VDI solutions are setup&lt;/p&gt;
&lt;p&gt;Now this may not seem like an issue but there is a reason that later version of TS moved to a listener model; it was to reduce the amount of resources used by idle sessions (and these were just virtual sessions within an OS, not the whole OS itself sitting there).&lt;br /&gt;
    &lt;br /&gt;
  The solution would be to find a way to QUICKLY (read less than 15-30 seconds) provision a VM that&amp;rsquo;s ready for use. I&amp;rsquo;m not sure how to do this yet, but its one solution. Another solution (or workaround) would be to determine max load in the farm in any, (say 15 minute) period. If you could accept 6 new logons in 15 minutes then the minimum number of VMs available would be 6. When one is used by a user logging in, another would be created. The one being created would still have a 5 VM buffer before any users tried to get to it.&amp;nbsp; Now this would be a pretty intense solution, and not elegant by any means, but it&amp;rsquo;s probably just one idea of 100 that other people have to solve this issue. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A way to centrally patch and maintain the pooled VMs that is easier than managing a bunch of unique desktops&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yeah, now you&amp;rsquo;ve just added a bunch of VMs to your environment that you need to patch and upgrade constantly. Sure you can dump WSUS in there for Patch Tuesdays, or you can use your existing SMS infrastructure, but there is obviously and added cost for this.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Today most people are doing that; using existing tools. Personally I think that if the previous issue is solved (a way to quickly provision VMs) then we will solve this. I mean if the VMs are built and broken down all the time, and when built come from a centralized template for the pool being published, then the template would just need to be updated and through the life of the VM (logon and logoff) the VM would be created with the new patches. This of course solves the problems for pooled VMs, but not unique ones. You still need to manage those just like desktops. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Will VDI take over the world? I doubt it. I think it will have its place just like other &amp;ldquo;Virtualization&amp;rdquo; technologies like Citrix and TS, Softricity and AppStream, etc. VDI has a place and will solve issues, but it&amp;rsquo;s just that&amp;mdash;another solution to a problem. It&amp;rsquo;s not the solution to all of our problems. Right now VDI is in its infancy. Those that go down that road are bound to have to jump some serious technical hurdles to create an easily managed system. Just like the first multi-user systems, VDI will solve your problem today, but will be hard to manage compared to some other systems and require some learning curve for your staff. Hopefully over the next few months vendors will get on board and make some of the technology a reality. Citrix is supposedly working on something to help with brokering of the sessions in a more elegant fashion, but that is for another article.&lt;/p&gt;
&lt;p&gt;If you have other VDI challenges or solutions you want to note, post to the comments section of this article. VDI is new, and no one has all the answers. That&amp;rsquo;s what makes it fun.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=10213" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Technical Articles" scheme="http://www.brianmadden.com/tags/Technical+Articles/default.aspx" /><category term="Server Virtualization" scheme="http://www.brianmadden.com/tags/Server+Virtualization/default.aspx" /><category term="VDI" scheme="http://www.brianmadden.com/tags/VDI/default.aspx" /></entry><entry><title>BriForum 2006 Video: Ron Oglesby on Citrix Large Farm Design</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2005/11/13/briforum-2006-video-ron-oglesby-on-citrix-large-farm-design.aspx" /><id>/blogs/ronoglesby/archive/2005/11/13/briforum-2006-video-ron-oglesby-on-citrix-large-farm-design.aspx</id><published>2005-11-14T00:00:00Z</published><updated>2005-11-14T00:00:00Z</updated><content type="html">&lt;p&gt;Ron Oglesby is well-known for many reasons in this community, one of which is his experience with large server farms. (Hundreds of servers, thousands upon thousands of users.) In this session, Ron is going to share his experience with you and talk about what he learned about how Citrix REALLY works when it&amp;#39;s put under pressure.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s his session from &lt;a href="http://www.briforum.com"&gt;BriForum 2005&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.brianmadden.com/attachments/BriForum%202005%20-%20Debugging%20and%20Tuning%20Applications%20on%20Terminal%20Services.wmv"&gt;&lt;img style="WIDTH:40px;HEIGHT:50px;" alt="" hspace="0" src="http://www.brianmadden.com/images/icons/wmv.gif" align="middle" border="0" /&gt;&lt;/a&gt; &lt;a href="http://www.brianmadden.com/attachments/BriForum%202005%20-%20Citrix%20Large%20Farm%20Design%20-%20Ron%20Oglesby.wmv"&gt;Download the video of this session (WMV format - 67MB)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.brianmadden.com/attachments/BriForum%202005%20-%20Debugging%20and%20Tuning%20Applications%20on%20Terminal%20Services.mp3"&gt;&lt;img style="WIDTH:40px;HEIGHT:50px;" alt="" hspace="0" src="http://www.brianmadden.com/images/icons/mp3.gif" align="middle" border="0" /&gt;&lt;/a&gt; &lt;a href="http://www.brianmadden.com/attachments/BriForum%202005%20-%20Citrix%20Large%20Farm%20Design%20-%20Ron%20Oglesby.mp3"&gt;Download the audio from this session (MP3 format - 15MB)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.brianmadden.com/attachments/BriForum%202005%20-%20Citrix%20Large%20Farm%20Design%20-%20Ron%20Oglesby.ppt"&gt;&lt;img alt="" hspace="0" src="http://www.brianmadden.com/images/icons/ppt.gif" align="middle" border="0" /&gt;Download the PowerPoint slides from this session (4MB)&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=9356" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Videos" scheme="http://www.brianmadden.com/tags/Videos/default.aspx" /></entry><entry><title>How the Default Load Evaluator can Ruin your Day</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/12/09/how-the-default-load-evaluator-can-ruin-your-day.aspx" /><id>/blogs/ronoglesby/archive/2004/12/09/how-the-default-load-evaluator-can-ruin-your-day.aspx</id><published>2004-12-10T00:01:00Z</published><updated>2004-12-10T00:01:00Z</updated><content type="html">&lt;p&gt;&lt;em&gt;This is the true story of a Citrix administrator&amp;#39;s worst day on the job. It&amp;#39;s about how the loss of five Citrix servers in his environment brought the remaining twelve down, why the default load evaluator is to blame, and how you can prevent it from happening in your environment.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;...So I get a call from a client asking me to perform a “root cause analysis” as to why their “entire farm” went down all at once. The words “root cause” coming from this client is pretty strange seeing how most days any problems they have are solved by a simple reboot of the offending server (but I digress).  Anyway, I schedule the next day to come onsite and get a concall going to get some initial information. &lt;/p&gt;
&lt;p&gt;It seems that the day before the entire farm became “unavailable” in the course of about 30 minutes. The event that seemed to start it was the failure of a single switch. Of course the obvious questions was, “Is your entire farm on that switch?” No, the farm was actually split across four major switches with a switch in each rack that uplinks to these four.  The total number of servers in the farm was 18, with 17 hosting apps and a dedicated data collector.  The 18 servers were split between 5 different racks because the environment had grown over time and it made sense to keep them separate in case of power loss to a rack or a &lt;em&gt;SWITCH FAILURE&lt;/em&gt; in a rack.&lt;/p&gt;
&lt;p&gt;After showing up on site, looking at the environment, reviewing the performance data on the servers just prior to “The Crash,” and asking a few simple questions, we quickly figured out what had happened. One simple failure and a couple of default settings had brought the entire farm to its knees.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s how it went down:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Switch in rack two fails. This disconnects the users that were attached to Servers 1 through 5. Average user load: 52 users per server.&lt;/li&gt;
&lt;li&gt;These 250 odd users then attempt to reconnect to their application via the NFuse page.&lt;/li&gt;
&lt;li&gt;The remaining 12 servers in the farm are running at about 51 or 52 users per server. &lt;/li&gt;
&lt;li&gt;The Data collector looks at load and begins to distribute users to the server with the lowest load. Server 9 has only 45 users and begins to see a little of the black hole effect referenced in &lt;a href="http://www.brianmadden.com/content/content.asp?ID=254"&gt;this article&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Server 9’s performance suddenly goes in the toilet. The other remaining servers follow shortly. &lt;/li&gt;
&lt;li&gt;Within 10 minutes these 12 servers now have an extra 20-25 users per server trying to connect to them.&lt;/li&gt;
&lt;li&gt;15 minutes into this a number of servers are no longer sending performance data or are sending data with “gaps” in it where the server seems to pause.&lt;/li&gt;
&lt;li&gt;Users continue to disconnect and reconnect in an attempt to get to a “better server” which only worsens the problem due to the increase in logon and logoff processes.&lt;/li&gt;
&lt;li&gt;30 minutes into this process the Citrix admin begins to disable logons to the server but finds a number of them unresponsive.&lt;/li&gt;
&lt;li&gt;Well, let&amp;#39;s just say its not a pretty afternoon.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;So what happened? Some might say he didn’t have enough servers? But unless you go into DR mode who has an extra 25-30% capacity lying around? No, they had tested these servers and found that they could go up to 60 maybe 62 users before performance went in the toilet. But 70-75 users per server was just to much.&lt;/p&gt;
&lt;p&gt;To understand what happened you need to look at the Citrix default load evaluator that gets used when you begin to use load balancing with default configurations. This load evaluator looks at one metric only: user count on the server. To make matters worse its default maximum is 100 users regardless of the hardware you have or the applications you are running.  This basically means that the ZDC thinks the server can still handle new load until you reach 100 total users. So when this environment lost 5 servers at once the other 12 were asked to accept a load that they could not handle. &lt;/p&gt;
&lt;p&gt;The cure to this problem is to setup an evaluator based on your maximum user load and possibly a couple of other metrics. If they had setup an evaluator with a max load of 60 or 62 (their theoretical maximum), the other 12 servers would have stopped accepting connections once they reached that point. Sure 100 or 120 users would have not been able to connect till the servers were brought back up, but it’s better than the almost 900 users that were affected that day for several hours. &lt;/p&gt;
&lt;p&gt;Personally I would recommend that you set the user load on your new evaluator right at the point where performance starts to degrade. Sometimes an extra session or two can sneak in beyond the load evaluator settings. In addition I would recommend throwing in some other metrics like memory in use and processor utilization. These are nice generic metrics that almost any environment can use. If you happen to know your bottleneck on your servers use that metric in your evaluator too. The trick is to keep the remaining productive servers/users online even if you have a massive failure somewhere else.&lt;/p&gt;
&lt;p&gt;These guys had run on the default evaluator for almost two years without a problem. Sure they would loose a server once in a while or roll one or two out for maintenance, but they never had lost five at once. Of course this situation also could have been avoided if their servers had been patched into more than the single switch in the rack, but then you could always have a power loss in the rack, or my personal favorite, the time a pipe above a server room broke and poured water directly onto two racks. Just because you make the NICs and power supplies and everything else redundant doesn’t mean things can&amp;#39;t happen.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=7445" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Load Balancing" scheme="http://www.brianmadden.com/tags/Load+Balancing/default.aspx" /><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="War Stories" scheme="http://www.brianmadden.com/tags/War+Stories/default.aspx" /></entry><entry><title>Scripting MetaFrame Data Store Printer Mapping</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/06/27/scripting-metaframe-data-store-printer-mapping.aspx" /><id>/blogs/ronoglesby/archive/2004/06/27/scripting-metaframe-data-store-printer-mapping.aspx</id><published>2004-06-28T00:00:00Z</published><updated>2004-06-28T00:00:00Z</updated><content type="html">&lt;p&gt;This article is the third in Ron Oglesby’s “Scripting for MetaFrame” series.&lt;/p&gt;
&lt;p&gt;In this series of articles I focus on how you can use scripting in a Terminal Server or Citrix MetaFrame environment to automate common and recurring tasks. This article shows a script that uses MFCOM to bulk delete all of the printer mappings out of the MetaFrame data store. &lt;/p&gt;
&lt;p&gt;This script is generally used when you’re trying to clean up your environment. It was originally written for a farm that had an enormous list of printer driver mappings (over 1000) that needed to all be deleted to start fresh with a new mapping file. Deleting each of these mappings one at a time via the Citrix Management Console was out of the question, so we created two scripts to do it for us. The first deletes all the mappings from the data store, and the second re-importes a list of mappings from a text file. This allowed us to create a “gold” list of mappings, clean out the old garbage, and import our new mappings—all in a few minutes.&lt;/p&gt;
&lt;p&gt;In this article we’ll take a close look at the script that deletes the mappings. Later in the article I’ll provide you with both the DelMap and AddMap scripts, but since they’re so similar I’ll explain only one of them but give you both. (Hey! A two for one... How cool is that?). Let’s get started by looking at the first section of our script:&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;lt;package&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;job id=&amp;quot;Print Driver Mappings&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; File:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DelPMap.wsf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description:&amp;nbsp;&amp;nbsp;&amp;nbsp; Deletes all Print Driver Mappings from the MetaFrame &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;farm Data Store.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Requirements:&amp;nbsp;&amp;nbsp; WSH 5.5 or higher.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Deletes all Print Driver Mappings from the MetaFrame farm Data Store.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;on MetaFrame Servers in the farm.&amp;nbsp; It will save current mappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;in the OutPutFile for later use.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;example&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CScript //nologo DelPMap.wsf&lt;br /&gt;&amp;lt;/example&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;reference object=&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;As you can see this is a WSF script using basic VBS. You can execute the script by using the “cscript” interpreter. Now let’s declare our variables. Nothing out of the ordinary here. &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fso, f, ts, LogFileName, OutPutFileName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim theFarm, theMappings, Map, sDriver, sPlatform, cDriver&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Once the variables are declared we create (or connect to) the FileSystemObject. This will be used later on for logging purposes and to output the “old” mappings to a file for later retrieval.&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;The first logic in the script parses the command line looking for an argument. The syntax of this script requires that you specify and output file to dump the current mappings to. &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;Parse the command line&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set Args = Wscript.Arguments&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not Args.Count = 1 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;Usage: DelPMap.wsf OutPutFile&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Once we notice the argument we then create the output file if it doesn’t exist. &lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;create the OutPut file if it doesn&amp;#39;t exist&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;OutPutFileName = Args(0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(OutPutFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fso.CreateTextFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(Now &amp;amp; &amp;quot;&amp;nbsp; -&amp;nbsp; Delete this line before using as an input file&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(&amp;quot;Server Driver=Client Driver - Delete this line before using as an input file&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;If you notice we write a line “Server Driver=Client Driver - Delete this line before using as an input file&amp;quot;)” This file will be written to the text file to let the next person running an AddMap script to delete the line before using this as an input file for importing printer mappings into the datastore. &lt;br /&gt;Once the output file is created we then configure our log file name and create it. As you can see, this example is hardcoded to C:. This is sloppiness on my part. :-)&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&lt;br /&gt;&amp;#39;define the log file name here&lt;br /&gt;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;LogFileName = &amp;quot;c:\DelPMap.txt&amp;quot;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&lt;br /&gt;&amp;#39;create the log file if it doesn&amp;#39;t exist&lt;br /&gt;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(LogFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fso.CreateTextFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(Now)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(&amp;quot;Server Driver=Client Driver, Success/Failure&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Now that our log files and output files are created we then begin to access the MetaFrame farm object:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;#39; Create MetaFrame Farm Object&lt;br /&gt;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set theFarm = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t create MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Then we initialize the farm:&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;#39; Initialize the farm&lt;br /&gt;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;theFarm.Initialize(MetaFrameWinFarmObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t&amp;nbsp; Initialize MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;After that we verify that the current user executing the script is a citrix administrator. If not, the functions in the script will fail so we want to stop it here.&amp;nbsp; Also (if haven’t noticed yet) this format so far follows the examples in the Citrix SDK pretty closely. (You can download the SDK for free from the &lt;a href="http://www.citrix.com/cdn"&gt;Citrix Developer Network&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;#39; Check Citrix Admin Credentials&lt;br /&gt;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;You must be a Citrix admin to run this script&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Now that all that beginning stuff is out of the way the script gets more interesting. First, we initialize the PrintDriverMappings within the farm. If we can’t access the mappings the script quits. After that we start a simple FOR loop. For each print driver mapping it finds in the farm, it gathers the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server driver name&lt;/li&gt;
&lt;li&gt;Server driver platform&lt;/li&gt;
&lt;li&gt;Client driver name&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We then delete the mapping and write it to the output file in this format:&lt;/p&gt;
&lt;p&gt;ServerDriverName=ClientDriverName&lt;/p&gt;
&lt;p&gt;This is the same format that can be used as an input file for the script that re-adds the mappings.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Read and delete the driver mapping&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;set theMappings = theFarm.WinFarmObject.PrinterDriverMappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t Initialize PrintDriverMappings object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;For each Map in theMappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sDriver = Map.ServerDriverName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sPlatform = Map.ServerDriverPlatform&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cDriver = Map.ClientDriverName&lt;br /&gt;&amp;#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;wscript.echo sDriver &amp;amp; &amp;quot;, &amp;quot; &amp;amp; sPlatform &amp;amp; &amp;quot;, &amp;quot; &amp;amp; cDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map.Delete&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;If Not Err.Number = 0 then&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;Next, we have a IF statement that checks for success or failure and writes it to the log file.&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;#39;*****************************************************&lt;br /&gt;&amp;#39;write failure into log file&lt;br /&gt;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp;&amp;nbsp;&amp;quot; Mapping Deletion Failure ****&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;write success into log file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp; &amp;quot;&amp;nbsp; Mapping Deletion Successful&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;end if &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Next &amp;#39;Map&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;End the Script&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Script Complete, Log file written to: &amp;quot; &amp;amp; LogFileName &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/job&amp;gt;&lt;br /&gt;&amp;lt;/package&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;At the end of the script we simply echo that the script is complete and show the user the log file location.&amp;nbsp; A great thing you can do with this is to get a new mapping list together, test it, make sure its perfect, then (in a matter of minutes) completely clean up your old mappings and replace them with new ones.&lt;/p&gt;
&lt;p&gt;Below you’ll find the complete code for both the DelMap and AddMap scripts. Happy scripting!&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;lt;package&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;job id=&amp;quot;Print Driver Mappings&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; File:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DelMap.wsf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description:&amp;nbsp;&amp;nbsp;&amp;nbsp; Deletes all Print Driver Mappings from the MetaFrame &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;farm Data Store.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Requirements:&amp;nbsp;&amp;nbsp; WSH 5.5 or higher.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Deletes all Print Driver Mappings from the MetaFrame farm Data Store.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;on MetaFrame Servers in the farm.&amp;nbsp; It will save current mappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;in the OutPutFile for later use.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;example&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CScript //nologo DelPMap.wsf&lt;br /&gt;&amp;lt;/example&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;reference object=&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fso, f, ts, LogFileName, OutPutFileName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim theFarm, theMappings, Map, sDriver, sPlatform, cDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;Parse the command line&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set Args = Wscript.Arguments&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not Args.Count = 1 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;Usage: DelPMap.wsf OutPutFile&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;create the OutPut file if it doesn&amp;#39;t exist&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;OutPutFileName = Args(0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(OutPutFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fso.CreateTextFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(Now &amp;amp; &amp;quot;&amp;nbsp; -&amp;nbsp; Delete this line before using as an input file&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(&amp;quot;Server Driver=Client Driver&amp;nbsp; -&amp;nbsp; Delete this line before using as an input file&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;define the log file name here&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;LogFileName = &amp;quot;c:\DelPMap.txt&amp;quot;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;create the log file if it doesn&amp;#39;t exist&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(LogFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fso.CreateTextFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(Now)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(&amp;quot;Server Driver=Client Driver, Success/Failure&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Create MetaFrame Farm Object&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set theFarm = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t create MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Initialize the farm&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;theFarm.Initialize(MetaFrameWinFarmObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t&amp;nbsp; Initialize MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Check Citrix Admin Credentials&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;You must be a Citrix admin to run this script&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Read and delete the driver mapping&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;set theMappings = theFarm.WinFarmObject.PrinterDriverMappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t Initialize PrintDriverMappings object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;For each Map in theMappings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sDriver = Map.ServerDriverName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sPlatform = Map.ServerDriverPlatform&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cDriver = Map.ClientDriverName&lt;br /&gt;&amp;#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;wscript.echo sDriver &amp;amp; &amp;quot;, &amp;quot; &amp;amp; sPlatform &amp;amp; &amp;quot;, &amp;quot; &amp;amp; cDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map.Delete&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(OutPutFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;If Not Err.Number = 0 then&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;write failure into log file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp;&amp;nbsp;&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; Driver Mapping Deletion Failure ******* &amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;write success into log file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp; &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; Driver Mapping Deletion Successful&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;end if &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Next &amp;#39;Map&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;End the Script&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Scipt Complete, Log file written to: &amp;quot; &amp;amp; LogFileName &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/job&amp;gt;&lt;br /&gt;&amp;lt;/package&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;Here is the AddMap script and a sample input file for it. Notice that the input file has no quotes around the driver names. It’s simply a client driver name followed by an equal sign and a server driver name. The output from the DelMap listed above creates a file exactly like this. In addition, you could modify the DelMap script so it DOESN’T delete the mappings and instead just records them to the output file. This will then allow you to edit the text file and get ready for the deletion and re-importation for the mappings.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;font color="#990000"&gt;Input file sample:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;HP LaserJet 4/4M=HP LaserJet 4&lt;br /&gt;HP LaserJet 4P/4MP=HP LaserJet 4P&lt;br /&gt;HP LaserJet 4 Plus/4M Plus=HP LaserJet 4 Plus&lt;br /&gt;HP LaserJet 4Si/4Si MX=HP LaserJet 4Si&lt;br /&gt;HP LaserJet 4V/4MV=HP LaserJet 4V&lt;br /&gt;HP LaserJet 5/5M - Enhanced=HP LaserJet 5&lt;br /&gt;HP LaserJet 5/5M - Standard=HP LaserJet 5&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;AddMap.wsf Script&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;lt;package&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;job id=&amp;quot;Print Driver Mappings&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; File:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddMap.wsf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description:&amp;nbsp;&amp;nbsp;&amp;nbsp; Adds Print Driver Mappings to the MetaFrame farm Data Store.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Requirements:&amp;nbsp;&amp;nbsp; WSH 5.5 or higher.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/comment&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Adds Print Driver Mappings to the MetaFrame farm Data Store. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;example&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CScript //nologo AddPMap.wsf InputFile&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;InputFile must be in the format ClientDriver=ServerDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;with no spaces around the equals sign&lt;br /&gt;&amp;lt;/example&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/runtime&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;reference object=&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;script language=&amp;quot;VBScript&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Dim fso, f, ts, LogFileName, Args, InputFileName, eqCount&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim theFarm, theMap, sDriver, sPlatform, cDriver, OSVer&lt;br /&gt;&amp;nbsp;&amp;nbsp;set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;OSVer = &amp;quot;1&amp;quot;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;Parse the command line&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set Args = Wscript.Arguments&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not Args.Count = 1 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;Usage: AddPMap.wsf InputFile&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39;Verify Input File&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;InputFileName = Args(0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(InputFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;The input file is not found.&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;Usage: AddPMap.wsf Inputfile&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;define the log file name here&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;LogFileName = &amp;quot;c:\AddPMap.txt&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;create the log file if it doesn&amp;#39;t exist&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;If Not fso.FileExists(LogFileName) Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fso.CreateTextFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(NOW)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.WriteLine(&amp;quot;Server Driver=Client Driver, Success/Failure&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;ts.close&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Create MetaFrame Farm Object&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set theFarm = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameFarm&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t create MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Initialize the farm&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;theFarm.Initialize(MetaFrameWinFarmObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t&amp;nbsp; Initialize MetaFrameFarm object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End if&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Check Citrix Admin Credentials&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;You must be a Citrix admin to run this script&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Quit 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39; Create PrintDriverMappings object&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;set theMap = CreateObject(&amp;quot;MetaFrameCOM.MetaFramePrinterDriverMapping&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;if Err.Number &amp;lt;&amp;gt; 0 Then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Can&amp;#39;t create PrintDriverMapping object&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Echo &amp;quot;(&amp;quot; &amp;amp; Err.Number &amp;amp; &amp;quot;) &amp;quot; &amp;amp; Err.Description&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Wscript.Quit Err.Number&lt;br /&gt;&amp;nbsp;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;*****************************************************&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;#39; Input and add the driver mapping&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#39;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Set objTextStream = fso.OpenTextFile(InputFileName, 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Do Until objTextStream.AtEndOfStream&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mapping = objTextStream.ReadLine&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;eqCount = InStr(Mapping, &amp;quot;=&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cDriver = Left(Mapping, (eqCount-1))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sDriver = Right(Mapping, (Len(Mapping)-eqCount))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;theMap.ServerDriverName = sDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;theMap.ServerDriverPlatform = OSVer&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;theMap.ClientDriverName = cDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;theMap.Save&lt;br /&gt;&amp;#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;wscript.echo cDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; sDriver&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;If Not Err.Number = 0 then&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;write failure into log file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp;&amp;nbsp;&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; Driver Mapping Addition Failed ******* &amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;write success into log file&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set f = fso.GetFile(LogFileName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set ts = f.OpenAsTextStream(8, -2)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.WriteLine(sDriver &amp;amp; &amp;quot;=&amp;quot; &amp;amp; cDriver &amp;amp; &amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; Driver Mapping Addition Successful&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ts.close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;end if &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;Loop &amp;#39;objTextStream&lt;br /&gt;&amp;nbsp;&amp;nbsp;objTextStream.Close&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;br /&gt;&amp;nbsp;&amp;#39;End the Script&lt;br /&gt;&amp;nbsp;&amp;#39;*****************************************************&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#990000"&gt;&amp;nbsp;&amp;nbsp;WScript.Echo &amp;quot;Scipt Complete, Log file written to: &amp;quot; &amp;amp; LogFileName &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/job&amp;gt;&lt;br /&gt;&amp;lt;/package&amp;gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6379" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Technical Articles" scheme="http://www.brianmadden.com/tags/Technical+Articles/default.aspx" /><category term="Scripting" scheme="http://www.brianmadden.com/tags/Scripting/default.aspx" /><category term="Printing" scheme="http://www.brianmadden.com/tags/Printing/default.aspx" /></entry><entry><title>Basic KIX Login Script for Citrix Users</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/06/11/basic-kix-login-script-for-citrix-users.aspx" /><id>/blogs/ronoglesby/archive/2004/06/11/basic-kix-login-script-for-citrix-users.aspx</id><published>2004-06-11T06:30:00Z</published><updated>2004-06-11T06:30:00Z</updated><content type="html">&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;This article is part of Ron Oglesby&amp;#39;s &lt;a href="http://www.brianmadden.com/subject.asp?ID=34"&gt;Scripting for MetaFrame Series&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;In this series of articles I focus on how an you can use scripting in a Terminal Server / Citrix MetaFrame environment for common and recurring tasks. This article covers the basics of using a KIX login script to configure your Citrix users’ environment.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;As an administrator, you have a choice of many different scripting languages. My personal favorite (and the favorite of many Citrix admins) is KIX (&lt;a href="http://www.kixtart.org"&gt;available for free&lt;/a&gt;). While VBS has its place and is perfect for administrative tasks, KIX is the true king for logon scripts in MetaFrame. Its ease of use, the fact it’s a simple (and forgiving) language, and its focus on modifying the user’s environment make it perfect for MetaFrame and Terminal Server users. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Before we get into some of the common functions you’ll perform for the users, let’s start with some basic logic for your script. A really good practice is to break your script into two parts: initial user configuration and logon settings.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The first part of a KIX script is usually the initial configuration of the user. These are settings that your only need to run once if using roaming profiles or local profiles on a single server. Such settings might include:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l0 level1 lfo1;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Configuring the Outlook profile&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l0 level1 lfo1;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Setting certain registry entries for applications&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l0 level1 lfo1;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Copying a file into the user’s home directory&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The second part of the script is used for settings or processes that need to be run at each time the user logs on. These settings may include:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l1 level1 lfo2;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Updating a file based on time or date for the user&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l1 level1 lfo2;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Changing frequently modified registry entries or application settings to reflect new or modified values&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l1 level1 lfo2;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Checking for and installing printers into the session&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal" style="MARGIN:0in 0in 0pt;mso-list:l1 level1 lfo2;tab-stops:list .5in;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Mapping drives&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The reason I like to break these into two parts is for speed. While you could run both parts of the script every time the script is run, I like to run the “run once” type of settings only once. Basically I create a registry key for the user during the script and use version info to determine if they have run the latest version of the script. If they have, the script can skip the “run once” section. If they haven’t, they run the entire script and get the new settings. This allows you to speed up your logons a little, which is always important in a Citrix environment.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Okay, let’s move on to the script itself. First of all, you should keep a history of the script within it. The extra lines in the script won’t affect performance. I keep a simple version number at the beginning of my logon scripts:&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* logon.KIX configures the user&amp;#39;s profile *****************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1 Base Build. Outlook settings and printers&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;*****************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.1 disables the adobe splash screen&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;*****************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.2 disables autoload of IM *****************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.3 disables autoload of IM when Outlook is launched *****************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.4 Enables outlook to attach EXE and URL files **********&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;These numbers can then be used as the value for the registry key the script checks, and creates or modifies.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The first step in my script is to check for the current version of the script that this user has run:&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;$VER = ReadValue (&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Version&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;This command sets the variable “$VER” equal to the value of a registry key by using a simple ReadValue command. The format for this command is as follows:&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ReadValue (“Hive\key\subkey\subkey”,”Value you wish to read”)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;It’s so simple it’s sick. I now know that the variable $VER is equal to the value set in the users’ registry location HKCU\Software\RapidApp\Version. At this point we can throw a quick IF in there to see if the user is current or not:&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;IF $VER=1.4&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;GOTO ALWAYS&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ELSE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;GOTO RUNONCE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Here we check to see if they have a value of 1.4. If they do I send them to the “ALWAYS” section of my script that runs each time a user logs on. If that registry value does not equal 1.4 then they run the next section (“RUNONCE”), then continue onto “ALWAYS”. (For brevity I have changed my scripts here and made them very simple to use. The scripts below may not represent the version descriptions above)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:RUNONCE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Outlook Config&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;$OTLK = ReadValue (&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Otlk&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IF $OTLK&amp;lt;&amp;gt;1&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Run &amp;quot;d:\Progra~1\Micros~1\Office10\Outlook.exe /ImportPRF D:\admin\scripts\Outlook.prf&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Rapidapp&amp;quot;,&amp;quot;Otlk&amp;quot;, &amp;quot;1&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Notice here that I check to see if their Outlook profile has ever been configured. If not I launching Outlook with an Import PRF switch. Most of my remote users use a desktop and this is a simple and easy way to do it. Another way to do this (in new versions of Office) is to simple set a key in a specific spot in HKCU for IMPORTPRF with a value of the location of the PRF. This will configure outlook to use the PRF file the first time they launch it too.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Continuing in the “run once” part of the script, I then begin to set some registry keys I need for certain applications. As you can see below I assume that the keys I want are not there so I create them then writing the value I want. The great thing about this is that if the key (folder) does exist the addkey will just fail and the script will continue on to write (or overwrite) the value I am importing.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Disable Splash screen for adobe reader ADDED WITH VER1.1&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Acrobat Reader\5.0\AdobeViewer&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Acrobat Reader\5.0\AdobeViewer&amp;quot;,&amp;quot;DISPLAYABOUTDIALOG&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Adobe Acrobat\5.0\AdobeViewer&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Adobe Acrobat\5.0\AdobeViewer&amp;quot;,&amp;quot;DISPLAYABOUTDIALOG&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Disable the IM auto-loader ADDED WITH VER 1.3 and 1.4 for published apps&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;DelValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run&amp;quot;, &amp;quot;MSMSGS&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\IM&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\IM&amp;quot;,&amp;quot;Enabled&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Enables a user to see and attach EXEs and URLs within outlook&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\SECURITY\&amp;quot;,&amp;quot;Level1Remove&amp;quot;, &amp;quot;exe;url&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;**************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Write the version info into the registry. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Version&amp;quot;, &amp;quot;1.4&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Notice how the AddKey, WriteValue, ReadValue commands and syntax within KIX are simple and self-explanatory. Part of the appeal of KIX is that it is very simple to use but still offers great power for modifying the user environment. If you are going to use KIX I highly recommend getting the KIXtart.CHM file that is floating around on the internet. It’s a nice help file with samples for each command and function in KIX. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;In addition, right at the end of the first section of the script I update the version info in the user’s registry. This is what allows us to limit its use and thus speed up the logon. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;With all of the basic configuration and registry keys I want added to the user I now move onto my “ALWAYS” Section. This section will run every time regardless of version of the script. Here I map two drives (drives used by applications only run from Citrix), add two printers, set a default printer for users in my Chicago office, and I replace a file (and ini) in their home dir and put their Windows username in a specific value in the INI. This INI gets changed about every three days so I have found this a simple way to keep up with it.&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:ALWAYS&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************************************************************************* &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Map drives for Citrix users. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE L: /DELETE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE K: /DELETE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE L: &lt;a&gt;\\RAFS1\DOCs12&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE K: &lt;a&gt;\\RAFS2\DJQ&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Set the 4000 and 4500 printers for the Chicago Users&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;IF INGROUP(&amp;quot;CHIUsers&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;addprinterconnection(&amp;quot;\\RAFS1\HP4000&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;addprinterconnection(&amp;quot;\\RAFS1\HP4500&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;setdefaultprinter(&amp;quot;\\RAFS1\HP LaserJet 4500&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ELSE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;? &amp;quot;Non-Chicago User&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Copy the DOCs12.ini and modify username settings&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;COPY “\\RAFS1\Source\W2HCM.ini&amp;quot; &amp;quot;%homedrive%%homepath%\windows\DOCs12.INI&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteProfileString(&amp;quot;%homedrive%%homepath%\windows\DOCs12.ini&amp;quot;,&amp;quot;Session&amp;quot;,&amp;quot;User&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:END&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;As you may have noticed I have no error handling in this script. Basically this script is so simple that not much is needed. But as you get more advanced and start creating more detailed scripts you may need to build in some error checking. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Anyway, basic KIX logon scripts are easy to do and allow you to do almost anything to the user’s environment. Here I’ve shown you how to map drives, read and write registry values, copy files, modify INI files, setup printers, check for group membership and even use version controls to speed up the logon process. Below is the complete sample script. Obviously there is much more you can do with KIX (MUCH more) and in a future article we will go into more detailed and interesting KIX scripts. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* logon.KIX configures the user&amp;#39;s profile&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1 Base Build. Outlook settings and printers&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.1 disables the adobe splash &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;screen&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.2 disables autoload of IM&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.3 disables autoload of IM&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;when &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;OutLook is launched &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************* Ver 1.4 Enables outlook to attach EXE and URL files &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;$VER = ReadValue (&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Version&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;IF $VER=1.4&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;GOTO ALWAYS&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ELSE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;GOTO RUNONCE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:RUNONCE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Outlook Config&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;$OTLK = ReadValue (&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Otlk&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IF $OTLK&amp;lt;&amp;gt;1&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Run &amp;quot;d:\Progra~1\Micros~1\Office10\Outlook.exe /ImportPRF D:\admin\scripts\Outlook.prf&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Rapidapp&amp;quot;,&amp;quot;Otlk&amp;quot;, &amp;quot;1&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Disable Splash screen for adobe reader ADDED WITH VER1.1&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Acrobat Reader\5.0\AdobeViewer&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Acrobat Reader\5.0\AdobeViewer&amp;quot;,&amp;quot;DISPLAYABOUTDIALOG&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Adobe Acrobat\5.0\AdobeViewer&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\ADOBE\Adobe Acrobat\5.0\AdobeViewer&amp;quot;,&amp;quot;DISPLAYABOUTDIALOG&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Disable the IM auto-loader ADDED WITH VER 1.3 and 1.4 for published apps&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;DelValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run&amp;quot;, &amp;quot;MSMSGS&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\IM&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\IM&amp;quot;,&amp;quot;Enabled&amp;quot;, &amp;quot;00000000&amp;quot;, &amp;quot;REG_DWORD&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;; Enables a user to see and attach EXEs and URLs within outlook&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook\SECURITY\&amp;quot;,&amp;quot;Level1Remove&amp;quot;, &amp;quot;exe;url&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;**************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Write the version info into the registry. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;AddKey(&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteValue(&amp;quot;HKEY_CURRENT_USER\Software\RapidApp&amp;quot;,&amp;quot;Version&amp;quot;, &amp;quot;1.4&amp;quot;, &amp;quot;REG_SZ&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:ALWAYS&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;************************************************************************* &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Map drives for Citrix users. &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE L: /DELETE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE K: /DELETE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE L: &lt;a&gt;\\RAFS1\DOCs12&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;USE K: &lt;a&gt;\\RAFS2\DJQ&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Set the 4000 and 4500 printers for the Chicago Users&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;IF INGROUP(&amp;quot;CHIUsers&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;addprinterconnection(&amp;quot;\\RAFS1\HP4000&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;addprinterconnection(&amp;quot;\\RAFS1\HP4500&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;setdefaultprinter(&amp;quot;\\RAFS1\HP LaserJet 4500&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ELSE&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;? &amp;quot;Non-Chicago User&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;ENDIF&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;;*************************************************************************&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;; Copy the DOCs12.ini and modify username settings&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;COPY “\\RAFS1\Source\W2HCM.ini&amp;quot; &amp;quot;%homedrive%%homepath%\windows\DOCs12.INI&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;WriteProfileString(&amp;quot;%homedrive%%homepath%\windows\DOCs12.ini&amp;quot;,&amp;quot;Session&amp;quot;,&amp;quot;User&amp;quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;:END&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6307" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Technical Articles" scheme="http://www.brianmadden.com/tags/Technical+Articles/default.aspx" /><category term="Scripting" scheme="http://www.brianmadden.com/tags/Scripting/default.aspx" /></entry><entry><title>Writing a Script to take a MetaFrame Server Online or Offline</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/05/27/writing-a-script-to-take-a-metaframe-server-online-or-offline.aspx" /><id>/blogs/ronoglesby/archive/2004/05/27/writing-a-script-to-take-a-metaframe-server-online-or-offline.aspx</id><published>2004-05-27T09:10:00Z</published><updated>2004-05-27T09:10:00Z</updated><content type="html">&lt;p&gt;In this series of articles I focus on how an you can use scripting in a Terminal Server / Citrix MetaFrame environment for common and recurring tasks. This article goes into the details of a set of scripts created to take a server offline by removing it from all published applications and then bringing it back online by adding it back into the server list for its published applications.&lt;/p&gt;
&lt;p&gt;Since this is the first article in this series, I’ll start by stating some perquisites. It is assumed that the reader has some knowledge of basic scripting. While you don’t have to be a VBS/WSH expert to write these scripts it does help to have some basic VBS skills. Future articles will also deal with CMD and KIX scripting but this one utilizes VBS. Now, onto the fun!&lt;/p&gt;
&lt;p&gt;One of the most common questions I hear about MetaFrame scripting is how to script common tasks normally done within the CMC. Administrators often want to script tasks they do almost every day or write a simple script to ensure that new applications get the same default settings each time, etc.&lt;/p&gt;
&lt;p&gt;This article looks at a basic MFCOM script that dumps a list of published applications to a text file and removes a server from all its published applications. (In other words, it takes a server offline.) Then, a second script reads from that text file and re-publishes all the applicationss to that server (putting the server back online). These scripts (called “svrOnline” and “svrOffline”) were originally written by Ronn Martin at Citrix as samples for Doug Brown. In this article, we’ll go over the basics of these scripts and show you how RapidApp has added some basic logic to them for use during large numbers of automated reboots.&lt;/p&gt;
&lt;p&gt;The first thing you should do before you write any script is to see if anyone has written something like it before. With scripting there is no need to re-invent the wheel. Save yourself some time by perusing sites like thethin.net and Citrix.com/cdn to see if there are scripts you can re-use or modify to fit your needs. With that in mind, let’s take a look at the first script we hacked: srvOffline.VBS.&lt;/p&gt;
&lt;p&gt;SrvOffline.VBS uses the MFCOM object to determine which applications a server is publishing. It then enumerates these application names and writes them to a text file for later use. Basically, you run the script using the following command line and get a text file with the name of the server and all of its apps:&lt;/p&gt;
&lt;p&gt;Cscript svroffline.vbs SERVERNAME C:\path &lt;/p&gt;
&lt;p&gt;This script also removes all the published application assignments from the server, so after it’s run you can do your maintenance by allowing users to log off gracefully and then taking control of the machine. When you’re done, you run the second script to put the server back in the list:&lt;/p&gt;
&lt;p&gt;Cscript svrOnline.vbs SERVERNAME C:\Path&lt;/p&gt;
&lt;p&gt;Let’s take a look at the whole script before breaking it down and modifying it to fit our needs:&lt;/p&gt;
&lt;p&gt;*********************************************************************&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;svrOffline.vbs&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Description: Take a MF XP server &amp;quot;offline&amp;quot; by unpublishing all applications&lt;br /&gt;&amp;#39;       published from the server. The published app names are stored&lt;br /&gt;&amp;#39;       to a text file in a path specified in the command line so that&lt;br /&gt;&amp;#39;       the server can be brought back &amp;#39;online&amp;quot; by the svrOnline script.&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Usage: Two required command line parameters - 1) MF XP server name (case&lt;br /&gt;&amp;#39;    sensitive 2) file path (with trailing &amp;quot;\&amp;quot; character)&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;    e.g. &amp;gt;cscript svrOffline.vbs MFSVR1 C:\WINNT\TEMP\&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;********************************************************************&lt;/p&gt;
&lt;p&gt;  Dim fso&lt;br /&gt;  Dim fp&lt;br /&gt;  Dim svrName&lt;br /&gt;  Dim savePath&lt;br /&gt;  Dim mfSvr&lt;br /&gt;  Dim mfApp&lt;br /&gt;  Dim objArgs&lt;/p&gt;
&lt;p&gt;  Set objArgs = WScript.Arguments&lt;br /&gt;  If objArgs.Count &amp;gt; 1 Then&lt;br /&gt;  &lt;br /&gt;    svrName = objArgs(0)&lt;br /&gt;    savePath = objArgs(1)&lt;br /&gt;    &lt;br /&gt;    Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;/p&gt;
&lt;p&gt;    Set fp = fso.CreateTextFile(savePath &amp;amp; svrName &amp;amp; &amp;quot;.txt&amp;quot;, True, False)&lt;br /&gt;    &lt;br /&gt;    Set mfSvr = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameServer&amp;quot;)&lt;br /&gt;    mfSvr.Initialize 6, svrName&lt;br /&gt;    &lt;br /&gt;    For Each mfApp In mfSvr.Applications&lt;br /&gt;      mfApp.RemoveServer svrName&lt;br /&gt;      mfApp.SaveData&lt;br /&gt;      fp.WriteLine mfApp.DistinguishedName&lt;br /&gt;    Next&lt;br /&gt;    &lt;br /&gt;    fp.Close&lt;/p&gt;
&lt;p&gt;  Else&lt;br /&gt;    MsgBox &amp;quot;Usage: svrOffline.vbs  &amp;quot;&lt;br /&gt;  End If&lt;br /&gt; &lt;br /&gt;You’ll notice right off the bat that after declaring the variables the author checks for possible command line script arguments with these two lines:&lt;/p&gt;
&lt;p&gt;Set objArgs = WScript.Arguments&lt;br /&gt;If objArgs.Count &amp;gt; 1 Then&lt;/p&gt;
&lt;p&gt;Notice that Ronn checks to see if the number of arguments is greater than one. If not he jumps to the end of the script and pops up a message box that shows the proper syntax. It’s important to notice this since your modification may have more arguments and you may want to set this to a fixed number.&lt;/p&gt;
&lt;p&gt;The next section of the script (if the objArgs.count is greater than 1) is the real meat of the script. Let’s look at the next four lines in the script:&lt;br /&gt;  &lt;br /&gt;    svrName = objArgs(0)&lt;br /&gt;    savePath = objArgs(1)&lt;br /&gt;    &lt;br /&gt;    Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;/p&gt;
&lt;p&gt;    Set fp = fso.CreateTextFile(savePath &amp;amp; svrName &amp;amp; &amp;quot;.txt&amp;quot;, True, False)&lt;br /&gt;    &lt;br /&gt;The first two lines set the svrName and savePath variables to the arguments passed from the command line. “svrName” is the server name you are taking offline and “savePath” is where the you want the text file with the application names written to. The next two lines then setup the script for logging the published application names. This is done by accessing the File System Object which is then used to create the text file with a name and path based on the two arguments passed into the script. &lt;/p&gt;
&lt;p&gt;The next two lines in the script are the first ones to actually touch any MetaFrame information. Here we begin to interact with the MFCOM object and locate the server name that was passed into the script as an argument.&lt;/p&gt;
&lt;p&gt;    Set mfSvr = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameServer&amp;quot;)&lt;br /&gt;    mfSvr.Initialize 6, svrName&lt;/p&gt;
&lt;p&gt;With the server object located, the script then parses the server object for all applications that it is hosting. You can see the For Each loop that looks for the application then for each application it finds it does three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Removes the server from the list of servers hosting that application. 
&lt;li&gt;Saves that changes. 
&lt;li&gt;Writes the Distinguished Name of the Published application to the text file we are creating.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Once all the apps have been removed from the server the script then closes the log file and exits&lt;br /&gt;    &lt;br /&gt;    For Each mfApp In mfSvr.Applications&lt;br /&gt;      mfApp.RemoveServer svrName&lt;br /&gt;      mfApp.SaveData&lt;br /&gt;      fp.WriteLine mfApp.DistinguishedName&lt;br /&gt;    Next&lt;br /&gt;    &lt;br /&gt;    fp.Close&lt;/p&gt;
&lt;p&gt;  Else&lt;br /&gt;    MsgBox &amp;quot;Usage: svrOffline.vbs  &amp;quot;&lt;br /&gt;  End If&lt;br /&gt; &lt;br /&gt;As you can see, this is a pretty slick little script. As you can imagine the svrOnline.vbs does the exact opposite of this script. It reads the text file and re-adds the specified server into the list of servers for each published application in the file.&lt;/p&gt;
&lt;p&gt;“Quick and to the point” describes this script pretty well. Does it fit your needs? I have no idea. But I can show you some of the modifications I made using this script as my base. Here’s what part of the script looked like once we finished:&lt;/p&gt;
&lt;p&gt;Set fp = fso.CreateTextFile(savePath &amp;amp; svrName &amp;amp; &amp;quot;.txt&amp;quot;, True, False)&lt;/p&gt;
&lt;p&gt;If fso.FileExists(LogPath &amp;amp; svrName &amp;amp; &amp;quot;-Apps.log&amp;quot;) Then&lt;br /&gt;  Set fpl = fso.OpenTextFile(LogPath &amp;amp; svrName &amp;amp; &amp;quot;-Apps.log&amp;quot;, 8)&lt;br /&gt;Else&lt;br /&gt;  Set fpl = fso.CreateTextFile(LogPath &amp;amp; svrName &amp;amp; &amp;quot;-Apps.log&amp;quot;, True, False)&lt;br /&gt;End If&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;fpl.WriteLine &amp;quot;On &amp;quot; &amp;amp; Date &amp;amp; &amp;quot; at &amp;quot; &amp;amp; Time &amp;amp; &amp;quot; the server &amp;quot; &amp;amp; svrName &amp;amp; &amp;quot; was removed from the following applications: &amp;quot;&lt;br /&gt;    &lt;br /&gt;For Each anApp In theServer.Applications&lt;br /&gt;  anApp.LoadData(TRUE)&lt;br /&gt;  &amp;#39;DisplayMessage = WshShell.Popup(&amp;quot;DistinguishedName: &amp;quot; &amp;amp; anApp.DistinguishedName, 2, &amp;quot;&amp;quot;) &lt;br /&gt;  anApp.RemoveServer svrName&lt;br /&gt;  anApp.SaveData&lt;br /&gt;  fp.WriteLine anApp.DistinguishedName&lt;br /&gt;  fpl.WriteLine anApp.DistinguishedName&lt;br /&gt;Next&lt;/p&gt;
&lt;p&gt;fpl.WriteLine &amp;quot;The end of the applications list on the server &amp;quot; &amp;amp; svrName&lt;br /&gt;fpl.WriteLine &amp;quot; &amp;quot;&lt;/p&gt;
&lt;p&gt;fp.Close&lt;br /&gt;fpl.Close&lt;/p&gt;
&lt;p&gt;One thing you’ll notice was that the script had no logic to determine if that file was already there. If the offline script was accidentally run more than once, the second time it ran it would see no published applications attached to the server and create a blank file. To mitigate this we added some logic to see if the file existed. If it did we opened the file and append to it instead of creating a new one. In addition, when we write the application names to the file we start with a date and time they were removed for later identification.&lt;/p&gt;
&lt;p&gt;This little bit of logic ensured that we wouldn’t have problems running the scripts unattended. Our concern was that the offline script might run (on a schedule) then the online script might not run if there was a failure somewhere. (This was also on a schedule). If this happened we would have no idea what applications were on the server if the offline ran again at its next scheduled interval. A simple bit of modification to the script handled our problems.&lt;/p&gt;
&lt;p&gt;Output from this script is a simple text file with a list of apps. The cool thing is that you can tie this into your reboot scripts to allow the server to remain offline while you do maintenance, or, in our case, to allow it to remain offline for 15-20 minutes while the server was up but packages were installed.&lt;/p&gt;
&lt;p&gt;How can you use this script? It depends on your environment. You can use the svrOnline and svrOffline as they sit (full scripts shown below) or modify them to act as part of your reboots. Our modified versions were tied into the reboot schedule and ran before the server rebooted then a little while after it came back up. It’s up to you to see where they fit. Happy Scripting!&lt;/p&gt;
&lt;p&gt;Look for the next article in the series in which we will create a basic KIX login script for MetaFrame users. &lt;/p&gt;
&lt;p&gt;&amp;#39;***********************************************************************&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;svrOffline.vbs&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Description: Take a MF XP server &amp;quot;offline&amp;quot; by unpublishing all applications&lt;br /&gt;&amp;#39;       published from the server. The published app names are stored&lt;br /&gt;&amp;#39;       to a text file in a path specified in the command line so that&lt;br /&gt;&amp;#39;       the server can be brought back &amp;#39;online&amp;quot; by the svrOnline script.&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Usage: Two required command line parameters - 1) MF XP server name (case&lt;br /&gt;&amp;#39;    sensitive 2) file path (with trailing &amp;quot;\&amp;quot; character)&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;    e.g. &amp;gt;cscript svrOffline.vbs MFXPTS05 C:\WINNT\TEMP\&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;***********************************************************************&lt;/p&gt;
&lt;p&gt;  Dim fso&lt;br /&gt;  Dim fp&lt;br /&gt;  Dim svrName&lt;br /&gt;  Dim savePath&lt;br /&gt;  Dim mfSvr&lt;br /&gt;  Dim mfApp&lt;br /&gt;  Dim objArgs&lt;/p&gt;
&lt;p&gt;  Set objArgs = WScript.Arguments&lt;br /&gt;  If objArgs.Count &amp;gt; 1 Then&lt;br /&gt;  &lt;br /&gt;    svrName = objArgs(0)&lt;br /&gt;    savePath = objArgs(1)&lt;br /&gt;    &lt;br /&gt;    Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;/p&gt;
&lt;p&gt;    Set fp = fso.CreateTextFile(savePath &amp;amp; svrName &amp;amp; &amp;quot;.txt&amp;quot;, True, False)&lt;br /&gt;    &lt;br /&gt;    Set mfSvr = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameServer&amp;quot;)&lt;br /&gt;    mfSvr.Initialize 6, svrName&lt;br /&gt;    &lt;br /&gt;    For Each mfApp In mfSvr.Applications&lt;br /&gt;      mfApp.RemoveServer svrName&lt;br /&gt;      mfApp.SaveData&lt;br /&gt;      fp.WriteLine mfApp.DistinguishedName&lt;br /&gt;    Next&lt;br /&gt;    &lt;br /&gt;    fp.Close&lt;/p&gt;
&lt;p&gt;  Else&lt;br /&gt;    MsgBox &amp;quot;Usage: svrOffline.vbs  &amp;quot;&lt;br /&gt;  End If&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;#39;***********************************************************************&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;svrOnline.vbs&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Description: Bring a MF XP server &amp;quot;online&amp;quot; by re-publishing applications &lt;br /&gt;&amp;#39;       published from the server. The published app names are stored&lt;br /&gt;&amp;#39;       to a text file in a path specified in the command line that is&lt;br /&gt;&amp;#39;       the output of the svrOffline script.&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;Usage: Two required command line parameters - 1) MF XP server name (case&lt;br /&gt;&amp;#39;    sensitive 2) file path (with trailing &amp;quot;\&amp;quot; character)&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;    e.g. &amp;gt;cscript svrOnline.vbs MFXPTS05 C:\WINNT\TEMP\&lt;br /&gt;&amp;#39;&lt;br /&gt;&amp;#39;***********************************************************************  &lt;br /&gt;  &lt;br /&gt;  Dim fso&lt;br /&gt;  Dim fp&lt;br /&gt;  Dim svrName&lt;br /&gt;  Dim savePath&lt;br /&gt;  Dim mfSvr&lt;br /&gt;  Dim mfApp&lt;br /&gt;  Dim appName&lt;br /&gt;  Dim mfAppBinding&lt;br /&gt;  &lt;br /&gt;  Set objArgs = WScript.Arguments&lt;br /&gt;  If objArgs.Count &amp;gt; 1 Then&lt;br /&gt;  &lt;br /&gt;    svrName = objArgs(0)&lt;br /&gt;    savePath = objArgs(1)&lt;br /&gt;    &lt;br /&gt;    Set fso = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)&lt;br /&gt;    Set fp = fso.OpenTextFile(savePath &amp;amp; svrName &amp;amp; &amp;quot;.txt&amp;quot;, 1, vbFalse)&lt;br /&gt;    &lt;br /&gt;    Set mfSvr = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameServer&amp;quot;)&lt;br /&gt;    mfSvr.Initialize 6, svrName&lt;br /&gt;    &lt;br /&gt;    While Not fp.AtEndOfStream&lt;br /&gt;      Set mfApp = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameApplication&amp;quot;)&lt;br /&gt;      appName = fp.ReadLine&lt;br /&gt;      mfApp.Initialize 3, appName&lt;br /&gt;      mfApp.LoadData True&lt;br /&gt;      &lt;br /&gt;      Set mfAppBinding = CreateObject(&amp;quot;MetaFrameCOM.MetaFrameAppSrvBinding&amp;quot;)&lt;br /&gt;      mfAppBinding.Initialize 6, svrName, appName&lt;br /&gt;          &lt;br /&gt;      mfApp.AddServer mfAppBinding&lt;br /&gt;      mfApp.SaveData&lt;/p&gt;
&lt;p&gt;    Wend&lt;br /&gt;    &lt;br /&gt;    fp.Close&lt;br /&gt;    &lt;br /&gt;  Else&lt;br /&gt;    MsgBox &amp;quot;Usage: svrOnline.vbs  &amp;quot;&lt;br /&gt;  End If&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6252" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Technical Articles" scheme="http://www.brianmadden.com/tags/Technical+Articles/default.aspx" /><category term="Scripting" scheme="http://www.brianmadden.com/tags/Scripting/default.aspx" /><category term="Support" scheme="http://www.brianmadden.com/tags/Support/default.aspx" /></entry><entry><title>Terminal Server 2003 GPOs, Gadgets, Utilities, and Tools</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/05/13/terminal-server-2003-gpos-gadgets-utilities-and-tools.aspx" /><id>/blogs/ronoglesby/archive/2004/05/13/terminal-server-2003-gpos-gadgets-utilities-and-tools.aspx</id><published>2004-05-13T09:00:00Z</published><updated>2004-05-13T09:00:00Z</updated><content type="html">This PowerPoint presentation by Ron Oglesby details all the cool free add-on stuff for Windows 2003 Terminal Services and Citrix MetaFrame Presentation Server. It covers things like flex profiles, WMI, MFCOM, and other free tools. Ron originially gave this presentation at CUG Tech in Norway in April 2004.&lt;br /&gt;&lt;a href="http://www.brianmadden.com/media/p/6200.aspx"&gt;Windows 2003 Group Policy - Ron Oglesby.ppt&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6201" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Third Party Software" scheme="http://www.brianmadden.com/tags/Third+Party+Software/default.aspx" /><category term="Microsoft Terminal Services" scheme="http://www.brianmadden.com/tags/Microsoft+Terminal+Services/default.aspx" /><category term="Presentations" scheme="http://www.brianmadden.com/tags/Presentations/default.aspx" /><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /></entry><entry><title>Server Farm Design with a Focus on Disaster Recovery</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/05/05/server-farm-design-with-a-focus-on-disaster-recovery.aspx" /><id>/blogs/ronoglesby/archive/2004/05/05/server-farm-design-with-a-focus-on-disaster-recovery.aspx</id><published>2004-05-05T06:50:00Z</published><updated>2004-05-05T06:50:00Z</updated><content type="html">&lt;p&gt;As organizations continue to rely more and more on server-based computing solutions, it&amp;#39;s more important than ever to design Citrix MetaFrame server farms that can withstand the loss of a single site or network connection.&lt;/p&gt;
&lt;p&gt;In this presentation, Ron Oglesby discusses a step-by-step approach you can follow to ensure that your server farms are as resilient as possible.&lt;/p&gt;
&lt;p&gt;Ron originally gave this presentation at CUG Tech 2004 in Oslo, Norway.&lt;/p&gt;&lt;br /&gt;&lt;a href="http://www.brianmadden.com/media/p/6183.aspx"&gt;Server Farm design with a focus on disaster recovery - Ron Oglesby.ppt&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6184" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Presentations" scheme="http://www.brianmadden.com/tags/Presentations/default.aspx" /><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /></entry><entry><title>Designing one of the Largest MetaFrame Farms in the World</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/05/03/designing-one-of-the-largest-metaframe-farms-in-the-world.aspx" /><id>/blogs/ronoglesby/archive/2004/05/03/designing-one-of-the-largest-metaframe-farms-in-the-world.aspx</id><published>2004-05-04T00:00:00Z</published><updated>2004-05-04T00:00:00Z</updated><content type="html">&lt;p&gt;Ron Oglesby is known throughout the world as one of the most experienced large farm designers out there. In this presentation, Ron talks about the priciples needed to design a Citrix MetaFrame farm of over 900 servers.&lt;/p&gt;
&lt;p&gt;Ron originally gave this presentation at CUG Tech 2004 in Norway.&lt;/p&gt;&lt;br /&gt;&lt;a href="http://www.brianmadden.com/media/p/6181.aspx"&gt;Designing one of the largest MetaFrame Farms in the World - Ron Oglesby.ppt&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6182" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Presentations" scheme="http://www.brianmadden.com/tags/Presentations/default.aspx" /><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /></entry><entry><title>Architecting for a MetaFrame 3.0 (Hudson) Environment</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/04/30/architecting-for-a-metaframe-3-0-hudson-environment.aspx" /><id>/blogs/ronoglesby/archive/2004/04/30/architecting-for-a-metaframe-3-0-hudson-environment.aspx</id><published>2004-04-30T06:45:00Z</published><updated>2004-04-30T06:45:00Z</updated><content type="html">Ron Oglesby orginally gave this presentation at the Norway CUG Tech 2004 in April, a few days before Citrix MetaFrame Presentation Server 3.0 (MPS3) was released. Not only does&amp;nbsp;Ron discuss&amp;nbsp;the major changes and new features of MPS3 and how they&amp;#39;re different than MetaFrame XP, he also talks about the design impact of each new feature.&lt;br /&gt;&lt;a href="http://www.brianmadden.com/media/p/6179.aspx"&gt;Architecting for a Hudson Environment MPS 3.0 - Ron Oglesby.ppt&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6180" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Presentations" scheme="http://www.brianmadden.com/tags/Presentations/default.aspx" /><category term="Citrix" scheme="http://www.brianmadden.com/tags/Citrix/default.aspx" /><category term="Citrix MetaFrame Presentation Server 3.0" scheme="http://www.brianmadden.com/tags/Citrix+MetaFrame+Presentation+Server+3.0/default.aspx" /></entry><entry><title>Terminal Services 2003: What it Does and Doesn't Do</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/04/28/terminal-services-2003-what-it-does-and-doesn-t-do.aspx" /><id>/blogs/ronoglesby/archive/2004/04/28/terminal-services-2003-what-it-does-and-doesn-t-do.aspx</id><published>2004-04-28T20:00:00Z</published><updated>2004-04-28T20:00:00Z</updated><content type="html">This presentation by Ron Oglesby takes a hard look at what Terminal Services on Windows 2003 really does and where it falls short. Ron originally gave this presentation at CUG Tech 2004 in Norway.&lt;br /&gt;&lt;a href="http://www.brianmadden.com/media/p/6165.aspx"&gt;2003 Terminal Services - What it does and doesn&amp;#39;t do - Ron Oglesby.ppt&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=6166" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author><category term="Load Balancing" scheme="http://www.brianmadden.com/tags/Load+Balancing/default.aspx" /><category term="Third Party Software" scheme="http://www.brianmadden.com/tags/Third+Party+Software/default.aspx" /><category term="Microsoft Terminal Services" scheme="http://www.brianmadden.com/tags/Microsoft+Terminal+Services/default.aspx" /><category term="Presentations" scheme="http://www.brianmadden.com/tags/Presentations/default.aspx" /></entry><entry><title>MVP Global Summit, Final Day</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/04/08/mvp-global-summit-final-day.aspx" /><id>/blogs/ronoglesby/archive/2004/04/08/mvp-global-summit-final-day.aspx</id><published>2004-04-08T10:31:00Z</published><updated>2004-04-08T10:31:00Z</updated><content type="html">The week is over. Wheewww. What a week. I am just exhausted. This week has basically been a non-stop, go go go, event since Sunday night. From the Opening night party through the fair well party tonight everything has been great (though tiring)....(&lt;a href="http://www.brianmadden.com/blogs/ronoglesby/archive/2004/04/08/mvp-global-summit-final-day.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=118396" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author></entry><entry><title>MVP Global Summit Day 3, Executives Day</title><link rel="alternate" type="text/html" href="/blogs/ronoglesby/archive/2004/04/06/mvp-global-summit-day-3-executives-day.aspx" /><id>/blogs/ronoglesby/archive/2004/04/06/mvp-global-summit-day-3-executives-day.aspx</id><published>2004-04-07T00:45:00Z</published><updated>2004-04-07T00:45:00Z</updated><content type="html">Today was the day when they got all the MVP pods together in one big room and the Microsoft executives tell us how great we all are and how much they appreciate us, etc, etc. Frankly, for an ego like mine this was nothing new, but I digress :-)....(&lt;a href="http://www.brianmadden.com/blogs/ronoglesby/archive/2004/04/06/mvp-global-summit-day-3-executives-day.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.brianmadden.com/aggbug.aspx?PostID=118392" width="1" height="1"&gt;</content><author><name>Ron Oglesby</name><uri>http://www.brianmadden.com/members/Ron-Oglesby/default.aspx</uri></author></entry></feed>