Category Archives: Deployment

Windows 7, IE8 and Adobe Flash flickering

I’m rolling out 64bit Windows 7 where I work and, though initial test PCs seemed fine in this regard, I discovered that Dell OptiPlex GX620 machines built using my unattended install have a flickering problem on web pages with Javascript content and Flash in IE8. Uninstall Adobe Flash and the problem disappears. Installing the latest build of Flash 10.1 doesn’t help, even disabling hardware acceleration in the Flash player settings.

Researching the problem online turns up little, though I did spot a few clues which led me to a solution:

  • This thread on the Microsoft forums feature quite a lot of people with the same issue name-checking Intel 945G chipset, but also ATI. Having had an ATI card of my own, I found that their driver releases can be pretty rough around the edges to say the least
  • This thread mentions that the problem tends to manifest itself with Windows 7 x64 (though I don’t have any of the affected models running x86 builds to test)
  • This thread on Overclockers.co.uk also mentions the Intel GMA 950
  • My own work PC (an iMac with an ATI card running Windows 7 x64), does not exhibit this problem, nor do Optiplex 745 (Intel Q965), nor Optiplex 780 (Intel Series 4) models
  • One Optiplex 620 which I built by hand to use as an early performance test machine does not exhibit the problem. If I remember correctly, I only installed drivers which were missing once Windows was installed…

So, as much as people seem to be blaming Adobe, it does look like a display driver issue. However I was using the most up to date Intel 945G driver version (8.15.10.1930).

Because I had injected this driver during the unattended install OfflineServicing phase, removing it in Device Manager and selecting Delete the driver software for this device did not work. The device was re-detected as Standard VGA Graphics Adaptor for a few seconds, then the same Intel driver was installed once again. So I had to:

  • Device Manager > select the Graphics card > Update Driver > Browse my computer for driver software > Let me pick from a list of device drivers on my computer > Intel(R) 82945G Express Chipset Family (Microsoft Corporation – WDDM 1.0)

Then after a reboot the problem disappeared. The original driver included with Windows 7  (8.15.10.1749) is clearly better than the newer one from the Intel website. It turned out that my working early test build machine was running 8.15.10.1912, though I cannot find that on Intel’s site.

UPDATE – The 8.15.10.1912 driver can be obtained from Microsoft Update Catalog using the search string Intel 82945G Express then ordering by version number. You’ll need to use Internet Explorer because it requires an ActiveX control to be installed. You’ll see there are two corresponding downloads. Add them both to the basket – one is the x86, the other is x64 but you won’t be able to tell them apart until they’re downloaded.

People building machines from a deployment image will therefore need to make sure that the newest Intel Display driver  is not added to their WIM or unattended build if it will be used on PCs with 945G chipsets. In the case of my unattended, I add drivers specifically by WMI model string so I shall move the Intel driver out of the Common folder and add it only to those builds which need it. I guess another issue will be that Windows Update will offer the newer Intel driver too.

UPDATE 2 – I have built another workstation from an unattended install with that 8.15.10.1912 driver and it also exhibits the Flash flickering problem (even though it’s fine on a system built by hand). So it looks like something to do with how the driver is added during the offlineServicing phase that is causing the problem. Once again, this does not affect Intel GMA drivers added during unattended installs for other non-GMA 950 chipsets. So for now I am leaving all OptiPlex GX620 systems on the generic Windows-included driver.

Advertisements

Customizing Windows 7 unattend.xml

Windows 7, like Vista, uses an XML answer file to configure the OS install. What’s neat about this is that even though you use the WAIK‘s WSIM tool to edit and validate it, you can customize it and add your own sections for software packages etc. as you can see from the example below, though these custom sections will need to be inserted after the sections that WSIM validates. This answer file can easily be parsed with VBScript using MSXML DOM, allowing for variables like passwords, driver sets, product keys and so on to be inserted at build time.

Why use an unattended install?

If you’ve always used an unattended install to build your workstations, you’ll know that they can be extremely versatile. If you already have a scripted build for XP with applications then chances are you’ll want to tweak those scripts to work with Windows 7. Sure, Sysprep images are handy too, but unless all your machines are the same, or all your packaged app requirements are identical, then you’ll need to add a load of scripted customization to them anyway. Which begs the question: why not just use an unattended install? That way you eliminate application problems that sometimes surface after image-based deployment. In a previous job I remember Roxio deployment in particular was a nightmare for this reason.

