jump to navigation

New Tool: ZTIAppVerify.wsf – Logs the status of all installed applications. November 8, 2010

Posted by keithga in MDT 2010, Troubleshooting, VBscript.
comments closed

Someone posted this question on a E-Mail list today:

Subject: Applications log file

Hi all,

I am working on building a LTI solution for Win7. [… is] there […] a simple solution to create a log file at the end of the deployment phase. This log file must contains a list of all applications installed in the task sequence.

It’s possible?

It got me thinking, and I realized that I *had* created a script to perform this exact same problem early this year, yet never posted it here to my blog.

So without further delay:  Introducing new tool ZTIAppVerify.wsf!

Details:

This script performs two tasks:

  1. 1. It will enumerate through the Applications specified in the Wizard, the CustomSettings.ini, and/or MDT Database. In other words, it will parse the Applications and the MandatoryApplications list properties and attempt to see if the installation was successful.
    How does it determine if the installation was successful?  If you populated the “UninstallKey” when creating your Application in MDT, that Key must then exist in the uninstall registry. For MSI applications, that UnInstallKey is just the Product Key. An Error is generated if the Key is not found (meaning the install was not successful).
  2. The script will also enumerate through all the Uninstall Registry Keys on the local machine:
    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\…
    This is the list that is populated when you go to the Control Panel to remove an application (and a lot more). Note that output will contain the “UninstalKey” for use later on.

Just place this script in your MDT 2010 Task Sequence, somewhere *after* the ZTIApplication.wsf script(s) are run.

Sample Output:

For example, in the 2nd case listed above, the script will display a list of installed programs, the “UninstallKey”, and a friendly name for the application:

…
INSTALLED:   {23170F69-40C1-2702-0465-000001000000} \ 7-Zip 4.65 (x64 edition)
INSTALLED:   {25097770-2B1F-49F6-AB9D-1C708B96262A} \ System Center Operations Manager 2007 R2 Agent
INSTALLED:   {26A24AE4-039D-4CA4-87B4-2F86416017FF} \ Java(TM) 6 Update 17 (64-bit)
INSTALLED:   {29C93182-34F6-3275-A18D-59326851CD57} \ Microsoft Windows SDK for Visual Studio 2008 .NET Framework Tools - enu
INSTALLED:   {2F14965D-567B-4E59-ADEB-0A2CC1E3ADDF} \ Sql Server Customer Experience Improvement Program
INSTALLED:   {31E8F586-4EF7-4500-844D-BA8756474FF1} \ Windows Automated Installation Kit
INSTALLED:   {347F1DAD-AFF5-4F68-84F5-69AEB3EE1D24} \ Microsoft Deployment Toolkit 2010 Update 1 (5.1.1642.01)
…

Link:

http://cid-5407b03614346a99.office.live.com/self.aspx/Blog/ZTIAppVerify.zip

New Tool: USB Boot Tool October 28, 2010

Posted by keithga in MDT 2010, Uncategorized, VBscript.
comments closed

Overview:

The purpose of the tool is to add/remove WinPE Boot.wim file(s) to a USB Flash Drive using a wizard. 

It is designed to integrate with the Microsoft Deployment Toolkit 2010.

Description:

It should be smart enough to find USB flash drives, find any local  MDT 2010 Litetouch.wim files, automatically mark the drive/partition active (if not already set), and it can add/remove multiple *.wim files to a single USB Flash drive if there is enough space.

This is ideal if you want multiple Litetouch WIMs, For example x86 *and* x64 litetouch.wim files on the same USB stick, or Litetouch WIMs from multiple Deployment shares (One production server, one test server)..

USBootTool.hta is a standalone *.hta file, and requires no other components/libraries.

Installation/Operation:

· Just copy this script to your %deploymentshare%\Boot\ directory.

· When the script starts up it will display the Litetouch.wim files present on that directory. If not present it will enumerate through the Deployment shares mounted in the MDT console.

Screen Shots:

clip_image001

· Note the tool found my Flash Drive, parsed the BCD file and found three entries.

· I click “add” to add a *.wim file.

clip_image002

· Note that the tool found several *.wim files in my deployment share.

