Welcome to TechNet Blogs Sign in | Join | Help

New Solution Accelerator Beta Available

The beta version of the Configuration Manager Dashboard is now available on the Connect website.  You can gain access with this link:

https://connect.microsoft.com/InvitationUse.aspx?ProgramID=4505&InvitationID= SCD-BGMB-FK9M&SiteID=14

So what is the Configuration Manager Dashboard?  Here’s the quick overview:

image

And a picture showing an example of what it can do (you can customize it to add your own charts too):

image

Want to present your ConfigMgr statistics and metrics using something prettier than just simple results?  Download it and try it out.

Posted by mniehaus | 2 Comments

Fixing Office Upcoming Appointments gadget to work with Office 2010

I just finished installing Office 2010 on all my home computers, and immediately ran into a “wife acceptance factor” issue: the “Outlook Upcoming Appointments” Sidebar gadget didn’t work:

image

“Fix it.”  Sigh.  Fortunately, it wasn’t hard to do.  Locate the “C:\Users\<user ID>\AppData\Local\Microsoft\Windows Sidebar\Gadgets\OutlookAppointmentsGadget[1].gadget\en-US\js” folder and in it you’ll see a file called Outlook.vbs.  Open it in your favorite text editor and find the two lines that mention Outlook “12” and change them to reference Outlook “14” instead.  Change this:

if value = "Outlook.Application.12" then

to:

if value = "Outlook.Application.14" then

and this:

if mid(outlookApplication.Version, 1, 2) <> "12" then

to this:

if mid(outlookApplication.Version, 1, 2) <> "14" then

Save the changes, close the gadget, and open it again.  You should then see something that works:

image

If only all application compatibility issues were that simple…

Posted by mniehaus | 0 Comments

Have questions about MDT 2010?

We have created a new forum on TechNet specifically for MDT-related questions – no question is too simple or too advanced.  You can access the forum via http://social.technet.microsoft.com/Forums/en-US/mdt/threads.  It’s been around for a couple of months, but we haven’t publicized it too heavily so we could slowly ramp up.

As always, I seem to be keeping too busy to spent a lot of time responding to questions on the forum, but fortunately there are several other experts (including Tim Mintner, Keith Garner, and Johan Arwidmark) who have been helping out with that.

Posted by mniehaus | 1 Comments

Ready for Office 2010? It’s not far away.

The Office 2010 Beta has been available for a short while now and should be released sometime next year.  I’m already quite attached to it, and not only because of the “People Pane” in Outlook 2010 and its coming ties to various social networks.

To help with the coming migration, some new Office compatibility tools have been released.  See http://blogs.technet.com/gray_knowlton/archive/2009/12/04/office-2010-application-compatibility-tools-beta-now-available.aspx for more details.

Also, if you aren’t yet running the Key Management Service (KMS) or using Multiple Activation Keys (MAK) with Windows Vista or Windows 7, you’ll probably want to study up on Volume Activation, as Office 2010 will use it too.  There’s also a new beta version of the Volume Activation Management Tool (VAMT) 2.0 available for download here.

12/10/2009 Addendum:  There is another new download that might be useful at http://www.microsoft.com/downloads/details.aspx?FamilyID=600c2142-abc3-4fea-9271-0c326c45dc8f&displaylang=en.  It’s a poster that describes the deployment and installation options for Office 2010.

Posted by mniehaus | 0 Comments

RIS-style naming with MDT 2010: Use a web service

I’ve been toying around with using a web service that could be used to implement RIS-style computer naming.  Unfortunately, I haven’t had time to work on it much in the last year or so, so I’ll post the code as-is and tell you up front that it’s not really complete – you might need to make some changes to it to meet your specific needs.  So here’s the code (written using Visual Studio 2008 and .NET 3.5), which shows how easy it is to do LDAP queries and object creation using .NET:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.DirectoryServices;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;

