Slimdown11 – turn Windows 11 or LTSC 2024 into classic/legacy Windows

Discussion in 'Windows 11' started by SunLion, Mar 2, 2025.

  1. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    I’d like to add one more thing: this label name

    Code:
    IF "%Net35%"=="1" (SET "DN=Enable Net35") ELSE (SET "DN=Don't Enable Net35")
    should be changed to this, otherwise it becomes active in every case.

    Code:
    IF "%EnableNet35%"=="1" (SET "DN=Enable Net35") ELSE (SET "DN=Don't Enable Net35")
    The other sections are working great for me too, and the install.wim file is 4.70 GB. This can be reduced even further—it’s possible to get it down to 4 GB by removing Edge Defender. @SunLion, thank you very much for all your hard work.
     
  2. SunLion

    SunLion MDL Expert

    May 11, 2011
    1,721
    6,563
    60
    OK

    Corrected.

    Thank you.
     
  3. Mavericks Choice

    Mavericks Choice MDL Guru

    Aug 5, 2015
    4,405
    17,028
    150
    It may not be of importance for all though the included uwp apps are now outdated eg "modern calc".
     
  4. SunLion

    SunLion MDL Expert

    May 11, 2011
    1,721
    6,563
    60
    #2064 SunLion, Aug 4, 2026
    Last edited: Aug 4, 2026
    (OP)
    I'll check and update it.

    Thanks.

    I will wait for the next update to release the new package.
     
  5. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    The `UseCustomList` variable is a section that was forgotten or omitted in the script. As a result, even if you open the GUI using the C key and make selections, the `CustomRemovalList.txt` file is created, but this list is never processed, and therefore no additional packages are removed. Only the settings (1–23) in the main menu are applied.
    This code should be added immediately above the “Remove Provisioned AppxPackages” line.


    Code:
    echo.
    echo.
    if "%UseCustomList%"=="1" if exist "!CustomList!" (
        echo ============================================================
        echo Applying Custom Removal List from PackageSelector...
        echo ============================================================
        FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "APPX:" "!CustomList!" 2^>nul') DO (
            "%DISM11%" /English /quiet /Image:"%~dp0mount" /Remove-ProvisionedAppxPackage /PackageName:%%B
        )
        FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "CAPABILITY:" "!CustomList!" 2^>nul') DO (
            "%DISM11%" /English /quiet /Image:"%~dp0mount" /Remove-Capability /CapabilityName:%%B
        )
        FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "FEATURE:" "!CustomList!" 2^>nul') DO (
            "%DISM11%" /English /quiet /Image:"%~dp0mount" /Disable-Feature /FeatureName:%%B /Remove
        )
    )
     
  6. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    I think the "UseCustomList" blog is very helpful; I’m removing the languages that will save a lot of space—it’s a great feature. I’m testing it right now, and I’m sure it will reduce the size of the install.wim file.
     
  7. SunLion

    SunLion MDL Expert

    May 11, 2011
    1,721
    6,563
    60
    I need to look into this carefully, because there's code to remove appxpackage, to disable features, etc.

    It seems to me that something is still being duplicated when this code is used.

    I need to look into this more closely...

    Thank you for your help.
     
  8. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    #2068 sergey130270, Aug 8, 2026
    Last edited: Aug 9, 2026
    Code:
    This block effectively dynamically removes components from the mounted WIM based on a custom list. Сan try parsing it.
    
    1. First, it checks whether the Custom List is enabled.
    if "%UseCustomList%"=="1" if "!CustomList!" exists. (
    That is, the block does nothing at all if:
    UseCustomList is not equal to 1;
    the file specified in CustomList does not exist.
    This is good: the module can be left optional.
    
    2. Then it reads the APPX from the list
    FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "APPX:" "!CustomList!" 2^>nul') DO (
    "%DISM11%" /English /quiet /Image:"%~dp0mount" /Remove-ProvisionedAppxPackage /PackageName:%%B
    )
    
    For example, if CustomList contains:
    APPX:Microsoft.XboxApp_...
    APPX:Microsoft.BingWeather_...
    APPX:Microsoft.GamingApp_...
    findstr finds lines with APPX:.
    
    And this one The
    tokens=1,* delims=: part splits the string by ::
    %%A = APPX
    %%B = Microsoft.XboxApp_...
    And then:
    DISM /Remove-ProvisionedAppxPackage
    That is, the Provisioned Appx is removed from the offline image.
    
    3. CAPABILITY
    Then the scheme is completely similar:
    FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "CAPABILITY:" "!CustomList!" 2^>nul') DO (
    "%DISM11%" /English /quiet /Image:"%~dp0mount" /Remove-Capability /CapabilityName:%%B
    )
    
    For example:
    CAPABILITY:Language.Basic~~~ru-RU~0.0.1.0
    will result in:
    DISM /Remove-Capability /CapabilityName:Language.Basic~~~ru-RU~0.0.1.0
    
    4. FEATURE
    And the third type:
    FOR /F "tokens=1,* delims=:" %%A IN ('findstr /i "FEATURE:" "!CustomList!" 2^>nul') DO (
    "%DISM11%" /English /quiet /Image:"%~dp0mount" /Disable-Feature /FeatureName:%%B /Remove
    )
    
    For example:
    FEATURE:Internet-Explorer-Optional-amd64
    will become:
    DISM /Disable-Feature /FeatureName:Internet-Explorer-Optional-amd64 /Remove
    
    An important point here:
    /Disable-Feature and /Remove
    mean not just disabling the Feature, but removing the component's payload from the image.
    
    And this is where the potential lies. This code, that is, logic that independently determines:
    
    Provisioned AppxPackages;
    Capabilities;
    Features;
    What to remove;
    What to keep.
    
    And this example allows you to create an external list, for example:
    APPX:Microsoft.XboxApp_...
    APPX:Microsoft.BingWeather_...
    CAPABILITY:Language.Basic~~~...
    FEATURE:printing-Foundation-Features
    
    And a single universal handler will automatically parse these three categories.
    That is, instead of storing huge blocks in the BAT:
    DISM ... /Remove-ProvisionedAppxPackage ...
    DISM ... /Remove-ProvisionedAppxPackage ...
    DISM ... /Remove-Capability ...
    DISM ... /Disable-Feature ...
    DISM ... /Disable-Feature ...
    ...
    You can potentially have one handler + external list.
    
     
  9. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    #2069 sergey130270, Aug 8, 2026
    Last edited: Aug 9, 2026
    What's especially interesting is that UseCustomList allows you to separate the processing logic from the removal list itself.
    Code:
    For example:
    APPX:Microsoft.Xbox...
    APPX:Microsoft.BingWeather...
    CAPABILITY:Language.Basic~~~de-DE~...
    CAPABILITY:Language.Basic~~~fr-FR~...
    FEATURE:Internet-Explorer-Optional-amd64
    And the script itself understands:
    
    APPX: -/Remove-ProvisionedAppxPackage
    CAPABILITY: -/Remove-Capability
    FEATURE: -/Disable-Feature /Remove
    
     
  10. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    I decided not to use the “usecustomlist.txt” file because the .ps1 file adds everything—whether installed or not—to the list, which was causing the script to fail. Instead, I made additions to the other capability and features files.
     
  11. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    None of the language files are installed, but they are being added to the usecustomlist.txt file as if they were installed, and the script is throwing an error. I’ve tried many times—I even tried editing the .ps1 file—but I wasn’t successful.
     
  12. SunLion

    SunLion MDL Expert

    May 11, 2011
    1,721
    6,563
    60
    I was thinking that several of these components are already removed by the script.

    So, there might be some redundancy in the selection for removal.

    But it's worth a try to see what happens, especially since it expands the range of removal options.

    I'll also add the code suggested by @otvertka and run some tests...


    @otvertka and @sergey130270:

    Thanks for the help!
     
  13. SunLion

    SunLion MDL Expert

    May 11, 2011
    1,721
    6,563
    60
    I feel the same way. Let's proceed without the customlist.txt file and, if possible, expand the existing lists.
     
  14. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    First, you need to look at the example and examine it in its entirety.

    Especially the places where:
    UseCustomList and CustomList are created and set are important.

    Because the section you showed is just the executor. You need to understand how the list is formed.
     
  15. otvertka

    otvertka MDL Member

    Aug 13, 2009
    109
    253
    10
    I mounted the ISO file, and all the capabilities (those that are installed) and features (those that are enabled) within it should be included in this list (usecustomlist.txt)—either by creating it manually or by editing the .ps1 file to list only the necessary ones.
     

    Attached Files:

  16. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    #2076 sergey130270, Aug 8, 2026
    Last edited: Aug 9, 2026
    Code:
    The first test is to remove one specific language.
    For example, suppose you had tr-TR installed in your list.
    Directly to the offline image:
    
    :: --- Test: Remove Turkish language ---
    
    "%DISM11%" /English /Image:"%~dp0mount" ^
    /Remove-Capability ^
    /CapabilityName:Language.Basic~~~tr-TR~0.0.1.0
    
    If this works successfully, the next step is to automatically remove all tr-TR Capabilities:
    
    Language.Basic
    Language.Handwriting
    Language.OCR
    Language.Speech
    Language.TextToSpeech
    
     
  17. sainfo

    sainfo MDL Addicted

    Dec 6, 2021
    707
    1,590
    30
    #2077 sainfo, Aug 8, 2026
    Last edited: Aug 9, 2026
    Hello, could you please share the relevant parts of your code that select the Capabilities_State.txt and Features_State.txt files for execution?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  18. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    #2078 sergey130270, Aug 9, 2026
    Last edited: Aug 9, 2026
    Hi guys.
    Code:
    TEST PROPOSAL: CustomRemovalList + Existing Capability Removal
    
    DESCRIPTION
    -----------
    The existing script already has working DISM logic for removing Windows
    Capabilities. This test does not replace that logic.
    
    The only change is to read CAPABILITY: entries from CustomRemovalList.txt
    and add them to the existing RemoveCapabilities list.
    
    TEST FILE
    ---------
    Create this file next to the main script:
    
    CustomRemovalList.txt
    
    For the first test:
    
    CAPABILITY:Language.Basic~~~tr-TR~0.0.1.0
    CAPABILITY:Language.Handwriting~~~tr-TR~0.0.1.0
    CAPABILITY:Language.OCR~~~tr-TR~0.0.1.0
    CAPABILITY:Language.TextToSpeech~~~tr-TR~0.0.1.0
    
    
    TEST CODE
    ---------
    Insert this block after RemoveCapabilities is created and before the
    existing "for %%P in (!RemoveCapabilities!) do (" loop.
    
    :: --- Custom Capability List ---
    set "UseCustomList=1"
    set "CustomList=%~dp0CustomRemovalList.txt"
    
    if "%UseCustomList%"=="1" if exist "!CustomList!" (
        echo.
        echo ------------------------------------------------------------
        echo Applying Custom Capability List...
        echo ------------------------------------------------------------
    
        for /F "tokens=1,* delims=:" %%A in (
            'findstr /i /b "CAPABILITY:" "!CustomList!" 2^>nul'
        ) do (
            set "RemoveCapabilities=!RemoveCapabilities! %%B"
            echo [CUSTOM] %%B
        )
    )
    
    
    EXISTING REMOVAL CODE
    ---------------------
    Keep the existing DISM removal loop unchanged:
    
    for %%P in (!RemoveCapabilities!) do (
        echo [Removing] %%P
    
        "%DISM11%" /English /Image:"%MountDir%" ^
            /Remove-Capability ^
            /CapabilityName:%%P >nul 2>&1
    
        if !errorlevel! equ 0 (
            echo [OK] %%P
        ) else (
            echo [SKIPPED] %%P
        )
    )
    
    
    EXPECTED RESULT
    ---------------
    The custom entries should first appear as:
    
    [CUSTOM] Language.Basic~~~tr-TR~0.0.1.0
    [CUSTOM] Language.Handwriting~~~tr-TR~0.0.1.0
    [CUSTOM] Language.OCR~~~tr-TR~0.0.1.0
    [CUSTOM] Language.TextToSpeech~~~tr-TR~0.0.1.0
    
    Then the existing DISM loop should process them:
    
    [Removing] Language.Basic~~~tr-TR~0.0.1.0
    [OK] Language.Basic~~~tr-TR~0.0.1.0
    
    If a Capability is not installed:
    
    [Removing] Language.OCR~~~tr-TR~0.0.1.0
    [SKIPPED] Language.OCR~~~tr-TR~0.0.1.0
    
    
    EXPLANATION
    -----------
    This is only a test of the connection between CustomRemovalList.txt
    and the existing Capability removal mechanism.
    
    No counters, PowerShell, automatic list generation, or new DISM removal
    logic are used.
    
    If this works, the same approach can later be tested for APPX: and
    FEATURE: entries using the existing removal handlers.
    
     
  19. sergey130270

    sergey130270 MDL Senior Member

    May 15, 2014
    350
    558
    10
    #2079 sergey130270, Aug 9, 2026
    Last edited: Aug 9, 2026
    Test Result: was successful.
    The CustomRemovalList.txt was correctly read, and the CAPABILITY: entries were successfully added to the existing RemoveCapabilities list.
    One important requirement was identified during testing:
    setlocal EnableDelayedExpansion is required for this block to work correctly.
    the custom Capability entries are processed correctly.
    The [SKIPPED] result in mine particular test is expected because the tested Windows image does not contain the selected tr-TR language Capabilities.
    So the test confirms that the CustomRemovalList.txt RemoveCapabilities existing DISM removal logic works correctly.
    The custom Capability entries are processed correctly.
     
  20. sainfo

    sainfo MDL Addicted

    Dec 6, 2021
    707
    1,590
    30
    This is all very interesting, of course, but also quite difficult to implement, in my opinion. I think the proposed approach using Capabilities_State.txt and Features_State.txt is more promising and simpler. The only thing is, I’ll test this approach as well if @otvertka shares the code for managing these files with us. I tried controlling them via PowerShell, but it didn't work...
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...