· I can modify the description if required.

clip_image003

· The script will copy all the necessary files to the Flash Drive.

· It will also place the *.wim file in a separate folder. The folder name is a GUID to prevent conflicts.

· I can repeat the process to add other *.wim files to my USB flash drive

 Source

http://cid-5407b03614346a99.office.live.com/self.aspx/Blog/USBBootTool.zip

-k

P2V Migration for Software Assurance Beta 2 Now Available – with System Center Configuration Manager 2007 integration September 26, 2010

Posted by keithga in Announcements, MDT 2010, System Center Configuration Manager, Troubleshooting, USMT, VBscript, Windows 7.
comments closed

 

We’ve been busy here at Xtreme Consulting Group, recently Keith worked as a Developer on the P2V Migration project with Microsoft.

For more information on P2V Migration, click here.

P2V Migration adds documentation and support of System Center Configuration Manager 2007 Zero Touch Installation! 

What is better than spending a moment to kick off a completely automated process to redeliver an existing operating system as a virtual machine within a new build of Windows 7?
Answer: Making the entire process “zero touch” without necessitating a visit to the target computer or manually initiating the migration!

P2V Migration for Software Assurance can now be implemented using System Center Configuration Manager 2007 Operating System Deployment as well as native Lite Touch Installation with the Microsoft Deployment Toolkit 2010 U1. Computer refresh, replace and restore task sequence templates for Configuration Manager are included and documented in this Beta release.

clip_image001 P2V Migration templates integrated with Microsoft Deployment Task Sequence options in System Center Configuration Manager. Can be created and advertised as with other task sequence options.

Additional optimizations beyond Configuration Manager functionality included in this release are:

1. Better flexibility for backing-up and restoring VHD files using default file locations

2. Support for PCs using system and boot volumes

3. Globalization of scripts to handle varying regional and locale formats

4. General bug fixes and improved documentation

These fixes reflect the feedback of our Connect community and MVPs – thanks to everyone for submitting feedback!

Download P2V Migration for Software Assurance Beta 2 now:

P2V Migration for Software Assurance

New to P2V Migration for Software Assurance?

 

This solution was built to help unblock OS deployments by redelivering blocking users’ old Windows environments, applications and browsers seamlessly in Windows 7 using automated physical-to-virtual migration

P2V Migration for Software Assurance uses the Microsoft Deployment Toolkit, Sysinternals Disk2VHD and optionally System Center Configuration Manager 2007 to convert a user’s existing Windows XP or newer client environment to a virtual hard disk then automates the delivery of an updated and personalized Windows 7 operating system containing a virtual machine with the user’s previous Windows environment, applications and Web browser. The user’s previous virtual desktop retains its existing management components, domain membership and policies. The process also publishes applications and the browser for the user to access them seamlessly within Windows 7’s start menu.

How it Works

clip_image002 Completely automated process enables the previous operating system to be a child virtual machine inside the Windows 7 host.
clip_image003 Standalone application and Internet Explorer links published from virtual machine to native Windows 7 start menu. These applications can be launched individually using RemoteApp integration – without showing the entire virtual machine’s desktop.

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group

UserTile Automation June 23, 2010

Posted by Micah Rowland in USMT, VBscript, Windows 7.
16 comments

Recently a customer requested that two accounts be created during the MDT process and required each to have a preset user account picture (referred to by Windows as the User Tile). There are a number of ways to accomplish this, USMT/Easy Transfer wizard being the easiest. However, due to the processes they already had built into the base image, I decided the best tack was to investigate the actual process employed in storing the User Tile and build automation that could quickly accomodate changes to the specifications of which image to use. After a quick search of the web, it seems that this particular problem, programatically changing the User Tile has not yet found a solution. I present to you my findings along with a sample script to tackle this seemingly simple manual process.

The first step in automating any process is to do it manually first and watch what happens. I rely on the Sysinternals tool Process Monitor as well as Process Explorer for most of my research. Launching Process Explorer as an administrator led me down a few dead ends. It was only after running Process Explorer in the System context using PSExec with the -s and -i switches that I was able to locate the location that Windows 7 uses to store the user tile.

