Windows Splash Screen for the Task Sequence Progress

image

image

image

Lets face it, the Task Sequence progress bar is dated.  Does it work and serve a purpose, yes, does it look like Windows 98, heck yeah.

image
Picture credit: Adam Gross

As part of my quest to modernize it, I first google, found a couple good options:

I based it on Option 2, SMSAgents, it didn’t require an install, which we’d have to jump through hoops for, but scripts we can run all day.  Yeah, I also see some bad logic there.. but moving along…
Since I’ve based it on SMSAgent’s Script, PLEASE PLEASE read his post, it goes into more information that I’m not going to regurgitate here.

Changes I’ve made:

  • Made the text continue to loop entire time running
  • Added Step Names
  • Added Windows Upgrade Engine %
  • Have it Exit script if TS has Error and launches Error Dialog
  • Running it as System instead of User
    • Allow to pull in Task Sequence Variables
    • Changes many of the options to TS variables
      • Rotating Text
      • Color Scheme

I wanted it to be run during our in place upgrades, but it also works during OSD.  I have it monitor the setup engine to display a % during the upgrade, something CM Dialogs also added in 1902, however I’ve added a % complete vs just a status bar.  Glad they added it though!
Example task sequence progress with Windows upgrade progress

How it works… it’s a Task Sequence “Module”
image
Variables for each Text Line, SA_001 ….
The script will grab all variables and create an array of any variable values that the variable name starts with “SA_”

image
The color scheme is also created via variables.

Having a group with both of these sets, allows you to have different text and or color scheme during different task sequences.

image
Then we launch the script that creates the splash screen, using ServiceUI to make it show on the user’s screen.  Lastly, we disable the native progress UI.

The Splash Screen will now continue until:

  • Manual intervention: Alt + F4
    • This is really handy when you are doing testing, thankfully most users will probably never try this.
  • Error code. If step name = “Launch Custom Dialog”, it will exit the Script.  We are using error handling based on Adam Gross’s Better TS, which goes into more detail.
  • A reboot. (AKA end of Phase one which auto reboots)

Upgrade % Complete.  The Script monitors the step names, when the step name: “Upgrade Operating System. DO NOT TURN OFF YOUR PC”, once that step is triggered, it activates the “textbox” that monitors and updates the Setup Engine % Complete.

In the Parent TS:
image

I have a lot of notes in the actual script, hopefully everything makes sense.
You’ll need to modify a few items to match the name of the steps, or rename steps in your TS to match the script, it’s up to you.

After MMS, mid-may, I’ll be uploading the entire Upgrade Task Sequence Group, 19 Task Sequences in all.

To implement, grab SMSAgent’s download which includes all of the required pieces. So if you haven’t read his blog yet do it NOW, then download his version, and replace one file with this:

Script: Create-FullScreenBackground.ps1

NOTE, there is an updated script(s) in the WaaS Download, it fixes and issue as mentioned here: https://smsagent.blog/2020/03/12/windows-10-splash-screen-issue-fixed-for-w10-1909-configmgr-task-sequence/

<# 
 2019-08-09 - Fixed Typo - Thanks @SuneThomsenDK
 2019-03-20 Modified by @gwblok
 Added Several Text Boxes  (3 & 4)
 Text Box 3 = TS Step Name (Pulled from TS Variable)
 Text Box 4 = Windows Setup Engine % Complete (Pulled from Registry)

 This now pulls in the Rotating Text from the Task Sequence variables.. use "Set Dynamic Task Sequence Variable" Step, then create as many as you like.
  - Variable Name must start with SA_ ex: (SA Splash Array)
    SA_001 This Line never actually displays
    SA_002 We're upgrading you to Windows 10 %SMSTS_BUILD%
    SA_003 It may take 60 - 120 minutes
    WindowBackGroundDefault
 This now pulls colors from the Task Sequence variables as well. Example TS Vars SC_ (SC Splash Color)
    SC_WindowBackGroundDefault = Default Color of Back Ground
    SC_ColourBrighterAnimation1 = Starting Color -> Fades to SC_ColourBrighterAnimation2
    SC_ColourBrighterAnimation2
    SC_ColourDarkerAnimation1 = Starting Color -> Fades to SC_ColourDarkerAnimation2
    SC_ColourDarkerAnimation2

        SC_ColourBrighterAnimation1 Should be set the same as SC_ColourDarkerAnimation2
        SC_ColourBrighterAnimation2 Should be set the same as SC_ColourDarkerAnimation1

 SMSAgent https://smsagent.blog/2018/08/21/create-a-custom-splash-screen-for-a-windows-10-in-place-upgrade/
 Creates a full screen 'background' styled for a Windows 10 upgrade, and hides the task bar
 Called by the "Show-OSUpgradeBackground" script
