Hi, just a quick post about an idea I wanted to share with you all:
A request from a colleague -since we are using MDT to deploy our corporate machines- was to create a mechanism that prevents the re-partitioning and formatting of hard drives that have already been deployed with MDT.
Now this can easily be done by creating the following steps in your deployment task sequence:
figure 1.1: Set Task Sequence Variable – DeploymentType
As you can see above, the Task Sequence Variable “DeploymentType” will be set, during the execution of the task sequence. But how can we achieve this only happens if for example the machine has already been installed with MDT a previous time?
figure 1.2: Task Sequence Variable Condition
By setting a condition on this Task Sequence Variable. For example by checking if a certain file exists. Naturally it is key, that this file will be created at the first initial deployment of the machine, or the file is created manually afterwards. The reason why I check both C: and D: drive, is that within Windows PE, it may occur that sometimes your C: drive is detected as D: drive due to the “System Reserved” or “System” partition.
This way I’m always right.
Now, to generate a file for identification, I’ve created a powershell script, which dumps certain Task Sequence Variables queried by the ZTIGather.wsf script in a text file, together with a couple of WMI queries:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#Setting $ScriptFile = $MyInvocation.MyCommand.Name $ScriptLocation = Split-Path $MyInvocation.MyCommand.Path -Parent $Path = "C:\MDTRollout" $TaskSequenceName = "MDT Task Sequence: $TSEnv:TaskSequenceName" $DeploymentType = "Deployment Type: $TSEnv:DeploymentType" $JoinDomain = "Domain: $TSEnv:JoinDomain" $JoinWorkgroup = "Workgroup: $TSEnv:JoinWorkgroup" $OSDComputerName = Gwmi Win32_ComputerSystem | Select Caption $OSDComputerName = $OSDComputerName.Caption $OSDComputerName = "ComputerName: $OSDComputerName" $MachineObjectOU = "Organizational Unit: $TSEnv:MachineObjectOU" $Make = "Manufacturer: $TSEnv:Make" $Model = "Model: $TSEnv:Model" $AssetTag = "AssetTag: $TSEnv:AssetTag" $SerialNumber = "SerialNumber: $TSEnv:SerialNumber" $Language = "Present Windows Languages: $TSEnv:ImageLanguage001, $TSEnv:ImageLanguage002, $TSEnv:ImageLanguage003, $TSEnv:ImageLanguage004" $Version = Gwmi Win32_Operatingsystem | Select Caption $Version = $Version.Caption $Version = "Windows Operating System: $Version" $Architecture = "Windows Platform Architecture: $TSEnv:Architecture" $BDE = "Bitlocker Enabled: $TSEnv:IsBDE" $BDEKey = (Get-BitLockerVolume -MountPoint C).KeyProtector.RecoveryPassword $BDEKey = "Bitlocker Recovery Key: $BDEKey" $Date = Get-Date $Date = "Deployment Date: $Date" $Text = @" ================================================== !!! Deployment Information !!! $TaskSequenceName $DeploymentType $OSDComputerName $JoinDomain $JoinWorkgroup $MachineObjectOU $Date !!! Hardware Information !!! $Make $Model $AssetTag $SerialNumber $Language $Version $Architecture !!! Miscellaneous Information !!! $BDE $BDEKey End of Information ================================================== "@ If (-NOT (Test-Path $Path )) { MD $Path ; Set-ItemProperty -Path $Path -Name Attributes -Value ([System.IO.FileAttributes]::Hidden) -Force } If ( (Test-Path "$Path\DeploymentInfo.txt" )) { $Text | Add-Content "$Path\DeploymentInfo.txt" } If (-NOT (Test-Path "$Path\DeploymentInfo.txt" )) { $Text | Out-File -Filepath "$Path\DeploymentInfo.txt" } |
The script is pretty straight forward:
First it sets the invocation path, which is the path from where the script is called. Then it sets the variables which are needed as input for the script. And the cool thing is, since ZTIGather.wsf queries the entire machine, we can use the MDT Task Sequence Variables as input for our script, which will be dumped into the text file.
To determine the computername, I wanted to use the OSDComputerName task sequence variable, but strangely enough, it outputted the AssetTag instead, for this reason I used the WMI query:
1 |
Gwmi Win32_ComputerSystem | Select Caption |
And the same thing goes for the Windows Operating Sytem version:
1 |
Gwmi Win32_Operatingsystem | Select Caption |
And bitlocker recovery key:
1 |
(Get-BitLockerVolume -MountPoint C).KeyProtector.RecoveryPassword |
I then just needed to format these results in a readable usable manner, to get all my variables straight.
Now that’s out of the way, I needed a folder to store this information in, but I don’t want to bother end-users looking into it. So I create a folder called “MDTRollout” and placed it in the root of C:\ and give it the “Hidden” attribute, also I perform a check if the folder itself does not exist, in that case it will be created.
The same thing goes for the text file which is automatically created, if it does not exist. And if the file exists, it will add the content, for example when the machine is reïnstalled for the 2nd, 3rd, or 50th time.
And now to show you the result:
figure 1.3: No folder present at first
figure 1.4: running the script
figure 1.5: Task Sequence has finished
figure 1.7: Contents of the DeploymentInfo.txt
There you have it, a little usefull file which can be used to quickly evaluate the computer’s identity and configuration. Which on it’s turn, forms the basis to perform a MDT REFRESH scenario, instead of a NEWCOMPUTER scenario.
The script can be placed in the .\DeploymentShare\Scripts folder, and executed with a “Run Powershell Script” step from within the Task Sequence properties pane. You can call the script as following: “%Scriptroot%\MDT_DeploymentInfo.ps1”, the great thing about doing it this way, is that MDT handles the execution policy of powershell which would otherwise prevent the execution of the script. Normally it is necessary to set the policy to “Bypass” or “Unrestricted”.
figure 1.8: Calling the script
figure 1.9: Testing it yourself
Now to test the script yourself, a custom task sequence with the following two steps should do the trick:
- “Gather”
- “Run PowerShell Script”
Hope this can be of use to anyone else.
Find attached the screenshots used, and the actual script, which can be downloaded
Cheers and have great 2014/2015! Merry Christmas and a Happy New Year!!!!