PowerShell add DaRT Remote Control to SCCM Boot Image Early V2

Ok so I’m sure like a lot of people out there we all love those scripts that Johan Arwidmark, Mikael Nystrom, Peter Löfgren and all the other MVPs write that make our lives easier!

Any way Johan recently released an awesome PowerShell script to inject DaRT into a ConfigMgr boot image and configure remote control from the MDT Monitoring node using a  launching script written by Alexey Semibratov.
Adding DaRT to ConfigMgr Boot Images – And starting it earlier than early

The beauty of adding this to your boot image is the point at which you are then able to remote control a task sequence, you can literally remote control the machine being built before the DP password has been entered, allowing the ConfigMgr Admin(s) to easily troubleshoot an issue.

I want to make it clear that the original script was created by Johan and without his work I would not have come up with this. What I have done (having a spare Saturday) is tweak it a little to take parameters and configure it all. This means you do not have to open any files to change any information 🙂 I even update the XML for you, install Dart, the works!

Anyway head over to here to download the script: Add-DartToBootImageV2

The steps for configuration are as follows:

  • Create a folder to drop the Add-DartToBooImageV2 files into. E.g “E:\Setup\Scripts\Add-DartToBooImageV2” Note: no spaces please 🙂
Folder structure for Add-DarttobootimageV2
  • Copy all script files downloaded from above and your version of the MSDaRT100.MSI (DaRT 10 x64) installer into that folder as well.
  • Next head over to you MDT deployment share and grab the monitoring service address.
MDT Deployment Share Monitoring Host Address
  • Now head over to ConfigMgr and grab the Name of the boot image you would like to enable DaRT remote control on.
  • Once you have collected that information open a command prompt as Administrator on your site server.
  • Now navigate (cd) to E:\Setup\Scripts\Add-DartToBooImageV2
  • Ensure the drive you choose has enough space to mount the boot image as the script will create and clean up for you.
  • And run the script with the following command line:
.\Add-DartToBootImageV2.ps1 -EventServiceLocation http://your-cm-01.yourdomain.local:9800 -BootImageName 'MDT 8450 x64' -MountDrive J -SiteServer your-cm-01.yourdomain.local -SiteCode P01

Running the script:

Add-DartToBootImageV2.ps1 Running
Add-DartToBootImageV2.ps1 Running 2

Reaping the rewards:

PXE boot with DaRT 10 SCCM MDT

The script:

##################################################################################################################
#
#  Original Author: Johan Arwidmark  
#  Updated By: Richie Schuster - C5 Alliance - SCCMOG.com
#  Date:   28/07/2018
#          03/08/2018 - Changed Folder search to get volume and select on data drives only as found issue on VMware VMs
#                       Added default paths for installs MDT and Dart to speed up script for multiple Images.
#                       
#  Script: Add-DartToBootImageV2.ps1
#  Usage: Powershell.exe -ExecutionPolicy Bypass -File .\Add-DartToBootImageV2.ps1 -EventServiceLocation http://roary-cm-01.roary.local:9800 -BootImageName 'MDT 8450 x64' -MountDrive J -SiteServer ROARY-CM-01.ROARY.LOCAL -SiteCode ROR
#
##################################################################################################################

param(
    [parameter(Mandatory=$true, HelpMessage="Please enter the FQDN and PortNumber of the Server that host the MDT Monitoring Service. E.g http://roary-cm-01.roary.local:9800")]
    [ValidateNotNullOrEmpty()]
    [string]$EventServiceLocation,
    [parameter(Mandatory=$true, HelpMessage="Please enter the name of the bootimage you would like to inject DaRT into.")]
    [ValidateNotNullOrEmpty()]
    [string]$BootImageName,
    [parameter(Mandatory=$true, HelpMessage="Please select the Mount Drive i.e ")]
    [ValidateNotNullOrEmpty()]
    [string]$MountDrive,
    [parameter(Mandatory=$true, HelpMessage="Please enter the FQDN of your Site Server")]
    [ValidateNotNullOrEmpty()]
    [string]$SiteServer,
    [parameter(Mandatory=$true, HelpMessage="Please enter you Site Code.")]
    [ValidateNotNullOrEmpty()]
    [string]$SiteCode
)

# Check for elevation
Write-Host "Checking for elevation"

If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator"))
{
    Write-Warning "Oupps, you need to run this script from an elevated PowerShell prompt!`nPlease start the PowerShell prompt as an Administrator and re-run the script."
    Write-Warning "Aborting script..."
    Break
}

# Connect to ConfigMgr
if((Get-Module ConfigurationManager) -eq $null) {
    Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
}
if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null) {
    New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $SiteServer 
}
Set-Location "$($SiteCode):\" 