The User Tiles configuration information is stored in Windows registry at HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\########, where ######## is a unique 8 digit hexadecimal ID, in as a binary value named UserTile. But how can we cross reference a username to this 8-digit ID? Glad you asked!

Taking a further look at the registry key, you’ll notice that beneath the user ids, there is another key called Names. If you expand this key you’ll see a list of all local user accounts on the system. Upon opening any of the user keys you’ll notices that only a default value exists. However, take a look at the value type… It is not a standard type, but a hexidecimal number 0x### where the ### id crossreferences nicely with the list of user ids above. In our script we need only pad this value with leading 0′s until it reaches the desired 8-digits. Trying to retrieve this hexidecimal “type” throws exceptions in nearly every method I tried. Exporting the key to a .reg file gave me the output I needed to be able to search for a specific username and retrieve its id.

The SAM Hive of the registry is not generally accessible to any user accounts and is configured, by default, to only be accessed by the System account. To maintain security, both the read and the write operations necessary to modify the UserTiles programmatically are accomplished by executing the operations in the System context. Execution in the system context is accomplished by utilizing the PSExec tool.

When a user interactively changes the UserTile by means of the User Account control panel, Windows resizes the image specified by the user to 128×128 and saves new image as a 24-bit bitmap file in the C:\ProgramData\Microsoft\User Account Pictures\ folder as USERNAME.bmp. The bitmap is then stored in the registry in the SAM and the user’s contact card is updated.

The binary data is composed of a header followed by a payload containing the binary graphic used for the UserTile and closed with a footer that contains the path to the file used as the UserTile. The header is 16 bytes long.

  1. 12-bytes (seem to be constant at 01 00 00 00 03 00 00 00 01 00 00 00)
  2. 4-byte field representing the size of the payload

The payload data reveals that the image stored in the registry is 126×126 pixels, presumably to make up for the 1 pixel wide border around the image when displayed on the logon screen and on the start menu. Further, the image is stored in 16-bit color depth using BI_BITFIELDS compression.

The footer contains the type of image file used and the location of the file used using Unicode (2-bytes per character). The format is as follows:

  1. 4-byte field (purpose unknown, possibly the length of the following field)
  2. A null-terminated Unicode string representing the file type
    1. Eg. “bmp” = 62 00 6D 00 70 00 00 00
  3. 4-byte field (purpose unknown, always 02 00 00 00)
  4. 4-byte field representing the payload (bitmap) size in bytes
  5. A null-terminated Unicode string representing the file location padded to the nearest 4 bytes.

Phew! Needless to say, this level of detail is not necessary for part 1 of this post, however in crafting a truely dynamic programmatic approach to changing the uer tile, we will need this information.

Solution:

It should be possible to engineer an application that accepts a username and a bitmap file to use. However, for part 1, it is simpler to export the registry keys from a sample machine using either the reg.exe or the regedit.exe utility under the System context using PSExec.

When scripting this automation, we must be aware that the first time PSExec is run, a EULA must be accepted. To avoid this, the following registry file is imported (AcceptPSExecEULA.reg):

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Sysinternals\PsExec]
"EulaAccepted"=dword:00000001

The following script was created to accomplish the goal of changing the UserTiles:

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'   Title:   User Tile Change Script
'   Author:  Micah Rowland (Xtreme Consulting)
'   Date:    07/14/2010
'   Desc:    This script is designed to programatically replace
'            a single local user's User Tile on Windows Vista
'            and above.
'   Prereq:  This script requires the use of PSExec available
'            from http://live.sysinternals.com/psexec.exe
'   Usage:   UserTile.vbs USERNAME USERTILEFILE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
CONST FORREADING = 1
CONST FORWRITING = 2

set objShell = CreateObject("Wscript.Shell")
set objFSO = CreateObject("Scripting.FileSystemObject")
set objArgs = Wscript.Arguments
set objShell = CreateObject("Wscript.shell")
if CheckArgs() <> "" then
     Wscript.echo Checkargs() & vbcrlf
     wscript.echo "Arguments Invalid. Usage: ChangeUserPicture.vbs USERNAME UserTileFile"
     wscript.quit()
