Need help to run a power shell script with in the Invoke-AppDeployToolkit.ps1 for V4

Hi,

I have been looking for a help to create a Intune package to run one of my power shell script for user Interaction with defer prompts…

I have been following the v4 document by adding the Start-ADTProcess to run my power shell script with in the Invoke-AppDeployToolkit.ps1 but it is failed (attached the script and error message)

1 Like

Looking at the error message, it looks like the ‘Upgrade_Windows.ps1’ script being called is probably executing an application that is not valid for the OS platform you are executing it on…
We may need a bit more info to help
What Operating System are you running this on and is it an x86 (32-bit), x64 (64-bit) or ARM64 (64-bit) version?
Do you know what the app is that is being called?
Is this app supported on the architecture or OS of the machine where you are running it?

Thanks for the reply.
What Operating System are you running this on and is it an x86 (32-bit), x64 (64-bit) or ARM64 (64-bit) version? Windows 10 x64
Do you know what the app is that is being called? it’s a power shell script

Is this app supported on the architecture or OS of the machine where you are running it? Yes. I have tested script manully on the traget device.

I am curious to know how to run a powershell script in PSADPT newer version.

I think you misunderstood, I can see that it calls a PowerShell script, but what is the App that the PowerShell script is running....
I think your Screen grab of the comment section from the code gives some clues on lines 18 and 19
If you are allowed to share the script, it might be helpful to paste a copy of the contents using the Preformatted Text button on the toolbar <\>
Paste your code between the two lines of 3 `
It gives us an idea what your code is doing

1 Like
# ---------------------------------------------------------------------------------------------------
#  Begin Parameter Definitions (user-overridable)
# ---------------------------------------------------------------------------------------------------
param (
    [string]$Win11WorkingDirectory = "C:\Temp\Win11",
    # IMPORTANT: Set $ServiceUIPath to your own Azure Blob Storage URL containing ServiceUI.exe
    # OR
    # Place ServiceUI.exe in the root of your Win32 package and set this to: "$PSScriptRoot\ServiceUI.exe"
    # (This script does NOT host or provide ServiceUI.exe.)
    [string]$ServiceUIPath = "$PSScriptRoot\ServiceUI.exe",
    [int]$MinRequiredFreeSpaceGB = 30
)
# ---------------------------------------------------------------------------------------------------
#  End Parameter Definitions (user-overridable)
# ---------------------------------------------------------------------------------------------------


# ---------------------------------------------------------------------------------------------------
# Relaunch Script in 64-bit PowerShell (if currently running in 32-bit on x64 system)
# ---------------------------------------------------------------------------------------------------
if ("$env:PROCESSOR_ARCHITEW6432" -ne "ARM64") {
    Write-Host "Not on ARM64"
    if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe") {   

        
        # Relaunch as 64-bit
        & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath"
        
        Write-Host "Relaunched as a 64-bit process"
        Exit $lastexitcode
    }
}


# ------------------------------------
# Begin Defining Script Variables
# ------------------------------------

# ------------------------------------
# Script Version Info
# ------------------------------------
[int]$ScriptVersion = 26


# ========================================
# Variables: Logging
# ========================================
$Now = Get-Date -Format MM-dd-yyyy-HH-mm-ss
$LogFile = "C:\Windows\Logs\Win11_Upgrade-$Now.log"
$DriverLog = "C:\Windows\Logs\UnsignedPrinterDrivers.csv"
$TranscriptFile = "C:\Windows\Logs\Win11_Upgrade_Transcript-$Now.log"
Start-Transcript -Path $TranscriptFile
Write-Host "Starting upgrade using script version: $($ScriptVersion)"


# ========================================
# Variables: Script Configuration
# ========================================
$upgradeArgs = "/quietinstall /skipeula /auto upgrade /copylogs $Win11WorkingDirectory"


# ========================================
# Languages to keep (use RFC 5646 format)
# Use a comma seperated list if you need more languages
# ========================================
$PreserveLanguages = @('en-US')


# ========================================
# Variables: ServiceUI
# ========================================
$ServiceUIDestination = "$Win11WorkingDirectory\ServiceUI.exe"


# ========================================
# Variables: Used for the compat appraiser
# ========================================
$CompatAppraiserPath = 'C:\Windows\system32\CompatTelRunner.exe'
$RegistryPathAppCompat = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\TargetVersionUpgradeExperienceIndicators\'
$RegValueGStatus = 'GStatus'
$RegValueUpgEx = 'UpgEx'
$RegValueRedReason = 'RedReason'


# ========================================
# Variables: For idle process check (mostly unused since v21)
# ========================================
$monitoredExeName = "windows10upgraderapp.exe"
$monitoredProcName = [System.IO.Path]::GetFileNameWithoutExtension($monitoredExeName)
[int]$cpuIdleThresholdMinutes = 5
[int]$timeoutSeconds = 7200
[int][int]$checkIntervalSeconds = 15
$elapsedSeconds = 0
[int]$checkIntervalSeconds = 15
[int]$maxWaitSeconds = 7200  # 2 hours


# ========================================
# Variables: Default time (min) to sleep when calling sleepNow function
# ========================================
[int]$sleepTime = 30

# ------------------------------------
# End Defining Script Variables
# ------------------------------------

# Create the working directory if it doesn't exist
if (-not (Test-Path $Win11WorkingDirectory)) {
    mkdir $Win11WorkingDirectory
}
 

# Make sure that we are not already in Windows 11
$isWin11 = (Get-WmiObject Win32_OperatingSystem).Caption -Match "Windows 11"

if ($isWin11) {
    write-host "Windows 11"
    Stop-Transcript
    Exit 0
}
Else {
    write-host  "We are in Windows 10."
   
    # ------------------------------------
    # Begin Functions
    # ------------------------------------

    function LogMessage {
        <#
    .SYNOPSIS
    Writes a formatted log message to both the console and a persistent log file, including the line number.

    .DESCRIPTION
    Logs messages with timestamp, severity level (INFO, WARN, ERROR), component name, and the script line number.

    .PARAMETER Message
    The message text to log.

    .PARAMETER Component
    An optional label for the log source (e.g., a function name). Defaults to 'Script'.

    .PARAMETER Type
    1 = INFO, 2 = WARN, 3 = ERROR

    .OUTPUTS
    Writes to both screen and $LogFile
    #>

        param (
            [Parameter(Mandatory = $true)]
            [string]$Message,

            [string]$Component = "Script",

            [ValidateSet('1', '2', '3')]
            [int]$Type = 1
        )

        $timeStamp = Get-Date -Format "HH:mm:ss"
        $dateStamp = Get-Date -Format "yyyy-MM-dd"
        $levelText = switch ($Type) {
            1 { "INFO" }
            2 { "WARN" }
            3 { "ERROR" }
        }

        # Try to get line number from call stack
        $callStack = Get-PSCallStack
        $caller = if ($callStack.Count -gt 1) { $callStack[1] } else { $null }
        $lineInfo = if ($caller) { "Line $($caller.ScriptLineNumber)" } else { "Line ?" }

        $formattedMessage = "[${dateStamp} ${timeStamp}] [$levelText] [$Component] [$lineInfo] $Message"

        # Output to console with color
        switch ($Type) {
            1 { Write-Host $formattedMessage -ForegroundColor Gray }
            2 { Write-Host $formattedMessage -ForegroundColor Yellow }
            3 { Write-Host $formattedMessage -ForegroundColor Red }
        }

        # Always write to file
        $formattedMessage | Out-File -FilePath $LogFile -Append -Encoding UTF8
    }

    
    function Clean-Drivers {
        <#
        .SYNOPSIS
        Detects and removes unsigned Microsoft printer drivers that may block Windows 11 upgrades.

        .DESCRIPTION
        This function scans all installed printer drivers, identifies those published by Microsoft that are unsigned, 
        and removes them along with any associated printers. It then reinstalls built-in Microsoft virtual printers 
        (such as Microsoft Print to PDF and XPS Document Writer) if they were removed. 

        Unsigned drivers are logged to a CSV file for reference.

        .OUTPUTS
        None. Writes log entries and exports a CSV of unsigned drivers to $driverLog.

        .NOTES
        This remediation targets known upgrade blocks related to legacy unsigned Microsoft print drivers 
        (e.g., Type 3 kernel-mode drivers).
        #>
        Write-Host "Scanning installed printer drivers..."
        $unsignedDrivers = @()
        $removedDrivers = @()
        Get-PrinterDriver | ForEach-Object {
            $driver = $_
            $driverName = $driver.Name

            # Get detailed info from Win32_PrinterDriver
            $wmiDriver = Get-WmiObject -Query "SELECT * FROM Win32_PrinterDriver WHERE Name = '$driverName'" -ErrorAction SilentlyContinue

            if ($wmiDriver -and $wmiDriver.DriverPath -and (Test-Path $wmiDriver.DriverPath)) {
                $sig = Get-AuthenticodeSignature -FilePath $wmiDriver.DriverPath

                if ($sig.Status -ne 'Valid' -and $driver.Publisher -like '*Microsoft*') {
                    LogMessage -message ("Unsigned Microsoft driver found: $driverName")
                    $unsignedDrivers += [PSCustomObject]@{
                        DriverName      = $driverName
                        DriverPath      = $wmiDriver.DriverPath
                        SignatureStatus = $sig.Status
                        Publisher       = $driver.Publisher
                    }
                }
            }
        }

        # Log results
        if ($unsignedDrivers.Count -gt 0) {
            $unsignedDrivers | Export-Csv -Path $driverLog -NoTypeInformation
            LogMessage -message ("Logged unsigned drivers to $driverLog") -Type 1 -Component 'Clean-Drivers'

            # Remove associated printers first
            LogMessage -message ("Removing printers using unsigned drivers...") -Type 1 -Component 'Clean-Drivers'
            Get-Printer | Where-Object { $_.DriverName -in $unsignedDrivers.DriverName } | ForEach-Object {
                LogMessage -message (" - > Removing printer: $($_.Name)") -Type 1 -Component 'Clean-Drivers'
                Remove-Printer -Name $_.Name -ErrorAction SilentlyContinue
            }

            # Remove the unsigned drivers
            LogMessage -message ("Removing unsigned Microsoft printer drivers...") -Type 1 -Component 'Clean-Drivers'
            foreach ($driver in $unsignedDrivers) {
                LogMessage -message ("  -> Removing driver: $($driver.DriverName)") -Type 1 -Component 'Clean-Drivers'
                Remove-PrinterDriver -Name $driver.DriverName -ErrorAction SilentlyContinue
                $removedDrivers += $driver.DriverName
            }

            # Conditionally reinstall Microsoft virtual printers if removed
            if ($removedDrivers -match "Microsoft Print to PDF") {
                LogMessage -message ("Reinstalling Microsoft Print to PDF...") -Type 1 -Component 'Clean-Drivers'
                Add-WindowsCapability -Online -Name "Printing.PrintToPDF~~~~0.0.1.0" -ErrorAction SilentlyContinue
            }

            if ($removedDrivers -match "Microsoft XPS Document Writer") {
                LogMessage -message ("Reinstalling Microsoft XPS Document Writer...") -Type 1 -Component 'Clean-Drivers'
                Add-WindowsCapability -Online -Name "Printing.XPSServices~~~~0.0.1.0" -ErrorAction SilentlyContinue
            }
        }
        else {
            LogMessage -message ("No unsigned Microsoft printer drivers found.") -Type 1 -Component 'Clean-Drivers'
        }
    }

    function ExtractNumbers([string]$str) {
        <#
        .SYNOPSIS
        Extracts numeric characters from a string and returns them as a long integer.

        .DESCRIPTION
        This utility function removes all non-numeric characters from the input string 
        and returns the result as a 64-bit integer ([long]).

        Used to parse disk or partition numbers from formatted strings 
        (e.g., "harddisk0" → 0).

        .PARAMETER str
        The input string from which to extract numeric digits.

        .OUTPUTS
        System.Int64 (long)

        .EXAMPLE
        ExtractNumbers "harddisk1"  # Returns: 1
        #>
        $cleanString = $str -replace "[^0-9]"
        return [long]$cleanString
    }

    # Define function to check partition style
    Function Get-PartitionStyle {
        $disk = Get-Disk | Where-Object { $_.PartitionStyle -ne "RAW" -and $_.IsBoot -eq $true }
        if (!$disk) {
            LogMessage -Message ("Could not determine the boot disk. Ensure the system is properly configured.") -Type 2 -Component 'Get-PartitionStyle'
            return
        }
        return $disk.PartitionStyle
    }
    
    function IsProcessIdle {
        <#
        .SYNOPSIS
        Waits for a process to remain below 1% real-time CPU usage for a defined period.

        .DESCRIPTION
        Uses Get-Counter to poll the process’s % Processor Time every few seconds. If CPU usage stays
        under 1% for the full IdleMinutes threshold, or if the process exits, the function returns $true.
        If MaxWaitSeconds is reached first, the function returns $false.

        .PARAMETER ProcessName
        The name of the process to monitor (without ".exe").

        .PARAMETER ExpectedPathPart
        Optional. A partial string to match in the process path.

        .PARAMETER IdleMinutes
        The number of continuous minutes the process must remain under 1% CPU usage.

        .PARAMETER MaxWaitSeconds
        The maximum number of seconds to wait before timing out.

        .PARAMETER checkIntervalSeconds
        Interval between checks. Default: 15 seconds.

        .OUTPUTS
        [bool] - $true if idle threshold met or process exited; $false if timed out.

        .EXAMPLE
        if (IsProcessIdle -ProcessName "SetupHost" -ExpectedPathPart "\$WINDOWS.~BT\Sources") {
            LogMessage -message "SetupHost.exe confirmed idle"
        }
        #>

        param (
            [string]$ProcessName,
            [string]$ExpectedPathPart = $null,
            [int]$IdleMinutes = 5,
            [int]$MaxWaitSeconds = 7200,
            [int]$checkIntervalSeconds = 15
        )

        $idleSeconds = 0
        $waitSeconds = 0

        while ($waitSeconds -lt $MaxWaitSeconds) {
            $process = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue | Where-Object {
                if ($ExpectedPathPart) {
                    try { $_.Path -like "*$ExpectedPathPart*" } catch { $false }
                }
                else {
                    $true
                }
            }

            if (-not $process) {
                return $true  # Treat as idle if process exited
            }

            try {
                $counterPath = "\Process($ProcessName*)\% Processor Time"
                $cpuUsage = (Get-Counter -Counter $counterPath -ErrorAction Stop).CounterSamples.CookedValue
                $cpuAvg = [math]::Round(($cpuUsage | Measure-Object -Average).Average, 2)

                if ($cpuAvg -lt 1) {
                    $idleSeconds += $checkIntervalSeconds
                    if ($idleSeconds -ge ($IdleMinutes * 60)) {
                        return $true
                    }
                }
                else {
                    $idleSeconds = 0
                }
            }
            catch {
                # Handle cases where Get-Counter fails (e.g., instance not found)
                LogMessage -message "Failed to sample CPU for $($ProcessName): $($_.Exception.Message)" -Type 3 -Component 'Upgrade'
                $idleSeconds = 0
            }

            Start-Sleep -Seconds $checkIntervalSeconds
            $waitSeconds += $checkIntervalSeconds
        }

        LogMessage -message "$ProcessName did not become idle in time. Max wait of $($MaxWaitSeconds / 60) minutes exceeded." -Type 3 -Component 'Upgrade'
        return $false
    }


    function SleepNow {
        <#
    .SYNOPSIS
    Pauses script execution for a specified number of minutes with periodic logging.

    .DESCRIPTION
    This function puts the script to sleep for a given number of minutes. During the sleep,
    it logs a message every 60 seconds showing the remaining time, and then logs a final 
    message when the wait period is over.

    .PARAMETER Length
    The number of minutes to sleep.

    .OUTPUTS
    None. This function is used for timing and logging purposes only.

    .EXAMPLE
    SleepNow -Length 15
    Logs a message every minute for 15 minutes, then logs "Time to wake up sleepy head!".
    #>

        param (
            [Parameter(Mandatory = $true)]
            [int]$Length  # Length in minutes
        )

        $totalSeconds = $Length * 60
        $remaining = $totalSeconds

        while ($remaining -gt 0) {
            Start-Sleep -Seconds 60
            $remaining -= 60

            if ($remaining -gt 0) {
                $minutes = [int]($remaining / 60)
                $seconds = $remaining % 60
                LogMessage -message ("Sleeping for another $minutes min and $seconds second") -Component 'SleepNow'
            }
        }

        LogMessage -message ("Time to wake up sleepy head!") -Component 'SleepNow'
    }


    function DisplayPartitionInfo([string[]]$partitionPath) {
        <#
        .SYNOPSIS
        Retrieves and logs partition size and free space for a given partition path.

        .DESCRIPTION
        Uses WMI (Win32_Volume) to find the volume associated with the provided device path(s).
        Logs total capacity and available free space, and returns both values as a two-element array.

        Used during WinRE analysis or resizing to understand disk layout and available space.

        .PARAMETER partitionPath
        An array of partition access paths (e.g., {"\\?\Volume{...}\"}).

        .OUTPUTS
        System.Object[]
        Returns an array: [TotalSize (bytes), FreeSpace (bytes)]

        .EXAMPLE
        DisplayPartitionInfo "\\?\Volume{abc123}\"
        # Logs and returns: 500107862016, 120034467840
        #>
        $volume = Get-WmiObject -Class Win32_Volume | Where-Object { $partitionPath -contains $_.DeviceID }
        LogMessage -message ("  Partition capacity: " + $volume.Capacity) -Type 1 -Component 'DisplayPartitionInfo'
        LogMessage -message ("  Partition free space: " + $volume.FreeSpace) -Type 1 -Component 'DisplayPartitionInfo'
        return $volume.Capacity, $volume.FreeSpace
    } 
    
    function Backup-WinRE {
        <#
    .SYNOPSIS
    Backs up WinRE.wim and ReAgent.xml to C:\WinRE_Backup.

    .DESCRIPTION
    Copies both the recovery image (WinRE.wim) and configuration file (ReAgent.xml)
    to C:\WinRE_Backup. Logs actions and returns $true if both backups succeed.

    .OUTPUTS
    [bool] - $true if both files were backed up, otherwise $false.
    #>

        $sourceWim = "$env:SystemRoot\System32\Recovery\WinRE.wim"
        $sourceXml = "$env:SystemRoot\System32\Recovery\ReAgent.xml"
        $backupFolder = "C:\WinRE_Backup"
        $backupWim = Join-Path $backupFolder "WinRE.wim"
        $backupXml = Join-Path $backupFolder "ReAgent.xml"

        if (!(Test-Path $backupFolder)) {
            New-Item -Path $backupFolder -ItemType Directory | Out-Null
        }

        $success = $true

        if (Test-Path $sourceWim) {
            try {
                Copy-Item -Path $sourceWim -Destination $backupWim -Force
                LogMessage -message "Backed up WinRE.wim to $backupWim" -Component 'Backup-WinRE'
            }
            catch {
                LogMessage -message "Failed to back up WinRE.wim: $($_.Exception.Message)" -Type 3 -Component 'Backup-WinRE'
                $success = $false
            }
        }
        else {
            LogMessage -message "No WinRE.wim found at $sourceWim to back up" -Type 2 -Component 'Backup-WinRE'
            $success = $false
        }

        if (Test-Path $sourceXml) {
            try {
                Copy-Item -Path $sourceXml -Destination $backupXml -Force
                LogMessage -message "Backed up ReAgent.xml to $backupXml" -Component 'Backup-WinRE'
            }
            catch {
                LogMessage -message "Failed to back up ReAgent.xml: $($_.Exception.Message)" -Type 3 -Component 'Backup-WinRE'
                $success = $false
            }
        }
        else {
            LogMessage -message "No ReAgent.xml found at $sourceXml to back up" -Type 2 -Component 'Backup-WinRE'
            # not fatal, continue
        }

        return $success
    }

    function Restore-WinRE {
        <#
    .SYNOPSIS
    Restores the WinRE.wim and ReAgent.xml files from backup if they were previously saved.

    .DESCRIPTION
    Copies the backed-up WinRE image and configuration file from C:\WinRE_Backup to their original system locations
    in C:\Windows\System32\Recovery. Re-registers the WinRE image using ReAgentC.

    .OUTPUTS
    [bool] - $true if restore and re-registration were successful, otherwise $false.
    #>

        $backupFolder = "C:\WinRE_Backup"
        $backupWim = Join-Path $backupFolder "WinRE.wim"
        $backupXml = Join-Path $backupFolder "ReAgent.xml"
        $recoveryFolder = "$env:SystemRoot\System32\Recovery"
        $targetWim = Join-Path $recoveryFolder "WinRE.wim"
        $targetXml = Join-Path $recoveryFolder "ReAgent.xml"

        $restoreSuccess = $true

        # --- Restore WinRE.wim ---
        if (-not (Test-Path $targetWim) -and (Test-Path $backupWim)) {
            try {
                Copy-Item -Path $backupWim -Destination $targetWim -Force
                LogMessage -message "Restored WinRE.wim to $targetWim" -Component 'Restore-WinRE'
            }
            catch {
                LogMessage -message "Failed to restore WinRE.wim: $($_.Exception.Message)" -Type 3 -Component 'Restore-WinRE'
                $restoreSuccess = $false
            }
        }
        elseif (-not (Test-Path $backupWim)) {
            LogMessage -message "Backup WinRE.wim not found at $backupWim" -Type 3 -Component 'Restore-WinRE'
            $restoreSuccess = $false
        }
        else {
            LogMessage -message "WinRE.wim already exists at $targetWim — no restore needed." -Component 'Restore-WinRE'
        }

        # --- Restore ReAgent.xml ---
        if (-not (Test-Path $targetXml) -and (Test-Path $backupXml)) {
            try {
                Copy-Item -Path $backupXml -Destination $targetXml -Force
                LogMessage -message "Restored ReAgent.xml to $targetXml" -Component 'Restore-WinRE'
            }
            catch {
                LogMessage -message "Failed to restore ReAgent.xml: $($_.Exception.Message)" -Type 2 -Component 'Restore-WinRE'
                # not fatal
            }
        }
        elseif (Test-Path $targetXml) {
            LogMessage -message "ReAgent.xml already exists at $targetXml — no restore needed." -Component 'Restore-WinRE'
        }

        # --- Re-register WinRE image if WIM is now present ---
        if (Test-Path $targetWim) {
            try {
                $output = ReAgentC.exe /setreimage /path $recoveryFolder /target $env:SystemRoot 2>&1
                if ($LASTEXITCODE -eq 0) {
                    LogMessage -message "ReAgentC /setreimage successful. Output:`n$($output -join "`n")" -Component 'Restore-WinRE'
                }
                else {
                    LogMessage -message "ReAgentC /setreimage failed. Output:`n$($output -join "`n")" -Type 3 -Component 'Restore-WinRE'
                    $restoreSuccess = $false
                }
            }
            catch {
                LogMessage -message "Exception occurred during ReAgentC /setreimage: $($_.Exception.Message)" -Type 3 -Component 'Restore-WinRE'
                $restoreSuccess = $false
            }
        }
        else {
            LogMessage -message "WinRE.wim is still missing at $targetWim. Cannot re-register." -Type 3 -Component 'Restore-WinRE'
            $restoreSuccess = $false
        }

        return $restoreSuccess
    }


Thanks, So I can see that your Upgrade_Windows.ps1 script can execute a number of different executables (.exe) files during it’s run.
I’ve found references to 6 (different) .exe’s in the script on:
Line 11 [string]$ServiceUIPath = "$PSScriptRoot\ServiceUI.exe",
Line 28 & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath"
Line 72 $ServiceUIDestination = "$Win11WorkingDirectory\ServiceUI.exe"
Line 78 $CompatAppraiserPath = 'C:\Windows\system32\CompatTelRunner.exe'
Line 88 $monitoredExeName = "windows10upgraderapp.exe"
Line 579 $output = ReAgentC.exe /setreimage /path $recoveryFolder /target $env:SystemRoot 2>&1

It could be anyone of these executables that is triggering the original error

I may not have access to all the executables you are calling , so I can’t test this script fully.

But, If you leave PSADT out of the equation, Are you able to run this script successfully (as an admin) on a test machine (a sandbox for example)?
It would be useful to know which executable it is tripping up over.
I have a suspicion it maybe one of the last 3 listed above - The last one ReAgentC.exe is part of the Windows Recovery Environment so may only work inside Windows PE (Pre-execution Environment).

I’d suggest you go away and get the script working properly outside of PSADT before asking for PSADT help

I think the issue is more that you’re doing something like Start-ADTProcess -FilePath .\SomeRandomVoodooScript.ps1, instead of Start-ADTProcess -FilePath powershell.exe -ArgumentList "-File "$($adtSession.DirFiles)\SomeRandomVoodooScript.ps1"

1 Like

Thanks for reviewing the script…
Yes I have tried this script as a Admin without PSAPDT. It is working as expected and my windows 10 device got upgraded to windows 11 (while user log in).

You may get the full script from github here below
GitHub - PowerStacks-BI/UpgradeWindows: PowerShell script to perform an in-place upgrade of Windows 10 to Windows 11.

Meanwhile will try the below solution.
" I think the issue is more that you’re doing something like Start-ADTProcess -FilePath .\SomeRandomVoodooScript.ps1 , instead of Start-ADTProcess -FilePath powershell.exe -ArgumentList "-File "$($adtSession.DirFiles)\SomeRandomVoodooScript.ps1"

Thanks for jumping on it. I will try to change the command line but I don’t see any -File parameter in Start-ADTProcess syntax. Will this be help here?

Just noticed the missing closing double quote and the need to escape the extra pair of double quotes - So try this:

Start-ADTProcess -FilePath powershell.exe -ArgumentList "-File `"$($adtSession.DirFiles)\SomeRandomVoodooScript.ps1`""
3 Likes

I will check and update. Is the source power shell file should be in root or files folder?

My collegue used this after he had some troubles with the quotes. He asked ChatGPT and this finally worked.

Start-ADTProcess -FilePath "powershell.exe" -ArgumentList @("-WindowStyle", "Hidden", "-File", "E:\Apps\winlogbeat-8.17.2-windows-x86_64\install-service-winlogbeat.ps1")

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.