#>

Param($DeviceName)

try
{
    $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
    #New-Item C:\temp\ScreenBackground.log -ItemType File
}
catch
{
	Write-Verbose "Not running in a task sequence."
}

# Add required assemblies
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase,System.Windows.Forms,System.Drawing
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
Add-Type -Path "$PSSCriptRoot\bin\MahApps.Metro.dll"
Add-Type -Path "$PSSCriptRoot\bin\System.Windows.Interactivity.dll"

# Find screen by DeviceName
$Screens = [System.Windows.Forms.Screen]::AllScreens
$Screen = $Screens | Where {$_.DeviceName -eq $DeviceName}

# Add custom type to hide the taskbar
# Thanks to https://stackoverflow.com/questions/25499393/make-my-wpf-application-full-screen-cover-taskbar-and-title-bar-of-window
$Source = @"
using System;
using System.Runtime.InteropServices;

public class Taskbar
{
    [DllImport("user32.dll")]
    private static extern int FindWindow(string className, string windowText);
    [DllImport("user32.dll")]
    private static extern int ShowWindow(int hwnd, int command);

    private const int SW_HIDE = 0;
    private const int SW_SHOW = 1;

    protected static int Handle
    {
        get
        {
            return FindWindow("Shell_TrayWnd", "");
        }
    }

    private Taskbar()
    {
        // hide ctor
    }

    public static void Show()
    {
        ShowWindow(Handle, SW_SHOW);
    }

    public static void Hide()
    {
        ShowWindow(Handle, SW_HIDE);
    }
}
"@
Add-Type -ReferencedAssemblies 'System', 'System.Runtime.InteropServices' -TypeDefinition $Source -Language CSharp