namespace DemoWebService
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class NameService : System.Web.Services.WebService
    {
        [WebMethod]
        public String GenerateName(String dnsDomain, String prefix, String uuid, String machineObjectOU)
        {
            // Build the search
            DirectoryEntry entry =
                new DirectoryEntry("LDAP://" + dnsDomain);
            DirectorySearcher search = new DirectorySearcher(entry,
               "(name=" + prefix + "*)");

            // Execute the search and build a list of the matching names and their UUIDs
            Dictionary<String, Guid> existingNames = new Dictionary<String, Guid>();
            foreach (SearchResult result in search.FindAll())
            {
                String name = result.Properties["name"][0].ToString().ToUpper();
                Guid netbootGuid = new Guid();
                if (result.Properties["netbootGuid"].Count > 0)
                    netbootGuid = new Guid((byte[])result.Properties["netbootGuid"][0]);
                Trace.WriteLine("Found computer " + name + " with GUID " + netbootGuid.ToString());
                existingNames.Add(name, netbootGuid);
            }

            // See if we can find an existing match.  If so, return it.
            Guid existingUuid = new Guid(uuid);
            if (existingNames.ContainsValue(existingUuid))
            {
                foreach (String name in existingNames.Keys)
                    if (existingNames[name] == existingUuid)
                    {
                        // TODO: Maybe we want to move the computer object to the specified OU
                        return name;
                    }
            }

            // Find the first available name in sequence
            String nextName = null;
            for (Int32 i = 1; i <= 999; i++)
            {
                String testName = prefix + i.ToString("000");
                if (!existingNames.ContainsKey(testName))
                {
                    nextName = testName;
                    break;
                }
            }
            if (nextName == null)
                return null;  // All names were taken

            // Add the computer to AD
            try
            {
                DirectoryEntry dirEntry = new DirectoryEntry("LDAP://" + machineObjectOU);
                DirectoryEntry newUser = dirEntry.Children.Add("CN=" + nextName, "computer");
                newUser.Properties["samAccountName"].Value = nextName + "$";
                newUser.Properties["netbootGUID"].Value = existingUuid.ToByteArray();
                newUser.Properties["description"].Value = "Added by MDT";
                newUser.CommitChanges();
                newUser.Close();
            }
            catch (Exception e)
            {
                Trace.WriteLine("Unable to add computer: " + e.ToString());
            }

            // Return the name
            return nextName;
        }

    }
}

To use this, you would add an entry to CustomSettings.ini to call the web service.  That would look something like this:

[Settings]
Priority=Default, GetName
Properties=DnsDomain, Prefix

[Default]
Prefix=MDTTEST
DnsDomain=mydomain.com
MachineObjectOU=OU=Workstations,DC=mydomain,DC=com

[GetName]
WebService=http://myserver/NameService.asmx/GenerateName
Parameters=DnsDomain, Prefix, UUID, MachineObjectOU
OSDComputerName=string

The web service would be passed the DNS domain name (mydomain.com), computer prefix (MDTTEST), the current machine’s SMBIOS UUID, and the OU to which new computers should be added.  It will return a name starting with the specified prefix and ending with the next available three-digit number.  So the first machine would be MDTTEST001, the second MDTTEST002, etc.  These computer names are added to Active Directory with the “netbootGUID” attribute set, so that if the machine is ever rebuilt it will use the same computer name again.  (The code purposely doesn’t try to find any computer object with that SMBIOS UUID.  Instead, it only looks for computers with the right prefix that have a matching UUID.  This might not be the behavior you want, but it was the behavior I wanted.)

The output from ZTIGather.wsf when processing this INI file would look something like this:

Added new custom property DNSDOMAIN
Added new custom property PREFIX
Using from [Settings]: Rule Priority = DEFAULT, GETNAME
------ Processing the [DEFAULT] section ------
Property MACHINEOBJECTOU is now = OU=Workstations,DC=mydomain,DC=com
Using from [DEFAULT]: MACHINEOBJECTOU = OU=Workstations,DC=mydomain,DC=com
Property DNSDOMAIN is now = mydomain.com
Using from [DEFAULT]: DNSDOMAIN = mydomain.com
Property PREFIX is now = MDTTEST
Using from [DEFAULT]: PREFIX = MDTTEST
------ Processing the [GETNAME] section ------
Determining the INI file to use.
Using COMMAND LINE ARG: Ini file = CS.ini
Finished determining the INI file to use.
Using COMMAND LINE ARG: Ini file = CS.ini
CHECKING the [GETNAME] section
About to execute web service call using method POST to http://server/NameService.asmx/GenerateName: DnsDomain=mydomain.com&Prefix=MDTTEST&UUID=814100CD-CE48-CB11-A536-B7561D1E4450&MachineObjectOU=OU=Workstations,DC=mydomain,DC=com
Response from web service: 200 OK
Successfully executed the web service.
Property OSDCOMPUTERNAME is now = MDTTEST001
Obtained OSDCOMPUTERNAME value from web service:  string = MDTTEST001

