You are here:   Research
  |  Login

Welcome to my blog, quickest way to find articles is usually to search for them.

Minimize
Search in All Title Contents
 
     

Quick Fix - MDT Environment Variables set in PowerShell are not flushed to Variables.dat

Aug 07 2016

When setting variables in MDT Lite Touch, they need to be written to Variables.dat to be able to survive a reboot. This is of course very much needed when using a custom PowerShell frontend or script in the WinPE phase.

Bug in MDT 2013 Update 2

When setting variables in VBScript they are automatically flushed to Variables.dat, but not when setting them via PowerShell. For example if you have the IP Address (OSDADAPTER0IPADDRESSLIST) set to 192.168.1.200, and you change it via PowerShell, it get’s updated in memory, but not in the Variables.dat file on disk.

Workarounds

There are two things you can do to fix the problem:

1. Update the Variables.dat file directly in your PowerShell script. The Variables.dat file is really just a XML file, so it’s easy to update. Here is how the open source PowerShell Deployment for MDT does it:

function Save-PSDVariables
{
    $v = [xml]"<?xml version=`"1.0`" ?><MediaVarList Version=`"4.00.5345.0000`"></MediaVarList>"
    Get-ChildItem TSEnv: | % {
        $element = $v.CreateElement("var")
        $element.SetAttribute("name", $_.Name) | Out-Null
        $element.AppendChild($v.createCDATASection($_.Value)) | Out-Null
        $v.DocumentElement.AppendChild($element) | Out-Null
    }
    $path = "$(Get-PSDLocaldataPath)\Variables.dat"
    $v.Save($path)
    return $path
}

2. Call a VBscript that resets the value to whatever value your PowerShell script set, then just run that script after your PowerShell script. 

Here is an example (I named the script ZTIFlushVariables.wsf):

<job id="ZTIFlushVariables">
    <script language="VBScript" src="ZTIUtility.vbs"/>
    <script language="VBScript">

    ' Flush variables set via PowerShell to Variables.dat (workaround for bug in MDT 2013 Update 2)

    Dim oTSEnv
    Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")

    Dim oVar
        For Each oVar In oTSEnv.GetVariables

        ' Only worry about variables that have a value
        If oEnvironment.Item(oVar) <> "" Then

            ' Log variable before flush
            oLogging.CreateEntry "---------------------------------------------------------------------------", LogTypeInfo    
            oLogging.CreateEntry "Before Flush: " & oVar & " variable from Variables.dat: " & oEnvironment.GetDat(oVar), LogTypeInfo    

            ' Flush the variable
            oEnvironment.Item(oVar) = oEnvironment.Item(oVar)

            ' Log variable after flush
            oLogging.CreateEntry "After Flush: " & oVar & " variable from Variables.dat: " & oEnvironment.GetDat(oVar), LogTypeInfo    

        End if

    Next

    </script>
</job>

Logging

If you are curious what values the script writes back to the variables.dat file, you can open the ZTIFlushVariables.log file.

image

image
Example when a task sequence calls the script after a custom PowerShell frontend sets new values.








Happy deployment, and thanks for reading!


What our lawyers makes us say:

This information is provided "AS IS" with no warranties, confers no rights and is not supported by the authors or Deployment Artist.

Copyright © 2017 by Deployment Artist (the company behind deployment research). All rights reserved. No part of the information on this web site may be reproduced or posted in any form or by any means without the prior written permission of the publisher.

Shorthand: Don't pass off our work as yours, it's not nice.

Blog Archive

Minimize