Freigeben über


Encoding sensitive information in CustomSettings.ini and Bootstrap.ini

One of the questions I received after presenting a session at TechEd Europe was about encoding any clear-text passwords that you might place into the Bootstrap.ini file, so that if someone looked at the file they wouldn’t be able to tell what value it represented.  I suggested that it would be fairly simple to write a script that would take an encoded value, decode it, and save the decoded value to the “real” task sequence variable.  That evening, a script was written and a blog post started.

As the MDT scripts already provide everything needed to do this, the resulting scripts are pretty simple, with more comments than lines of code.  For the already-typed up scripts, see the attachment below. 

First, let’s talk about the approach.  We need to have encoded values that we can decode.  It’s easy enough to save those encoded values in task sequence variables, set via CustomSettings.ini or Bootstrap.ini.  So imagine something like this:

[Settings]
Priority=Decode, Default
Properties=EncodedUserPassword

[Decode]
EncodedUserPassword=SGVsbG8=

There’s not much to that:  I have declared a new variable called EncodedUserPassword, and set the value of that variable to “SGVsbG8=”, which is the base64-encoded equivalent of the string “Hello”.

The next step then is to decode that encoded value.  The simplest way of doing this is to use a user exit script.  The logic for that needs to do the following:

  • Look for a list of “encoded” variable names.  Because MDT already has the concept of “sensitive” variables (passwords, product keys, etc.), we can use that same list of variables as a starting point (although you could obviously add your own list).  To build the name of the “encoded” variable, we just prepend the word “Encode” to the variable as an easy-to-remember (and easy-to-script) convention.
  • For each “encoded” variable name, see if we can find a value for it.  If so, we’ll decode it and store it in the non-encoded variable.  For example, we would take “EncodedUserPassword”, if not blank, and store it in “UserPassword”.

The basic logic:

For each sVar in Array("USERID", "USERPASSWORD", "USERDOMAIN", "DOMAINADMIN", "DOMAINADMINPASSWORD", "DOMAINADMINDOMAIN", _
"ADMINPASSWORD", "BDEPIN", "TPMOWNERPASSWORD", "ADDSUSERNAME", "ADDSPASSWORD", _
"SAFEMODEADMINPASSWORD", "USERNAME", "USERPASSWORD", "PRODUCTKEY")

    ' If the encoded value exists, decode it and save it to the proper task sequence variable

    If oEnvironment.Item("Encoded" & sVar) <> "" then
oLogging.CreateEntry "Decoding variable Encoded" & sVar & " for assignment to " & sVar, LogTypeInfo
oEnvironment.Item(sVar) = oStrings.Base64Decode(oEnvironment.Item("Encoded" & sVar))
End if
Next

(Don’t try to copy and paste this, as it’s not complete and it doesn’t wrap nicely in the blog posting.  Use the already typed-up version attached below.)  The only real “magic” in this code is to use the “oStrings.Base64Decode” function, which already exists in MDT’s ZTIUtility.vbs script (as MDT actually stores these variables base64-encoded – if you think about that, you realize that we’re taking an encoded value, decoding it, then telling MDT to save it back again encoded.  Kind of silly, yes, but it does mean you won’t ever see the value in clear text.)

To use this user exit script in CustomSettings.ini, you need to copy the “DecodeExit.vbs” script into your deployment share’s “Scripts” folder, then add a reference to it in CustomSettings.ini:

[Settings]
Priority=Decode, Default
Properties=EncodedUserPassword

[Decode]
EncodedUserPassword=SGVsbG8=
UserExit=DecodeExit.vbs

OK, great, you’re all set to go now right?  Well, not really.  Look again at my example:  It’s setting the “UserPassword” variable.  That’s the password used to make a connection to the deployment share.  It really wouldn’t do any good to set that one in CustomSettings.ini.  Instead, it needs to be set in Bootstrap.ini.  Simple enough, right?  Just copy and paste the same lines into Bootstrap.ini.  Well, almost, as there is one additional challenge:  You have to get MDT to include the user exit script in the boot image, so that it’s available when the boot image is generated.  There are two ways that you could do that:

    • Create a folder somewhere that is accessible via a UNC path, e.g. \\SERVER\ExtraFiles$.  Inside of that folder, create a “Deploy” folder, and inside that, a “Scripts” folder.  Place a copy of DecodeExit.vbs in that “Scripts” folder.  Then update the deployment share properties to specify that UNC path for the “Extra directory to add” path.
    • Find the “LiteTouchPE.xml” file that defines what files MDT adds into the boot image.  Edit the file to add a new entry for DecodeExit.vbs that looks something like this:

<Copy source="%DEPLOYROOT%\Scripts\DecodeExit.vbs" dest="Deploy\Scripts\DecodeExit.vbs" />