end if

strUsername = objArgs(0)
strUserTileFile = objArgs(1)
strUserIndex = GetUserIndex()
set objFile = objFSO.GetFile(strUserTileFile)
set objTS = objFile.OpenAsTextStream(1)
strUserTile = objTS.ReadAll
wscript.echo strUserTile
strRegFile = objShell.ExpandEnvironmentStrings("%temp%") & "\UserIndexes2.reg"
set objRegFile = objFSO.OpenTextFile(strRegFile, ForWriting, true)
contents = "Windows Registry Editor Version 5.00" & vbcrlf & vbcrlf & "[HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\" & strUserIndex & "]" & vbcrlf & strUserTile
objRegFile.Write contents
objRegFile.Close

strImport = "PSEXEC -S -I reg import " & strRegFile
objShell.Run strImport

Function GetUserIndex

     ' This function exports the Names key of the SAM from the registry to determine a match between the user account provided
     ' and its hex ID for use in creating the new registry file for import. Because the .reg file is exported in Unicode format
     ' we use the type command to pipe it from stdout to a new text file.

     strUsername = objArgs(0)
     strUserTileFile = objArgs(1)
     objShell.run "cmd /c reg export HKLM\SAM\SAM\Domains\Account\Users\Names %temp%\UserIndexes.reg /y"
     wscript.sleep(500)
     objShell.run "CMD /C type %temp%\userindexes.reg > %temp%\userindexes.txt"
     wscript.sleep(500)
     set objFile = objFSO.GetFile(objShell.ExpandEnvironmentStrings("%temp%") & "\userindexes.txt")
     set objRegExport = objFile.OpenAsTextStream(FORREADING)
     curLine = objRegExport.ReadLine()
     do until instr(lcase(curLine), lcase(strUserName)) or objRegExport.atendofStream
          curLine = objRegExport.ReadLine
     loop
     if objRegExport.AtEndOfStream then
          wscript.echo "Username not found."
          wscript.quit()
     else
          curLine = ObjRegExport.ReadLine
          tmpGetUserIndex = mid(curLine, instr(curLine, "(") + 1, len(curline) - instr(curline, "(") - (len(curLine) - instr(curline, ")")+1))
          do until len(tmpGetUserIndex) = 8
               tmpGetUserIndex = "0" & tmpGetUserIndex
          loop
          GetUserIndex = tmpGetUserIndex
     end if
End Function

Function CheckArgs()
     ' This function makes sure that 2 arguments were provided and that the filename provided exists
     if objArgs.Count <> 2 then
          CheckArgs = "Exactly 2 arguments must be specified."
     elseif not objFSO.FileExists(objArgs(1)) then
          CheckArgs = "File not found."
     else
          CheckArgs = ""
     end if
 End Function

The script syntax is: SetUserTile.vbs USERNAME FILE

The file used by this script consists of only the UserTile value from a registry export of a preconfigured UserTile. This can be accomplished by setting a local user account’s picture, opening regedit using the psexec -s -i regedit.exe command, navigating to the SAM key mentioned above, determining the correct user account as detailed above, and exporting the key. Then remove all data in the .reg file except the “UserTile=hex:…” entry.

To leverage this script, a command-script file was created and added to the Software Installation task sequence.

reg import AcceptPSExecEULA.reg
cscript SetUserTile.vbs "USERNAME" DATAFILE.txt

I hope to have a commandline based program developed in the future to tackle this which will accept any sized bitmap image as it’s input as opposed to using a captured registry value. I hope you have enjoyed this post. If you have any questions feel free to ask!

How MDT does Application Installation January 20, 2010

Posted by keithga in MDT 2010, Troubleshooting, VBscript, Windows 7.
14 comments

Been working lately on adding some Application Installation packages to MDT, and I’ve seen some good, bad, and ugly packages.

So, what makes an application installation compatible with MDT (or other scripted installation methods, for that matter)?

Good question.

Microsoft Installer (MSI)

The good!

More and more products are being released lately as MSI packages. Most MSI Packages are easy to automate. For example, I typically use the following parameters:

