Michael Niehaus' Windows and Office deployment ramblings
As you may have noticed, either from the http://blogs.technet.com/msdeployment blog or via an e-mail announcement from http://connect.microsoft.com, we have released MDT 2010 Update 1 Beta. If you haven’t yet downloaded this to try it out, sign up now to get the files.
So what’s new in this version? Well, there are a few new features, such as:
There are also lots of bug fixes and other minor enhancements, mostly based on the feedback we have received from people using MDT 2010.
Try out the beta and provide feedback via Connect as soon as you can – we want to get any remaining issues taken care of as soon as possible so that we can get a final release out this summer.
I mentioned in the blog post at http://blogs.technet.com/b/mniehaus/archive/2012/07/21/mdt-2012-update-1-always-applying-images-with-imagex.aspx that MDT 2012 Update 1 no longer uses SETUP.EXE to install Windows 7 and above. One side effect of this is that $OEM$ folders are no longer going to be copied, since that was something that SETUP.EXE did that the MDT LTIApply.wsf script doesn’t handle.
I’ve never been a big fan of using the $OEM$ folder structure, as it’s just as easy to add explicit XCOPY steps into the task sequence. But for those of you out there that are using them, you can leverage the attached script (see the attachment link below) in your task sequence to do that.
To set this up, first copy the script into your deployment share. Then, add a new step to the task sequence right after the “Install Operating System” step to run the script. It should look like this:
Now, it will follow the original MDT logic for locating the appropriate $OEM$ folder to use, checking in this order:
where %DeployRoot% is the path to the deployment share, %TaskSequenceID% is the ID of the running task sequence (e.g. WIN8), %SourcePath% is the path within the deployment share for the operating system being used, and %Architecture% is either X86 or X64, depending on the boot image being used. (That’s a bit of a flaw in the original MDT logic since we now support cross-platform deployments – it would choose an X86 $OEM$ folder even if you were deploying an X64 operating system. That’s probably a good sign that no one is using this option. Most people use the last one.)
Once it finds a folder, it will look for two folders in that $OEM$ folder and copy them to the appropriate place for the new OS:
The script doesn’t deal with any other folders because it’s too messy to do that from within Windows PE – drive letters aren’t the same as what they would end up being in the full OS.
I’ve been doing a session at various events over the years called “Troubleshooting Windows Deployments” or something similar to that. Today is the latest, presenting the session at TechEd New Zealand in Auckland. It’s been tweaked some over the years, but the basic flow has always been the same:
Well, I figure it’s about time to turn some of this into documentation and start working on some deeper content – basically, turning the current session into a book. Of course you don’t write a book overnight (especially when you have a day job), so I expect this to be an incremental process. But rather than wait until it’s done and then publish the whole thing, I’d like to take a different approach: publish sections as I manage to work on them.
So here’s my first section, talking about the various log files that may be of interest during the deployment process. (See the attachment below.) With any luck, I’ll add to that every now and then until everything in the session is included in the document – and then keep going…
I mentioned a while back that I wanted to do a blog post talking about how to troubleshoot the new MDT 2012 monitoring feature for Lite Touch deployments, but first I had to actually describe it. If you haven’t reviewed that post, you might want to check it out first at http://blogs.technet.com/b/mniehaus/archive/2012/03/09/mdt-2012-new-feature-monitoring.aspx.
So now let’s talk about troubleshooting. First, let’s look at the server side. You have to enable monitoring on a computer that has MDT 2012 installed. When you use Deployment Workbench on that computer and check the box to enable monitoring, Workbench will first check to see if the specified monitoring host name is local:
It doesn’t really matter if you specify an IP address, a short host name, or a fully-qualified host name, as long as the clients can resolve whatever you specify. If you specify a name that Workbench doesn’t think is local (because Workbench itself can’t resolve the name back to an IP address assigned to the current machine), it won’t try to install the monitoring component; instead, it will try to contact that server to see if monitoring is running on that computer. If it is, great; if it isn’t, you’ll see an error message:
If you look closely at the error “tip” at the end of the “Monitoring host” line, you’ll see a message like “Unable to connect to the specified server and port”. If you think you specified the local computer name and got that error, then Workbench couldn’t figure out that it was the local computer name (something that’s harder to do than you might think). If you are specifying a different server and see this error, then it’s having problems communicating with that other server.
Tip #1: Make sure the name you specify in Workbench can be resolved to the IP address of the current machine.
You’ve checked the checkbox and can’t see that anything happened. So what was actually done? Two things:
Tip #2: Make sure the “Microsoft Deployment Toolkit Monitor Service” is installed and running. If it’s not installed and it should be, you can uncheck the box, click apply, then check the box again and click apply to reinstall it. If it’s installed but not running, try to start it.
Tip #3: Make sure the entry was added to CustomSettings.ini by looking at the Rules tab. Because of a peculiarity with the way Workbench works, if you make any changes to the Rules tab after you’ve clicked the “Enable monitoring” checkbox but before you’ve clicked OK, it’s possible that the changes made on the Rules tab overlay the EventService entry in CustomSettings.ini, but it’s easy enough to put it back manually.
The service has two dependencies:
So there’s no dependency on IIS or SQL Server. The service uses .NET to host a web server as part of the service process, and it uses a SQL Compact database (basically a set of DLLs, which ship with MDT, that run in the service process) to store the monitoring information. It’s designed to be easy to install and run.
Tip #4: If you try to start the service and it won’t start, that most likely means the ports you chose were already in use. (If you want to know what’s using the ports, use a tool like TCPView, available from http://technet.microsoft.com/en-us/sysinternals/bb897437.) Pick different ports.
While it’s always possible that there could be some other reason the service fails, I haven’t seen any other causes. But if you know the ports are not in use and the service still won’t start, capture a trace using DebugView (http://technet.microsoft.com/en-us/sysinternals/bb896647) to see if it provides any further clues. If not, contact Microsoft Support for assistance.
The monitoring service listens on the two ports that you specified. The first of these ports (9800) is used by computers being deployed to send progress events. The second (9801) is used by Workbench itself to query information about deployments being monitored. To make sure these ports are accessible, we can manually connect to each one using Internet Explorer.
To verify the “event port” from the monitor server itself, you can use a URL such as:
http://localhost:9800/MDTMonitorEvent/
If that works, you should see a response like:
That’s a proper response in this case – the web service doesn’t expect to be called in this way (an HTTP GET request instead of an HTTP POST request), so it’s telling you the proper way to call the service.
To verify the “data port” from the monitor server itself, you can use a URL such as:
http://localhost:9801/MDTMonitorData/
This response (which is an ODATA feed in case you are curious) confirms that the data feed is working as expected.
But those are the easy queries – they are using “localhost”, which is almost never subject to firewall restrictions. Next, you need to try these queries remotely, using the appropriate “remote” URLs:
http://mdt-server:9800/MDTMonitorEvent/
http://mdt-server:9801/MDTMonitorData/
If those work, great. If they don’t, then you need to make sure that whatever firewall is running on the monitoring server allows the ports you specified (e.g. 9800 and 9801) to be accessed from remote hosts.
Tip #5: Make sure you can access the monitor service ports both locally and remotely. Adjust the firewall rules as necessary.
Note that there are other networking “challenges” that can get in the way, e.g. IPSec domain isolation. In this configuration, computers that aren’t domain-joined, e.g. running from Windows PE, can’t talk to domain-joined computers because they aren’t using encrypted IPsec communication. This type of configuration will never work – you would need to set up the monitoring service on a “boundary server” that has been configured to allow non-IPsec traffic on the configured ports. So don’t assume that if a “remote” URL works from a domain-joined machine, it will also work from a workgroup machine (or Windows PE) – know how your network is configured.
When the EventService task sequence variable is set (via the processing of CustomSettings.ini), each MDT script executed in the task sequence will send an event to the monitor service on the “event port” URL. When this succeeds, you’ll see a message like this:
If a script is unable to send an event, you’ll see something different:
That’s a clear sign that something isn’t right. Make sure the service is running, that the firewall ports are open, etc. – the same challenges we already reviewed.
Tip #6: Check the client logs to make sure the clients are able to talk to the monitoring service.
Another way you might notice an issue: If the monitor service isn’t running, the clients will still try to connect to it, eventually timing out. This timeout process will cause a delay at the end of each step in the task sequence, so if you are watching the task sequence progress dialog, you’ll see steps that you never noticed before (because they usually run so fast) now taking a long time.
When you try to look at the monitoring data from Workbench, it calls a PowerShell cmdlet (Get-MDTMonitorData), then that PowerShell cmdlet makes the “data port” query to retrieve the details from the monitoring service. If the service is working as expected, you can see the list of monitored machines in Workbench. If the service isn’t working, you’ll see something like this instead:
Good advice, make sure the service is running
Still having issues? Post them as comments here, or send me an e-mail at mniehaus@microsoft.com and we’ll try to figure out what’s going on.
One of the steps in the Configuration Manager installation process is to manually create the “System Management” container in Active Directory, then give the ConfigMgr computer account the ability to create objects in it. Yes, even with Configuration Manager 2012, this is still something that needs to be done manually.
So that was this evening’s challenge: Automating that seemingly simple task. As with all automation tasks, you always hope that someone has already solved the problem. But even with searching multiple search engines (something that always pains me), I didn’t really find what I was looking for. (No executables, no third-party tools, no ugly ADSI code, and ideally no VBScript – PowerShell is the future.) So I created a new PowerShell script, incorporating bits and pieces from several other scripts. The basic steps:
Sounds simple enough, and except for the ACL part, it is. The complete script:
#Requires -version 2.0 # *************************************************************************** # # File: SystemManagement.ps1 # # Version: 1.0 # # Author: Michael Niehaus # # Purpose: Create the AD "System Management" container needed for # ConfigMgr 2007 and 2012, and grant access to the current # computer account. # # This requires PowerShell 2.0 and Windows Server 2008 R2. # # Usage: Run this script as a domain administrator, from the ConfigMgr # server. No parameters are required. # # ------------- DISCLAIMER ------------------------------------------------- # This script code is provided as is with no guarantee or waranty concerning # the usability or impact on systems and may be used, distributed, and # modified in any way provided the parties agree and acknowledge the # Microsoft or Microsoft Partners have neither accountabilty or # responsibility for results produced by use of this script. # # Microsoft will not provide any support through any means. # ------------- DISCLAIMER ------------------------------------------------- # # *************************************************************************** # Load the AD module Import-Module ActiveDirectory # Figure out our domain $root = (Get-ADRootDSE).defaultNamingContext # Get or create the System Management container $ou = $null try { $ou = Get-ADObject "CN=System Management,CN=System,$root" } catch { Write-Verbose "System Management container does not currently exist." } if ($ou -eq $null) { $ou = New-ADObject -Type Container -name "System Management" -Path "CN=System,$root" -Passthru } # Get the current ACL for the OU $acl = get-acl "ad:CN=System Management,CN=System,$root" # Get the computer's SID $computer = get-adcomputer $env:ComputerName $sid = [System.Security.Principal.SecurityIdentifier] $computer.SID # Create a new access control entry to allow access to the OU $ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid, "GenericAll", "Allow", "All" # Add the ACE to the ACL, then set the ACL to save the changes $acl.AddAccessRule($ace) Set-acl -aclobject $acl "ad:CN=System Management,CN=System,$root"
#Requires -version 2.0
# *************************************************************************** # # File: SystemManagement.ps1 # # Version: 1.0 # # Author: Michael Niehaus # # Purpose: Create the AD "System Management" container needed for # ConfigMgr 2007 and 2012, and grant access to the current # computer account. # # This requires PowerShell 2.0 and Windows Server 2008 R2. # # Usage: Run this script as a domain administrator, from the ConfigMgr # server. No parameters are required. # # ------------- DISCLAIMER ------------------------------------------------- # This script code is provided as is with no guarantee or waranty concerning # the usability or impact on systems and may be used, distributed, and # modified in any way provided the parties agree and acknowledge the # Microsoft or Microsoft Partners have neither accountabilty or # responsibility for results produced by use of this script. # # Microsoft will not provide any support through any means. # ------------- DISCLAIMER ------------------------------------------------- # # ***************************************************************************
# Load the AD module
Import-Module ActiveDirectory
# Figure out our domain
$root = (Get-ADRootDSE).defaultNamingContext
# Get or create the System Management container
$ou = $null try { $ou = Get-ADObject "CN=System Management,CN=System,$root" } catch { Write-Verbose "System Management container does not currently exist." }
if ($ou -eq $null) { $ou = New-ADObject -Type Container -name "System Management" -Path "CN=System,$root" -Passthru }
# Get the current ACL for the OU
$acl = get-acl "ad:CN=System Management,CN=System,$root"
# Get the computer's SID
$computer = get-adcomputer $env:ComputerName $sid = [System.Security.Principal.SecurityIdentifier] $computer.SID
# Create a new access control entry to allow access to the OU
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid, "GenericAll", "Allow", "All"
# Add the ACE to the ACL, then set the ACL to save the changes
$acl.AddAccessRule($ace) Set-acl -aclobject $acl "ad:CN=System Management,CN=System,$root"
The same script is attached.
Now that Configuration Manager 2012 RC2 is available, people will certainly start updating their labs – and finding out that the SQL version check in the ConfigMgr installer is looking for some very specific SQL maintenance levels. (I’ve pulled out plenty of my own hair doing this recently.) The release notes cover the supported versions:
Supported versions of SQL Server 2008 for RC2: SQL Server 2008 SP2 Standard and Enterprise CU7 SQL Server 2008 R2 SP1 and CU4 SQL Server Express 2008 R2 and CU4
Supported versions of SQL Server 2008 for RC2:
If you are running SQL 2008 SP2, install CU7 from http://support.microsoft.com/kb/2617148. If you are running SQL Server 2008 R2 SP1, use CU4 from http://support.microsoft.com/kb/2633146. If you aren’t yet on the needed service pack levels, upgrade now, then install the cumulative updates :-)
One of the slow operations in the MDT Deployment Workbench is the initial “Update deployment share” process that has to completely generate new Lite Touch boot images. I always assumed that this was slow due to the amount of I/O being generated by the update process.
Recently, ATI and Dataram released a trial version of their RAMdisk software at http://www.radeonramdisk.com (not that I am endorsing the product – it just happened to come through my Twitter feed and it works on Windows 8), so I had a chance to test the assumption: What would happen if the temporary storage used by MDT to generate the boot images would be on a RAMdisk?
So I installed the software on my laptop, created a 2GB RAMdisk, and formatted it as an NTFS disk. First, I “completely regenerated” the MDT boot images without using the RAMdisk. That process finished in six minutes and 15 seconds (6:15). Then, to get it to use the RAMdisk, I did the following:
That looks sort of like this:
So what difference did it make? Well, instead of 6:15, the whole process finished in 4:55. Not too shabby, about 20% faster, but I expected more. So why wasn’t it any faster? Well, it turns out it’s just a case of shifting the bottleneck. Watching the process using ProcMon and the Windows 8 task manager, I could see that the process was CPU-bound; the RAMdisk utilization was negligible. Hmm, I guess it’s time for a faster CPU…
The trial software doesn’t support server OSes or more than 4GB of RAM; you have to purchase the full version for that. Maybe I’ll try that sometime: Imagine a VM where the entire VHD is in a RAMdisk. I wonder how long that would take…
In MDT 2012, we added support for DaRT integration into an MDT Lite Touch boot image, as well as a new monitoring feature that integrated with DaRT to make remote control into Windows PE easy. See http://blogs.technet.com/b/mniehaus/archive/2011/11/28/mdt-2012-new-feature-dart-integration.aspx and http://blogs.technet.com/b/mniehaus/archive/2012/07/27/mdt-2012-update-1-dart-8-support.aspx for more information.
In MDT 2012 Update 1, we now can use the MDT monitoring feature with ConfigMgr deployments, which also means we can simplify the process of using DaRT remote control with ConfigMgr. DaRT isn’t required to enable monitoring, but without it obviously you won’t have the DaRT remote control integration.
Here are the steps that you need to go through to implement this:
There are some limitations with this implementation worth pointing out:
For those of you using ConfigMgr 2012, you may be interested in this. When ConfigMgr 2012 Cumulative Update 1 was released, it was discovered that you could no longer create a new task sequence using MDT 2012 Update 1 and the “Create MDT Task Sequence” wizard. When you tried, you would get an error like so:
Microsoft.ConfigurationManagement.ManagementProvider.SmsConnectionException: Failed to validate property Type. ---> System.Runtime.InteropServices.COMException: Failed to validate property Type. at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options) at Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlConnectionManager.ExecuteMethod(String methodClass, String methodName, Dictionary`2 methodParameters, Boolean traceParameters) --- End of inner exception stack trace --- at Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlConnectionManager.ExecuteMethod(String methodClass, String methodName, Dictionary`2 methodParameters, Boolean traceParameters) at Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlConnectionManager.ExecuteMethod(String methodClass, String methodName, Dictionary`2 methodParameters) at Microsoft.BDD.Wizards.SCCM_ImportTaskSequenceTask.DoWork(SmsPageData smspageData, Dictionary`2 data)
A new MDT 2012 Update 1 download has now been released containing a fix for that:
http://www.microsoft.com/en-us/download/details.aspx?id=25175
From the text on that page:
MDT 2012 Update 1 version 6.1.2373.0 (Version 6.1.1 on this page) was made available for download on September 19, 2012 and adds support for System Center Configuration Manager 2012 CU1 and System Center Configuration Manager 2012 SP1 Beta. It can be identified as MDT build 6.1.2373.0 in the MDT Workbench console or in the installer program properties. This is the latest version and we recommend all users run the latest version when they can to ensure the smoothest experience during future upgrades.
So for those of you keeping track, the original MDT 2012 Update 1 release was build 6.1.2369.0, while the new release is 6.1.2373.0. Other than this wizard fix and some documentation updates for ConfigMgr 2012 SP1 Beta, there are no other changes. So if you are using ConfigMgr 2012, please download the new version, install it, and then repeat the “Configure ConfigMgr Integration” process to integrate the updated binaries into your ConfigMgr console. (You don’t need to recreate any task sequences or change the MDT toolkit files package if you are already running MDT 2012 Update 1.)
If you are only using Lite Touch, you don’t need to upgrade, but there would be no harm in doing so. Note that after doing this you would need to update your deployment shares, boot media, etc.
Be sure to read the great new posting on the “Building Windows 8” blog:
http://blogs.msdn.com/b/b8/archive/2011/09/07/bringing-hyper-v-to-windows-8.aspx
(Read through the comments too, which talk about support for sleep and hibernate.)
There is one prominent statement made:
Hyper-V requires a 64-bit system that has Second Level Address Translation (SLAT).
That means you have a great reason to consider using the 64-bit version of Windows 8, and why you should buy only hardware with 64-bit support. But what about the second part of that, SLAT support? Well, all you really need to understand is that SLAT is a processor feature that improves virtual machine performance, especially when using higher-end video cards (e.g. those used on client machines). Read more about the benefits in the Hyper-V R2 announcement:
http://technet.microsoft.com/en-us/library/dd446676(WS.10).aspx
This mentions that Intel and AMD have different implementations of this. Intel calls theirs “Enhanced Page Tables” (EPT), while AMD refers to it as “Nested Page Tables” (NPT). Regardless, what you really care about is whether or not a particular processor includes the support. That’s not always easy to figure out from the vendor’s web sites. Fortunately, there is a newly-updated tool available on the SysInternals web site called Coreinfo that will tell you all about a processor’s capabilities:
http://technet.microsoft.com/en-us/sysinternals/cc835722
Mark Russinovich updated this utility recently to add the ability to detect both Intel EPT and AMD NPT. Here’s what the output would look like if your machine has an Intel processor with the needed support:
The AMD output will be slightly different (and not because it’s on a white background instead of a black one):
In both cases, the asterisk (“*”) in the second column indicates that the feature is present. (A minus, “-“, shows if it isn’t.) Be careful if running this in a VM or on a machine currently running a hypervisor, as these will mask the real processor capabilities.)
So check out your machines today to see if they are ready for Windows 8 client Hyper-V!