# Find the user identity from the domain if possible
Try
{
    $PrincipalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::Domain, [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain())
    $GivenName = ([System.DirectoryServices.AccountManagement.Principal]::FindByIdentity($PrincipalContext,[System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName,[Environment]::UserName)).GivenName
    $PrincipalContext.Dispose()
}
Catch {}

# Create a WPF window
$Window = New-Object System.Windows.Window
if ($TSENV){$window.Background = $tsenv.Value('SC_WindowBackGroundDefault')}
Else{$window.Background = "#012a47"}
$Window.WindowStyle = [System.Windows.WindowStyle]::None
$Window.ResizeMode = [System.Windows.ResizeMode]::NoResize
$Window.Foreground = [System.Windows.Media.Brushes]::White
$window.Topmost = $True

# Get the bounds of the primary screen
$Bounds = $Screen.Bounds

# Assemble a grid
$Grid = New-object System.Windows.Controls.Grid
$Grid.Width = "NaN"
$Grid.Height = "NaN"
$Grid.HorizontalAlignment = "Stretch"
$Grid.VerticalAlignment = "Stretch"

# Add a column
$Column = New-Object System.Windows.Controls.ColumnDefinition
$Grid.ColumnDefinitions.Add($Column)

# Add rows
$Row = New-Object System.Windows.Controls.RowDefinition
$Row.Height = "1*"
$Grid.RowDefinitions.Add($Row)
$Row = New-Object System.Windows.Controls.RowDefinition
$Row.Height = [System.Windows.GridLength]::Auto
$Grid.RowDefinitions.Add($Row)
$Row = New-Object System.Windows.Controls.RowDefinition
$Row.Height = [System.Windows.GridLength]::Auto
$Grid.RowDefinitions.Add($Row)
$Row = New-Object System.Windows.Controls.RowDefinition
$Row.Height = "1*"
$Grid.RowDefinitions.Add($Row)

# Add a progress ring
$ProgressRing = [MahApps.Metro.Controls.ProgressRing]::new()
$ProgressRing.Opacity = 0
$ProgressRing.IsActive = $false
$ProgressRing.Margin = "0,0,0,60"
$Grid.AddChild($ProgressRing)
$ProgressRing.SetValue([System.Windows.Controls.Grid]::RowProperty,1)

# Add a textblock
$TextBlock = New-Object System.Windows.Controls.TextBlock
If ($GivenName)
{
    $TextBlock.Text = "Hi $GivenName"
}
Else
{
    $TextBlock.Text = "Hey Team Member"
}
$TextBlock.TextWrapping = [System.Windows.TextWrapping]::Wrap
$TextBlock.MaxWidth = $Bounds.Width
$TextBlock.Margin = "0,0,0,120"
$TextBlock.FontSize = 50
$TextBlock.FontWeight = [System.Windows.FontWeights]::Light
$TextBlock.VerticalAlignment = "Top"
$TextBlock.HorizontalAlignment = "Center"
$TextBlock.Opacity = 0
$Grid.AddChild($TextBlock)
$TextBlock.SetValue([System.Windows.Controls.Grid]::RowProperty,2)

# Add a textblock
$TextBlock2 = New-Object System.Windows.Controls.TextBlock
$TextBlock2.Margin = "0,0,0,60"
$TextBlock2.Text = "Don't turn off your PC"
$TextBlock2.TextWrapping = [System.Windows.TextWrapping]::Wrap
$TextBlock2.MaxWidth = $Bounds.Width
$TextBlock2.FontSize = 25
$TextBlock2.FontWeight = [System.Windows.FontWeights]::Light
$TextBlock2.VerticalAlignment = "Bottom"
$TextBlock2.HorizontalAlignment = "Center"
$TextBlock2.Opacity = 0
$Grid.AddChild($TextBlock2)
$TextBlock2.SetValue([System.Windows.Controls.Grid]::RowProperty,3)

# Add a textblock (@gwblok Change)
$TextBlock3 = New-Object System.Windows.Controls.TextBlock
$TextBlock3.Margin = "0,0,0,120"
$TextBlock3.Text = "Task Sequence Step Should be Here"
$TextBlock3.TextWrapping = [System.Windows.TextWrapping]::Wrap
$TextBlock3.MaxWidth = $Bounds.Width
$TextBlock3.FontSize = 15
$TextBlock3.FontWeight = [System.Windows.FontWeights]::Light
$TextBlock3.VerticalAlignment = "Bottom"
$TextBlock3.HorizontalAlignment = "Center"
$TextBlock3.Opacity = 0
$Grid.AddChild($TextBlock3)
$TextBlock3.SetValue([System.Windows.Controls.Grid]::RowProperty,4)

# Add a textblock (@gwblok Change)
$TextBlock4 = New-Object System.Windows.Controls.TextBlock
$TextBlock4.Margin = "0,0,60,60"
$TextBlock4.Text = "Windows Setup Engine: 0%"
$TextBlock4.TextWrapping = [System.Windows.TextWrapping]::Wrap
$TextBlock4.MaxWidth = $Bounds.Width
$TextBlock4.FontSize = 20
$TextBlock4.FontWeight = [System.Windows.FontWeights]::Light
$TextBlock4.VerticalAlignment = "Bottom"
$TextBlock4.HorizontalAlignment = "Right"
$TextBlock4.Opacity = 0
$TextBlock4.Visibility = 'Hidden'
$Grid.AddChild($TextBlock4)
$TextBlock4.SetValue([System.Windows.Controls.Grid]::RowProperty,5)

# Add to window
$Window.AddChild($Grid)

# Create some animations
if ($TSENV)
    {
    $FadeinAnimation = [System.Windows.Media.Animation.DoubleAnimation]::new(0,1,[System.Windows.Duration]::new([Timespan]::FromSeconds(3)))
    $FadeOutAnimation = [System.Windows.Media.Animation.DoubleAnimation]::new(1,0,[System.Windows.Duration]::new([Timespan]::FromSeconds(3)))
    $ColourBrighterAnimation = [System.Windows.Media.Animation.ColorAnimation]::new($tsenv.Value('SC_ColourBrighterAnimation1'),$tsenv.Value('SC_ColourBrighterAnimation2'),[System.Windows.Duration]::new([Timespan]::FromSeconds(5)))
    $ColourDarkerAnimation = [System.Windows.Media.Animation.ColorAnimation]::new($tsenv.Value('SC_ColourDarkerAnimation1'),$tsenv.Value('SC_ColourDarkerAnimation2'),[System.Windows.Duration]::new([Timespan]::FromSeconds(5)))
    }
Else
    {
    $FadeinAnimation = [System.Windows.Media.Animation.DoubleAnimation]::new(0,1,[System.Windows.Duration]::new([Timespan]::FromSeconds(3)))
    $FadeOutAnimation = [System.Windows.Media.Animation.DoubleAnimation]::new(1,0,[System.Windows.Duration]::new([Timespan]::FromSeconds(3)))
    $ColourBrighterAnimation = [System.Windows.Media.Animation.ColorAnimation]::new("#012a47","#1271b5",[System.Windows.Duration]::new([Timespan]::FromSeconds(5)))
    $ColourDarkerAnimation = [System.Windows.Media.Animation.ColorAnimation]::new("#1271b5","#012a47",[System.Windows.Duration]::new([Timespan]::FromSeconds(5)))
    }



if ($TSENV)
    {
    $TextArrayVars = (New-Object -COMObject Microsoft.SMS.TSEnvironment).GetVariables() | Where-Object {$_ -Like "SA_*"}
    $TextArray = foreach ($Values in $TextArrayVars) {$tsenv.Value($Values)}
    }
Else
    {
    # An array of sentences to display, in order. Leave the first one blank as the 0 index gets skipped.
    $TextArray = @(
        "This Line never actually displays"
        "We're upgrading you to Windows 10 $($TSENV.Value('SMSTS_BUILD'))"
        "It may take 60 - 120 minutes"
        "Your PC will restart several times"
        "Should anything go wrong, contact your..."
        "... Line of Business Help Desk."
        )
    }
$script:i = 0
# Start a dispatcher timer. This is used to control when the sentences are changed.
$TimerCode = {

    $ProgressRing.IsActive = $True
    
    # The IF statement number should equal the number of sentences in the TextArray
    $NumberofElements = $TextArray.Count -1
    If ($script:i -lt $NumberofElements)
    {
        $FadeoutAnimation.Add_Completed({            
            $TextBlock.Opacity = 0
            $TextBlock.Text = $TextArray[$script:i]
            $TextBlock.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)

        })   
        $TextBlock.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeoutAnimation) 
    }
    # The final sentence to display ongoing
    ElseIf ($script:i -eq $NumberofElements)
    {
        $script:i = 0
        $FadeoutAnimation.Add_Completed({            
            $TextBlock.Opacity = 0
            $TextBlock.Text = "We're upgrading this PC to Windows 10 $($TSENV.Value('SMSTS_BUILD'))"
            $TextBlock.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)

        })   
        $TextBlock.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeoutAnimation) 
    }
    Else
        {
        # Restore the taskbar
        [Taskbar]::Show()

        # Restore the mouse cursor
        [System.Windows.Forms.Cursor]::Show()

        $DispatcherTimer.Stop()
        $DispatcherTimerTS.Stop()
        exit
        }

    
    if ($tsenv)
        {
        #If Error Window Launches, Exit Splash Screen - Make sure your Error Dialog step is named below
        #Using this Method for Error Handling: https://www.asquaredozen.com/2018/12/14/building-an-even-better-task-sequence/
        if ($tsenv.Value('_SMSTSCurrentActionName') -eq "Launch Custom Dialog") 
            {
            # Restore the taskbar
            [Taskbar]::Show()

            # Restore the mouse cursor
            [System.Windows.Forms.Cursor]::Show()

            $DispatcherTimer.Stop()
            $DispatcherTimerTS.Stop()
            Exit
            }
         #Stop the TS Timer, set new Text Message for the Step Name, and "Activate" the % Complete Text Box
         if ($DispatcherTimerTS.IsEnabled -and $tsenv.Value('_SMSTSCurrentActionName') -eq "Upgrade Operating System. DO NOT TURN OFF YOUR PC") 
            {
            $DispatcherTimerTS.Stop()
            $TextBlock3.Text = "Windows 10 Setup Engine Running Upgrade Process"
            $TextBlock4.Visibility = 'Visible'
            }
          if ($DispatcherTimerTS.IsEnabled -and $tsenv.Value('_SMSTSCurrentActionName') -eq "Upload Inventory Data") 
            {
            $DispatcherTimerTS.Stop()
            $TextBlock3.Text = "Nearly Complete, just one more reboot, right after it displays the logon screen."
            }        
         
         if ($DispatcherTimerUpgrade.IsEnabled -eq $false -and $tsenv.Value('_SMSTSCurrentActionName') -eq "Upgrade Operating System. DO NOT TURN OFF YOUR PC") 
            {
            $DispatcherTimerUpgrade.Start()
            }
        }
    #If Not in TS... Exit!
    Else 
        {
         Restore the taskbar
        [Taskbar]::Show()

         Restore the mouse cursor
        [System.Windows.Forms.Cursor]::Show()

        $DispatcherTimer.Stop()
        $DispatcherTimerTS.Stop()
        Exit
        }

    $ColourBrighterAnimation.Add_Completed({            
        $Window.Background.BeginAnimation([System.Windows.Media.SolidColorBrush]::ColorProperty,$ColourDarkerAnimation)
    })   
    $Window.Background.BeginAnimation([System.Windows.Media.SolidColorBrush]::ColorProperty,$ColourBrighterAnimation)

    $Script:i++
}
#Main Text Timer
$DispatcherTimer = New-Object -TypeName System.Windows.Threading.DispatcherTimer
$DispatcherTimer.Interval = [TimeSpan]::FromSeconds(10)
$DispatcherTimer.Add_Tick($TimerCode)

