Category Archives: Batch

The cmd.exe command line below uses mountvol.exe in order to delete the old and to set the new drive letter assignment (where E: represents the old and Z: the new drive letter):

MS DOS

1

2

3

4

5

6

FOR/F%VIN(

'mountvol.exe E: /L'

)DO(

mountvol.exeE:/D

mountvol.exeZ:%V

)

The FOR /F command parses a mountvol command that returns the CD-ROM drive’s volume name. The volume name looks like this:

MS DOS

1

\\?\Volume{1d926311-403a-11d9-94c8-806d6172696f}\

If FOR /F successfully determines a volume name it executes two mountvol commands, the first one deletes the current drive letter assignment the seconds one sets the new drive letter assignment (using the volume name).

A Microsoft Windows installation that is properly optimized to run from a Citrix PVS vDisk in standard mode won’t start the Windows Update Service and a couple of other background services that alter the system. It makes no sense to start these services because PVS redirects any write access to the write cache that is known to be volatile. When it comes to maintenance the system needs to be started from the vDisk in a writeable state (that is nowadays a maintenance version/vhd snapshot of the vDisk). In order to let the system pull updates from Microsoft WSUS the Windows Update service needs to be configured to start. Following the maintenance tasks, as part of re-sealing the vDisk, the service will be disabled again through the PVS TargetOSOptimizer.exe utility.

How about a startup script that configures and starts the Windows Update service automatically dependent on the vDisk mode? Here we go:

So, what happens here? Basically, the batch file uses the so-called personality data. In course of booting from vDisk PVS injects these data to a file called Personality.ini in the root directory of the vDisk file system. The script leverages a command line tool called GetPersonality.exe to retrieve the value for $WriteCacheType. A value of 0 indicates that the vDisk is writeable (private mode or maintenance version) and, thus, the script configures the Windows Update service to start automatically and starts it. Additional read: Managing Target Device Personality.

How to use? Save the script as a batchfile on the vDisk, for example in a scripts folder. Configure it to run on system startup (Windows task scheduler, LGPO, whatever).

Disclaimer: I hope that the information in this post is valuable to you. Your use of the information contained in this post, however, is at your sole risk. All information on this post is provided “as is”, without any warranty, whether express or implied, of its accuracy, completeness, fitness for a particular purpose, title or non-infringement, and none of the third-party products or information mentioned in the work are authored, recommended, supported or guaranteed by me. Further, I shall not be liable for any damages you may sustain by using this information, whether direct, indirect, special, incidental or consequential, even if it has been advised of the possibility of such damages.

“Is there something like WSUS for XenApp, or is it possible to extend Microsoft WSUS in order to download and apply updates and hotfixes to our XenApp servers?” No. But you can try my simple XenApp hotfix deployment framework that I want to share with you today.

Introduction

While (Cloud) service providers have evolved (or are evolving) an ideal approach to maintain their XenApp server farms there are uncountable companies across all sizes that are running one or more XenApp farms w/o a proper maintenance concept. Plenty of these companies indeed have service time windows with corresponding tasks. But quite often the implementation lacks class meaning that at the worst the admin updates each and every damned (sorry) XenApp server by hand.

A year ago or so, I developed a bunch of batch files that build a simple script framework for automated XenApp hotfix installation. My goals were to build a solution that supports the broadest range of XenApp farms as possible on the one hand and to build a “learning” framework that identifies new hotfixes in the source folder tree on its own (and releases the admin from the challenge to script). Therefore I chose Batch scripting and ini files instead of PowerShell and XML. Furthermore my solution either relies on MFCOM (API for legacy XenApp before version 6) nor it uses XenApp PowerShell Cmdlets. It just leverages cmd.exe and some standard commands that you’ll find on every Windows Server with Terminal Services or Remote Desktop Services. In short, the XenApp hotfix deployment framework is designed to update XenApp 4.5/5.0/6.0/6.5 on Windows Server 2003/2003 R2/2008/2008 R2.

Simple means basic. Please don’t expect a superduper allrounder solution. The script framework cares about the sessions though (if you want), gives them some (configurable) grace time and repeatedly sends a warning message. And it disables logons as well. This seems quite a lot but in a perfect world you would like a solution that monitors itself and stops processing on all remaining servers in case of fault for example.

Requirements

The XenApp hotfix deployment framework just needs storage space on a central folder share. The scripts and related files on its own allocate less than 200 KB, but you need to take the hotfix files into account as they’ll be stored inside the framework’s folder structure as well.

Strictly speaking, a dedicated active directory account that runs the maintenance process is not really required. But it is recommended to create such an account, especially if you opt for an automated invocation of the maintenace process via scheduled task for example.

Give the account that runs the maintenance appropriate access on the above mentioned share. Of course the account needs administrative access on the XenApp servers to be able to install the hotfixes successfully.

That’s all, nothing more required from a technical perspective.

