当前位置 : 主页 > 操作系统 > centos >

MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用

来源:互联网 收集:自由互联 发布时间:2023-08-21
前言 由于工作等原因(借口),距离发布上一篇MDT系列的文章已经过去一年 ::twemoji:sweat:: 上一章我记录了基于MDT如何使用一个Task即可实现制作Windows基础wim镜像+DIY基础软件+捕捉镜像。

前言

由于工作等原因(借口),距离发布上一篇MDT系列的文章已经过去一年 ::twemoji:sweat::

上一章我记录了基于MDT如何使用一个Task即可实现制作Windows基础wim镜像+DIY基础软件+捕捉镜像。传送门

有好多同学一直咨询在制作捕捉镜像的时候遇到的常见的2个问题:

  • 如何彻底的移除掉Windows10中内置的应用;
  • 手动移除掉一些应用后就无法执行sysprep该如何解决;
  • 接下来我会分别用两篇文章去记录我使用的解决方法。本篇将介绍:如何按需移除掉Windows10中内置应用。


    环境准备

    • Windows 10 Enterprise v22H2.
    • MDT环境搭建请参考MDT系列文章,本文将略过此环节
    • Office365应用添加请参考自定义Office 365客户端并使用 MDT部署
    • 创建模版制作任务请参考MDT部署Windows系列 (十一): 进阶篇—制作完美的Win10 21H2系统镜像模板

    本文为 微风 原创文章.经实践,测试,整理发布.如需转载请联系作者获得授权,并注明转载地址.


    操作说明

    获取内置应用清单

    微软在过去几年,几乎每个版本的Windows都会有新增一些新的内置应用。为了便于前后的效果对比,我这里也通过ISO安装一个默认系统。

    默认系统安装完成后,手动更新系统补丁以及Windows Store应用。

    基于微软介绍,Windows内置应用包含以下两种:

    官方文档

  • 预配应用:Provisioned Apps
  • 系统应用:System Apps
  • 然后以管理员身份执行powershell,并执行以下命令,即可将系统中所有预配应用的列表列出:

    # 获取provisioned-apps Get-AppxProvisionedPackage -Online | Format-Table DisplayName, PackageName # 获取system-apps Get-AppxPackage -PackageTypeFilter Main | ? { $_.SignatureKind -eq "System" } | Sort Name | Format-Table Name, InstallLocation

    通过上述方法即可获取到当前系统的所有内置应用,然后将你需要保留的应用名称单独记录下来,后面通过脚本执行除去现有记录的应用外,其他所有内置应用执行卸载操作。

    注意:因为不同的Windows版本其内置的应用清单会有所不同,所以我这里做一个需要保留的应用白名单,除白名单外的应用均执行卸载。


    卸载脚本

    <# .SYNOPSIS Remove built-in apps (modern apps) from Windows 10. .DESCRIPTION 此脚本将删除所有未在此脚本的“白名单”中指定的预配包中内置应用程序。 它支持MDT和ConfigMgr使用,但仅适用于在线场景,所以它不能在WinPE阶段执行。 有关每个Windows 10版本中可用应用程序的更详细列表,请参阅此处的文档: https://docs.microsoft.com/en-us/windows/application-management/apps-in-windows-10 .EXAMPLE .\Invoke-RemoveBuiltinApps.ps1 #> Begin { # White list of Features On Demand V2 packages $WhiteListOnDemand = "NetFX3|DirectX|Tools.DeveloperMode.Core|Language|InternetExplorer|ContactSupport|OneCoreUAP|WindowsMediaPlayer|Hello.Face|Notepad|MSPaint|PowerShell.ISE|ShellComponents" # White list of appx packages to keep installed $WhiteListedApps = New-Object -TypeName System.Collections.ArrayList $WhiteListedApps.AddRange(@( "Microsoft.DesktopAppInstaller", "Microsoft.Office.OneNote", "Microsoft.Messaging", "Microsoft.MSPaint", "Microsoft.Windows.Photos", "Microsoft.StorePurchaseApp", "Microsoft.MicrosoftOfficeHub", "Microsoft.MicrosoftStickyNotes", "Microsoft.WindowsAlarms", "Microsoft.WindowsCalculator", "Microsoft.WindowsCommunicationsApps", # Mail, Calendar etc "Microsoft.WindowsSoundRecorder", "Microsoft.WindowsStore" )) # Windows 10 version 1809 $WhiteListedApps.AddRange(@( "Microsoft.ScreenSketch", "Microsoft.HEIFImageExtension", "Microsoft.VP9VideoExtensions", "Microsoft.WebMediaExtensions", "Microsoft.WebpImageExtension" )) # Windows 10 version 1909 $WhiteListedApps.AddRange(@( "Microsoft.Outlook.DesktopIntegrationServicess" )) # Windows 10 version 2004 $WhiteListedApps.AddRange(@( "Microsoft.VCLibs.140.00" )) # Windows 10 version 20H2 $WhiteListedApps.AddRange(@( "Microsoft.MicrosoftEdge.Stable" )) # Windows 10 version 2H2 $WhiteListedApps.AddRange(@( "Microsoft.WindowsCamera", "Microsoft.YourPhone", "Microsoft.ZuneMusic", "Microsoft.ZuneVideo", "Microsoft.Microsoft3DViewer" # Add the appname which you want keep here. )) } Process { # Functions function Write-LogEntry { param( [parameter(Mandatory = $true, HelpMessage = "Value added to the RemovedApps.log file.")] [ValidateNotNullOrEmpty()] [string]$Value, [parameter(Mandatory = $false, HelpMessage = "Name of the log file that the entry will written to.")] [ValidateNotNullOrEmpty()] [string]$FileName = "RemovedApps.log" ) # Determine log file location $LogFilePath = Join-Path -Path $env:windir -ChildPath "Temp\$($FileName)" # Add value to log file try { Out-File -InputObject $Value -Append -NoClobber -Encoding Default -FilePath $LogFilePath -ErrorAction Stop } catch [System.Exception] { Write-Warning -Message "Unable to append log entry to $($FileName) file" } } # Initial logging Write-LogEntry -Value "Starting built-in AppxPackage, AppxProvisioningPackage and Feature on Demand V2 removal process" # Determine provisioned apps $AppArrayList = Get-AppxProvisionedPackage -Online | Select-Object -ExpandProperty DisplayName # Loop through the list of appx packages foreach ($App in $AppArrayList) { Write-LogEntry -Value "Processing appx package: $($App)" # If application name not in appx package white list, remove AppxPackage and AppxProvisioningPackage if (($App -in $WhiteListedApps)) { Write-LogEntry -Value "Skipping excluded application package: $($App)" } else { # Gather package names $AppPackageFullName = Get-AppxPackage -Name $App | Select-Object -ExpandProperty PackageFullName -First 1 $AppProvisioningPackageName = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -like $App } | Select-Object -ExpandProperty PackageName -First 1 # Attempt to remove AppxPackage if ($AppPackageFullName -ne $null) { try { Write-LogEntry -Value "Removing AppxPackage: $($AppPackageFullName)" Remove-AppxPackage -Package $AppPackageFullName -ErrorAction Stop | Out-Null } catch [System.Exception] { Write-LogEntry -Value "Removing AppxPackage '$($AppPackageFullName)' failed: $($_.Exception.Message)" } } else { Write-LogEntry -Value "Unable to locate AppxPackage for current app: $($App)" } # Attempt to remove AppxProvisioningPackage if ($AppProvisioningPackageName -ne $null) { try { Write-LogEntry -Value "Removing AppxProvisioningPackage: $($AppProvisioningPackageName)" Remove-AppxProvisionedPackage -PackageName $AppProvisioningPackageName -Online -ErrorAction Stop | Out-Null } catch [System.Exception] { Write-LogEntry -Value "Removing AppxProvisioningPackage '$($AppProvisioningPackageName)' failed: $($_.Exception.Message)" } } else { Write-LogEntry -Value "Unable to locate AppxProvisioningPackage for current app: $($App)" } } } # Complete Write-LogEntry -Value "Completed built-in AppxPackage, AppxProvisioningPackage and Feature on Demand V2 removal process" }


    脚本用法

    将上述脚本复制并保存到MDT的Scripts目录中,我的存放在%SCRIPTROOT%\Custom\Remove-Builtin-Apps\Invoke-RemoveBuiltinApps.ps1

    该脚本也可以用在SCCM的Task中,具体使用方法请参考下图

    MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用_MDT


    执行效果

    本篇不再介绍如何捕捉镜像以及过程中创建暂停任务功能,如需可参考上一篇文档。

    执行前应用的数量:

    MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用_MDT部署Windows_02

    任务执行状态:

    执行后应用的数量:

    MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用_MDT_03

    日志文件:

    MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用_MDT_04


    后续

    至此,已经完成在制作捕捉镜像时移除不需要的系统内置应用的需求。

    但如果不出意外(你的环境中服务器、客户端能否访问互联网并且执行了系统更新时)你将会在Sysprep过程中遇到如下错误:(

    MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows内置应用_MDT_05

    Error SYSPRP Package <PackageFullName> was installed for a user, but not provisioned for all users. This package will not function properly in the sysprep image. <Date> <Time>, Error SYSPRP Failed to remove apps for the current user: 0x80073cf2. <Date> <Time>, Error SYSPRP Exit code of RemoveAllApps thread was 0x3cf2. ....

    下一篇我将介绍使用多种方式解决因删除或更新包含内置Windows映像的Microsoft Store应用后Sysprep失败的问题。


    Enjoy ~~ :) 

    【本文转自:香港服务器 http://www.558idc.com/hk.html提供,感谢支持】
    上一篇:mongodb数据如何导入到clickhouse
    下一篇:没有了
    网友评论