#Step Name Timer Controls
#Runs at every 1/2 second to try to make sure it catches all of the step names.
$TimerCodeTS = {
        
        $TestInfo = $tsenv.Value('_SMSTSCurrentActionName')
        $TextBlock3.Text = $TestInfo

}
$DispatcherTimerTS = New-Object -TypeName System.Windows.Threading.DispatcherTimer
$DispatcherTimerTS.Interval = [TimeSpan]::FromMilliseconds(500)
$DispatcherTimerTS.Add_Tick($TimerCodeTS)

#Timer for Upgrade % - Should be inactivate until activated in the Main Text Timer when it reaches the upgrade step.    
$TimerCodeUpgrade = {
        
        
        $TestInfoUpgrade = Get-ItemPropertyValue -Path "HKLM:\SYSTEM\Setup\MoSetup\Volatile" -Name "SetupProgress"
        if ($TestInfoUpgrade) {$TextBlock4.Text = "Windows Setup Engine: $($TestInfoUpgrade) %"}
        else {$TextBlock4.Text = "Windows Setup Engine: Initializing"}


}
$DispatcherTimerUpgrade = New-Object -TypeName System.Windows.Threading.DispatcherTimer
$DispatcherTimerUpgrade.Interval = [TimeSpan]::FromSeconds(5)
$DispatcherTimerUpgrade.Add_Tick($TimerCodeUpgrade)