Microsoft have certainly made things considerably easier with the release of the Microsoft Deployment Toolkit 2010 but, though it offers a great introduction into the process of automated system building, it lacks the flexibility of rolling your own build process – in particular if you already have a host database. When I decide to rebuild a machine, it boots Windows PE from WDS, looks up its MAC address in the host database and reads the model type from WMI and will offer default choices in my build script menus based on that. It also works out which is the nearest site file server to use for the install.

The problem with Sysprep deployment if you have a very mixed hardware environment is that you either have to:

  • Create a WIM image for each different hardware type (lots of boring maintenance when changes are required)
  • Add a huge bulk of drivers to a single WIM image with DISM
  • Use the AuditSystem phase to connect to a driver share and re-detect all the hardware

Since Windows Vista and later versions effectively just install a WIM and run a hardware detection phase during their normal install process, Sysprep no longer offers much of a speed improvement over an unattended build.

Device drivers

Additional mass storage and networking drivers that will be essential during setup are detected in the Windows PE instance (which we booted from WDS) Driver Store and ‘reflected’ into the installed OS. As you build your custom Windows PE boot image, add these using DSIM as described in my post on the subject.

Since we can read the PC model name from the BIOS via WMI, we can add a tailored device path to the offlineServicing phase of setup. This allows for easy maintenance of driver bundles, since we can arrange them by model type (which certainly beats having dozens of SoundMAX audio drivers lumped together), and we can limit which drivers are offered to each model – particularly useful when a driver causes problems for some models, as with the GMA950 driver and Adobe Flash on Intel 945G motherboards.

I noticed that this is in fact considerably neater that the method used in MDT2010’s ZTIDrivers.wsf script, which copies drivers to the local system then invokes the AuditSystem phase, running the PnP detection routines a second time, slowing down the install. Useful for an OEM like Dell I suppose, whose PCs are often started from their factory image with no connectivity, but not ideal for corporate LANs.

Sample autounattend.xml with custom sections at the end

Note 1 – I couldn’t find any examples of this online, but I discovered that the values for pre-populating the Internet Explorer 8 Search Providers can be obtained by configuring a workstation, then harvesting the registry settings from HKCU\Software\Microsoft\Internet Explorer\SearchScopes. I have highlighted the relevant lines in the XML below.