Either approach will work.  After you make either change, you’ll need to update the deployment share to generate new boot images (then import those to WDS, generate new boot CDs, etc.).  The advantage of the first is that it will survive MDT upgrades.  The advantage of the second is that it’s easier to do and will detect script changes (e.g. if you modify the script to include more variables and then want to update the boot image again).

So how do you come up with the encoded value in the first place?  Well, if you search the internet, you’ll find lots of “base64 encoder” web pages, so you can always do that.  Or you can use the second script that I’ve attached, Encode.wsf, which leverages the matching “oStrings.Base64Encode” function from ZTIUtility.vbs.  You would run the script like so:

cscript.exe Encode.wsf /Value:”Hello"

It will display the resulting encoded value on the console, so you can then copy-and-paste into CustomSettings.ini or Bootstrap.ini.

As usual, even the simplest setup requires a lot of explanation…

DecodeExit.zip

Comments

  • Anonymous
    January 01, 2003
    Powershelly! Some of this is copy pasted from others including Michael :) : #function borrowed from gallery.technet.microsoft.com/.../Powershell-script-to-33887eb2 function ConvertFrom-Base64($stringfrom) {   $bytesfrom  = [System.Convert]::FromBase64String($stringfrom);   $decodedfrom = [System.Text.Encoding]::UTF8.GetString($bytesfrom);    return $decodedfrom   }