# Event: Window loaded
$Window.Add_Loaded({
    
    # Activate the window to bring it to the fore
    $This.Activate()

    # Fill the screen
    $Bounds = $screen.Bounds
    $Window.Left = $Bounds.Left
    $Window.Top = $Bounds.Top
    $Window.Height = $Bounds.Height
    $Window.Width = $Bounds.Width

    # Hide the taskbar
    [TaskBar]::Hide()

    # Hide the mouse cursor
    [System.Windows.Forms.Cursor]::Hide()

    # Begin animations
    $TextBlock.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)
    $TextBlock2.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)
    $TextBlock3.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)
    $TextBlock4.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)
    $ProgressRing.BeginAnimation([System.Windows.Controls.TextBlock]::OpacityProperty,$FadeinAnimation)
    $ColourBrighterAnimation.Add_Completed({            
        $Window.Background.BeginAnimation([System.Windows.Media.SolidColorBrush]::ColorProperty,$ColourDarkerAnimation)
    })   
    $Window.Background.BeginAnimation([System.Windows.Media.SolidColorBrush]::ColorProperty,$ColourBrighterAnimation)

})

# Event: Window closing
$Window.Add_Closing({

    # Restore the taskbar
    [Taskbar]::Show()

    # Restore the mouse cursor
    [System.Windows.Forms.Cursor]::Show()

    $DispatcherTimer.Stop()
    $DispatcherTimerTS.Stop()
})