Note 2 – Somewhat confusingly, in the offlineServicing phase Microsoft-Windows-PnpCustomizationsNonWinPE will fail to connect to your file server for drivers unless you connect to its FQDN (assuming the unattended launched the OS build from a share referencing just the NetBIOS name). Fail to do this and %systemroot%\panther\setupact.log will reveal that it fails to connect with error 0x4C3 (multiple credentials on connection to the same server). What’s bizarre is that there certainly aren’t multiple credentials in use – I use the same ones throughout. I wrote up this problem and solution in this thread on the MSFN Forums. I suspect this might be caused because I launch setup.exe from a network drive rather than mounting the OS WIM image from a WDS server (I wanted to maintain consistency with my other legacy OS builds). I have highlighted this on line 57.

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>en-US</UILanguage>
            </SetupUILanguage>
            <InputLocale>0809:00000809</InputLocale>
            <SystemLocale>en-GB</SystemLocale>
            <UILanguage>en-US</UILanguage>
            <UserLocale>en-GB</UserLocale>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ComplianceCheck>
                <DisplayReport>Never</DisplayReport>
            </ComplianceCheck>
            <Diagnostics>
                <OptIn>false</OptIn>
            </Diagnostics>
            <DiskConfiguration>
                <WillShowUI>Always</WillShowUI>
            </DiskConfiguration>
            <DynamicUpdate>
                <Enable>true</Enable>
                <WillShowUI>OnError</WillShowUI>
            </DynamicUpdate>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <MetaData wcm:action="add">
                            <Key>/IMAGE/NAME</Key>
                            <Value>Windows 7 PROFESSIONAL</Value>
                        </MetaData>
                    </InstallFrom>
                </OSImage>
            </ImageInstall>
            <UserData>
                <AcceptEula>true</AcceptEula>
                <FullName>IT</FullName>
                <Organization>My company</Organization>
                <ProductKey>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
            </UserData>
            <EnableNetwork>true</EnableNetwork>
        </component>
    </settings>
    <settings pass="offlineServicing">
        <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DriverPaths>
                <PathAndCredentials wcm:action="add" wcm:keyValue="common">
                    <Credentials>
                        <Domain>domain.com</Domain>
                        <Password>Password</Password>
                        <Username>unattended</Username>
                    </Credentials>
                    <Path>\\myserver.domain.com\UNATTENDED\drivers\7-x64\common</Path>
                </PathAndCredentials>
                <PathAndCredentials wcm:action="add" wcm:keyValue="build">
                    <Credentials>
                        <Domain>*value to be set by install.vbs*</Domain>
                        <Password>*value to be set by install.vbs*</Password>
                        <Username>*value to be set by install.vbs*</Username>
                    </Credentials>
                    <Path>*value to be set by install.vbs*</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
    </settings>
    <settings pass="generalize">
        <component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Home_Page>http://mycompany.com</Home_Page>
            <CompanyName>My Company</CompanyName>
            <FavoritesOnTop>true</FavoritesOnTop>
            <FilterLevel>High</FilterLevel>
            <Help_Page></Help_Page>
            <DisableFirstRunWizard>true</DisableFirstRunWizard>
            <DisableWelcomePage>true</DisableWelcomePage>
            <PlaySound>true</PlaySound>
            <ShowInformationBar>true</ShowInformationBar>
            <UserAgent></UserAgent>
            <Window_Title_CN></Window_Title_CN>
            <SearchScopes>
                <Scope wcm:action="add">
                    <ScopeDefault>true</ScopeDefault>
                    <ScopeKey>Search1</ScopeKey>
                    <ScopeDisplayName>Google</ScopeDisplayName>
                    <ScopeUrl>http://www.google.com/search?q={searchTerms}&amp;sourceid=ie7&amp;rls=com.microsoft:{language}:{referrer:source}&amp;ie={inputEncoding?}&amp;oe={outputEncoding?}</ScopeUrl>
                    <FaviconURL>http://www.google.com/favicon.ico</FaviconURL>
                    <SuggestionsURL>http://clients5.google.com/complete/search?q={searchTerms}&amp;client=ie8&amp;mw={ie:maxWidth}&amp;sh={ie:sectionHeight}&amp;rh={ie:rowHeight}&amp;inputencoding={inputEncoding}&amp;outputencoding={outputEncoding}</SuggestionsURL>
                </Scope>
                <Scope wcm:action="add">
                    <ScopeKey>Search2</ScopeKey>
                    <ScopeDisplayName>Bing</ScopeDisplayName>
                    <FaviconURL>http://www.bing.com/favicon.ico</FaviconURL>
                    <ScopeUrl>http://www.bing.com/search?q={searchTerms}&amp;form=IE8SRC&amp;src=IE-SearchBox</ScopeUrl>
                    <SuggestionsURL>http://api.bing.com/qsml.aspx?query={searchTerms}&amp;market={Language}&amp;form=IE8SSC&amp;maxwidth={ie:maxWidth}&amp;rowheight={ie:rowHeight}&amp;sectionHeight={ie:sectionHeight}</SuggestionsURL>
                </Scope>
            </SearchScopes>
            <EnableLinksBar>false</EnableLinksBar>
            <PrintBackground>true</PrintBackground>
        </component>
        <component name="Microsoft-Windows-RemoteAssistance-Exe" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <fAllowFullControl>true</fAllowFullControl>
            <fAllowToGetHelp>true</fAllowToGetHelp>
        </component>
        <component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SkipAutoActivation>true</SkipAutoActivation>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ComputerName>*</ComputerName>
            <ProductKey>XXXXX-YYYYY-ZZZZZ-YYYYY-XXXXX</ProductKey>
            <RegisteredOrganization>My Company</RegisteredOrganization>
            <RegisteredOwner>IT</RegisteredOwner>
        </component>
        <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <fDenyTSConnections>false</fDenyTSConnections>
        </component>
        <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Identification>
                <Credentials>
                    <Domain>*value to be set by install.vbs*</Domain>
                    <Password>*value to be set by install.vbs*</Password>
                    <Username>*value to be set by install.vbs*</Username>
                </Credentials>
                <JoinDomain>domain.com</JoinDomain>
                <MachineObjectOU>OU=Windows 7,OU=Workstations,DC=domain,DC=com</MachineObjectOU>
            </Identification>
        </component>
        <component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DomainProfile_EnableFirewall>false</DomainProfile_EnableFirewall>
        </component>
        <component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <UserAuthentication>1</UserAuthentication>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SystemLocale>en-GB</SystemLocale>
            <UILanguage>en-GB</UILanguage>
            <UserLocale>0809:00000809</UserLocale>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <RegisteredOrganization>My Company</RegisteredOrganization>
            <RegisteredOwner>IT</RegisteredOwner>
            <TimeZone>GMT Standard Time</TimeZone>
            <OEMInformation>
                <Manufacturer>*</Manufacturer>
                <Model>*</Model>
            </OEMInformation>
            <OOBE>
                <HideEULAPage>true</HideEULAPage>
                <NetworkLocation>Work</NetworkLocation>
                <ProtectYourPC>1</ProtectYourPC>
            </OOBE>
            <UserAccounts>
                <AdministratorPassword>
                    <Value>MwBifhgftytredjghAcwB0AHIAYQ584jkhkgtEAcwBzAHcAbwByAGQA</Value>
                    <PlainText>false</PlainText>
                </AdministratorPassword>
                <LocalAccounts>
                    <LocalAccount wcm:action="add">
                        <Password>
                            <Value>QQBTAEUANABoAGchgfhgfd357wrysAHMAcwB3AG8AcgBkAA==</Value>
                            <PlainText>false</PlainText>
                        </Password>
                        <Name>cust_localuser</Name>
                        <DisplayName>cust_localuser</DisplayName>
                        <Description>Dummy user required for unattended - delete later</Description>
                        <Group>users</Group>
                    </LocalAccount>
                </LocalAccounts>
            </UserAccounts>
            <VisualEffects>
                <FontSmoothing>ClearType</FontSmoothing>
            </VisualEffects>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Description>Connect to unattended share</Description>
                    <CommandLine>net use *value to be set by install.vbs*</CommandLine>
                </SynchronousCommand>
                <SynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Description>Launch package installer</Description>
                    <CommandLine>cscript *value to be set by install.vbs*</CommandLine>
                    <RequiresUserInput>true</RequiresUserInput>
                </SynchronousCommand>
            </FirstLogonCommands>
            <AutoLogon>
                <Password>
                    <Value>MwBifhgftytredjghAcwB0AHIAYQ584jkhkgtEAcwBzAHcAbwByAGQA</Value>
                    <PlainText>false</PlainText>
                </Password>
                <Username>Administrator</Username>
                <LogonCount>1</LogonCount>
                <Enabled>true</Enabled>
            </AutoLogon>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim://myserver/unattended/os/7-x64/sources/install.wim#Windows 7 PROFESSIONAL" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
    <!-- MY COMPANY CUSTOMIZATIONS BELOW-->
    <mycompany:custom xmlns:mycompany="urn:schemas-domain-com:mycompany">
        <!-- build description -->
        <cust_description>standard workstation</cust_description>
        <!-- list of packages to install in order. Descriptions are read from U:\scripts\packages.csv -->
        <cust_packages>office2k7.cmd,adobe.cmd,flash.cmd,java.cmd,fonts.cmd</cust_packages>
        <!-- start of the model name string, as reported by WMI, comma separated - allows auto-selection of build. -->
        <cust_models>OptiPlex 745,OptiPlex GX620,VMware Virtual Platform</cust_models>
        <!-- do we want packages.vbs to activate Windows? -->
        <cust_activate>false</cust_activate>
        <!-- do we want a hibernation file wasting disk space? If set to false packages.vbs will disable hibernation support -->
        <cust_hibernate>false</cust_hibernate>
    </mycompany:custom>