# Get Boot image from ConfigMgr
$BootImage = Get-CMBootImage -Name $BootImageName
$BootImagePath = $BootImage.ImagePath
$XMLPath = "$PSScriptRoot\Unattend.xml"
$EnableDart = "$PSScriptRoot\EnableDart.wsf"
$SampleFiles = "$PSScriptroot"
$MountPath = "$($MountDrive):\DartMount"
$MDTDefaultPath = "C:\Program Files\Microsoft Deployment Toolkit\Templates"
$MDTFolderName = "Microsoft Deployment Toolkit\Templates"
$REGUninstall = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
$DartDefaultPath = "C:\Program Files\Microsoft DaRT"
$DartDispName = 'Microsoft Dart 10'
$DartFolderName = "Microsoft DaRT"
$DartMSI = "$PSScriptroot\MSDaRT100.msi"

#Function to find folders
Function FindFolder($FolderName){
    #$Drives = Get-PSDrive -p FileSystem | Select-Object -ExpandProperty Name
    $Drives =  Get-Volume | Where-Object { ($_.FileSystemLabel -ne "System Reserved") -and ( $_.DriveType -like "Fixed") -and ( $_.FileSystem -like "NTFS")} | Select-Object -ExpandProperty DriveLetter | Sort-Object
    $InstallPath = $null
    :findfolder Foreach ($drive in $Drives) {
        If ($InstallPath -eq $null) {
            $Counter++
            Write-host "Searching drive $($drive):\ for folder: '$($FolderName)' Drive count is $($Counter) out of $($Drives.Count)" -ForegroundColor Yellow
            $InstallPath = Get-ChildItem -Recurse -Force "$($drive):\" -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $true) -and ( $_.FullName -like "*$FolderName") } | Select-Object -ExpandProperty FullName
        }
        Else {
                Write-Host "Found folder at: $($InstallPath)" -ForegroundColor Green
                return $InstallPath
                break findfolder
        }
    }
    #Write-Warning "Could not find the install Folder $Foldername exiting";break
    $InstallPath = "NotFound"
    return $InstallPath
}

# Check for PRE Reqs
Set-Location C:
if (!(Test-Path -Path "$XMLPath")) {Write-Warning "Could not find Unattend.xml path, check it is in script root and retry. aborting...";Break}
if (!(Test-Path -Path "$BootImagePath")) {Write-Warning "Could not find boot image, aborting...";Break}
if (!(Test-Path -Path "$DartMSI")) {Write-Warning "Could not DaRT MSI, Please place MSDaRT100.msi in script root folder, aborting...";Break}
if (!(Test-Path -Path "$MountPath")) {
    Write-Warning "Could not find mount path, Creating..."
    try {
        New-item -Path "$MountPath" -ItemType Directory -ErrorAction SilentlyContinue -Force
        Write-Host "Successfully Created Mount Path at:  $($MountPath)" -ForegroundColor Green
    }
    catch [System.Exception]{
        Write-Host "Failed to create Mount Path at:  $($MountPath) Error Message:  $($_.Exception.Message)";Break
    }
    }
#Check if dart is installed - If not install it.
$DaRT10 = Get-ItemProperty "$REGUninstall\*" | Where-Object DisplayName -Like $DartDispName
if($DaRT10.VersionMajor -eq “10”){
    Write-Host "Dart is installed searching for CAB file location"
    If (Test-Path -Path $DartDefaultPath){
        $DartInstallPath = $DartDefaultPath
    }
    Else {
        $DartInstallPath = FindFolder($DartFolderName)
    }
    $DartCab = $DartInstallPath + "\v10\Toolsx64.cab"
    if (Test-Path -Path "$DartCab"){
        Write-Host "Found DaRT x64 CAB at: $($DartCab)" -ForegroundColor Green
    } 
    else {
        Write-Warning "Could not find DaRT 10 Toolsx64.cab, Please remove older version of DaRT and retry. aborting...";
        Break
    }
}
else{
    Write-Warning "Could not find any DaRT version installed. Installing DaRT MSI in root of folder."
    $DartArgs = "/i $DartMSI /qb /norestart /L*v $env:windir\temp\MSDaRT100_Install.Log"
    $process = Start-Process -FilePath "msiexec.exe" -ArgumentList $DartArgs -Wait -NoNewWindow -PassThru
    If ($process.ExitCode -ne 0) {
        Write-Warning "Failed to install DaRT 10 please check the log at $($env:windir)\temp\MSDaRT100_Install.Log Install EXITCODE: $process.ExitCode";break
    }
    Else {
        Write-Host "DaRT 10 installed at: $ENV:ProgramFiles\$DartFolderName" -ForegroundColor Green

    }
    $DartCab = "$ENV:ProgramFiles\$DartFolderName" + "\v10\Toolsx64.cab"
    if (!(Test-Path -Path "$DartCab")) {Write-Warning "Could not find DaRT Toolsx64.cab, aborting...";Break}
}
If (Test-Path -Path $MDTDefaultPath){
    $MDTInstallationPath = $MDTDefaultPath
    }
Else {
 $MDTInstallationPath = FindFolder($MDTFolderName)
}
if (!(Test-Path -Path "$MDTInstallationPath" -ErrorAction SilentlyContinue)) {
    Write-Warning "Could not find MDT, please install MDT and re run script, aborting...";Break
    }