# Event: Allows to close the window on right-click (uncomment for testing)
<#
$Window.Add_MouseRightButtonDown({

    $This.Close()

})
#>

# Display the window
$DispatcherTimer.Start()
$DispatcherTimerTS.Start()
$DispatcherTimerUpgrade.Start()
$Window.ShowDialog()

POSTED ON GARYTOWN.COM

27 thoughts on “Windows Splash Screen for the Task Sequence Progress”

    • Yes, as long as you’ve added PowerShell & .Net to your WinPE image. Pretty sure I did test it in WinPE and it worked, but I’d have to test again to confirm.

      Reply
  1. Hi Garry,

    Did you figure out how to display the users name instead of Team Member ?

    I can see that SMSagent is calling the script with “Invoke-PSScriptAsUser.ps1”, I tried that and then calling “Show-OSUpgradeBackground-Variable.ps1” from the above script.. but it wont get any further than Hey ‘Name’, after that it just quits – have you tried to get that part working ?

    The good part is that the Name get displayed properly queried from AD, but it just breaks after that.

    Reply
    • Yes, I just don’t individualize it. But it wouldn’t be hard to do. I already have a script in the process that finds the logged on Console USERNAME (not friendly name) and writes that to Registry, you could simply modify that script to create a TS Var, or have the Splash Screen grab the info from the Registry. Script: OSUninstall-GetUserName.ps1

      Reply
      • Yes I did already noticed the username in registry, but i wanted the friendly name displayed.
        I got it working by queering AD with ADSI.

        Reply
  2. I’m running into an issue where all I see is a gray splash once the PS script is called up using Service-UI. Any ideas?

    Reply
  3. Hi Gary,

    I’m just starting to test the IPU processes, and am running into this step erroring out. Upon running the “showOSUpgradeBackground-Variable.ps1, it throws “Failed to run the Action: Deployment Screen. Unknown error (Error: FFFFFFF; source: unknown).

    Here’s the full snippet from the logs:

    Command line is being logged (‘OSDDoNotLogCommand’ is not set to ‘True’) InstallSoftware 9/26/2019 4:20:33 PM 7688 (0x1E08)
    Command line “C:\WINDOWS\ccmcache\u\ServiceUI.exe” -process:TSProgressUI.exe C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File Show-OSUpgradeBackground-Variable.ps1 returned 4294967295 InstallSoftware 9/26/2019 4:20:33 PM 7688 (0x1E08)
    ReleaseSource() for C:\WINDOWS\ccmcache\u. InstallSoftware 9/26/2019 4:20:33 PM 7688 (0x1E08)
    reference count 1 for the source C:\WINDOWS\ccmcache\u before releasing InstallSoftware 9/26/2019 4:20:33 PM 7688 (0x1E08)
    Released the resolved source C:\WINDOWS\ccmcache\u InstallSoftware 9/26/2019 4:20:33 PM 7688 (0x1E08)
    Process completed with exit code 4294967295 TSManager 9/26/2019 4:20:33 PM 3772 (0x0EBC)
    !——————————————————————————————–! TSManager 9/26/2019 4:20:33 PM 3772 (0x0EBC)
    Failed to run the action: Deployment Screen.
    Unknown error (Error: FFFFFFFF; Source: Unknown) TSManager 9/26/2019 4:20:33 PM 3772 (0x0EBC)
    Not in SSL TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Set a global environment variable _SMSTSLastActionRetCode=-1 TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Set a global environment variable _SMSTSLastActionName=Deployment Screen TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Set a global environment variable _SMSTSLastActionSucceeded=false TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Clear local default environment TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Let the parent group (Launch if User Logged ON) decides whether to continue execution TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Let the parent group (OSD Module – Splash Screen) decide whether to continue execution TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Let the parent group (Launch Splash Screen) decide whether to continue execution TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    The execution of the group (Launch Splash Screen) has failed and the execution has been aborted. An action failed.
    Operation aborted (Error: 80004004; Source: Windows) TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Failed to run the last action: Deployment Screen. Execution of task sequence failed.
    Unknown error (Error: FFFFFFFF; Source: Unknown) TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Not in SSL TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Task Sequence Engine failed! Code: enExecutionFail TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    **************************************************************************** TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)
    Task sequence execution failed with error code 80004005 TSManager 9/26/2019 4:20:34 PM 3772 (0x0EBC)

    Not much to go on. If after it fails out and reboots, if I launch it from a PS window from within the cache, it launches and runs fine. Any ideas on where I can start looking?

    Reply
    • Nevermind. I figured it out. I originally deployed it with no user interaction (which prevented TSProgressUI.exe wasn’t running, so it bombed out. I redeployed leaving the default user experience settings and it progressed like a charm.

      Reply
  4. I’ve been implementing this for our 1809 in-place upgrade roll-out with your collection of WaaS TSs. When adding Onevinn’s TSLaunch tool to the mix and using the config action to logout user before the TS begins leads to the error “Process Not Found: [TSProgressUI.exe].”

    Is there a way to have the Splash Screen launch without having an active user present at the time of TS execution? I’d really hope this can be done but if not the custom lock screens with the legal text notifications are in place. 😉

    Thanks for all your work!!

    Reply
    • The Splash Screen is basically an app, and needs a user session to run in. If no one is logged on, splash screen isn’t going to run. I actually thought Onevinn had something that would run on top of the lock screen, but I haven’t looked into it to confirm. If you ever get your idea working for having a splash screen cover the lock screen (no one logged on), let me know.

      Reply
      • I had to go the route of using Onevinn’s UPGBackground which is paired with TSLaunch for this to work with no user logged on. I used their latest beta version and it’s been going great! I did have to disable the Lockscreen PRE & POST steps in the upgrade TS otherwise it interrupts UPGBackground from running and takes you to the login screen. It does serve the purpose of preventing users from tampering with their computer while it’s in progress.

        I did like the customization options of Splash Screen with the rolling text and where the text could be changed in a later party of the TS.

        Again thanks for your work and the many resources you’ve provided here!

        Reply
  5. Works great in Windows but trying to get working in WinPE. The splash screen does show and it says Hey Team Member but then closes and I see the progress bar flash with the “Disable Progress UI” step before it disables it and the task sequence continues without a issue. Is this just not meant for WinPE?

    Reply
  6. Hi Gary, great work!

    I am using your splash screen and for an in-place upgrade one thing I notice is that the % does not appear on any of the tasks, how do you make the % appear so the user knows were the upgrade is up to?

    Peter

    Reply
    • The script checks Step names, if you renamed this step: Upgrade Operating System. DO NOT TURN OFF YOUR PC, then it would never know to start showing the %. You need to modify the script to know which is your upgrade step.

      Reply
  7. “Lastly, we disable the native progress UI.”

    Can yo elaborate?
    What line in the script?
    Will this also disable the “Getting Ready” and “Just a moment” screens?

    Cool stuff!
    Thank you!

    Reply
    • Most of the functionality will work in MDT too.
      I don’t recall how to dynamically grab TS variables in MDT, but basically you should be able to replace the code for ConfigMgr TS Variable lookups with MDT.

      Reply
      • Thanks Gary, that’s exactly what i did and it worked! Now to figure out how to hide the tsprogressui in MDT without it flashing back up after every step.

        Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.