This isn’t quite as flexible as the RIS naming, where you could use other variables in the computer name, but there’s no reason you couldn’t add more logic to cover those cases too.  There’s also no guarantee that the web service will add the computer account to the same DC that the computer ends up using, which could cause some naming conflicts if the new computer object doesn’t replicate before the computer tries to join the domain.  Use at your own risk :-)

Posted by mniehaus | 0 Comments

Workaround posted for ConfigMgr SP2 issue with USMT 4.0

Levi Stevens posted a blog entry today describing a workaround for an issue with ConfigMgr SP2 and USMT 4.0 that causes USMT to not capture all of the user state information.  See http://blogs.technet.com/configmgrteam/archive/2009/12/01/known-issue-migrating-from-windows-xp-to-windows-7-with-usmt-when-used-with-configmgr-2007-sp2-os-deployment-may-not-migrate-all-settings.aspx for all the details.

We are still working on a KB article for MDT 2010 that provides a similar fix.  That KB article (which will be 977565 once it is finally available) will describe the changes necessary to ZTIUserState.wsf.  (They are pretty minor, just adding two lines to set the working directory to the folder containing the USMT binaries before running scanstate.exe or loadstate.exe.)

Posted by mniehaus | 2 Comments

Dynamic application detection with Lite Touch, Revisited

Over a year ago, I posted a blog entry at http://blogs.technet.com/mniehaus/archive/2008/09/25/dynamic-application-detection-with-lite-touch.aspx with details on how to automatically detect installed applications during a Lite Touch deployment, enabling those to be pre-selected when the application list is presented.  Due to changes in the XML file schemas, this script needs some updates for MDT 2010 to be truly “correct”.  The updated script follows, showing how to create a user exit that leverages the ZTIConfigFile script to enumerate all the available (enabled, visible) applications.

Option Explicit