Msiexec.exe /qb- /l*vx  %LogPath%\<file>.log REBOOT=ReallySuppress UILevel=67 ALLUSERS=2 /i <File>.msi

MDT will easily handle this installation script, and install properly for most MSI packages. Yea!

Non-MSI Packages

However, it is possible that you are working with a custom installation package, or perhaps developing your own. What are the rules necessary to make the package work in MDT?

Rule 1: Provide unattended installs

The install program should have a way to install in a unattended manner. Typically this is done by some sort of command line switch to the installer program or script: /quiet /silent /q whatever. MDT 2010 is a fully automated installation system, and the automation will break if there are any user prompts blocking installation.

For example, if you have a MSI installer package, you can call MSIExec.exe with the /q[bn][-] parameter.

This also equally important for errors. If the install package generates errors, it should provide a method to log the errors to a file for analysis later, rather than prompting the user for interaction with a blocking Error Message Box.

Rule 2: Do not exit until done

The install programs should not exit until all setup tasks have finished. If the setup program returns, yet there are still installation tasks being performed in the background, MDT has no way to determine this. So MDT may continue with the next installation, or perhaps a reboot thus causing conflicts with the installation running in the background.

For example, say you have two installation packages, A.Exe and B.Msi. A.Exe is just a Self Extracting Executable that expands A.MSI to the %temp% folder, and kicks off msiexec.exe. However, A.Exe calls msiexec.exe and doesn’t wait, instead A.Exe promptly exits. MDT does not know what is running in the background, and instead continues installing the next package in the list B.Msi. However since A.Msi is running in the backgound, and MSIExec only allows one installation at a time, B.Msi will fail.

Instead A.Exe should wait until Msiexec.exe /i A.msi has finished.

Rule 3: No rebooting

Sometimes an install package will need to reboot to complete the installation. Reboots, for example, are required to update any file that is already open and in use. It’s a common misconception that you need to reboot to install a device driver, you don’t (unless the driver is in use).

However problems arise if the setup program, when running in an unattended matter, decides to reboot on it’s own, without letting the calling script (in this case MDT), know before hand. It may be a couple of seconds before all processes have a chance to shutdown. It’s possible that MDT may try to continue installing the next program in the order or other cleanup tasks, when it shouldn’t.

Instead, a program should return Windows.h Error Code: 3010 ( ERROR_SUCCESS_REBOOT_REQUIRED ).

This will let MDT know that a reboot is required, reboot the machine, and *then* continue with the rest of the installation packages.

Other Notes

There are a few other notes that I wish I could mention to the authors of installation packages:

  • Be aware that the installation may be performed under one user account, but the program may be used under another account. When calling MSIExec.exe, I usually call it with the ALLUSERS=2 property.
  • Please make it easy to determine what the unattended/silent installation procedures are. It’s not always easy to determine what the command line parameters are.
  • If you have a Self Extracting Executable that calls msiexec.exe, please provide a way to pass logging and other properties (see above) to msiexec.exe.
  • Speaking of Self Extracting Exe files that call *.msi packages. Please just provide the *.msi install package, it’s much easier.
  • On your web site, please provide direct access to your install packages, rather than going through some web logic. Several populat sites, for example will attempt to offer you *only* the x86 or x64 binaries depending on which platform you are running on, even though I may need both for packaging.
  • Please keep the desktop free from links/icons, or provide a property in MSI to disable shortcuts creation on the desktop (I’m talking to you Adobe Reader). I like keeping my desktop clean.
  • Speaking of options, please provide ways on the command line to enable/disable most common features.

 

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group

Friendly names when Selecting the Domain OU in MDT 2010 December 11, 2009

Posted by keithga in MDT 2010, VBscript.
7 comments

Came across a question in a forum recently:

In MDT 2010 when I am in the Deployment Wizard I can select the option to join a domain, enter in my domain and near the bottom I have the option to select my OU with a dropdown menu.
Within my control folder of my deployment share I have a file called DomainOUList.xml that has a long list of all the OUs I want our techs to be able to select from. The structure of the file looks something like this:

<DomainOUs>
<DomainOU>OU=Desktops,OU=Accounting,OU=Calgary,DC=MYDOMAIN,DC=AD</DomainOU>