Overview

The XenApp hotfix deployment framework consists of a main script, a bunch of library scripts, one or more config files, a folder structure, and – last but not least – a naming convention with a hidden sense (below more).

The main script, XenAppMaintenance.cmd, initializes and controls the progress of the maintenance work.

The config file, Settings.ini, includes changeable global settings that configure logging and session warning timeframe for example. Additional config files (per XenApp Server) can be placed aside the Settings.ini in order to overwrite to common settings for whatever reason or purpose.

The folder structure separates the framework components. This helps the admin to locate easily a config file or to save a new hotfix for example.

The naming convention for additional config files, for library scripts, and hotfix subfolders make up an important part of the framework. For example a part of a hotfix subfolder name is tied to the library script that the framework shall use in order to install the hotfix inside that folder.

Download and unzip the XenApp hotfix deployment framework to the shared folder

Open the file\Config\Settings.ini in order to configure settings (optional).

Download hotfixes from www.citrix.com. For each hotfix, create a subdirectory in the Source folder of the framework. A hotfix subdirectory consists of three parts separated by an underscore: three-digit installation order number, action library script, and optionally a comment. For example, the subdir “010_InstallMsp_CTX126679” stands for order number 10, use action script “InstallMsp” to install the hotfix, and article number CTX126679.

Invoke Maintenance

This is simple. Just double click XenAppMaintenance.cmd or create a scheduled task.

Disclaimer: I hope that the information in this post is valuable to you. Your use of the information contained in this post, however, is at your sole risk. All information on this post is provided “as is”, without any warranty, whether express or implied, of its accuracy, completeness, fitness for a particular purpose, title or non-infringement, and none of the third-party products or information mentioned in the work are authored, recommended, supported or guaranteed by me. Further, I shall not be liable for any damages you may sustain by using this information, whether direct, indirect, special, incidental or consequential, even if it has been advised of the possibility of such damages.

With this post I share a small batch file that leverages the devcon utility from Microsoft to remove hidden network interfaces.

Recently Citrix identified an issue with those “Ghost NICs” when trying to image a target machine that resides on a virtualization platform like VMware (see CTX133188). NICs can be hidden of leftover from when the machine was built or when the virtualization tools were installed. If the PVS target software binds itself to one of these hidden NICs it won’t allow bnistack to load a vDisk properly.

Next question is how to get devcon because there’s no official download page. Check out this blog post

Disclaimer: I hope that the information in this post is valuable to you. Your use of the information contained in this post, however, is at your sole risk. All information on this post is provided “as is”, without any warranty, whether express or implied, of its accuracy, completeness, fitness for a particular purpose, title or non-infringement, and none of the third-party products or information mentioned in the work are authored, recommended, supported or guaranteed by me. Further, I shall not be liable for any damages you may sustain by using this information, whether direct, indirect, special, incidental or consequential, even if it has been advised of the possibility of such damages.

Initially I intended to migrate the stuff related to batch scripting to the new blog as well. Due to lack of time and motivation I decided to postpone this task or rather to wait if I receive requests like “I’m wondering if you are considering bringing back your old content back”

I will tell you a secret: the old site is still online – check Batch Howto. In order to avoid trouble with the new site I needed to remove the permalinks, therefore I’m afraid your bookmarks/favorites to old site content may be broken.

When it comes to large file downloads one should use a download manager which at least is able to resume broken downloads. Windows has a built-in download manager service called Background Intelligent Transfer Service(BITS). Some of us at Login Consultants (including me) prefer to script large file downloads with the Microsoft’s BITS Admin Utility – Bitsadmin. This article explains how to use Bitsadmin to download a file.

The BITS service is built into Windows XP, Vista, Server 2003, and Server 2008. For example the Windows Automatic Update, WSUS 3.0, or Microsoft SCCM 2007 depend on BITS to transfer files like Windows Updates and software packages. For one thing BITS has been designed for robustness over slow or unstable network connections, and for another thing BITS is a background process that economizes on bandwidth usage. If a download does not complete due to a network problem or restart of your machine, BITS will automatically try to continue the download from where it left off, and repeat this until the whole file has been retrieved. BITS file transfers can be invoked and managed from the command line with the Bitsadmin utility which is part of the Windows Support Tools.

Please note that this article applies to Bitsadmin 3.0 and the version of BITS that is included in Windows Vista SP1.

In order to download a file with Bitsadmin, respectively BITS, you need to type a series of Bitsadmin commands to create a download job, to add the file the the job, eventually to set credentials and proxy settings, and finally to start the download job. Bitsadmin has many command line switches, for this see also Bitsadmin’s help by typing “bitsadmin” at the command prompt. For our purposes we need the switches CREATE, ADDFILE, SETNOTIFYCMDLINE, COMPLETE, SETCREDENTIALS (maybe), and RESUME.