Else {
    Write-Host "Found MDT at: $($MDTInstallationPath)" -ForegroundColor Green 
}
if (!(Test-Path -Path "$EnableDart")) {Write-Warning "Could not find EnableDart.wsf, aborting...";Break}
if (!(Test-Path -Path "$XMLPath")) {Write-Warning "Could not find Unattend.xml, aborting...";Break}

Write-Host "##################################################################################" -ForegroundColor Green
Write-Host "All Pre Reqs found starting continuing..." -ForegroundColor Green
Write-Host "##################################################################################" -ForegroundColor Green

Write-Host "Updating Unattend.XML with new Event Service Location: $($EventServiceLocation)..." -ForegroundColor Green
#Update Unattend.xml with new event service location.
#Get the XML
$XML = (Get-Content $XMLPath)
#Set the base new command
$UpdateCMD = 'wscript.exe X:\Deploy\Scripts\EnableDart.wsf ','/EventService:',' /_SMSTSCurrentActionName:"Booted into WinPE"'
Write-Host "New CMD will be: $($UpdateCMD[0])$($UpdateCMD[1])$($EventServiceLocation)$($UpdateCMD[2])" -ForegroundColor Yellow
$CMD = $XML.unattend.settings.component.RunSynchronous.RunSynchronousCommand
$CMD.Path = $UpdateCMD[0] + $UpdateCMD[1] + $EventServiceLocation + $UpdateCMD[2]
try {
    $XML.Save($XMLPath)
    Write-Host "Successfully Saved new command line to XML: $($UpdateCMD[0])$($UpdateCMD[1])$($EventServiceLocation)$($UpdateCMD[2])"-ForegroundColor Green
}
Catch [System.Exception]{
    Write-Warning "Failed to Save new command line: '$($UpdateCMD[0])$($UpdateCMD[1])$($EventServiceLocation)$($UpdateCMD[2])' Error Message: '$($_.Exception.Message)' aborting..."
    Break;
}

# Mount the boot image
Mount-WindowsImage -ImagePath $BootImagePath -Index 1 -Path $MountPath  

# Add the needed files to the boot image
expand.exe $DartCab -F:* $MountPath
Remove-Item $MountPath\etfsboot.com -Force
Copy-Item $MDTInstallationPath\DartConfig8.dat $MountPath\Windows\System32\DartConfig.dat


if (!(Test-Path -Path "$MountPath\Deploy\Scripts")) {New-Item -ItemType directory $MountPath\Deploy\Scripts}
if (!(Test-Path -Path "$MountPath\Deploy\Scripts\x64")) {New-Item -ItemType directory $MountPath\Deploy\Scripts\x64}
Copy-Item $EnableDart $MountPath\Deploy\Scripts
Copy-Item $XMLPath $MountPath
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ZTIDataAccess.vbs" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ZTIUtility.vbs" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ZTIGather.wsf" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ZTIGather.xml" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ztiRunCommandHidden.wsf" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Scripts\ZTIDiskUtility.vbs" $MountPath\Deploy\Scripts
Copy-Item "$MDTInstallationPath\Distribution\Tools\x64\Microsoft.BDD.Utility.dll" $MountPath\Deploy\Scripts\x64

# Save changes to the boot image
Dismount-WindowsImage -Path $MountPath -Save
Start-Sleep -Seconds 2
#Cleanup Mount folder
Remove-Item -Path $MountPath -ErrorAction SilentlyContinue -Force

# Update the boot image in ConfigMgr
Set-Location "$($SiteCode):\" 
$GetDistributionStatus = $BootImage | Get-CMDistributionStatus
$OriginalUpdateDate = $GetDistributionStatus.LastUpdateDate
Write-Host "Updating distribution points for the boot image..." -ForegroundColor Yellow
Write-Host "Last update date was: $OriginalUpdateDate" -ForegroundColor Yellow
$BootImage | Update-CMDistributionPoint

# Wait until distribution is done
Write-Output ""
Write-Output "Waiting for distribution status to update..."

Do { 
$GetDistributionStatus = $BootImage | Get-CMDistributionStatus
$NewUpdateDate = $GetDistributionStatus.LastUpdateDate
 if ($NewUpdateDate -gt $OriginalUpdateDate) {
  Write-Output ""
  Write-Host "Yay, boot image distribution status updated. New update date is: $NewUpdateDate" -ForegroundColor Green
  Write-Host "Happy Deployment!" -ForegroundColor Green
 } else {
  Write-Host "Boot image distribution status not yet updated, waiting 10 more seconds"  -ForegroundColor Cyan
 }
 Start-Sleep -Seconds 10
}
Until ($NewUpdateDate -gt $OriginalUpdateDate)
############################################################# Done :)

 

4 Replies to “PowerShell add DaRT Remote Control to SCCM Boot Image Early V2”

  1. Hi,

    instead of a findfile for MDT, DaRT use this?

    $MDTDefaultPath = (Get-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Deployment 4”).Install_Dir
    $DartDefaultPath = (Get-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\DaRT\v10”).InstallPath

    regards, roland

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright 2016 SCCMOG | All Rights Reserved

css.php