Function UserExit(sType, sWhen, sDetail, bSkip)

    Dim oScriptFile
    Dim oXMLApps, dAllApps
    Dim sGUID
    Dim oNode, oKey
    Dim sValueName, sKey, sValue
    Dim oApplications

    ' Only do this before processing the rule contents

    If sWhen <> "BEFORE" then
        UserExit = Success
        Exit Function
    End if

    ' Make sure ZTIConfigFile is loaded

    On Error Resume Next
    Set oScriptFile = oFSO.OpenTextFile(oUtility.ScriptDir & "\ZTIConfigFile.vbs", 1, false)
    ExecuteGlobal oScriptFile.ReadAll
    On Error Goto 0

    ' Load the applications XML File

    Set oXMLApps = new ConfigFile
    oXMLApps.sFileType = "Applications"
    Set dAllApps = oXMLApps.FindItems

    ' Enumerate the applications

    For each sGUID in dAllApps

        Set oNode = dAllApps(sGUID)

        ' Retrieve the uninstall key node if present

            Set oKey = oNode.selectSingleNode("UninstallKey")

        ' If one was specified, look for the key in the registry

        If not (oKey is nothing) then

            ' Get the key name

            sKey = oKey.Text

            ' Check if the registry key exists by looking for well-known values

            For each sValueName in Array("DisplayName", "UninstallString", "QuietUninstallString")

                sValue = empty
                On Error Resume Next
                sValue = oShell.RegRead("HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\" & sKey & "\" & sValueName)
                On Error Goto 0

                If IsEmpty(sValue) then
                    On Error Resume Next
                    sValue = oShell.RegRead("HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" & sKey & "\" & sValueName)
                    On Error Goto 0
                End if

                ' If a value was found, add the application's GUID to the list so it gets pre-selected by the wizard

                If not IsEmpty(sValue) then

                    oLogging.CreateEntry "Uninstall registry key found for application " & oNode.selectSingleNode("Name").Text & ", application is present and will be reinstalled.", LogTypeInfo

                    ' Add the GUID if it doesn't already exist in the list

                    Set oApplications = oEnvironment.ListItem("Applications")
                    If not oApplications.Exists(oNode.Attributes.getNamedItem("guid").value) then
                        oApplications.Add oNode.Attributes.getNamedItem("guid").value, ""
                        oEnvironment.ListItem("Applications") = oApplications
                    End if

                    Exit For

                End if

            Next
        Else

            oLogging.CreateEntry "UninstallKey not specified for application " & oNode.selectSingleNode("Name").Text, LogTypeInfo

        End if

    Next

    UserExit = Success

End Function

The code has been updated some, but the concepts haven’t, so if you need more details on what this does check out the original article.

Posted by mniehaus | 0 Comments

In the Seattle area? Come to the Windows Networking User’s Group meeting

On Wednesday, December 2, the Windows Networking User’s Group is having their monthly meeting at the Microsoft office in Bellevue.  Chris Avis is the featured speaker this month, and the topic of his presentation is:

Windows 7 New Features: Windows XP Mode & Boot to VHD

Windows 7 introduces host of new features and technologies to simplify your work and make you more productive. Two technologies you may not have heard about are Windows XP Mode and the new “Boot to VHD” feature. 

Windows XP Mode allows administrators to migrate legacy applications from that Windows XP world into Windows 7 regardless of that applications compatibility with Windows 7. Windows XP Mode provides a virtualized instance of Windows XP that allows you to continue to run older applications while still enjoying the benefits of Windows 7. The best part of this deal is that it is FREE!

The Boot to VHD feature of Windows 7 allows you to boot a virtualized operating system “natively”. This provides for better resource utilization, access to some hardware components that normally can’t be used in a virtual machine, as well as eliminating boot code issues surrounding dual or multi-boot scenarios. Chris will discuss how to configure and run Boot to VHD features as well as some new options in Windows 7 that make creating and supporting this feature a breeze.

Pizza and soft drinks will be served at 6pm, with the presentation scheduled for 6:30pm.  If you are in the area and would like to attend, please RSVP.  For more details, visit the WNUG site at http://www.winnetusergroup.com/default.aspx.  (I hope to attend myself.)

Posted by mniehaus | 0 Comments

Two webcasts next week

I’ll be busy next week, with two different webcasts targeting different groups of people.  If you’re part of either group, please attend as I don’t want to be presenting to “virtual crickets”.

The first webcast targets Gold Certified, Certified, and Empower partners (you’ll need to be in one of those categories to register via the partner portal) as part of a “Technical Advisory Services Advisory Hour”.

Join the “Adding value to Microsoft Deployment Toolkit 2010: Extending Windows 7 Deployment” Seminar!

Microsoft Partners, find out how MDT 2010 simplifies the process of deploying Windows 7, while also providing many opportunities for customization.  Explore ways that you can extend MDT 2010, adding value to your customer’s Windows 7 deployment projects. Join this Web Seminar on December 1st from 10am-11am PST to learn how to simplify the process of deploying Windows 7.

Next Steps:

· Sign up for the Web Seminar: Adding value to Microsoft Deployment Toolkit 2010: Extending Windows 7 Deployment

· Download MDT 2010

· Learn more

The second webcast is part of the “Fireside Chat” series described by Graham Watson at http://blogs.technet.com/grahamtwatson/archive/2009/11/28/fire-side-chats.aspx.  These target user’s group leaders, MVPs, and other “influentials”, with about 15 minutes reserved for presentations and the rest of the time spent answering questions from the audience.  You can register at http://ug.gitca.org/sites/FireSideChats/default.aspx for either time (both are Pacific timezone, GMT-08:00).

Microsoft Deployment Toolkit 2010 - Solution Accelerator 

12/3/2009 9:00 AM

12/3/2009 4:00 PM

Moving to Windows7? Learn how Microsoft Deployment Toolkit 2010 can make your job easier. 
This Solution Accelerator is the recommended process and toolset for automating desktop and server deployment. 
Learn more about  installation, image creation, and deployment scenarios for using MDT. Senior Software Development Engineer Michael Niehaus will be leading this session and he’ll answer any questions you may have.
Michael is the lead developer for the Microsoft Deployment Toolkit. Prior to joining Microsoft in 2004, Michael spent his entire career in enterprise IT, focused on deploying and managing Microsoft software.

Posted by mniehaus | 0 Comments

MDT 2010 Wizard Example: Role Selection

We have seen lots of requests over the past couple of years for a wizard pane that allows you to select from a list of roles that should be applied to a machine, where those roles are defined in the MDT database.  There are a few examples of this available on the web, implemented in different ways.  I’ll throw another one into the mix, this one using an ADO.NET Data Services web service to get the needed data.  (If you didn’t read my previous posting about this setup, click here.)

<?xml version="1.0" encoding="utf-8"?>
<Wizard>
  <Global>
    <CustomStatement><![CDATA[
' ***************************************************************************
' File:	Roles.xml
' Author:	Michael Niehaus
' Version:	1.0
' Purpose:	Display a list of roles from the MDT database, retrieved
'	using an ADO.NET Data Services.web service.  One
'	or more roles can be selected.  After they have been
'	chosen, CustomSettings.ini needs to be re-processed
'	to pick up the new settings.  Ideally this would be done
'	after the wizard is complete (just in case someone 
'	navigated back to the screen after initially making
'	changes), but that requires changing LiteTouch.wsf.
'
' NOTE:	Be sure to modify the web service URL below
'
' ***************************************************************************
Function InitializeRoleList
	Dim sScript
	Dim oDataService
	Dim oRole
	Dim sRoles
	' Make sure that ZTIDataAccess.vbs is available since it isn't loaded by Wizard.hta
	sScript = oFSO.OpenTextFile(oUtility.ScriptDir & "\ZTIDataAccess.vbs", 1, false).ReadAll
	On Error Resume Next
	ExecuteGlobal sScript
	On Error Goto 0
	' Call the web service
	Set oDataService = New WebService
	oDataService.WebService = "http://localhost:62932/MDTDatabase.svc/RoleIdentity"
	oDataService.Method = "REST"
	Set oResult = oDataService.Query
	' Process the roles to populate the list of checkboxes
	sRoles = ""
	For each oRole in oResult.SelectNodes("//d:Role")
		sRoles = sRoles & "<input type=checkbox name=Roles id=Roles enabled value='" & oRole.Text & "'>" & oRole.Text & "</input><br>"
	Next
	' If no roles were found, set the div to indicate that
	If sRoles = "" then
		sRoles = "<label class=errmsg style='display: inline;' >No roles could be found."
	End if
	' Update the pane
	RoleList.InnerHTML = sRoles
End Function
Function ValidateRoleList
	' Flush the value to variables.dat, before we continue.
	SaveAllDataElements
	SaveProperties
	' Process full rules (needed to pick up the role settings, apps, etc.)
	sCmd = "wscript.exe """ & oUtility.ScriptDir & "\ZTIGather.wsf"""
	oItem = oShell.Run(sCmd, , true)
	ValidateRoleList = True
End Function
]]></CustomStatement>
  </Global>
  <Pane id="Roles">
    <Body><![CDATA[<H1>Select the roles to be assigned to this computer.</H1>
<br>
<div class=TreeList id=RoleList style="height: expression( GetDynamicListBoxSize(this) );">
<label class=errmsg style="display: inline;" >Loading roles...
<!-- List goes here -->
</div>
]]></Body>
    <Validation><![CDATA[ValidateRoleList]]></Validation>
    <Initialization><![CDATA[setTimeout GetRef("InitializeRoleList"), 0]]></Initialization>
  </Pane>
</Wizard>

While this is set up as a stand-alone wizard, you can insert this into an existing deployment wizard using the MDT Wizard Editor by following these steps:

  1. Launch the MDT Wizard Editor.
  2. Open the DeployWiz_Definition_ENU.xml file.
  3. Click on the “Global” pane.  Click “Add” on the “Settings” pane and choose to add a new “CustomStatement”.
  4. Select the new “CustomStatement” at the end of the “Settings” list.
  5. Select the VBScript code above (from the first comment line to the last End Function line) and copy it to the clipboard.
  6. Paste the copied VBScript code into the text box in the MDT Wizard Editor.  Edit the web service URL to specify your ADO.NET Data Services web service URL.
  7. Select a wizard pane (the new pane will be inserted after this one, so select appropriately).
  8. Select all the text above from “<Pane” through “</Pane>” and copy it to the clipboard.
  9. Right-click on the selected pane name in the MDT Wizard Editor and choose “Paste”.

What, your MDT Wizard Editor doesn’t have a “Paste” option?  Well, you need to download a new version from http://mdtwizardeditor.codeplex.com/, as I just added the paste capability tonight (along with other general usability improvements – I forced myself to actually use the program to create the rules wizard pane above and fixed all the behaviors I didn’t like while I was at it).

A few notes to mention:

  • Because the wizard runs after CustomSettings.ini has been processed, the role settings, applications, etc. wouldn’t be processed as the “Gather” process isn’t run again.  To work around this, I added logic above to run ZTIGather.wsf again.  This could add a delay when clicking “Next”, so you might choose to do this later (possibly by modifying LiteTouch.wsf).  The other problem with running ZTIGather.wsf from this wizard pane:  If you navigate back to this wizard pane and uncheck an item, it’s too late – the settings for that role have already been added into the task sequence environment.
  • The MDT 2010 wizard hypertext application (Wizard.hta) doesn’t load the ZTIDataAccess.vbs script needed to make web service calls from a wizard pane.  To work around this, I added logic above to dynamically load the file.  The other alternative would be to edit Wizard.hta to tell it to include the file.
  • The role list is populated asynchronously so that the wizard doesn’t appear to be hung.  This is done by the “setTimeout” initialization statement above.  Note that the “Next” (or “Finish”) button will be enabled even while this is happening, so if you don’t want to wait you can probably go ahead and click the button to move on to the next pane.
  • If you don’t have the ADO.NET Data Services web service set up and working, don’t expect this wizard pane to somehow magically fix it :-)
Posted by mniehaus | 0 Comments

Using the MDT database from a web service without writing code

One of the new features in the .NET Framework 3.5 SP1 is ADO.NET Data Services.  This enables you to expose the contents of a data source, e.g. a SQL Server database, through something that looks roughly like an RSS feed, accessed in a similar manner to a web service.  That’s nice but why do you care as an IT pro?  Well, it’s a convenient way of making the contents of the MDT database available to programs or scripts without forcing them to use ADO to access SQL Server directly.

The best part of ADO.NET Data Services:  You really don’t need to write any code.  Just walk through a few Visual Studio 2008 wizards and you’re done – almost.  There are two lines of code that I added, one to day that all the selected tables and rows can be accessed read-only, and a second that generates detailed errors if something doesn’t work.  The basic process is described at http://msdn.microsoft.com/en-us/data/cc745957.aspx.  (So I lied – you have to write two lines of code.)

The harder part of this is deploying the resulting ADO.NET Data Services project to an IIS server.  You need to have .NET 3.5 SP1 installed, then IIS and ASP.NET need to be installed.  You might need to run “ServiceModelReg.exe –i” to get the ADO.NET Data Services and WCF logic registered in IIS, see http://msdn.microsoft.com/en-us/library/ms732012.aspx for details.  You will definitely need to edit the database connection string in the Web.Config file to point to your server (and optionally the instance) as well as the database (Initial Catalog) that needs to be used.  And you might need to grant access to SQL Server, the database, and the database tables and views.  (See http://msdn.microsoft.com/en-us/library/ms998320.aspx if SQL Server is on the same machine.)  Really, it’s not that bad :-)

The actual ADO.NET Data Services files need to all be dropped in a directory.  After doing this, set up an application in IIS that points to this directory.  At that point, if everything is set up right, you should be able to access the the web service via a browser.  To test it out, try a URL like this:

http://yourserver/YourApplicationName/MDTDatabase.svc

If that gives you a list of objects available in the database (you might need to tell IE not to display the result in RSS Reader view to see the real contents – in IE8, that’s configured on the “Content” tab from the “Feeds and Slices” settings dialog), you know at least IIS, .NET, and ADO.NET are fine.  Then try a more specific URL to request all the computer records:

http://yourserver/YourApplicationName/MDTDatabase.svc/ComputerIdentity

That should result in something that looks like this:

image

 

Yes, kind of weird looking, but pretty easy to consume in a script.  So that’s the next step – making use of this data.  More on that in the next posting.

The full solution (Visual Studio project, source, binaries, etc.) is attached.

Posted by mniehaus | 0 Comments

Attachment(s): MDTDatabase.zip

New version of the MDT Wizard Editor is available

For those of you who customize the MDT wizards, you may want to check out the new version of the MDT Wizard Editor at http://mdtwizardeditor.codeplex.com.  The latest version 2.0, uploaded today, includes a few fixes (e.g. properly encoding XML file entries in CDATA sections), adds support for MDT 2010, and includes a few new features.

The first change you will notice is that there is now a menu bar:

image

 

Use the “File” menu to open menu definition files (XML files), save your changes, and to exit the program.  Use the “Wizard” menu to test a wizard definition file after you have made changes.

The testing process is the most significant change in this new version.  It will gather information from the machine (running ZTIGather, as long as it can find it) and then display all of the variable values before starting the wizard:

image

You can modify variables, remove variables, add variables – whatever you would like to do.  When you are ready to run the wizard, click the “Run” button.  Once you have completed the wizard, the dialog will be updated to show you the variables that were set after the wizard completed:

image

In this case, you can see the additional variables that were defined for keyboards, applications, BitLocker, etc.

If you find any issues with this release, or if you have any suggestions on how to improve the release (subject to my available time), please use the CodePlex “Issue Tracker” to submit new items.

Posted by mniehaus | 0 Comments

MDT 2010 New Feature #21: Copying extra folders

When MDT 2010 replicates content to a linked deployment share, you can choose whether to copy “standard folders” as part of that replication process.  These folders (Scripts, Tools, $OEM$, USMT) might be required by one or more of the task sequences being replicated, so we give you that option.  In the case of media, we always copy these four standard folders; you don’t get a choice as we assume everything in those folders is required by the current deployment share and therefore is also required by the media.

We have periodically received requests to allow for the replication of additional folders to linked deployment shares, as well as the inclusion of additional folders when creating media.  As a result of those requests, we added a mechanism for specifying a list of extra folders.  But there’s one challenge for that:  We didn’t provide a user interface for configuring those, so you have to use PowerShell to do it.  Unfortunately the documentation doesn’t even mention that this is possible, so consider this blog entry a documentation addendum :-)