How can I make it look like this:
Laptops / Accounting / Calgary / MYDOMAIN

I did some investigation, and discovered that MDT lacks the ability to display Friendly names in the Domain OU selection on the dialog box. This is a problem all the way back to BDD 2007.

Something I forgot to do.

Updated change

It s quick change to DeployWiz_Initialization.vbs to make the wizard display friendly names rather than the OU style.

First we introduce a new set of functions:

Function AddItemToMachineObjectOUOpt(item)   AddItemToMachineObjectOUOptEx item, itemEnd function

Function AddItemToMachineObjectOUOptEx(item,value)  Dim oOption

  set oOption = document.createElement("OPTION")  oOption.Value = value  oOption.Text = item  MachineObjectOUOptional.Add oOption  MachineObjectOUOptionalBtn.style.display = "inline"End function

I personally like to add *EX style function like this, it means that we can reduce the number of changed lines in the code, and keep the old version of the function around for compatibility.

Then later on we modify the code to read the DomainOUList.xml:

iRetVal = oUtility.FindFile( "DomainOUList.xml" , sFoundFile)
if iRetVal = SUCCESS then     For each oItem in oUtility.CreateXMLDOMObjectEx( sFoundFile ).selectNodes("//DomainOUs/DomainOU")

        if oItem.Attributes.getNamedItem("value") is nothing then             AddItemToMachineObjectOUOpt oItem.text         else
            AddItemToMachineObjectOUOptEx oItem.text, oItem.Attributes.getNamedItem("value").value         end if     Next
End if

If the DomainOUList.xml file contains a value attribute in the XML file, it will use that for the value, and the node for the Friendly Name:

<DomainOUs>
 <DomainOU>OU=Desktops,OU=Accounting,OU=Calgary,DC=MYDOMAIN,DC=AD</DomainOU>
 <DomainOU value="OU=Desktops,OU=Accounting,OU=Calgary,DC=MYDOMAIN,DC=AD" > DomainCalgaryAccountingDesktops </DomainOU>
</DomainOUs>

Full sample can be found at:

DeployWiz_Initialization.vbs

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group

MDT 2010 Application ordering (New Tool) December 9, 2009

Posted by keithga in MDT 2010, PowerShell, VBscript.
comments closed

Got an E-Mail from a friend of mine recently:

Are you bored? :-) Might be a good utility to build. The PowerShell script [..] posted at http://blogs.technet.com/mniehaus/archive/2009/09/09/sorting-the-contents-of-an-mdt-2010-deployment-share.aspx shows how to rearrange the items in a folder – basically, it just reorders the GUIDs in the group and then saves the modified GUID list. The script only does alphabetical sorting, but some might want to manually rearrange – not terribly easy to do in PowerShell, so it would require a real UI.

For most scenarios, I recommend using Application Dependencies to ensure that applications install in the correct order.

I really didn’t think much of it until recently. When I had some applications that could install stand alone, by themselves, however when both were installed, they needed to be installed in a specific order. If I were creating a CustomSettings.ini file, I would manually ensure that the Applications were placed in order. However, if the user selected the applications from the wizard, then there was no way to ensure the order of the apps unless we modified the order within the ApplicationGroups.xml manually. <yuck>

The blog above shows how application ordering can be done. Simply create a temporary sub-folder, an move the items *in order* to the temporary subfolder and then move everything back.

Solution

This solution should work for sorting both Folders and Application Items within MDT 2010. The application is a simple wrapper around the MDT 2010 Powershell provider, and simply makes calls to move Applications and/or folders using Powershell.

User Interface

The wizard will prompt you for the correct MDT 2010 Deployment Share to use. The deployment share must be visible within the MDT 2010 console on the same machine and using the same user account. If you have not opened any MDT 2010 Deployment shares on this computer and this account, please run the MDT 2010 console, and open your Deployment Share.

When selected, the wizard will display a list of all applications and application folders present on the MDT 2010 Deployment share. You may highlight the Application you wish to move, and use the “Move Up” and “Move Down” buttons to rearrange the order of the application. 

image 

