- Fix an issue with removal of Defender/OneDrive/Edge after FFU is complete

- Migrate Winget downloads to use Export-WingetPackage cmdlet as per issue Known Issue: Winget downloads fail on Non-English OS #50
- Add better logging when unable to find HDD when applying FFU
This commit is contained in:
rbalsleyMSFT
2024-09-04 13:20:35 -07:00
parent 6da9ece0d8
commit 7d74feec0c
2 changed files with 308 additions and 170 deletions
+302 -169
View File
@@ -332,7 +332,7 @@ param(
[bool]$AllowExternalHardDiskMedia,
[bool]$PromptExternalHardDiskMedia = $true
)
$version = '2408.2'
$version = '2409.1'
#Check if Hyper-V feature is installed (requires only checks the module)
$osInfo = Get-WmiObject -Class Win32_OperatingSystem
@@ -1679,33 +1679,82 @@ function Install-WinGet {
WriteLog "Downloading $($package.Name) from $($package.Url) to $destination"
Start-BitsTransferWithRetry -Source $package.Url -Destination $destination
WriteLog "Installing $($package.Name)..."
# Don't show progress bar for Add-AppxPackage - there's a weird issue where the progress stays on the screen after the apps are installed
$ProgressPreference = 'SilentlyContinue'
Add-AppxPackage -Path $destination -ErrorAction SilentlyContinue
# Set progress preference back to default
$ProgressPreference = 'Continue'
WriteLog "Removing $($package.Name)..."
Remove-Item -Path $destination -Force -ErrorAction SilentlyContinue
}
WriteLog "WinGet installation complete."
}
# function Confirm-WinGetInstallation {
# WriteLog 'Checking if WinGet is installed...'
# $wingetPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
# $minVersion = [version]"1.8.1911"
# if (-not (Test-Path -Path $wingetPath -PathType Leaf)) {
# WriteLog "WinGet is not installed. Downloading WinGet..."
# Install-WinGet -Architecture $WindowsArch
# }
# if (-not (Get-Command -Name winget -ErrorAction SilentlyContinue)) {
# WriteLog "WinGet not found. Downloading WinGet..."
# Install-WinGet -Architecture $WindowsArch
# }
# $wingetVersion = & winget.exe --version
# WriteLog "Installed version of WinGet: $wingetVersion"
# if ($wingetVersion -match 'v?(\d+\.\d+\.\d+)' -and [version]$matches[1] -lt $minVersion) {
# WriteLog "The installed version of WinGet $($matches[1]) does not support downloading MSStore apps. Downloading the latest version of WinGet..."
# Install-WinGet -Architecture $WindowsArch
# }
# # Check if Winget PowerShell module version 1.8.1911 or later is installed
# $wingetModule = Get-InstalledModule -Name Microsoft.Winget.Client -ErrorAction SilentlyContinue
# if ($wingetModule.Version -lt $minVersion -or -not $wingetModule) {
# WriteLog 'Microsoft.Winget.Client module is not installed or is an older version. Installing the latest version...'
# #Check if PSGallery is a trusted repository
# $PSGalleryTrust = (Get-PSRepository -Name 'PSGallery').InstallationPolicy
# if($PSGalleryTrust -eq 'Untrusted'){
# WriteLog 'Temporarily setting PSGallery as a trusted repository...'
# Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
# }
# Install-Module -Name Microsoft.Winget.Client -Force -Repository 'PSGallery'
# if($PSGalleryTrust -eq 'Untrusted'){
# WriteLog 'Setting PSGallery back to untrusted repository...'
# Set-PSRepository -Name 'PSGallery' -InstallationPolicy Untrusted
# WriteLog 'Done'
# }
# }
# }
function Confirm-WinGetInstallation {
WriteLog 'Checking if WinGet is installed...'
$wingetPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
$minVersion = [version]"1.8.1911"
if (-not (Test-Path -Path $wingetPath -PathType Leaf)) {
WriteLog "WinGet is not installed. Downloading WinGet..."
Install-WinGet -Architecture $WindowsArch
return
}
if (-not (Get-Command -Name winget -ErrorAction SilentlyContinue)) {
WriteLog "WinGet not found. Downloading WinGet..."
Install-WinGet -Architecture $WindowsArch
return
# Check if Winget PowerShell module version 1.8.1911 or later is installed
$wingetModule = Get-InstalledModule -Name Microsoft.Winget.Client -ErrorAction SilentlyContinue
if ($wingetModule.Version -lt $minVersion -or -not $wingetModule) {
WriteLog 'Microsoft.Winget.Client module is not installed or is an older version. Installing the latest version...'
#Check if PSGallery is a trusted repository
$PSGalleryTrust = (Get-PSRepository -Name 'PSGallery').InstallationPolicy
if($PSGalleryTrust -eq 'Untrusted'){
WriteLog 'Temporarily setting PSGallery as a trusted repository...'
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
}
Install-Module -Name Microsoft.Winget.Client -Force -Repository 'PSGallery'
if($PSGalleryTrust -eq 'Untrusted'){
WriteLog 'Setting PSGallery back to untrusted repository...'
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Untrusted
WriteLog 'Done'
}
}
$wingetVersion = & winget.exe --version
WriteLog "Installed version of WinGet: $wingetVersion"
if ($wingetVersion -match 'v?(\d+\.\d+\.\d+)' -and [version]$matches[1] -lt $minVersion) {
WriteLog "The installed version of WinGet $($matches[1]) does not support downloading MSStore apps. Downloading the latest version of WinGet..."
$wingetVersion = Get-WinGetVersion
if (-not $wingetVersion) {
WriteLog "WinGet is not installed. Installing WinGet..."
Install-WinGet -Architecture $WindowsArch
}
if (($wingetVersion -match 'v?(\d+\.\d+\.\d+)' -and [version]$matches[1] -lt $minVersion)) {
WriteLog "The installed version of WinGet $($matches[1]) does not support downloading MSStore apps. Installing the latest version of WinGet..."
Install-WinGet -Architecture $WindowsArch
return
}
}
@@ -1753,51 +1802,106 @@ function Set-InstallStoreAppsFlag {
}
}
# function Get-WinGetApp {
# param (
# [string]$WinGetAppName,
# [string]$WinGetAppId
# )
# $wingetSearchResult = & winget.exe search --id "$WinGetAppId" --exact --accept-source-agreements --source winget
# if ($wingetSearchResult -contains "No package found matching input criteria.") {
# if ($VerbosePreference -ne 'Continue'){
# Write-Error "$WinGetAppName not found in WinGet repository. Skipping download."
# Write-Error "Check the AppList.json file and make sure the AppID is correct."
# Write-Error "If OS language is not English, winget download may fail. We hope to have this addressed in a future release."
# }
# WriteLog "$WinGetAppName not found in WinGet repository. Exiting."
# WriteLog "Check the AppList.json file and make sure the AppID is correct."
# WriteLog "If OS language is not English, winget download may fail. We hope to have this addressed in a future release."
# Exit 1
# }
# $appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetAppName
# WriteLog "Creating $appFolderPath"
# New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
# WriteLog "Downloading $WinGetAppName to $appFolderPath"
# $downloadParams = @(
# "download",
# "--id", "$WinGetAppId",
# "--exact",
# "--download-directory", "$appFolderPath",
# "--accept-package-agreements",
# "--accept-source-agreements",
# "--source", "winget",
# "--scope", "machine",
# "--architecture", "$WindowsArch"
# )
# WriteLog "winget command: winget.exe $downloadParams"
# $wingetDownloadResult = & winget.exe @downloadParams | Out-String
# if ($wingetDownloadResult -match "No applicable installer found") {
# WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
# $downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
# $wingetDownloadResult = & winget.exe @downloadParams | Out-String
# if ($wingetDownloadResult -match "Installer downloaded") {
# WriteLog "Downloaded $WinGetAppName without specifying architecture."
# }
# }
# if ($wingetDownloadResult -notmatch "Installer downloaded") {
# WriteLog "No installer found for $WinGetAppName. Skipping download."
# Remove-Item -Path $appFolderPath -Recurse -Force
# }
# WriteLog "$WinGetAppName downloaded to $appFolderPath"
# $installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop
# $uwpExtensions = @(".appx", ".appxbundle", ".msix", ".msixbundle")
# if ($uwpExtensions -contains $installerPath.Extension) {
# $NewAppPath = "$AppsPath\MSStore\$WinGetAppName"
# Writelog "$WinGetAppName is a UWP app. Moving to $NewAppPath"
# WriteLog "Creating $NewAppPath"
# New-Item -Path "$AppsPath\MSStore\$WinGetAppName" -ItemType Directory -Force | Out-Null
# WriteLog "Moving $WinGetAppName to $NewAppPath"
# Move-Item -Path "$appFolderPath\*" -Destination "$AppsPath\MSStore\$WinGetAppName" -Force
# WriteLog "Removing $appFolderPath"
# Remove-Item -Path $appFolderPath -Force
# WriteLog "$WinGetAppName moved to $NewAppPath"
# Set-InstallStoreAppsFlag
# }
# else {
# Add-Win32SilentInstallCommand -AppFolder $WinGetAppName -AppFolderPath $appFolderPath
# }
# }
function Get-WinGetApp {
param (
[string]$WinGetAppName,
[string]$WinGetAppId
)
$wingetSearchResult = & winget.exe search --id "$WinGetAppId" --exact --accept-source-agreements --source winget
if ($wingetSearchResult -contains "No package found matching input criteria.") {
$Source = 'winget'
$wingetSearchResult = Find-WinGetPackage -id $WinGetAppId -MatchOption Equals -Source $Source
if (-not $wingetSearchResult) {
if ($VerbosePreference -ne 'Continue'){
Write-Error "$WinGetAppName not found in WinGet repository. Skipping download."
Write-Error "$WinGetAppName not found in WinGet repository. Exiting."
Write-Error "Check the AppList.json file and make sure the AppID is correct."
Write-Error "If OS language is not English, winget download may fail. We hope to have this addressed in a future release."
}
WriteLog "$WinGetAppName not found in WinGet repository. Exiting."
WriteLog "Check the AppList.json file and make sure the AppID is correct."
WriteLog "If OS language is not English, winget download may fail. We hope to have this addressed in a future release."
Exit 1
}
$appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetAppName
WriteLog "Creating $appFolderPath"
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
WriteLog "Downloading $WinGetAppName to $appFolderPath"
$downloadParams = @(
"download",
"--id", "$WinGetAppId",
"--exact",
"--download-directory", "$appFolderPath",
"--accept-package-agreements",
"--accept-source-agreements",
"--source", "winget",
"--scope", "machine",
"--architecture", "$WindowsArch"
)
WriteLog "winget command: winget.exe $downloadParams"
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
if ($wingetDownloadResult -match "No applicable installer found") {
WriteLog "WinGet command: Export-WinGetPackage -id $WinGetAppId -DownloadDirectory $appFolderPath -Architecture $WindowsArch -Source $Source"
$wingetDownloadResult = Export-WinGetPackage -id $WinGetAppId -DownloadDirectory $appFolderPath -Architecture $WindowsArch -Source $Source
if ($wingetDownloadResult.status -eq 'NoApplicableInstallers') {
# If no applicable installer is found, try downloading without specifying architecture
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
if ($wingetDownloadResult -match "Installer downloaded") {
$wingetDownloadResult = Export-WinGetPackage -id $WinGetAppId -DownloadDirectory $appFolderPath -Source $Source
if ($wingetDownloadResult.status -eq 'Ok') {
WriteLog "Downloaded $WinGetAppName without specifying architecture."
}
}
if ($wingetDownloadResult -notmatch "Installer downloaded") {
WriteLog "No installer found for $WinGetAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
else{
WriteLog "No installer found for $WinGetAppName. Exiting."
Remove-Item -Path $appFolderPath -Recurse -Force
Exit 1
}
}
WriteLog "$WinGetAppName downloaded to $appFolderPath"
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop
@@ -1819,15 +1923,105 @@ function Get-WinGetApp {
}
}
# function Get-StoreApp {
# param (
# [string]$StoreAppName,
# [string]$StoreAppId
# )
# $wingetSearchResult = & winget.exe search "$StoreAppId" --accept-source-agreements --source msstore
# if ($wingetSearchResult -contains "No package found matching input criteria.") {
# WriteLog "$StoreAppName not found in WinGet repository. Skipping download."
# return
# }
# WriteLog "Checking if $StoreAppName is a win32 app..."
# $appIsWin32 = $StoreAppId.StartsWith("XP")
# if ($appIsWin32) {
# WriteLog "$StoreAppName is a win32 app. Adding to $AppsPath\win32 folder"
# $appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreAppName
# }
# else {
# WriteLog "$StoreAppName is not a win32 app."
# $appFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $StoreAppName
# }
# New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
# WriteLog "Downloading $StoreAppName for $WindowsArch architecture..."
# $downloadParams = @(
# "download", "$StoreAppId",
# "--download-directory", "$appFolderPath",
# "--accept-package-agreements",
# "--accept-source-agreements",
# "--source", "msstore",
# "--scope", "machine",
# "--architecture", "$WindowsArch"
# )
# WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.'
# WriteLog "Attempting to download $StoreAppName and dependencies for $WindowsArch architecture..."
# $wingetDownloadResult = & winget.exe @downloadParams | Out-String
# # For some apps, specifying the architecture leads to no results found for the app. In those cases, the command will be run without the architecture parameter.
# if ($wingetDownloadResult -match "No applicable installer found") {
# WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
# $downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
# $wingetDownloadResult = & winget.exe @downloadParams | Out-String
# if ($wingetDownloadResult -match "Microsoft Store package download completed") {
# WriteLog "Downloaded $StoreAppName without specifying architecture."
# }
# }
# if ($wingetDownloadResult -notmatch "Installer downloaded|Microsoft Store package download completed") {
# WriteLog "Download not supported for $StoreAppName. Skipping download."
# Remove-Item -Path $appFolderPath -Recurse -Force
# return
# }
# if ($appIsWin32) {
# Add-Win32SilentInstallCommand -AppFolder $StoreAppName -AppFolderPath $appFolderPath
# }
# Set-InstallStoreAppsFlag
# # If $WindowsArch -eq 'ARM64', remove all dependency files that are not ARM64
# if ($WindowsArch -eq 'ARM64') {
# WriteLog 'Windows architecture is ARM64. Removing dependencies that are not ARM64.'
# $dependencies = Get-ChildItem -Path "$appFolderPath\Dependencies" -ErrorAction SilentlyContinue
# if ($dependencies) {
# foreach ($dependency in $dependencies) {
# if ($dependency.Name -notmatch 'ARM64') {
# WriteLog "Removing dependency file $($dependency.FullName)"
# Remove-Item -Path $dependency.FullName -Recurse -Force
# }
# }
# }
# }
# WriteLog "$StoreAppName has completed downloading. Identifying the latest version of $StoreAppName."
# $packages = Get-ChildItem -Path "$appFolderPath\*" -Exclude "Dependencies\*", "*.xml", "*.yaml" -File -ErrorAction Stop
# # WinGet downloads multiple versions of certain store apps. The latest version of the package will be determined based on the date of the file signature.
# $latestPackage = $packages | Sort-Object { (Get-AuthenticodeSignature $_.FullName).SignerCertificate.NotBefore } -Descending | Select-Object -First 1
# # Removing all packages that are not the latest version
# WriteLog "Latest version of $StoreAppName has been identified as $latestPackage. Removing old versions of $StoreAppName that may have downloaded."
# foreach ($package in $packages) {
# if ($package.FullName -ne $latestPackage) {
# try {
# WriteLog "Removing $($package.FullName)"
# Remove-Item -Path $package.FullName -Force
# }
# catch {
# WriteLog "Failed to delete: $($package.FullName) - $_"
# throw $_
# }
# }
# }
# }
function Get-StoreApp {
param (
[string]$StoreAppName,
[string]$StoreAppId
)
$wingetSearchResult = & winget.exe search "$StoreAppId" --accept-source-agreements --source msstore
if ($wingetSearchResult -contains "No package found matching input criteria.") {
WriteLog "$StoreAppName not found in WinGet repository. Skipping download."
return
$Source = 'msstore'
$wingetSearchResult = Find-WinGetPackage -id $StoreAppId -MatchOption Equals -Source $Source
if (-not $wingetSearchResult) {
if ($VerbosePreference -ne 'Continue'){
Write-Error "$WinGetAppName not found in WinGet repository. Exiting."
Write-Error "Check the AppList.json file and make sure the AppID is correct."
}
WriteLog "$WinGetAppName not found in WinGet repository. Exiting."
WriteLog "Check the AppList.json file and make sure the AppID is correct."
Exit 1
}
WriteLog "Checking if $StoreAppName is a win32 app..."
$appIsWin32 = $StoreAppId.StartsWith("XP")
@@ -1841,31 +2035,22 @@ function Get-StoreApp {
}
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
WriteLog "Downloading $StoreAppName for $WindowsArch architecture..."
$downloadParams = @(
"download", "$StoreAppId",
"--download-directory", "$appFolderPath",
"--accept-package-agreements",
"--accept-source-agreements",
"--source", "msstore",
"--scope", "machine",
"--architecture", "$WindowsArch"
)
WriteLog 'MSStore app downloads require authentication with an Entra ID account. You may be prompted twice for credentials, once for the app and another for the license file.'
WriteLog "Attempting to download $StoreAppName and dependencies for $WindowsArch architecture..."
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
# For some apps, specifying the architecture leads to no results found for the app. In those cases, the command will be run without the architecture parameter.
if ($wingetDownloadResult -match "No applicable installer found") {
WriteLog "WinGet command: Export-WinGetPackage -id $StoreAppId -DownloadDirectory $appFolderPath -Architecture $WindowsArch -Source $Source"
$wingetDownloadResult = Export-WinGetPackage -id $StoreAppId -DownloadDirectory $appFolderPath -Architecture $WindowsArch -Source $Source
if ($wingetDownloadResult.status -eq 'NoApplicableInstallerFound') {
# If no applicable installer is found, try downloading without specifying architecture
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
$downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
if ($wingetDownloadResult -match "Microsoft Store package download completed") {
WriteLog "Downloaded $StoreAppName without specifying architecture."
$wingetDownloadResult = Export-WinGetPackage -id $StoreAppId -DownloadDirectory $appFolderPath -Source $Source
if ($wingetDownloadResult.status -eq 'Ok') {
WriteLog "Downloaded $WinGetAppName without specifying architecture."
}
else{
WriteLog "No installer found for $WinGetAppName. Exiting"
Remove-Item -Path $appFolderPath -Recurse -Force
Exit 1
}
}
if ($wingetDownloadResult -notmatch "Installer downloaded|Microsoft Store package download completed") {
WriteLog "Download not supported for $StoreAppName. Skipping download."
Remove-Item -Path $appFolderPath -Recurse -Force
return
}
if ($appIsWin32) {
Add-Win32SilentInstallCommand -AppFolder $StoreAppName -AppFolderPath $appFolderPath
@@ -2054,68 +2239,6 @@ function Save-KB {
if ($WindowsArch -eq 'x64') {
[array]$WindowsArch = @("x64", "amd64")
}
#Keep for now, will remove in future
# foreach ($kb in $name) {
# $links = Get-KBLink -Name $kb
# foreach ($link in $links) {
# #Check if $WindowsArch is an array
# if ($WindowsArch -is [array]) {
# #Some file names include either x64 or amd64
# if ($link -match $WindowsArch[0] -or $link -match $WindowsArch[1]) {
# Start-BitsTransferWithRetry -Source $link -Destination $Path
# $fileName = ($link -split '/')[-1]
# break
# }
# # elseif (!($link -match 'x64' -or $link -match 'amd64' -or $link -match 'x86' -or $link -match 'arm64')) {
# # Write-Host "No architecture found in $link, assume it's for all architectures"
# # Start-BitsTransfer -Source $link -Destination $Path
# # $fileName = ($link -split '/')[-1]
# # break
# # }
# elseif (!($link -match 'x64' -or $link -match 'amd64' -or $link -match 'x86' -or $link -match 'arm64')) {
# WriteLog "No architecture found in $link, assume this is for all architectures"
# #FIX: 3/22/2024 - the SecurityHealthSetup fix was updated and now includes two files (one is x64 and the other is arm64)
# #Unfortunately there is no easy way to determine the architecture from the file name
# #There is a support doc that include links to download, but it's out of date (n-1)
# #https://support.microsoft.com/en-us/topic/windows-security-update-a6ac7d2e-b1bf-44c0-a028-41720a242da3
# #These files don't change that often, so will check the link above to see when it updates and may use that
# #For now this is hard-coded for these specific file names
# if ($link -match 'security'){
# #Make sure we're getting the correct architecture for the Security Health Setup update
# WriteLog "Link: $link matches security"
# if ($WindowsArch -eq 'x64'){
# if ($link -match 'securityhealthsetup_e1'){
# Writelog "Downloading $Link for $WindowsArch to $Path"
# Start-BitsTransferWithRetry -Source $link -Destination $Path
# $fileName = ($link -split '/')[-1]
# Writelog "Returning $fileName"
# break
# }
# }
# elseif ($WindowsArch -eq 'arm64'){
# if ($link -match 'securityhealthsetup_25'){
# Writelog "Downloading $Link for $WindowsArch to $Path"
# Start-BitsTransferWithRetry -Source $link -Destination $Path
# $fileName = ($link -split '/')[-1]
# Writelog "Returning $fileName"
# break
# }
# }
# continue
# }
# Start-BitsTransferWithRetry -Source $link -Destination $Path
# $fileName = ($link -split '/')[-1]
# }
# }
# else {
# if ($link -match $WindowsArch) {
# Start-BitsTransferWithRetry -Source $link -Destination $Path
# $fileName = ($link -split '/')[-1]
# break
# }
# }
# }
# }
foreach ($kb in $name) {
$links = Get-KBLink -Name $kb
foreach ($link in $links) {
@@ -3326,8 +3449,13 @@ function Get-FFUEnvironment {
foreach ($image in $mountedImages) {
$mountPath = $image.Path
WriteLog "Dismounting image at $mountPath"
Dismount-WindowsImage -Path $mountPath -discard | Out-null
WriteLog "Successfully dismounted image at $mountPath"
try {
Dismount-WindowsImage -Path $mountPath -discard | Out-null
WriteLog "Successfully dismounted image at $mountPath"
}
catch {
WriteLog "Failed to dismount image at $mountPath with error: $_"
}
}
}
@@ -3356,6 +3484,7 @@ function Get-FFUEnvironment {
Remove-FFUUserShare
WriteLog 'Removal complete'
}
Clear-InstallAppsandSysprep
#Clean up $KBPath
If (Test-Path -Path $KBPath) {
WriteLog "Removing $KBPath"
@@ -3388,7 +3517,6 @@ function Get-FFUEnvironment {
WriteLog "Cleaning up MSStore folder"
Remove-Item -Path "$AppsPath\MSStore" -Recurse -Force -ErrorAction SilentlyContinue
}
Clear-InstallAppsandSysprep
Writelog 'Removing dirty.txt file'
Remove-Item -Path "$FFUDevelopmentPath\dirty.txt" -Force
WriteLog "Cleanup complete"
@@ -3412,29 +3540,34 @@ function Clear-InstallAppsandSysprep {
WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove Defender Platform Update"
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
$CmdContent -notmatch 'd:\\Defender*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
# #Remove $DefenderPath
# WriteLog "Removing $DefenderPath"
# Remove-Item -Path $DefenderPath -Recurse -Force
# WriteLog "Removal complete"
#Clean up $DefenderPath
If (Test-Path -Path $DefenderPath) {
WriteLog "Removing $DefenderPath"
Remove-Item -Path $DefenderPath -Recurse -Force -ErrorAction SilentlyContinue
WriteLog 'Removal complete'
}
}
if ($UpdateOneDrive) {
WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove OneDrive install"
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
$CmdContent -notmatch 'd:\\OneDrive*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
# #Remove $OneDrivePath
# WriteLog "Removing $OneDrivePath"
# Remove-Item -Path $OneDrivePath -Recurse -Force
# WriteLog "Removal complete"
#Clean up $OneDrivePath
If (Test-Path -Path $OneDrivePath) {
WriteLog "Removing $OneDrivePath"
Remove-Item -Path $OneDrivePath -Recurse -Force -ErrorAction SilentlyContinue
WriteLog 'Removal complete'
}
}
if ($UpdateEdge) {
WriteLog "Updating $AppsPath\InstallAppsandSysprep.cmd to remove Edge install"
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
$CmdContent -notmatch 'd:\\Edge*' | Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
# #Remove $EdgePath
# WriteLog "Removing $EdgePath"
# Remove-Item -Path $EdgePath -Recurse -Force
# WriteLog "Removal complete"
#Clean up $EdgePath
If (Test-Path -Path $EdgePath) {
WriteLog "Removing $EdgePath"
Remove-Item -Path $EdgePath -Recurse -Force -ErrorAction SilentlyContinue
WriteLog 'Removal complete'
}
}
}
@@ -4003,30 +4136,30 @@ catch {
throw $_
}
#Clean up InstallAppsandSysprep.cmd
try {
WriteLog "Cleaning up $AppsPath\InstallAppsandSysprep.cmd"
Clear-InstallAppsandSysprep
}
catch {
Write-Host 'Cleaning up InstallAppsandSysprep.cmd failed'
Writelog "Cleaning up InstallAppsandSysprep.cmd failed with error $_"
throw $_
}
try {
if (Test-Path -Path "$AppsPath\Win32" -PathType Container) {
WriteLog "Cleaning up Win32 folder"
Remove-Item -Path "$AppsPath\Win32" -Recurse -Force
}
if (Test-Path -Path "$AppsPath\MSStore" -PathType Container) {
WriteLog "Cleaning up MSStore folder"
Remove-Item -Path "$AppsPath\MSStore" -Recurse -Force
}
}
catch {
WriteLog "$_"
throw $_
}
# #Clean up InstallAppsandSysprep.cmd
# try {
# WriteLog "Cleaning up $AppsPath\InstallAppsandSysprep.cmd"
# Clear-InstallAppsandSysprep
# }
# catch {
# Write-Host 'Cleaning up InstallAppsandSysprep.cmd failed'
# Writelog "Cleaning up InstallAppsandSysprep.cmd failed with error $_"
# throw $_
# }
# try {
# if (Test-Path -Path "$AppsPath\Win32" -PathType Container) {
# WriteLog "Cleaning up Win32 folder"
# Remove-Item -Path "$AppsPath\Win32" -Recurse -Force
# }
# if (Test-Path -Path "$AppsPath\MSStore" -PathType Container) {
# WriteLog "Cleaning up MSStore folder"
# Remove-Item -Path "$AppsPath\MSStore" -Recurse -Force
# }
# }
# catch {
# WriteLog "$_"
# throw $_
# }
#Create Deployment Media
If ($CreateDeploymentMedia) {
try {
@@ -128,13 +128,18 @@ $LogFileName = 'ScriptLog.txt'
$USBDrive = Get-USBDrive
New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null
$LogFile = $USBDrive + $LogFilename
$version = '2408.2'
$version = '2409.1'
WriteLog 'Begin Logging'
WriteLog "Script version: $version"
#Find PhysicalDrive
# $PhysicalDeviceID = Get-HardDrive
$hardDrive = Get-HardDrive
if($hardDrive -eq $null){
WriteLog 'No hard drive found. Exiting'
WriteLog 'Try adding storage drivers to the PE boot image (you can re-create your FFU and USB drive and add the PE drivers to the PEDrivers folder and add -CopyPEDrivers $true to the command line, or manually add them via DISM)'
Exit
}
$PhysicalDeviceID = $hardDrive.DeviceID
$BytesPerSector = $hardDrive.BytesPerSector
WriteLog "Physical BytesPerSector is $BytesPerSector"