From a PowerShell session, you would first need to load the MDT PowerShell snap-in (“Add-PSSnapIn Microsoft.BDD.PSSnapIn”) and then connect to the deployment share (simplest way is “Restore-MDTPersistentDrive” to get all the drives connected that you use in the Deployment Workbench).  In the case of linked deployment shares, you can get all the current properties like so:

image

Then setting the ExtraFolders property (which is empty by default) is achieved using “Set-ItemProperty”:

image

Because the ExtraFolders property is a list (array), you always need to specify the values as I did, using the PowerShell syntax of @(“Value1”, “Value2”).  If you only have a single value, it would look like @(“Value1”).

Media works the same way:

image

The folders you specify need to exist at the top level of the deployment share.  In my examples above, my deployment share is “C:\DeploymentShare” so the folders that must exist are “C:\DeploymentShare\MyFolder1” and “C:\DeploymentShare\MyFolder2”.  Make sure you specify folders that actually exist – otherwise you’ll get errors when MDT tries to copy those folders.

After doing this, you’ll notice an additional line in the output, highlighted below, telling you how many extra folders were copied:

image

Posted by mniehaus | 0 Comments

MDT 2010 New Feature #20: General Purpose ConfigMgr wizard

In MDT 2008, we provided unknown computer support for ConfigMgr 2007, since it didn’t provide that capability – you first had to import new computers into the ConfigMgr database before you could install an OS, so MDT helped automate that process.  When ConfigMgr 2007 R2 was released, it included unknown computer functionality, so we have now removed most of that from MDT 2010.