</unattend>
 

Sample VBScript code for parsing the XML using MSXML DOM

This is not a complete script – it’s intended purely to illustrate the concept.

'New OS - 7/Vista/2008/2008R2

'read the answer file
Set objXML = CreateObject("Microsoft.XMLDOM")
objXML.Async = "False"
objXML.Load(strMedia & "\sifs\" & strOS & "\" & strBuild & ".xml")

'Additional mass storage and Networking drivers that will be essential for the rest of the build are detected in the
'running Windows PE instance's Driver Store and reflected into the installed OS

'insert the non-WinPE PnP driver discovery paths and credentials for the offlineServicing pass
strXPath = "/unattend/settings[@pass='offlineServicing']/component[@name='Microsoft-Windows-PnpCustomizationsNonWinPE']/DriverPaths/PathAndCredentials/Credentials"
'we need to iterate since there may be several sets of credentials (one for each driver path)
Set colNodes=objXML.selectNodes(strXPath & "/Domain")
For Each objNode In colNodes
  objNode.Text = strDomainName
Next
Set colNodes=objXML.selectNodes(strXPath & "/Password")
For Each objNode In colNodes
  objNode.Text = strPass
Next
Set colNodes=objXML.selectNodes(strXPath & "/Username")
For Each objNode In colNodes
  objNode.Text = strUser  
Next

'Insert hostname
strXPath = "/unattend/settings[@pass='specialize']/component[@name='Microsoft-Windows-Shell-Setup']/ComputerName"
Set objNode=objXML.selectSingleNode(strXPath)
objNode.Text = strComputerName

'insert credentials for Domain join
On Error Resume Next
strXPath = "/unattend/settings[@pass='specialize']/component[@name='Microsoft-Windows-UnattendedJoin']/Identification/Credentials"
Set objNode=objXML.selectSingleNode(strXPath & "/Domain")
If Err.Number = 0 Then
  'Microsoft-Windows-UnattendedJoin exists - carry on modifying (workgroup builds won't have this section in the XML)
  objNode.Text = strDomainName
  Set objNode=objXML.selectSingleNode(strXPath & "/Password")
  objNode.Text = strPass
  Set objNode=objXML.selectSingleNode(strXPath & "/Username") 
  objNode.Text = strUser
