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

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.

About the author

Johan Arwidmark

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

>