One of the useful parts of this unknown computer process was a pre-execution hook that would run a wizard, leveraging the same wizard framework that we used for MDT 2010 Lite Touch deployments.  This was useful because we provided all the pieces to make it work:  the TSCONFIG.INI file that tells ConfigMgr what to run, the script that gets executed by ConfigMgr (referenced in TSCONFIG.INI), the rules processing logic to gather information from WMI and other data sources, and the wizard files themselves.

With MDT 2010, we’ve left these pieces in place, but set them up to do something more basic: prompt for a new computer name.  This is provided as a sort of general purpose “sample”, showing how to hook this into ConfigMgr.  While you might not find the sample particularly useful, you can edit the wizard definition (using Notepad or something like the MDT Wizard Editor, http://mdtwizardeditor.codeplex.com/) to add additional panes.

All the files related to this general purpose sample are located in the “C:\Program Files\Microsoft Deployment Toolkit\SCCM” directory:

  • ZTIMediaHook.wsf.  This is the pre-execution hook script that drives the whole process (gathering information from WMI and other sources, then displaying the wizard).
  • Deploy_SCCM_Definition_ENU.xml.  This file defines the wizard itself, which by default has one pane that asks for the computer name.
  • Deploy_SCCM_Scripts.vbs.  This file contains the initialization and validation scripts called by the wizard pane (which don’t do much in this case).
  • TSConfig.ini.  This file gets added to the boot image and tells ConfigMgr to run the ZTIMediaHook.wsf script.

So if you wanted too do some customization, the files you would want to change are the “Deploy_SCCM_Definition_ENU.xml” (to add or change wizard panes) and “Deploy_SCCM_Scripts.vbs” (to specify additional initialization or validation logic).

To actually get these pieces added into a boot image, you can check the “Add media hook files to enable the Deployment Wizard for this boot media” checkbox when running either the “Create Boot Image using Microsoft Deployment” wizard (which creates only new boot image which you would then need to configure the task sequence and ISOs to use) or the “Create Microsoft Deployment Task Sequence” wizard (which can create a new boot image as part of the task sequence creation process).

Booting from this boot image, you should see a wizard that looks like this:

image

You can then specify the computer name you want, which will set the OSDComputerName task sequence variable.  Like I said, pretty simple, but provided as a starting point for your own customizations – just edit the XML and VBS files, create a new boot image, and then deploy.  (Remember that all of these files are actually embedded in the boot image WIM file, so when you make changes you either need to create a new boot image or mount the existing one to change those files.  Update the distribution points after making changes.)

I’ve also attached a short video that shows the startup process (including the initial ConfigMgr wizard screen that can be used for specifying static IP information and for typing in the media password).

Posted by mniehaus | 0 Comments

Attachment(s): Hook.wmv

ConfigMgr SP2 is speedy

People have made fun of ConfigMgr, and every version of SMS before that, for being “slow moving software”.  For those of you who try to deploy software to a machine and then wait for it to actually happen, you know what I mean: it was guaranteed to take two minutes from the time you advertised it to the time the first clients acted on it.

With ConfigMgr SP2, a significant portion of that delay (which was actually happening on the client side, not on the server) was removed.  Now, I can add a new machine into a collection, then go to the machine and initiate a machine policy retrieval cycle and see a popup for new advertisements within a few seconds.  The first time that happened I was a bit startled by the result – surely something must be wrong.  But it wasn’t, the advertisement really was available that quickly.

ConfigMgr SP2 is still available as an RC through http://connect.microsoft.com, so you can try it out in your lab if you want.  It is expected to be released by the end of October.

Posted by mniehaus | 0 Comments
More Posts Next page »
 
Page view tracker