When you are done, press the “Commit” button to run the Powershell script that performs the re-ordering. The applications will not be sorted until the script has finished running.

The MDT 2010 Powershell Provider will do all the necessary work to ApplicaitonGroups.xml on the back end.

image

You can view the script by saving the results to a txt file.

Restrictions and Limitations

It is recommended that you backup your MDT 2010 deployment periodically,

You can sort the contents of only one folder at a time.

You can not sort Folders within Application entries. Folders are always displayed first.

Link

http://cid-5407b03614346a99.office.live.com/self.aspx/Blog/MDT2010Ordering.zip

License

This tool is provided “as-is”, with no warranties.
You agree not to hold the author, Keith Garner liable for any damages.
This tool is provided “Free of Charge” for “Evaluation” purposes only.
This tool is copyrighted by the author, Keith Garner, and he retains all
ownership, this tool is not public domain.
You are not permitted to redistribute this tool without the express written
consent of the author, Keith Garner.
The license for this tool can be revoked and/or superseded at any time, by the author, Keith Garner.
Of course, you should backup your critical files before running any 3rd party program downloaded off the internet.

By Keith Garner ( http://keithga.com ) – Deployment Consultant – Dec, 2009
Xtreme Consulting Group ( http://deployment.xtremeconsulting.com )
Microsoft Deployment Toolkit 2010 ( http://microsoft.com/deployment )
Copyright Keith Garner (keithga.com), All Rights Reserved.

New for MDT 2010: ZTIDomainJoin.wsf December 8, 2009

Posted by keithga in MDT 2010, VBscript.
20 comments

One of the new scripts for MDT 2010 is the ZTIDomainJoin.wsf script. This script will operate like NetDom.exe, Joining the machine to the Domain specified in the customsettings.ini and/or Deployment Wizard.

Normal Process

Before MDT 2010, the variables collected in the wizard for joining the domain were placed directly into the unattend.xml or unattend.txt file. The OS would then perform the join to the domain during (OOBE) Setup.

This tool came about because of several scenarios that could prevent the machine from successfully joining the domain during Windows Setup. For example. If the network did not have DHCP available, Windows Setup is not programmed with the correct Static IP address settings necessary for the Join Domain feature to contact the domain controller. Later on in the Task Sequence Steps, the ZTINICConfig.wsf script would correctly configure the Network Cards, however it was too late for joining the domain.

So we developed a new script ZTIDomainJoin.wsf as a thin wrapper around the WMI call Win32_ComputerSystem:JoinDomainOrWorkgroup(). If the script sees that the machine is already joined to the correct domain, no problem, it continues on, without any errors. However, if the script sees that a request was made to join the domain, and the machine is *not* in that correct domain, then it will attempt to join the domain and reboot. If there is a failure joining the domain, the script will retry up to 3 times before logging a failure and continuing.

Domain Policies that break MDT

Another scenario where this script works well is when a Domain has a Policy that blocks automation. For example a Legal disclaimer at login, or a rename of the local Administrator Account. Either one of these changes will break MDT.

One possible work around in these scenarios is to *remove* the domain join entries in the unattend.xml and unattend.txt templates on your MDT server, or remove the entries in the ZTIConfigure.xml script. Once removed, the ZTIConfigure.wsf script won’t populate the unattend.txt with the correct variables gathered form the CustomSettings.ini file and/or Deployment Wizard.

Then add the ZTIDomainJoin.wsf script near the *end* of the Deployment Task Sequence. Most of the automation will be complete by that point.

Variables

It takes the following variables:

  • JoinDomain – Name of domain to join
  • DomainAdmin – User Account used to Join Domain (must have permissions to perform Domain Join)
  • DomainAdminDomain – Domain of User account used to Join Domain
  • DomainAdminPassword – Password used to Join Domain
  • MachineObjectOU – Domain OU to join
  • DomainErrorRecovery – [Auto|MANUAL|FAIL]
    • Auto – Automatically try to Join to the domain, reboot and retry if there is a failure.
    • Manual – Stop processing the Task Sequence, and wait for the user to manually join the domain.
    • Fail – Stop the Task Sequence if the machine has not joined the domain.

Notes

Fail could be useful if you have applications that *require* the machine to be part of the domain. If for any reason, the machine failed to join the domain, you could call the ZTIDomainJoin.wsf script with the “Fail” Parameter to crash the installation process if the machine is not joined to the domain.

Manual style is a new feature in MDT 2010, where MDT can “Halt” the execution of the Task Sequence, and allow the user the ability to perform manual steps (without the pesky Task Sequence progress bar, which insists that it remain on “top”). Just follow the instructions to restart the task sequence.

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group

Identify Driver Problems in MDT 2010 Litetouch (new tool) November 19, 2009

Posted by keithga in MDT 2010, VBscript.
comments closed

This tool is in response to a common question:

In my MDT 2010 Litetouch environment, how do I identify which hardware devices are not being installed with the correct drivers?

Introducing the “Yellow Bang” tool!

Yellow bang is a slang term used to describe drivers that have “problems” represented by a Yellow exclamation point ( ! ) in the Windows Device Manager:

image

Now typically, most IT professionals will be using SCCM, that can gather from each machine in the environment, and query computer status in a more structured way. This solution is only designed for IT departments that are using Litetouch only.

New Tool

Use this tool in MDT 2010 to identify all drivers that have problems on a client machine running MDT Litetouch. These are the drivers that have a Yellow Exclamation point (Bang) in the Windows Device Manager. Simply add this script to your …\scripts\ directory, and add the script to your task sequence.

For each driver that is not working properly the details are written to the bdd.log and the ZTIYellowBang.log file for later review.

Example Output

For this example, I have a HP Laptop that is missing a driver for the ACPI\HPQ0004 device, which is the “HP 3D DriveGuard”. <meh>

Microsoft Deployment Toolkit version: 5.0.1641.0
SUCCESS: 0: Create object: Set oScriptClass = New ZTIYellowBang  DRIVER_ERROR [28: Device drivers are not installed.]
DeviceID [ACPI\HPQ0004\3&33FD14CA&0]
HardwareID [ACPI\HPQ0004]
HardwareID [*HPQ0004]
CompatibleID []
ZTIYellowBang processing completed successfully.

Steps

Simply copy the ZTIYellowBang.wsf script to the Deployment Share under the …\scripts\ directory. Then add the ZTIYellowBang.wsf script as a Step to your Task Sequence:

Cscript.exe “%ScriptRoot%\ZTIYellowBang.wsf

Links

http://cid-5407b03614346a99.office.live.com/self.aspx/Blog/ZTIYellowBang.zip

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group

How to add users to “Remote Desktop Users” Group November 18, 2009

Posted by keithga in MDT 2010, VBscript.
add a comment

Someone posted a question recently that I thought was intresting:

What is the correct way to use ZTIGroups.wsf, the Restore Groups MDT action, to populate local group membership of groups that have a space in the name?  As a test I’m trying to use CustomSettings.ini to add domain users/groups to the local Remote Desktop Users group.  I didn’t find a lot of detail in the MDT docs on doing anything other than Administrators or Power Users. 

I had done some work in ZTIGroups.wsf earlier this year. We added the ability to save the list of group names, and create the groups dynamically during restore time, in addition to the ability to add members to the group.

I had done testing with ZTIGroups.wsf, however I didn’t recall testing with the group “Remote Desktop Users” group. How did that work?

I tried running a command:

C:\>cscript ZTIGroups.wsf   /Groups1:"Remote Desktop Users"   "/Remote Desktop Users1:pickett\keith.garner"   /restore /Debug:True /DebugCapture

While looking at the output I noticed that the script was looking for a new property: “RemoteDesktopUsers”, where did that come from?

It turns out that the ZTIGroups.wsf script will look for members using the properly name derived from the name of the group being populated, *without* the spaces in the property name.

So running a deployment with the following properties in the customsettings.ini worked:

Groups001=Remote Desktop Users  RemoteDesktopUsers001=pickett\Keith.Garner

Keith

Keith Garner is a Deployment Specialist with Xtreme Consulting Group
Follow

Get every new post delivered to your Inbox.

Join 84 other followers