Grab the variables from the Task Sequence

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $tsenv.GetVariables() | % { Set-Variable -Name "$" -Value "$($tsenv.Value($))" } #Set Credentials to Task Sequence variable values $ClearID = ConvertFrom-Base64 -stringfrom "$UserID" $ClearDomain = ConvertFrom-Base64 -stringfrom "$UserDomain" $ClearPW = ConvertFrom-Base64 -stringfrom "$UserPassword" $User = "$ClearDomain$ClearID" $Password = ConvertTo-SecureString -String "$ClearPW" -AsPlainText -Force $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User,$Password

  • Anonymous
    January 01, 2003
    The problem with certs is that they secure the data, but who secures the cert?  Regardless, you can use the same type of user exit to implement any type of encoding or encrypting.  I just used a simple base64 encoding (which we always refer to as "obfuscation", not "encryption" or security of any kind) because it's simple and doesn't trick you into thinking this is somehow secure.

  • Anonymous
    January 01, 2003
    My mistake. I should modify the "LiteTouchPE.xml" inside "C:Program FilesMicrosoft Deployment ToolkitTemplates" instead of the 1 inside "DeploymentShareBoot"
    It works.

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    June 27, 2012
    Great post!

  • Anonymous
    June 30, 2012
    Good job, but still - it's security through obscurity... We could get real encryption with certs implemented...

  • Anonymous
    July 16, 2012
    Thanks Michael, you finally came up with the solution. It will be even better if you include it as part of MDT 2012 Update 1! To me, even though it is not 100% secured solution but it is way better than clear-text value for sure!

  • Anonymous
    July 19, 2012
    Nice job..it would be better if it is part of the GUI.

  • Anonymous
    August 28, 2012
    Hi Michael, great job. Tested with MDT 2012 U1 and works perfectly.

  • Anonymous
    October 08, 2012
    Thanks for the above.  I have followed the process and updated my customsettings.ini file - but please can someone advise what expression i need to use to call the encoded password? I have used the DomainAdminPassword=$EncodedUserPassword to join to the domain but it fails..... i'm not sure if i'm using the correct expression statement - pls can someone help

  • Anonymous
    October 30, 2013
    @OP, same question as Kulie. This "guide" is lacking a LOT of information needed to fully implement this solution. Also, this script doesn't seem to work in MDT 2013. I've tried to use it following your steps and during WinPE it hangs at "Processing Rule: DECODE"

  • Anonymous
    October 30, 2013
    See the note above starting with "You have to get MDT to include the user exit script in the boot image" - that explains the "hang" in Windows PE.  (The script actually fails when you skip this step.  The progress dialog is waiting forever for a script that failed in the background.)

  • Anonymous
    October 30, 2013
    And the sample above shows pretty much exactly what you would need to add to CustomSettings.ini.  Since everyone's file is different though, you might need to adjust it some, but the concept doesn't change.

  • Anonymous
    October 30, 2013
    The comment has been removed

  • Anonymous
    October 30, 2013
    The comment has been removed

  • Anonymous
    October 30, 2013
    If userexit scripts should be placed in the script directory with all the other wsf files, why is it recommended then to also setup an "extra directory" and put the vbs file in that as well? So to be 100% clear, if we follow your method above and use an "EncodedDomainAdminPassword" variable in the [Decode] section a "DomainAdminPassword" variable is not needed anywhere else in the customsettings.ini correct?

  • Anonymous
    October 31, 2013
    I've given up. Your Decode hangs during bootsrap no matter what I do. I've tried the extra directory, copying the files into the script DIR, and editing the LiteTouchPE xml file. Nothing works and I need to move on. Your thing might work in theory, but I can't get it working.

  • Anonymous
    March 12, 2014
    The comment has been removed

  • Anonymous
    April 17, 2014
    One point of clarity I would like to point out, the password example used in the above includes quotes. I was getting my encoded password by entering, as per the example, cscript.exe Encode.wsf /Value:”mypasswordhere" but my actual password did not have leading or closing quotes.

    For reference to others who may come along and try this my setup is MDT 2013 and am using this for deploying Windows 8.1 with update 1. I did not do the portions to add this to the boot disk, for that I require a login. Mostly because I am joining to a test domain while pulling files from a server in my production domain (and there is no trust from the production to the test domain) and because I have implemented a multi-MDT server boot disk (the MDT boot disk asks you what server, from a drop down, you want to connect to).

    Also, now that I was able to start using the built-in ability of MDT to join a domain, I had to remove the sections from UNATTEND.XML that does a domain join as I must have my joining done at the end of the task sequence due to GPO restrictions that prevent LITETOUCH.WSF from running, most notably via GPO we rename the admin account an change the password. For that same reason I also modified ZTIDomainJoin.wsf to remove the auto-reboot upon success as that would prevent the final stages of the TS form completing. I do my "Recover from Domain" as the last steps of the build and have enabled "finishaction=reboot" so the system will reboot when the summary screen has been acknowledged.

  • Anonymous
    May 11, 2014
    The comment has been removed

  • Anonymous
    May 12, 2014
    Pingback from Material de apoyo usado en la preconferencia de TechED NA 2014 (deployment??s) + links de interes – Freelance-IT Ags, Mex.

  • Anonymous
    May 13, 2014
    The comment has been removed

  • Anonymous
    November 26, 2014
    Thanks, Michael. Great article.
    As I understand, MDT transfers all sensitive information previously obfuscated? For example, when enter manually domainusernamepassword to access deployment share, this information transfers obfuscated with base64 encoding? Moreover, bootstrap.ini and Decode.wsf injected in boot image, and it's easy to extract passwords from boot CD, if you have one. Can you tell, if to implement strong encryption type and store boot images in WDS, not boot CD's, is it enough secure? Can sensitive information be sniffed such a way?
    Thanks. Have a nice day.

  • Anonymous
    January 27, 2015
    Just testing this and indeed it looks like it's the LiteTouchPE.xml in Templates folder that needs modifying as it will overwrite the one in Boot on deployment share update. Yet when I remove my UserPassword from Default in bootstrap.ini it doesn't get inserted during deployment.

  • Anonymous
    November 12, 2015
    Hello, I followed the instructions but I have a situation. machine is not able to get to the share. Password is missing. Could you hep me how to define?
    UserPassword: ............

  • Anonymous
    November 12, 2015
    Hello, I followed the instructions but I have a situation. machine is not able to get to the share. Password is missing. Could you hep me how to define?
    UserPassword: ............

  • Anonymous
    November 23, 2015
    Thanks for the great info. I really loved this. I would like to apprentice at the same time as you amend your web site, how could i subscribe for a blog site?
    For more info on showbox please refer below sites:
    http://showboxandroids.com/showbox-apk/
    http://showboxappandroid.com/
    Latest version of Showbox App download for all android smart phones and tablets. http://movieboxappdownloads.com/ - It’s just 2 MB file you can easily get it on your android device without much trouble. Showbox app was well designed application for android to watch movies and TV shows, Cartoons and many more such things on your smartphone.
    For showbox on iOS (iPhone/iPad), please read below articles:
    http://showboxappk.com/showbox-for-ipad-download/
    http://showboxappk.com/showbox-for-iphone/
    Showbox for PC articles:
    http://showboxandroids.com/showbox-for-pc/
    http://showboxappandroid.com/showbox-for-pc-download/
    http://showboxforpcs.com/
    There are countless for PC clients as it is essentially easy to understand, simple to introduce, gives continuous administration, effectively reasonable. it is accessible at completely free of expense i.e., there will be no establishment charges and after establishment it doesn't charge cash for watching films and recordings. Not simply watching, it likewise offers alternative to download recordings and motion pictures. The accompanying are the strides that are to be taken after to introduce Showbox application on Android. The above all else thing to be done is, go to the Security Settings on your Android telephone, Scroll down and tap on 'Obscure sources'.

  • Anonymous
    April 14, 2016
    The comment has been removed

  • Anonymous
    April 28, 2016
    Great scripts and instructions Michael. Works a treat!To add to this here is a good article to secure the deployment shares: http://www.ingmarverheij.com/mdt-secure-deployment-share/Cheers,Jeremy