Automatically update or remove an application in all of your ConfigMgr task sequences

There have been many times where I have needed to retire an old application but I can’t because the application in question is referenced in a few task sequences. Luckily this has become a little easier since ConfigMgr 1906 was released because Microsoft has added the task sequences tab in the application node. Unfortunately you can’t delete the application from the task sequence tab so it is still a tedious task that requires you to open each task sequence and remove or replace the application from each TS. This is why I wrote the following script to automate updating or removing an application from all of the task sequences that references the application.’

Eventually I will create a custom function for this that will make it easier to run but I figured if you are reading this, you are at least somewhat knowledgeable with Powershell :)

How to remove an application:

  1. Add the old application name to the $OldApplicationName variable
  2. Make the $Remove variable equal to $True

How to update an application

  1. Add the old application name to the $OldApplicationName variable
  2. Add the new application name to the $NewApplicationName variable
  3. Make the $Remove variable equal to $False


# Enter the name of the old application that you want to remove or replace
$OldApplicationName = ""
# Enter the new application name that that you want to use to replace the old application
$NewApplicationName = ""
# Make the remove variable value $true if you would like to remove an application from all task sequences
$Remove = ""
$OldApplication = Get-CMApplication "$OldApplicationName"

If($NewApplicationName) {

    $NewApplication = Get-CMApplication "$NewApplicationName"

$Application = Get-CMApplication -Name "$OldApplicationName"
# Get all task sequences that have the old application as a reference
$TaskSequences = Get-CMTaskSequence | Where-Object { $_.References.Package -eq $OldApplication.ModelName -and $ -eq "Citrix Build-PDC001FC"  }
If($TaskSequences) {
    ForEach ($TaskSequence in $TaskSequences) {
        Write-Host "Updating $($TaskSequence.Name)"
        # Get all install application steps
        $InstallApplicationSteps = (Get-CMTSStepInstallApplication -InputObject (Get-CMTaskSequence -Name $TaskSequence.Name)).Name
        ForEach($InstallApplicationStep in $InstallApplicationSteps) {
            # Get a list of applications that are in the install application step
            $ApplicationList = (Get-CMTSStepInstallApplication -InputObject $TaskSequence -StepName "$InstallApplicationStep").ApplicationName.Split(",")
            # Get application steps that reference the old application
            If($OldApplication.ModelName -in $ApplicationList) {
                # Try to replace the old application with the new application
                Try {
                    If($Remove -eq $False) {
                        $ModelNames = $ApplicationList.Replace($OldApplication.ModelName,$NewApplication.ModelName)
                    Else {
                        $ModelNames = $ApplicationList | Where-Object { $_ -ne $OldApplication.ModelName }
                Catch {
                    Write-Host "Failed to replace or remove old app"
                If($ModelNames -ne $Null -and $Remove -ne $True) {

                    # Add the new application to the application step
                    Write-Host "- Updating Step: $InstallApplicationStep"
                    Set-CMTSStepInstallApplication -InputObject $TaskSequence -StepName "$InstallApplicationStep" -Application ($ModelNames | ForEach { Get-CMApplication -ModelName $_ })

                Else {

                    Write-Host "- Removing Step: $InstallApplicationStep"
                    Remove-CMTSStepInstallApplication -InputObject $TaskSequence -StepName "$InstallApplicationStep" -Force


Else {
    Write-Host "Could not locate the application in any task sequence!"

Install-Font Function

Use the Install-Font function to install system fonts on Windows 10 1809 and above. Older scripts may not work with Windows 10 1809 and above since Windows will now try to install fonts in the user’s LOCALAPPDATA directory. This function will get around those issues and allow you to programmatically install fonts for all users again.

How to use the function:

Install Fonts from folder
Install-Font “C:\Temp\Helvetica Neue”

Install one font
Install-Font “C:\Temp\Helvetica Neue\HelveticaNeueLTStd-HvIt.otf”

Function Install-Font {

    .SYNOPSIS Install system fonts for all users
    .PARAMETER FontPath Provide path to a font or a folder containing fonts

    .PARAMETER Recurse Scan subdirectories
    .EXAMPLE - Install Fonts from folder
    Install-Font "C:\Temp\Helvetica Neue"
    .EXAMPLE - Install one font 
    Install-Font "C:\Temp\Helvetica Neue\HelveticaNeueLTStd-HvIt.otf"


    If(Test-Path $FontPath) {
        $FontFile = Get-Item -Path $FontPath

        If($FontFile -is [System.IO.DirectoryInfo]) {

            If($Recurse) {

                $Fonts = Get-ChildItem -Path $FontFile -Include ('*.fon','*.otf','*.ttc','*.ttf') -Recurse

            Else {

                $Fonts = Get-ChildItem -Path "$FontFile\*" -Include ('*.fon','*.otf','*.ttc','*.ttf')

            If(!$Fonts) {

                Throw ("Unable to find any fonts in the folder")


        ElseIf($FontFile -is [IO.FileInfo]) {

            If ($FontFile.Extension -notin ('.fon','.otf','.ttc','.ttf')) {

                Throw ("The file provided does not appear to be a valid font")


            $Fonts = $FontFile

        Else {
            Throw ("Expected font or folder")

    Else {

        Throw [System.IO.FileNotFoundException]::New("Could not find path: $FontPath")

    ForEach ($Font in $Fonts) {

        $FontName = $Font.Basename
        Write-Host "Installing font: $FontName"
        Copy-Item $Font "C:\Windows\Fonts" -Force
        New-ItemProperty -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -PropertyType String -Value $Font.Name -Force | Out-Null



Registry Keys for Windows 10 Application Privacy Settings

The following registry keys in this post control the privacy settings in Windows 10. These settings can be found in the GUI by going to SETTINGS\PRIVACY.
Read more

How to reset your start menu layout in Windows 10 1809

Well Microsoft has changed things again since my last post that showed you how to reset the start layout in Windows 10 1709. Now with 1809 there is a new key name and it does look to be slightly random so I am now having to use a wildcard. I’m currently only testing every other build so please keep me updated if this breaks with a spring feature upgrade release.

Remove-Item 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\*$start.tilegrid$'  -Force -Recurse
Get-Process Explorer | Stop-Process

Are you trying to reset the start layout for Windows 10 1709? Click here to find out how.

How to install Office 365 ProPlus updates during your SCCM build and capture task sequence

Have you tried to install Office 365 ProPlus updates during your SCCM build and capture task sequence and it never installed? Well that is most likely due to a registry key that was not updated. The update channel registry key value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration should not be pointing to your ccmcache folder. If it is, then this fix will work for you.

In order to update this key, you should run the following command before the Install Updates step in your task sequence.:
“C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe” /update SCHEDULEDTASK displaylevel=False

Note: This command must run before you attempt to install any Office 365 ProPlus software updates in your task sequence. If it does not then your update channel value will still be pointing to the ccmcache which will stop the updates from running.

Find more information here:

SCCM script to identify systems vulnerable to ADV180028

You can run the following script against an SCCM collection to identify a system’s Bitlocker encryption method. This will help you find any computers that may be vulnerable to ADV180028.

Note: Your system may be vulnerable if your encryption method is set to Hardware Encryption!

$EncryptionMethod = manage-bde -status C: | Where-Object {$_ -match "Encryption Method"}

If ($EncryptionMethod -ne $Null) {

    $EncryptionMethod = $EncryptionMethod.Split(":")[1].trim()

Else {

    $EncryptionMethod = "Encryption Method not found"



Learn more about ADV180028 here.
Learn how to deploy scripts in SCCM here.

How to disable Microsoft Teams from running at logon

If you landed on this page you are probablly working on packaging Microsoft Teams and have been banging your head against a desk trying to figure out how to disable it from loading at startup. Fortunately for you, I figured out a solution that works 100% of the time.

What do you need?
Microsoft Teams

Where to download?
Node.JS –
Microsoft Teams –
Notepad++ –

Brief background
Essentially, Microsoft Teams is a webpage in the background. It was developed with Electron which is a framework that lets developers create cross-platform desktop apps with web front-end technologies. Some other popular applications such as Skype, and Visual Studio Code were also built with using this technology.

With Electron apps, most of the source files for the application will be packaged into a file named app.asar. You can open the file in Notepad but you cannot save it since it is a READONLY file. From my experience, any changes made to it via Notepad will crash the app and prevent it from loading.

How do you do it?

  1. Download and install Microsoft Teams
  2. Download and install Node.JS
  3. Open the CMD prompt as an Administrator
  4. Run: npm install -g asar
  5. Run: asar extract "%LOCALAPPDATA%\Microsoft\Teams\current\resources\app.asar" C:\Temp\asar
    Note – Try running “C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Node.js\Node.js command prompt.lnk” if the command prompt does not recognize the ASAR command.
  6. Navigate to C:\Temp\asar\lib
  7. Locate desktopConfigurationManager.js and open the file with Notepad++
  8. Search for OPENATLOGIN (There should be two references) and set the value to FALSE as shown below in the screenshots:
    disable teams at startup
    disable teams at startupli>

    Last but not least, it is time to repackage everything!

  9. Run: asar pack "C:\TEMP\asar" "C:\TEMP\app.asar" --unpack *.node

Now that you have a customized app.asar, you can silently install Teams and also not worry about it launching at startup. See the install script below for an example:

# Install Microsoft Teams
Start-Process "$PSScriptRoot\Teams_windows_x64.exe" -ArgumentList "-s" -Wait

# Copy customized app.asar
Copy "$PSScriptRoot\app.asar" "$env:LOCALAPPDATA\Microsoft\Teams\current\resources\app.asar" -Force

Add a new custom Powershell module path

You can use the following script to add a new module path to the PSModulePath environmental variable. Adding modules to this path will allow you to use them in your own scripts and if you have Powershell 3.0+ these modules will be automatically loaded when you call one of the custom CMDLET’s.

Please replace the $ModulePath variable with the path that you would like to use.

$ModulePath = "YOUR PATH HERE"
$Path = (Get-ItemProperty -Path "HKLM:\SYSTEM\ControlSet001\Control\Session Manager\Environment").PSModulePath
$NewPath = "$ModulePath" + ";" + $Path

If($Path -notlike "*$ModulePath*") {
    Set-ItemProperty -Path "HKLM:\SYSTEM\ControlSet001\Control\Session Manager\Environment" -Name PSModulePath -Type String -Value "$NewPath"

AC Power Check For Laptops

The following script can be used in an SCCM or MDT upgrade task sequence to check if a laptop is connected to a charger. If the script detects that the laptop is not connected to a charger, it will prompt the user to connect the laptop to AC power.

$ChassisTypes = (Get-WmiObject -Class Win32_SystemEnclosure).ChassisTypes

Switch($ChassisTypes) {

    3 { $Chassis = "Desktop" }
    4 { $Chassis = "Desktop" }
    5 { $Chassis = "Desktop" }
    6 { $Chassis = "Desktop" }
    7 { $Chassis = "Desktop" }
    8 { $Chassis = "Laptop" }
    9 { $Chassis = "Laptop" }
    10 { $Chassis = "Laptop" }
    11 { $Chassis = "Laptop" }
    12 { $Chassis = "Laptop" }
    14 { $Chassis = "Laptop" }
    15 { $Chassis = "Desktop" }
    16 { $Chassis = "Desktop" }
    18 { $Chassis = "Laptop" }
    21 { $Chassis = "Laptop" }
    23 { $Chassis = "Server" }
    31 { $Chassis = "Laptop" }

If($Chassis -eq "Laptop") {

    Do {
      $PowerStatus = (Get-WmiObject -Class BatteryStatus  -Namespace root\wmi -ErrorAction SilentlyContinue).PowerOnLine

        If($PowerStatus -ne $True) {

            $TSEnv = New-Object -ComObject "Microsoft.SMS.TsProgressUI"
            $wshell = New-Object -ComObject Wscript.Shell
            $wshell.Popup("Please Connect AC Power - Click OK to Continue",0,"AC Power Check",0)
    Until($PowerStatus -eq $True)


Troubleshooting Script for Windows 10 Start Menu Issues

Since a lot of people are having issues with the start menu tiles in their images, I decided to create the following script to help others troubleshoot some common issues that may occur.

Note: This script is compatible with Windows 10 1709 and above.

The script will run through the following checks:

  • Checks to see if C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml exists
  • Checks if the current user’s LayoutModification.xml matches the default profile’s LayoutModification.xml.
  • Opens C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml so you can confirm whether or not this is the XML file that you imported in your OSD process.
  • Checks to see if HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$start.tilegrid$ is causing the issue.

Download The Script Now!

$CurrentUserStartMenu = "$env:LOCALAPPDATA\Microsoft\Windows\Shell\LayoutModification.xml"
$DefaultStartMenu = "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml"

If((Test-Path "$DefaultStartMenu") -eq $False) {

    Write-Host -ForegroundColor Red "$DefaultStartMenu does not exist!"
    Write-Host -ForegroundColor Green "Possible Solution - Use Import-StartLayout to import your start layout (You will need to login as a new user to see the changes)"
    $Prompt = Read-Host -Prompt "Press any key to exit"
    If($Prompt -ne $Null) {



Else {

    If((Get-FileHash $CurrentUserStartMenu).hash -ne (Get-FileHash $DefaultStartMenu).hash){

        Write-Host "The default profile layoutmodification.xml and the current user's layoutmodification.xml do not match!" -ForegroundColor Red
        Copy-Item "C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml" "$env:LOCALAPPDATA\Microsoft\Windows\Shell\LayoutModification.xml" -Force
        Remove-Item 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$start.tilegrid$' -Force -Recurse
        Get-Process Explorer | Stop-Process

        $Prompt = Read-Host -Prompt "Is your custom start layout visible when you launch the start menu? (YES, NO)"

        If($Prompt -like "Y*") {

            Write-Host "Solution - Copying the default profile's layoutmodification to $env:LOCALAPPDATA\Microsoft\Windows\Shell\LayoutModification.xml fixed the problem" -ForegroundColor Red
            $Prompt = Read-Host -Prompt "Press any key to exit"
            If($Prompt -ne $Null) {



        Else {

            Write-Host "Unable to determine a solution" -ForegroundColor Red
            $Prompt = Read-Host -Prompt "Press any key to exit"
            If($Prompt -ne $Null) {





    Write-Host -ForegroundColor Red "Confirm that the default start layout is the same start layout that you imported"
    Start-Process Notepad -ArgumentList "$DefaultStartMenu"

    $Prompt = Read-Host -Prompt "Is this the same layout that you imported? (YES, NO)"

    If($Prompt -like "Y*") {

        Remove-Item 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$start.tilegrid$' -Force -Recurse
        Get-Process Explorer | Stop-Process
        $Prompt = Read-Host -Prompt "Is your custom start layout visible when you launch the start menu? (YES, NO)"

            If($Prompt -like "Y*") {

                Write-Host 'Possible Solution - Delete Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$start.tilegrid$ from C:\Users\Default\NTUser.dat' -ForegroundColor Green
                $Prompt = Read-Host -Prompt "Press any key to exit"
                If($Prompt -ne $Null) {



            Else {

                Write-Host "Unable to determine a solution" -ForegroundColor Red
                $Prompt = Read-Host -Prompt "Press any key to exit"
                If($Prompt -ne $Null) {





    Else {
        Write-Host "Possible Solution - Replace C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml with your custom LayoutModification.xml(You will need to login as a new user to see the changes)" -ForegroundColor Green
        $Prompt = Read-Host -Prompt "Press any key to exit"
        If($Prompt -ne $Null) {




Older Posts »
Page 1 of 4