First of all, we need to create a new download job with Bitsadmin /CREATE

MS DOS

1

2

setbits_job=%random%

bitsadmin/create%bits_job%

Bitsadmin will confirm job creation by echoing the job GUID like “Created job {58C6770A-AB4E-477C-8944-33246EC8791E}”. For now, the job is created and its state is suspended. (Therefore, we will need to resume the job later in order to start the download process.)

2. Add File

Now we can add the file to the job with Bitsadmin /ADDFILE. We need to specify the job name, the download URL, and the file’s local name.

MS DOS

1

bitsadmin.exe/addfile%bitsjob%...aikl_en.isoC:\Downloads\aik_en.iso

Again, Bitsadmin will confirm the action. (Hint: if you want to add multiple files to a job take a look at Bitsadmin’s switch /ADDFILESET which reads each file’s remote URL and local name from a text file.)

3. Optional Settings

The job is still in suspended state, and we are almost ready to start the download. But to start with we should pay attention to three important and useful Bitsadmin switches: COMPLETE, SETNOTIFYCMDLINE, and SETCREDENTIALS

By default, Bitsadmin doesn’t tell anything about a finished file transfer. Even worse, though BITS may have downloaded a file completely you won’t find it unless you have completed the job explicitly. To kill two birds with one stone we will use Bitsadmin /SETNOTIFYCMDLINE to launch Bitsadmin /COMPLETE as loon as the transfer is finished. (Virtually, SETNOTIFYCMDLINE enables you to set a command line to execute for notification when the file download is finished.)

Maybe the file is located on a password protected web server. In this case you can add credentials to a job using Bitsadmin /SETCREDENTIALS. This time you have to go without an example. Please refer to Bitsadmin’s syntax help by typing “bitsadmin” at the command line.

4. Start/Resume Download

Finally, we are ready to resume the download job with Bitsadmin /RESUME:

MS DOS

1

bitsadmin/resume%bitsjob%

Now, BITS is downloading the file in the background. Since we have defined the launch of an according job completion command on transfer completion we can just wait and see… or check out some Bitsadmin command lines:

5. Monitor or Cancel Job

How to display information about the BITS job?

PowerShell

1

bitsadmin/info%bitsjob%

How to retrieve the size of the BITS job?

PowerShell

1

bitsadmin/getbytestotal%bitsjob%

How to retrieve the number of bytes transferred?

MS DOS

1

bitsadmin/getbytestransferred%bitsjob%

How to monitor the BITS copy manager?

MS DOS

1

bitsadmin/monitor

How to cancel the BITS job?

MS DOS

1

bitsadmin/cancel%bitsjob%

How to delete all BITS jobs?

MS DOS

1

bitsadmin/reset

6. Write a Shell Script

The batch file below, Bits-Download.cmd, simplifies the usage of Bitsadmin:

Bits-Download.cmd

MS DOS

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

@ECHO OFF

:: NAME

:: Bits-Download.cmd

::

:: SYNOPSIS

:: Downloads a remote file with BITS.

::

:: SYNTAX

:: Bits-Download remote_url local_name

::

:: DETAILED DESCRIPTION

:: The Bits-Download.cmd batch file uses BITS to download

:: the given remote file. Bits-Download.cmd requires the

:: BITS Admin Utility Bitsadmin.exe.

::

:: NOTES

:: Bits-Download.cmd was developed and tested on Windows Vista.

::

:: AUTHOR

:: Frank-Peter Schultze

::

:: DATE

:: 00:18 21.07.2008

SETLOCAL

IF"%2"==""(

TYPE"%~f0"|findstr.exe/R"^::"

GOTO:END

)

SETbits_job=bits%RANDOM%

SETremote_url="%~1"

IFNOTDEFINEDremote_url(

ECHO %~n0 : Cannot bind argument to parameter 'remote_url' because it is empty.

GOTO:END

)

SETlocal_name="%~2"

IFNOTDEFINEDlocal_name(

ECHO %~n0 : Cannot bind argument to parameter 'local_name' because it is empty.

In order to detect if a script was started in a terminal server session the script can check the SESSIONNAME environment variable which is only defined if the Terminal Services are installed on Windows 2000 Server, Windows Server 2003, and Windows XP clients (or newer). When a client connects via a RDP or ICA (Citrix) session, this variable is a combination of the connection name, i.e. “RDP-Tcp” or “ICA-Tcp”, followed by a pound symbol “#” and then the session number in three figures “nnn“. When logging on directly to the machine, this variable returns “Console”.

The VScript function below returns True if the SESSIONNAME variable resolve to a value beginning with “RDP” or “ICA”

In the Registry of Microsoft Operating Systems with V2 user profiles (as from Windows Vista and Windows Server 2008) there’s a value called Default. The expandable string value is located under this registry key:

MS DOS

1

HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ProfileList

With Windows PowerShell you can read the Default value’s data as follows: