PSD icon indicating copy to clipboard operation
PSD copied to clipboard

DaRT Remote Control from Monitoring

Open gakamor opened this issue 2 years ago • 14 comments

Unless I am doing something wrong, I don't believe this has been implemented yet. Are there any workarounds that would enable DaRT Remote Control from the Monitoring section of DeploymentWorkbench?

gakamor avatar May 05 '23 13:05 gakamor

Hello,

I'm going to test and let you know.

GeoSimos avatar May 25 '23 18:05 GeoSimos

I'm using DaRT with Powershell Deployment. I had to do some changes in PSDUtility.psm1 (in the Write-PSDEvent function) and add a script, that actually starts DaRT and populates the $tsenv: variables. Also I don't think DaRT will work if the client is behind NAT as the server is initiating the connection (this isn't an issue in my environment). The script uses IPv4. Not sure if DaRT supports IPv6 (I never tried it).

The Write-PSDEvent (inside PSDUtility.psm1) function was already prepared for DaRT support but some stuff was missing. First populate the following variables inside the function.

    $dartIP = $tsenv:dartIP
    $dartPort = $tsenv:dartPort
    $dartTicket = $tsenv:dartTicket

Also change the line containing Invoke-WebRequest. This way the webserver will get the required IP address, ticketid and the port for DaRT access.

$Return = Invoke-WebRequest "$tsenv:EventService/MDTMonitorEvent/PostEvent?uniqueID=$Lguid&computerName=$ComputerName&messageID=$messageID&severity=$severity&stepName=$stepName&currentStep=$CurrentStep&totalSteps=$TotalSteps&id=$id,$macaddress&message=$Message&dartIP=&dartPort=&dartTicket=&vmHost=$vmhost&vmName=$ComputerName" -UseBasicParsing

This is how Write-PSDEvent in PSDUtility.psm1 looks after the changes:

Function Write-PSDEvent {
    param(
        $MessageID,
        $Severity,
        $Message
    )

    if ($tsenv:EventService -eq "") {
        return
    }

    # a Deployment has started (EventID 41016)
    # a Deployment completed successfully (EventID 41015)
    # a Deployment failed (EventID 41014)
    # an error occurred (EventID 3)
    # a warning occurred (EventID 2)

    if ($tsenv:LTIGUID -eq "") {
        $LTIGUID = ([guid]::NewGuid()).guid
        New-Item -Path TSEnv: -Name "LTIGUID" -Value "$LTIGUID" -Force
        Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Property LTIGUID is $tsenv:LTIGUID"
        Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Saving Variables"
        $variablesPath = Save-PSDVariables
        Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Variables was saved to $variablesPath"
    }

    $MacAddress = $tsenv:MacAddress001
    $Lguid = $tsenv:LTIGUID
    $id = $tsenv:UUID
    $vmhost = 'NA'
    $ComputerName = $tsenv:OSDComputerName
    # Added dart variables:
    $dartIP = $tsenv:dartIP
    $dartPort = $tsenv:dartPort
    $dartTicket = $tsenv:dartTicket

    $CurrentStep = $tsenv:_SMSTSNextInstructionPointer
    if ($CurrentStep -eq "") {
        $CurrentStep = '0'
    }

    $TotalSteps = $tsenv:_SMSTSInstructionTableSize
    if ($TotalSteps -eq "") {
        $TotalSteps = '0'
    }
    $stepName = $tsenv:_SMSTSCurrentActionName
	$Message = "Error starting Wireguard service... ReturnValue: [$($WGServiceOutput.ReturnValue)]"
        # Added infos for dart.
	Write-PSDLog -Message "InvokingWebrequest: $tsenv:EventService/MDTMonitorEvent/PostEvent?uniqueID=$Lguid&computerName=$ComputerName&messageID=$messageID&severity=$severity&stepName=$stepName&currentStep=$CurrentStep&totalSteps=$TotalSteps&id=$id,$macaddress&message=$Message&dartIP=$dartIP&dartPort=$dartPort&dartTicket=$dartTicket&vmHost=$vmhost&vmName=$ComputerName"
        # Added infos for dart.
        $Return = Invoke-WebRequest "$tsenv:EventService/MDTMonitorEvent/PostEvent?uniqueID=$Lguid&computerName=$ComputerName&messageID=$messageID&severity=$severity&stepName=$stepName&currentStep=$CurrentStep&totalSteps=$TotalSteps&id=$id,$macaddress&message=$Message&dartIP=$dartIP&dartPort=$dartPort&dartTicket=$dartTicket&vmHost=$vmhost&vmName=$ComputerName" -UseBasicParsing
}

I'm using the following script to start DaRT:

<#
.SYNOPSIS
Starts DaRT remote access during WinPE phase
during Powershell Deployment.
.NOTES
Expects DaRT tools to be present in x:\windows\system32
https://github.com/DeploymentResearch/DRFiles/blob/master/Scripts/EnableDaRT/EnableDart.wsf
#>
param(
	[Switch]$Debug
)

if ($Debug) {
	$PSDDebug = $true
	$VerbosePreference = "Continue"
}

$RemoteRecoveryPath = "$env:systemdrive\Windows\System32\RemoteRecovery.exe"
$env:PSModulePath = $env:PSModulePath + ";$env:systemdrive\Deploy\Tools\Modules"
$invFile = "$env:systemdrive\Windows\System32\inv32.xml"

try {
    Import-Module "$env:systemdrive\deploy\tools\modules\Microsoft.BDD.TaskSequenceModule" -Scope Global -Force -ErrorAction Stop -Verbose:$False
    Import-Module "$env:systemdrive\deploy\tools\modules\PSDUtility\PSDUtility.psm1" -Scope Global -Force -Verbose:$False -ErrorAction Stop
    Import-Module "$env:systemdrive\deploy\tools\modules\PSDGather\PSDGather.psm1" -Force -Verbose:$False -Scope Global -ErrorAction Stop
} catch {
    Add-Content -Path "x:\Start-DaRT.log" -Value "Error during module import. Exiting."
    Add-Content -Path "x:\Start-DaRT.log" -Value $_
    exit
}
Get-PSDLocalInfo

Start-PSDLogging


<#
    Get WinPE version and apply a fix for some newer versions.
#>
try {
    [int]$WinPEBuildVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinPE" -Name "Version" -ErrorAction:Stop).Version.Split('.')[2]
} catch {
    Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Error retrieving build version. Exiting."
    Write-PSDLog -Message $_.Exception
}

Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): WinPEBuildVersion: [$WinPEBuildVersion]"
if ($WinPEBuildVersion -ge 19041) {
    Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Build version is greater or equal to 19041. Trying to set registry value to fix issues."
    try {
        Set-ItemProperty -Path "HKCU:\Console" -Value 0 -Type "DWord" -Name "ForceV2" -ErrorAction:Stop
    } catch {
        Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Error setting HKCU:\Console [ForceV2] to [0]. Exiting."
        Write-PSDLog -Message "Exiting Start-DaRT.ps1 due to error setting build version."
        Write-PSDLog -Message $_
        exit
    }
}

<#
    Check if remoterecovery can be accessed
#>


if ((-not($env:systemdrive -eq "X:")) -or (-not (Test-Path -Path $RemoteRecoveryPath))) {
    Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Systemdrive not equal x: or couldn't find [$env:systemdrive\System32\RemoteRecovery.exe].e. Exiting."
    Write-PSDLog -Message "Systemdrive not equal x:\ or couldn't find RemoteRecovery.exe. Exiting."
}
try {
    Start-Process -FilePath $RemoteRecoveryPath -WorkingDirectory "$env:systemdrive\Windows\System32" -ArgumentList "-nomessage" -WindowStyle "Minimized" -ErrorAction:Stop
} catch {
    Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): Error starting ."
    Write-PSDLog -Message  "Exiting Start-DaRT.ps1. Error executing RemoteRecovery.exe."
    Write-PSDLog -Message  $_.Exception
    exit
}

<#
    Wait after start of remote recovery for the inv32.xml file.
#>

for ($i = 0; ($i -lt 100) -and (-not (Test-Path -Path $invFile)); $i++) {
    Start-Sleep -Seconds 3
}

<#
    Read ticketid, ip addresses and ports from the file
#>
[xml]$xml = Get-Content -Path $invFile

<#
	At the moment this solution only supports a single IPv4 address.
	If the client obtained more than one IPv4 address, additional filtering is necessary.
#>

<#
    Restore psdvariables before adding dart infos to prevent problems...
#>
$mappingFile = "X:\Deploy\Tools\Modules\PSDGather\ZTIGather.xml"
Invoke-PSDRules -FilePath "X:\Deploy\Scripts\Bootstrap.ini" -MappingFile $mappingFile

Restore-PSDVariables | Out-Null

$DartInfos = $xml.e.c.t.l | Where-Object { $_.N -match "^([0-9]{1,3}\.){3}[0-9]{1,3}$" }


$tsenv:dartIp = $DartInfos.N
$tsenv:dartPort = $DartInfos.P
$tsenv:dartTicket = $xml.e.a.id
Save-PSDVariables | Out-Null

if (-not ($DartInfos)) {
	Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): No dartinfos..."
}
Write-PSDLog -Message "$($MyInvocation.MyCommand.Name): tsenv:EventService [$tsenv:EventService], tsenv:dartIp [$tsenv:dartIp], tsenv:dartPort [$tsenv:dartPort], tsenv:dartTicket [$tsenv:dartTicket]"

Write-PSDEvent -MessageID 41016 -severity 4 -Message "PSD sending DaRT infos..."

Stop-PSDLogging


if ($Debug) {
	Wait-Debugger
	Read-Host "Press enter to continue..."
}

I had to modify the script slightly, hope nothing broke. Add the script to the Prestart folder ("\PSDResources\Prestart\Start-DaRT.ps1") and make sure it is started by editing the unattend.xml for WinPE (Templates\Unattend_PE_x64.xml) - this way the script is added to the WinPE and started automatically before the deployment scripts kick in. Of course you can also use the Prestart functionallity of Powershell Deployment instead of editing the unattend.xml

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
            <Display>
                <ColorDepth>32</ColorDepth>
                <HorizontalResolution>1280</HorizontalResolution>
                <RefreshRate>60</RefreshRate>
                <VerticalResolution>720</VerticalResolution>
            </Display>
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Description>Set PowerShell execution policy</Description>
                    <Order>1</Order>
                    <Path>reg.exe add HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v ExecutionPolicy /t REG_SZ /d Unrestricted /f</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Description>Enable PowerShell scripts</Description>
                    <Order>2</Order>
                    <Path>reg.exe add HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v EnableScripts /t REG_DWORD /d 1 /f</Path>
                </RunSynchronousCommand>
		<RunSynchronousCommand wcm:action="add">
                    <Description>Run Start-DaRT.ps1</Description>
                    <Order>3</Order>
                    <Path>powershell.exe -noprofile -windowstyle hidden -file "X:\Deploy\Prestart\Start-DaRT.ps1"</Path>
                </RunSynchronousCommand>
		<RunSynchronousCommand wcm:action="add">
                    <Description>Run PSDStart.ps1</Description>
                    <Order>4</Order>
                    <Path>powershell.exe -noprofile -windowstyle hidden -file X:\Deploy\Scripts\PSDStart.ps1</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
</unattend>