End If
On Error Goto 0

'insert manufacturer and model into OEMinfo
strXPath = "/unattend/settings[@pass='oobeSystem']/component[@name='Microsoft-Windows-Shell-Setup']/OEMInformation/Manufacturer"
Set objNode=objXML.selectSingleNode(strXPath)
objNode.Text = strManufacturer
strXPath = "/unattend/settings[@pass='oobeSystem']/component[@name='Microsoft-Windows-Shell-Setup']/OEMInformation/Model"
Set objNode=objXML.selectSingleNode(strXPath)
objNode.Text = strModel & " - Your Company"

strXPath = "/unattend/settings[@pass='oobeSystem']/component[@name='Microsoft-Windows-Shell-Setup']/FirstLogonCommands/SynchronousCommand/CommandLine"
Set colNodes=objXML.selectNodes(strXPath)
For Each objNode In ColNodes
  'Insert the unattended share info and credentials
  If InStr (objNode.Text,"net use *value to be set by install.vbs*") Then
    objNode.Text = "net use " & strMedia & " \\" & strInstallServer & "\" & strShare & " /user:" & strUser & "@" & strDomainName & " " & strPass & " /persistent:no"
  End If
  'Record our build file selection for the package installer later
  If InStr (objNode.Text,"cscript *value to be set by install.vbs*") Then
    objNode.Text = "cscript //nologo " & strMedia & "\scripts\packages.vbs " & strMedia & " " & strOS & " " & strBuild & ".xml"
  End If
Next

Set objNode = Nothing
'write out the answer file
objXML.Save "x:\autounattend.xml" 
Set objXML = Nothing

Set custom LCD panel text on PowerEdge R710 servers

I recently bought a pair of these servers to take over VMware duties from a pair of HP ProLiant DL380 G5 servers. Having had a few bad Dell experiences years ago I had stopped buying PowerEdge machines as I considered their design to be inferior (think PE1850) but I’m pleasantly surprised by these R710 machines.

One thing I couldn’t figure out once they were racked, was how to set the custom LCD text when an iDRAC6 card is present.

In the server’s own BIOS options there is a Custom LCD field but entering text here and restarting doesn’t change the panel – it still just shows the Service Tag. Strangely, the iDRAC BIOS doesn’t offer you any control here at all, it just lists what the custom string currently is.

To make matters worse, I had accidentally got the desired result on one of the servers, but couldn’t get the second one configured. The answer lies with the buttons next to the LCD. Though you can view IP settings, temperature, power usage, etc., there is also a Setup option. With 48GB of RAM, each POST of the machine takes about 5 minutes so I had been too cautious to mess about with these options in case I undid some of my initial iDRAC config. I assumed that they would only provide a subset of the BIOS options. Wrong! You need to use the panel – even the iDRAC WebUI doesn’t seem to configure the LCD screen.

As it turns out, this is what you have to do on the front panel:

  • Push the select button (the tick or check symbol)
  • Press right and highlight Setup
  • Push the select button again
  • Scroll right until you see Set Home, and select
  • Then select Name
  • Scroll all the way right until User string, and select
  • Save: Yes

Though I don’t have any to test, I assume the PowerEdge R610 + iDRAC6 will be similar.

Maintaining a consistent Windows PE build

UPDATE – new much improved script here.

Having a WDS server with a bootable Windows PE instance is extremely useful. Got a server into a reboot loop by deleting a driver you were sure was inactive? Run out of space on C: and need to image and repartition? OS won’t boot but you need to salvage files? You get the picture. They key though, is making sure you’ve integrated all the network and mass storage controller drivers your hardware will need.

One of the most useful tools that’s not included in the image by default is ImageX – the tool for reading and writing WIM images. Pair this up with the GUI wrapper GImageX and you’ve got yourself a free replacement for Ghost.

Once you’ve downloaded WAIK, making a Windows PE build is a pain – there’s so much messy syntax to get right. Since you’re likely to keep needing to rebuild it to add more drivers, it’s a good idea to write a script to rebuild it from scratch each time. Here’s my build_pe_amd64.cmd:

set SOURCE=C:\WINPE_DRIVERS
set PATH=%PATH%;C:\Program Files\Windows AIK\Tools\PETools\;C:\Program Files\Windows AIK\Tools\%PROCESSOR_ARCHITECTURE%
set PATH=%PATH%;C:\Program Files\Windows AIK\Tools\Servicing
del c:\temp\pe_amd64\ISO\sources\boot.wim
del c:\temp\pe_amd64\winpe_amd64.iso
rd /s /q c:\temp\pe_amd64
call copype.cmd amd64 c:\temp\pe_amd64
dism /Mount-Wim /WimFile:c:\temp\pe_amd64\winpe.wim /Index:1 /MountDir:c:\temp\pe_amd64\mount
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\winpe-scripting.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\en-us\winpe-scripting_en-us.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\winpe-wmi.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\en-us\winpe-wmi_en-us.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\winpe-mdac.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\en-us\winpe-mdac_en-us.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\WinPE-HTA.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Package /PackagePath:"%ProgramFiles%\Windows AIK\Tools\PETools\amd64\WinPE_FPs\en-us\WinPE-HTA_en-us.cab"
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\common\vmxnet3\vmxnet3ndis5.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\pvscsi\pvscsi.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\perc4esi\oemsetup.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\lsi_sas\lsi_sas.inf /forceunsigned
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\nc373i_ris\b06nd.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\sa_5x6x\hpcisss.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\sa_p400\hpcissx2.inf
dism /image:c:\temp\pe_amd64\mount /Add-Driver /driver:%SOURCE%\x64\yk62\yk62x64.inf
copy "%ProgramFiles%\Windows AIK\Tools\PETools\amd64\bootsect.exe" c:\temp\pe_amd64\mount\Windows
copy /y %SOURCE%\common\*.cmd c:\temp\pe_amd64\mount\Windows\System32
copy "%SOURCE%\x64\Tools\*.*" c:\temp\pe_amd64\mount\Windows\System32
copy "%ProgramFiles%\Windows AIK\Tools\amd64\*.*" c:\temp\pe_amd64\mount\Windows\System32
md c:\temp\pe_amd64\mount\scripts
::script for launching my unattended OS installer
copy \\myserver\unattended\scripts\init.vbs c:\temp\pe_amd64\mount\scripts
dism /Unmount-Wim /MountDir:c:\temp\pe_amd64\mount /commit
imagex /export c:\temp\pe_amd64\winpe.wim 1 c:\temp\pe_amd64\ISO\sources\boot.wim
::uncomment the following line to build a bootable ISO image
::oscdimg -n -bc:\temp\pe_amd64\etfsboot.com c:\temp\pe_amd64\ISO c:\temp\pe_amd64\winpe_amd64.iso
ren c:\temp\pe_amd64\ISO\sources\boot.wim boot_amd64.wim
WDSUTIL /Verbose /Progress /Replace-Image /Image:"Microsoft Windows PE 3.0 (x64)" /ImageType:Boot /Architecture:x64 /ReplacementImage /Name:"Microsoft Windows PE 3.0 (x64)" /ImageFile:"c:\temp\pe_amd64\ISO\sources\boot_amd64.wim"
ren c:\temp\pe_amd64\ISO\sources\boot_amd64.wim boot.wim
cd\scripts