(A small issue I haven't solved yet is that the computer name field at this point in time is empty. So the first time the client contacs the server the computer name column in the MDT workbench will be empty.)

Now you still have to add the DaRT files to the MDT workbench and set the checkbox in the workbench, so they are added to the WinPE image. And you have to start the monitoring service. Both works the same way it did in MDT. The script for starting DaRT is based on some scripts Johan Arwidmark wrote: https://github.com/DeploymentResearch/DRFiles/tree/master/Scripts/EnableDaRT especially this one: https://github.com/DeploymentResearch/DRFiles/blob/master/Scripts/EnableDaRT/EnableDart.wsf

ASlowTurtle avatar Jun 02 '23 10:06 ASlowTurtle

Thanks for this. @GeoSimos is this on the roadmap?

JerichoJones avatar Mar 08 '24 19:03 JerichoJones

@JerichoJones as far as I know, there is no discussion for its inclusion yet, but I can ask.

GeoSimos avatar Mar 09 '24 15:03 GeoSimos

That would be great! Thanks.

On Sat, Mar 9, 2024 at 10:19 AM George Simos @.***> wrote:

@JerichoJones https://github.com/JerichoJones as far as I know, there is no discussion for its inclusion yet, but I can ask.

— Reply to this email directly, view it on GitHub https://github.com/FriendsOfMDT/PSD/issues/83#issuecomment-1986883655, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADEYBYIKZMJKYGVB4T2EWSDYXMSATAVCNFSM6AAAAAAXXEC3HOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBWHA4DGNRVGU . You are receiving this because you were mentioned.Message ID: @.***>

JerichoJones avatar Mar 09 '24 17:03 JerichoJones

That would be great! Thanks. On Sat, Mar 9, 2024 at 10:19 AM George Simos @.> wrote: @JerichoJones https://github.com/JerichoJones as far as I know, there is no discussion for its inclusion yet, but I can ask. — Reply to this email directly, view it on GitHub <#83 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADEYBYIKZMJKYGVB4T2EWSDYXMSATAVCNFSM6AAAAAAXXEC3HOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBWHA4DGNRVGU . You are receiving this because you were mentioned.Message ID: @.>

It looks that some functionality is getting implemented in the Prestart Menu on the dev branch (graphical buttons on the information screen): The Prestartmenu launches a menu within the boot sequence that provides other menus such as diskinfo, diskwipe, and static ip configuration. It can also detect if DART is installed in PE and will display a button for it.

GeoSimos avatar Mar 18 '24 20:03 GeoSimos

Thanks for the update

JerichoJones avatar Mar 22 '24 18:03 JerichoJones

@ASlowTurtle I had to modify settings.xml to get dart installed in WinPE_x64. I added Dart8 as shown below. Thanks!

<Boot.x64.FeaturePacks>winpe-mdac,dart8</Boot.x64.FeaturePacks>

JerichoJones avatar Apr 01 '24 22:04 JerichoJones

Since ADK no longer supports x86, MDT crashes when opening the WinPE tab (because it defaults to x86 first). It crashes because it is looking for the x86 WinPE_OCs folder in the ADK install directory; as a work around, run the command on same system where ADK is installed:

Mkdir "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\WinPE_OCs"

Then reopen Deployment Workbench. You can now navigate to that window and select DaRT as an option (of course the Tools.cab file needs to be copied to the Tools\x64 folder).

image

You don't need to select the other items such as .Net,, PowerShell and many others, as PSD will add those automatically. You can review the components in the Templates\LitetouchPE.xml file.

PowerShellCrack avatar Apr 02 '24 11:04 PowerShellCrack

I don't have a crashing problem. DaRT didn't show up as selectable under x64 until I made the change. This server has been running MDT x64 for many years and has been upgraded a few times. Maybe I got lucky.

JerichoJones avatar Apr 02 '24 19:04 JerichoJones

Now that I DaRT working I'm trying to find where the VM Connection button is defined so I can point it at DaRT.

JerichoJones avatar Apr 02 '24 19:04 JerichoJones

@mmanous01 the PrestartMenu has been added to the new release as default. There is no DART Remote start that I am aware of though besides using the script above.

PowerShellCrack avatar Sep 16 '24 01:09 PowerShellCrack

@JerichoJones did you ever find the VM connection button definition? I'm curious how that works if PSD is over HTTP/HTTPS

PowerShellCrack avatar Sep 16 '24 01:09 PowerShellCrack

No

JerichoJones avatar Jan 01 '25 19:01 JerichoJones