mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Merge branch '2407.1' of https://github.com/rbalsleyMSFT/FFU into 2407.1
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"apps": [
|
||||||
|
{
|
||||||
|
"name": "7-Zip",
|
||||||
|
"id": "7zip.7zip",
|
||||||
|
"source": "winget"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Company Portal",
|
||||||
|
"id": "9WZDNCRFJ3PZ",
|
||||||
|
"source": "msstore"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft Teams",
|
||||||
|
"id": "Microsoft.Teams",
|
||||||
|
"source": "winget"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
winget:7-Zip
|
|
||||||
store:Company Portal
|
|
||||||
@@ -33,11 +33,12 @@ for /d %%D in ("%basepath%\*") do (
|
|||||||
set "licensefile=%%F"
|
set "licensefile=%%F"
|
||||||
)
|
)
|
||||||
if defined mainpackage (
|
if defined mainpackage (
|
||||||
if exist "!dependenciesfolder!" (
|
|
||||||
set "dism_command=DISM /Online /Add-ProvisionedAppxPackage /PackagePath:"!mainpackage!""
|
set "dism_command=DISM /Online /Add-ProvisionedAppxPackage /PackagePath:"!mainpackage!""
|
||||||
|
if exist "!dependenciesfolder!" (
|
||||||
for %%G in ("!dependenciesfolder!\*") do (
|
for %%G in ("!dependenciesfolder!\*") do (
|
||||||
set "dism_command=!dism_command! /DependencyPackagePath:"%%G""
|
set "dism_command=!dism_command! /DependencyPackagePath:"%%G""
|
||||||
)
|
)
|
||||||
|
)
|
||||||
if defined licensefile (
|
if defined licensefile (
|
||||||
set "dism_command=!dism_command! /LicensePath:"!licensefile!""
|
set "dism_command=!dism_command! /LicensePath:"!licensefile!""
|
||||||
) else (
|
) else (
|
||||||
@@ -47,10 +48,14 @@ for /d %%D in ("%basepath%\*") do (
|
|||||||
echo !dism_command!
|
echo !dism_command!
|
||||||
!dism_command!
|
!dism_command!
|
||||||
)
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
:remaining
|
:remaining
|
||||||
endlocal
|
endlocal
|
||||||
|
for /r "D:\" %%G in (.) do (
|
||||||
|
if exist "%%G\Notepad++" (
|
||||||
|
powershell -Command "Remove-AppxPackage -Package NotepadPlusPlus_1.0.0.0_neutral__7njy0v32s6xk6"
|
||||||
|
)
|
||||||
|
)
|
||||||
REM The below lines will remove the unattend.xml that gets the machine into audit mode. If not removed, the OS will get stuck booting to audit mode each time.
|
REM The below lines will remove the unattend.xml that gets the machine into audit mode. If not removed, the OS will get stuck booting to audit mode each time.
|
||||||
REM Also kills the sysprep process in order to automate sysprep generalize
|
REM Also kills the sysprep process in order to automate sysprep generalize
|
||||||
del c:\windows\panther\unattend\unattend.xml /F /Q
|
del c:\windows\panther\unattend\unattend.xml /F /Q
|
||||||
|
|||||||
+155
-189
@@ -1660,102 +1660,72 @@ function Get-Office {
|
|||||||
|
|
||||||
function Install-WinGet {
|
function Install-WinGet {
|
||||||
param (
|
param (
|
||||||
[bool]$InstallWithDependencies
|
[string]$Architecture
|
||||||
)
|
)
|
||||||
$wingetPreviewLink = "https://aka.ms/getwingetpreview"
|
$packages = @(
|
||||||
$wingetPackageDestination = "$env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
|
@{Name = "VCLibs"; Url = "https://aka.ms/Microsoft.VCLibs.$Architecture.14.00.Desktop.appx"; File = "Microsoft.VCLibs.$Architecture.14.00.Desktop.appx"},
|
||||||
if ($InstallWithDependencies) {
|
@{Name = "UIXaml"; Url = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.$Architecture.appx"; File = "Microsoft.UI.Xaml.2.8.$Architecture.appx"},
|
||||||
$dependencies = @(
|
@{Name = "WinGet"; Url = "https://aka.ms/getwinget"; File = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"}
|
||||||
@{
|
|
||||||
Source = "https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx"
|
|
||||||
Destination = "$env:TEMP\Microsoft.VCLibs.x64.14.00.Desktop.appx"
|
|
||||||
},
|
|
||||||
@{
|
|
||||||
Source = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.x64.appx"
|
|
||||||
Destination = "$env:TEMP\Microsoft.UI.Xaml.2.8.x64.appx"
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
Start-BitsTransferWithRetry -Source $wingetPreviewLink -Destination $wingetPackageDestination
|
foreach ($package in $packages) {
|
||||||
foreach ($dependency in $dependencies) {
|
$destination = Join-Path -Path $env:TEMP -ChildPath $package.File
|
||||||
Start-BitsTransferWithRetry -Source $dependency.Source -Destination $dependency.Destination
|
WriteLog "Downloading $($package.Name) from $($package.Url) to $destination"
|
||||||
Add-AppxPackage -Path $dependency.Destination
|
Start-BitsTransferWithRetry -Source $package.Url -Destination $destination
|
||||||
Remove-Item -Path $dependency.Destination -Force -ErrorAction SilentlyContinue
|
WriteLog "Installing $($package.Name)..."
|
||||||
}
|
Add-AppxPackage -Path $destination -ErrorAction SilentlyContinue
|
||||||
Add-AppxPackage -Path $wingetPackageDestination
|
WriteLog "Removing $($package.Name)..."
|
||||||
Remove-Item -Path $wingetPackageDestination -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $destination -Force -ErrorAction SilentlyContinue
|
||||||
}
|
|
||||||
else {
|
|
||||||
# If WinGet was already installed, then installing the dependencies can cause an error if the system has a newer version of the dependencies than the ones downloaded.
|
|
||||||
WriteLog "Downloading WinGet..."
|
|
||||||
Start-BitsTransferWithRetry -Source $wingetPreviewLink -Destination $wingetPackageDestination
|
|
||||||
WriteLog "Installing WinGet..."
|
|
||||||
Add-AppxPackage -Path $wingetPackageDestination
|
|
||||||
WriteLog "Removing WinGet installer..."
|
|
||||||
Remove-Item -Path $wingetPackageDestination -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
}
|
||||||
|
WriteLog "WinGet installation complete."
|
||||||
}
|
}
|
||||||
|
|
||||||
function New-WinGetSettings {
|
function Confirm-WinGetInstallation {
|
||||||
$wingetSettingsFile = "$env:LOCALAPPDATA\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json"
|
$wingetPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe"
|
||||||
$wingetSettings = @(
|
$minVersion = [version]"1.8.1911"
|
||||||
'{'
|
if (-not (Test-Path -Path $wingetPath -PathType Leaf)) {
|
||||||
' "$schema": "https://aka.ms/winget-settings.schema.json",'
|
WriteLog "WinGet is not installed. Downloading WinGet..."
|
||||||
' '
|
Install-WinGet -Architecture $WindowsArch
|
||||||
' // For documentation on these settings, see: https://aka.ms/winget-settings'
|
return
|
||||||
' "experimentalFeatures": {'
|
|
||||||
' "storeDownload": true'
|
|
||||||
' },'
|
|
||||||
' "logging": {'
|
|
||||||
' "level": "verbose"'
|
|
||||||
' }'
|
|
||||||
'}'
|
|
||||||
)
|
|
||||||
$wingetSettingsContent = $wingetSettings -join "`n"
|
|
||||||
if (Test-Path -Path $wingetSettingsFile -PathType Leaf) {
|
|
||||||
$jsonContent = Get-Content -Path $wingetSettingsFile -Raw
|
|
||||||
# Check if storeDownload feature is already enabled
|
|
||||||
if ($jsonContent -notmatch '"storeDownload"\s*:\s*true') {
|
|
||||||
# Back up existing settings.json file
|
|
||||||
$backupWingetSettingsFile = $wingetSettingsFile + ".bak"
|
|
||||||
if (-not (Test-Path -Path $backupWingetSettingsFile -PathType Leaf)) {
|
|
||||||
WriteLog "Backing up existing WinGet settings.json file to $backupWingetSettingsFile"
|
|
||||||
Copy-Item -Path $wingetSettingsFile -Destination $backupWingetSettingsFile -Force | Out-Null
|
|
||||||
}
|
}
|
||||||
WriteLog "Creating WinGet settings.json file to allow the storeDownload feature. Writing file to $wingetSettingsFile"
|
if (-not (Get-Command -Name winget -ErrorAction SilentlyContinue)) {
|
||||||
$wingetSettingsContent | Out-File -FilePath $wingetSettingsFile -Encoding utf8 -Force
|
WriteLog "WinGet is not on the path. Downloading WinGet..."
|
||||||
|
Install-WinGet -Architecture $WindowsArch
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
$wingetVersion = & winget.exe --version
|
||||||
WriteLog "WinGet's settings.json file is already configured to enable the storeDownload feature."
|
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
|
||||||
else {
|
return
|
||||||
WriteLog "Creating WinGet settings.json file to allow the storeDownload feature. Writing file to $wingetSettingsFile"
|
|
||||||
$wingetSettingsContent | Out-File -FilePath $wingetSettingsFile -Encoding utf8 -Force
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Add-Win32SilentInstallCommand {
|
function Add-Win32SilentInstallCommand {
|
||||||
param (
|
param (
|
||||||
[string]$AppFolder,
|
[string]$AppFolder,
|
||||||
[string]$AppFolderPath
|
[string]$AppFolderPath,
|
||||||
|
[int]$LineNumber
|
||||||
)
|
)
|
||||||
$appName = $AppFolder
|
$appName = $AppFolder
|
||||||
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Include *.exe, *.msi -File -ErrorAction Stop
|
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Include "*.exe", "*.msi" -File -ErrorAction Stop
|
||||||
$installer = Split-Path -Path $installerPath -Leaf
|
if (-not $installerPath) {
|
||||||
$yamlFile = Get-ChildItem -Path "$appFolderPath\*" -Include *.yaml -File -ErrorAction Stop
|
WriteLog "No win32 app installers were found. Skipping the inclusion of $AppFolder"
|
||||||
|
Remove-Item -Path $AppFolderPath -Recurse -Force
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
$yamlFile = Get-ChildItem -Path "$appFolderPath\*" -Include "*.yaml" -File -ErrorAction Stop
|
||||||
$yamlContent = Get-Content -Path $yamlFile -Raw
|
$yamlContent = Get-Content -Path $yamlFile -Raw
|
||||||
$silentInstallSwitch = [regex]::Match($yamlContent, 'Silent:\s*(.+)').Groups[1].Value
|
$silentInstallSwitch = [regex]::Match($yamlContent, 'Silent:\s*(.+)').Groups[1].Value.Replace("'", "").Trim()
|
||||||
$silentInstallSwitch = $silentInstallSwitch.Replace("'", "").Trim()
|
|
||||||
if (-not $silentInstallSwitch) {
|
if (-not $silentInstallSwitch) {
|
||||||
WriteLog "Silent install switch for $appName could not be found. Skipping the inclusion of $appName."
|
WriteLog "Silent install switch for $appName could not be found. Skipping the inclusion of $appName."
|
||||||
Remove-Item -Path $appFolderPath -Recurse -Force
|
Remove-Item -Path $appFolderPath -Recurse -Force
|
||||||
return
|
return $false
|
||||||
}
|
}
|
||||||
$installerFileExtension = [System.IO.Path]::GetExtension($installer)
|
$installer = Split-Path -Path $installerPath -Leaf
|
||||||
if ($installerFileExtension -eq ".exe") {
|
if ($installerPath.Extension -eq ".exe") {
|
||||||
$silentInstallCommand = "`"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
|
$silentInstallCommand = "`"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
|
||||||
}
|
}
|
||||||
elseif ($installerFileExtension -eq ".msi") {
|
elseif ($installerPath.Extension -eq ".msi") {
|
||||||
$silentInstallCommand = "msiexec /i `"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
|
$silentInstallCommand = "msiexec /i `"D:\win32\$appFolder\$installer`" $silentInstallSwitch"
|
||||||
}
|
}
|
||||||
$cmdFile = "$AppsPath\InstallAppsandSysprep.cmd"
|
$cmdFile = "$AppsPath\InstallAppsandSysprep.cmd"
|
||||||
@@ -1765,83 +1735,126 @@ function Add-Win32SilentInstallCommand {
|
|||||||
Set-Content -Path $cmdFile -Value $cmdContent
|
Set-Content -Path $cmdFile -Value $cmdContent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Set-InstallStoreAppsFlag {
|
||||||
|
$cmdPath = "$AppsPath\InstallAppsandSysprep.cmd"
|
||||||
|
$cmdContent = Get-Content -Path $cmdPath
|
||||||
|
if ($cmdContent -match 'set "INSTALL_STOREAPPS=false"') {
|
||||||
|
WriteLog "Setting INSTALL_STOREAPPS flag to true in InstallAppsandSysprep.cmd file."
|
||||||
|
$updatedcmdContent = $cmdContent -replace 'set "INSTALL_STOREAPPS=false"', 'set "INSTALL_STOREAPPS=true"'
|
||||||
|
Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $updatedcmdContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Get-WinGetApp {
|
function Get-WinGetApp {
|
||||||
param (
|
param (
|
||||||
[string]$WinGetApp,
|
[string]$WinGetAppName,
|
||||||
|
[string]$WinGetAppId,
|
||||||
[int]$LineNumber
|
[int]$LineNumber
|
||||||
)
|
)
|
||||||
$wingetSearchResult = & winget.exe search --name "$WinGetApp" --exact --accept-source-agreements --source winget
|
$wingetSearchResult = & winget.exe search --id "$WinGetAppId" --exact --accept-source-agreements --source winget
|
||||||
if ($wingetSearchResult -contains "No package found matching input criteria.") {
|
if ($wingetSearchResult -contains "No package found matching input criteria.") {
|
||||||
WriteLog "$WinGetApp not found in WinGet repository. Skipping download."
|
WriteLog "$WinGetAppName not found in WinGet repository. Skipping download."
|
||||||
return
|
# Return false to not increment line number for silent install command.
|
||||||
|
return $false
|
||||||
}
|
}
|
||||||
$appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetApp
|
$appFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $WinGetAppName
|
||||||
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
|
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
|
||||||
$appFolder = Split-Path -Path $appFolderPath -Leaf
|
WriteLog "Downloading $WinGetAppName..."
|
||||||
WriteLog "Downloading $WinGetApp..."
|
$downloadParams = @(
|
||||||
$wingetDownloadResult = & winget.exe download --name "$WinGetApp" --exact --download-directory "$appFolderPath" --scope machine --source winget --architecture "$WindowsArch" | Out-String
|
"download",
|
||||||
|
"--id", "$WinGetAppId",
|
||||||
|
"--exact",
|
||||||
|
"--download-directory", "$appFolderPath",
|
||||||
|
"--accept-package-agreements",
|
||||||
|
"--accept-source-agreements",
|
||||||
|
"--source", "winget",
|
||||||
|
"--scope", "machine",
|
||||||
|
"--architecture", "$WindowsArch"
|
||||||
|
)
|
||||||
|
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
|
||||||
if ($wingetDownloadResult -match "No applicable installer found") {
|
if ($wingetDownloadResult -match "No applicable installer found") {
|
||||||
$wingetDownloadResult = & winget.exe download --name "$WinGetApp" --exact --download-directory "$appFolderPath" --scope machine --source winget | Out-String
|
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") {
|
if ($wingetDownloadResult -notmatch "Installer downloaded") {
|
||||||
WriteLog "$WinGetApp did not successfully download."
|
WriteLog "No installer found for $WinGetAppName. Skipping download."
|
||||||
Remove-Item -Path $appFolderPath -Recurse -Force
|
Remove-Item -Path $appFolderPath -Recurse -Force
|
||||||
return
|
return $false
|
||||||
|
}
|
||||||
|
WriteLog "$WinGetAppName has completed downloading to $appFolderPath"
|
||||||
|
$installerPath = Get-ChildItem -Path "$appFolderPath\*" -Exclude "*.yaml", "*.xml" -File -ErrorAction Stop
|
||||||
|
$uwpExtensions = @(".appx", ".appxbundle", ".msix", ".msixbundle")
|
||||||
|
if ($uwpExtensions -contains $installerPath.Extension) {
|
||||||
|
New-Item -Path "$AppsPath\MSStore\$WinGetAppName" -ItemType Directory -Force | Out-Null
|
||||||
|
Move-Item -Path "$appFolderPath\*" -Destination "$AppsPath\MSStore\$WinGetAppName" -Force
|
||||||
|
Remove-Item -Path $appFolderPath -Force
|
||||||
|
Set-InstallStoreAppsFlag
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Add-Win32SilentInstallCommand -AppFolder $WinGetAppName -AppFolderPath $appFolderPath -LineNumber $LineNumber
|
||||||
}
|
}
|
||||||
WriteLog "$WinGetApp has completed downloading."
|
|
||||||
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-StoreApp {
|
function Get-StoreApp {
|
||||||
param (
|
param (
|
||||||
[string]$StoreApp
|
[string]$StoreAppName,
|
||||||
|
[string]$StoreAppId,
|
||||||
|
[int]$LineNumber
|
||||||
)
|
)
|
||||||
$wingetSearchResult = & winget.exe search --name --exact "$StoreApp" --accept-source-agreements --source msstore
|
$wingetSearchResult = & winget.exe search "$StoreAppId" --accept-source-agreements --source msstore
|
||||||
if ($wingetSearchResult -contains "No package found matching input criteria.") {
|
if ($wingetSearchResult -contains "No package found matching input criteria.") {
|
||||||
WriteLog "$StoreApp not found in WinGet repository. Skipping download."
|
WriteLog "$StoreAppName not found in WinGet repository. Skipping download."
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# Skip the header lines and get the line with the app information
|
WriteLog "Checking if $StoreAppName is a win32 app..."
|
||||||
$appResult = $wingetSearchResult | Select-Object -Skip 2 | Select-Object -First 1
|
$appIsWin32 = $StoreAppId.StartsWith("XP")
|
||||||
# Split the line by whitespace and get the second-to-last item (the Id)
|
if ($appIsWin32) {
|
||||||
$appID = ($appResult -split '\s+')[-2]
|
WriteLog "$StoreAppName is a win32 app. Adding to $AppsPath\win32 folder"
|
||||||
# Checking app ID to determine if store app is a win32 app
|
$appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreAppName
|
||||||
WriteLog "Checking if $StoreApp is a win32 app..."
|
|
||||||
if ($appID.StartsWith("XP")) {
|
|
||||||
WriteLog "$StoreApp is a win32 app. Adding to $AppsPath\win32 folder"
|
|
||||||
$appFolderPath = Join-Path -Path "$AppsPath\win32" -ChildPath $StoreApp
|
|
||||||
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
|
|
||||||
$appFolder = Split-Path -Path $appFolderPath -Leaf
|
|
||||||
WriteLog "Downloading $StoreApp for $WindowsArch architecture..."
|
|
||||||
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String
|
|
||||||
if ($wingetDownloadResult -match "No applicable installer found") {
|
|
||||||
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
|
|
||||||
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String
|
|
||||||
if ($wingetDownloadResult -match $StoreApp){
|
|
||||||
WriteLog "Downloaded $StoreApp without specifying architecture."
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog "No installer found for $StoreApp. Skipping download."
|
WriteLog "$StoreAppName is not a win32 app."
|
||||||
Remove-Item -Path $appFolderPath -Recurse -Force
|
$appFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $StoreAppName
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Add-Win32SilentInstallCommand -AppFolder $appFolder -AppFolderPath $appFolderPath
|
|
||||||
return
|
|
||||||
}
|
|
||||||
$appFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $StoreApp
|
|
||||||
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
|
New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null
|
||||||
# Invoke-Process is not used here because it terminates the script if the exit code of the process is not zero.
|
WriteLog "Downloading $StoreAppName for $WindowsArch architecture..."
|
||||||
# WinGet's download command will return a non-zero exit code when downloading store apps, as attempting to download the license file always appears to cause an error.
|
$downloadParams = @(
|
||||||
WriteLog "Downloading $StoreApp and dependencies..."
|
"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 '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.'
|
||||||
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --architecture "$WindowsArch" --scope machine | Out-String
|
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.
|
# 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") {
|
if ($wingetDownloadResult -match "No applicable installer found") {
|
||||||
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
|
WriteLog "No installer found for $WindowsArch architecture. Attempting to download without specifying architecture..."
|
||||||
$wingetDownloadResult = & winget.exe download --name --exact "$StoreApp" --download-directory "$appFolderPath" --accept-package-agreements --accept-source-agreements --source msstore --scope machine | Out-String
|
$downloadParams = $downloadParams | Where-Object { $_ -notmatch "--architecture" -and $_ -notmatch "$WindowsArch" }
|
||||||
if ($wingetDownloadResult -match $StoreApp){
|
$wingetDownloadResult = & winget.exe @downloadParams | Out-String
|
||||||
WriteLog "Downloaded $StoreApp without specifying architecture."
|
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 -LineNumber $LineNumber
|
||||||
|
# Since a Win32 app was received, returning false to increment line number for silent install command
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
Set-InstallStoreAppsFlag
|
||||||
# If $WindowsArch -eq 'ARM64', remove all dependency files that are not ARM64
|
# If $WindowsArch -eq 'ARM64', remove all dependency files that are not ARM64
|
||||||
if ($WindowsArch -eq 'ARM64') {
|
if ($WindowsArch -eq 'ARM64') {
|
||||||
WriteLog 'Windows architecture is ARM64. Removing dependencies that are not ARM64.'
|
WriteLog 'Windows architecture is ARM64. Removing dependencies that are not ARM64.'
|
||||||
@@ -1855,42 +1868,12 @@ function Get-StoreApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
WriteLog "$StoreAppName has completed downloading. Identifying the latest version of $StoreAppName."
|
||||||
else {
|
|
||||||
WriteLog "No installer found for $StoreApp. Skipping download."
|
|
||||||
Remove-Item -Path $appFolderPath -Recurse -Force
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Many store apps can be found by winget search, but the download of the apps are unsupported.
|
|
||||||
if ($wingetDownloadResult -match "No applicable Microsoft Store package download information found.") {
|
|
||||||
WriteLog "No applicable Microsoft Store package download information found for $StoreApp. Skipping download."
|
|
||||||
Remove-Item -Path $appFolderPath -Recurse -Force
|
|
||||||
return
|
|
||||||
}
|
|
||||||
$cmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
|
|
||||||
if ($cmdContent -match 'set "INSTALL_STOREAPPS=false"') {
|
|
||||||
WriteLog "Setting INSTALL_STOREAPPS flag to true in InstallAppsandSysprep.cmd file."
|
|
||||||
$updatedcmdContent = $cmdContent -replace 'set "INSTALL_STOREAPPS=false"', 'set "INSTALL_STOREAPPS=true"'
|
|
||||||
Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $updatedcmdContent
|
|
||||||
}
|
|
||||||
WriteLog "$StoreApp has completed downloading. Identifying the latest version of $StoreApp."
|
|
||||||
$packages = Get-ChildItem -Path "$appFolderPath\*" -Exclude "Dependencies\*", "*.xml", "*.yaml" -File -ErrorAction Stop
|
$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.
|
# 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 = ""
|
$latestPackage = $packages | Sort-Object { (Get-AuthenticodeSignature $_.FullName).SignerCertificate.NotBefore } -Descending | Select-Object -First 1
|
||||||
$latestDate = [datetime]::MinValue
|
|
||||||
foreach ($package in $packages) {
|
|
||||||
$signature = Get-AuthenticodeSignature -FilePath $package.FullName
|
|
||||||
if ($signature.Status -eq 'Valid') {
|
|
||||||
$signatureDate = $signature.SignerCertificate.NotBefore
|
|
||||||
if ($signatureDate -gt $latestDate) {
|
|
||||||
$latestPackage = $package.FullName
|
|
||||||
$latestDate = $signatureDate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Removing all packages that are not the latest version
|
# Removing all packages that are not the latest version
|
||||||
WriteLog "Latest version of $StoreApp has been identified as $latestPackage. Removing old versions of $StoreApp that may have downloaded."
|
WriteLog "Latest version of $StoreAppName has been identified as $latestPackage. Removing old versions of $StoreAppName that may have downloaded."
|
||||||
foreach ($package in $packages) {
|
foreach ($package in $packages) {
|
||||||
if ($package.FullName -ne $latestPackage) {
|
if ($package.FullName -ne $latestPackage) {
|
||||||
try {
|
try {
|
||||||
@@ -1907,39 +1890,16 @@ function Get-StoreApp {
|
|||||||
|
|
||||||
function Get-Apps {
|
function Get-Apps {
|
||||||
param (
|
param (
|
||||||
[string]$AppsList
|
[string]$AppList
|
||||||
)
|
)
|
||||||
$apps = Get-Content -Path $AppsList
|
$apps = Get-Content -Path $AppList -Raw | ConvertFrom-Json
|
||||||
if (-not $apps) {
|
if (-not $apps) {
|
||||||
WriteLog "No apps were specified in AppsList.txt file."
|
WriteLog "No apps were specified in AppList.json file."
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
$wingetApps = @()
|
$wingetApps = $apps.apps | Where-Object { $_.source -eq "winget" }
|
||||||
$storeApps = @()
|
$storeApps = $apps.apps | Where-Object { $_.source -eq "msstore" }
|
||||||
$apps | ForEach-Object {
|
Confirm-WinGetInstallation
|
||||||
if ($_ -like 'winget:*') {
|
|
||||||
$wingetApps += $_.Substring(7).Trim()
|
|
||||||
}
|
|
||||||
elseif ($_ -like 'store:*') {
|
|
||||||
$storeApps += $_.Substring(6).Trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$wingetInstalled = Get-ChildItem -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\winget.exe" -ErrorAction SilentlyContinue
|
|
||||||
if (-not $wingetInstalled) {
|
|
||||||
WriteLog "WinGet is not installed. Downloading preview version of WinGet and its dependencies..."
|
|
||||||
Install-WinGet -InstallWithDependencies $true
|
|
||||||
}
|
|
||||||
$wingetOnPath = Get-Command winget -ErrorAction SilentlyContinue
|
|
||||||
if (-not $wingetOnPath) {
|
|
||||||
WriteLog "WinGet is not on the path. Downloading preview version of WinGet without dependencies..."
|
|
||||||
Install-WinGet -InstallWithDependencies $false
|
|
||||||
}
|
|
||||||
$wingetVersion = & winget.exe --version
|
|
||||||
# Preview release is needed to enable storeDownload experimental feature
|
|
||||||
if (-not ($wingetVersion -like "*preview*")) {
|
|
||||||
WriteLog "The preview version of WinGet is not installed. Downloading preview version of WinGet without dependencies..."
|
|
||||||
Install-WinGet -InstallWithDependencies $false
|
|
||||||
}
|
|
||||||
$lineNumber = 13
|
$lineNumber = 13
|
||||||
$win32Folder = Join-Path -Path $AppsPath -ChildPath "Win32"
|
$win32Folder = Join-Path -Path $AppsPath -ChildPath "Win32"
|
||||||
$storeAppsFolder = Join-Path -Path $AppsPath -ChildPath "MSStore"
|
$storeAppsFolder = Join-Path -Path $AppsPath -ChildPath "MSStore"
|
||||||
@@ -1949,8 +1909,11 @@ function Get-Apps {
|
|||||||
}
|
}
|
||||||
foreach ($wingetApp in $wingetApps) {
|
foreach ($wingetApp in $wingetApps) {
|
||||||
try {
|
try {
|
||||||
Get-WinGetApp -WinGetApp $wingetApp -LineNumber $lineNumber
|
$result = Get-WinGetApp -WinGetAppName $wingetApp.Name -WinGetAppId $wingetApp.Id -LineNumber $lineNumber
|
||||||
|
if ($null -eq $result) {
|
||||||
$lineNumber++
|
$lineNumber++
|
||||||
|
WriteLog "Line number incremented to $lineNumber"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "Error occurred while processing $wingetApp : $_"
|
WriteLog "Error occurred while processing $wingetApp : $_"
|
||||||
@@ -1959,13 +1922,16 @@ function Get-Apps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($storeApps) {
|
if ($storeApps) {
|
||||||
New-WinGetSettings
|
|
||||||
if (-not (Test-Path -Path $storeAppsFolder -PathType Container)) {
|
if (-not (Test-Path -Path $storeAppsFolder -PathType Container)) {
|
||||||
New-Item -Path $storeAppsFolder -ItemType Directory -Force | Out-Null
|
New-Item -Path $storeAppsFolder -ItemType Directory -Force | Out-Null
|
||||||
}
|
}
|
||||||
foreach ($storeApp in $storeApps) {
|
foreach ($storeApp in $storeApps) {
|
||||||
try {
|
try {
|
||||||
Get-StoreApp -StoreApp $storeApp
|
$result = Get-StoreApp -StoreAppName $storeApp.Name -StoreAppId $storeApp.Id -LineNumber $lineNumber
|
||||||
|
if ($result -eq $false) {
|
||||||
|
$lineNumber++
|
||||||
|
WriteLog "Line number incremented to $lineNumber"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "Error occurred while processing $storeApp : $_"
|
WriteLog "Error occurred while processing $storeApp : $_"
|
||||||
@@ -3383,7 +3349,7 @@ if ($InstallApps) {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
WriteLog "$AppsPath\InstallAppsandSysprep.cmd found"
|
WriteLog "$AppsPath\InstallAppsandSysprep.cmd found"
|
||||||
Get-Apps -AppsList "$AppsPath\AppsList.txt"
|
Get-Apps -AppList "$AppsPath\AppList.json"
|
||||||
if (-not $InstallOffice) {
|
if (-not $InstallOffice) {
|
||||||
#Modify InstallAppsandSysprep.cmd to REM out the office install command
|
#Modify InstallAppsandSysprep.cmd to REM out the office install command
|
||||||
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
|
$CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd"
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $True, Position = 0)]
|
||||||
|
$DeployISOPath,
|
||||||
|
[Switch]$DisableAutoPlay
|
||||||
|
)
|
||||||
|
$Host.UI.RawUI.WindowTitle = 'USB Imaging Tool Creator'
|
||||||
|
|
||||||
|
if($DeployISOPath){
|
||||||
|
$DevelopmentPath = $DeployISOPath | Split-Path
|
||||||
|
function WriteLog($LogText) {
|
||||||
|
$LogFileName = '\Script.log'
|
||||||
|
$LogFile = $DevelopmentPath + $LogFilename
|
||||||
|
Add-Content -path $LogFile -value "$((Get-Date).ToString()) $LogText" -Force -ErrorAction SilentlyContinue
|
||||||
|
Write-Verbose $LogText
|
||||||
|
}
|
||||||
|
Function Get-USBDrive {
|
||||||
|
$USBDrives = (Get-WmiObject -Class Win32_DiskDrive -Filter "MediaType='Removable Media'")
|
||||||
|
If ($USBDrives -and ($null -eq $USBDrives.count)) {
|
||||||
|
$USBDrivesCount = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$USBDrivesCount = $USBDrives.Count
|
||||||
|
}
|
||||||
|
WriteLog "Found $USBDrivesCount USB drives"
|
||||||
|
|
||||||
|
if ($null -eq $USBDrives) {
|
||||||
|
WriteLog "No removable USB drive found. Exiting"
|
||||||
|
Write-Error "No removable USB drive found. Exiting"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
return $USBDrives, $USBDrivesCount
|
||||||
|
}
|
||||||
|
Function Build-DeploymentUSB{
|
||||||
|
param(
|
||||||
|
[Array]$Drives
|
||||||
|
)
|
||||||
|
writelog "Checking if ffu files are present in the ffu folder"
|
||||||
|
$Images = Get-ChildItem -Path $FFUPath -Filter "*.ffu" -File -Recurse
|
||||||
|
writelog "Checking if drivers are present in the drivers folder"
|
||||||
|
$Drivers = Get-ChildItem -Path $DriversPath -Recurse
|
||||||
|
$DrivesCount = $Drives.Count
|
||||||
|
Writelog "Creating partitions..."
|
||||||
|
foreach ($USBDrive in $Drives) {
|
||||||
|
$DriveNumber = $USBDrive.DeviceID.Replace("\\.\PHYSICALDRIVE", "")
|
||||||
|
$Model = $USBDrive.model
|
||||||
|
$ScriptBlock = {
|
||||||
|
param($DriveNumber)
|
||||||
|
Clear-Disk -Number $DriveNumber -RemoveData -RemoveOEM -Confirm:$false
|
||||||
|
$Disk = Get-Disk -Number $DriveNumber
|
||||||
|
$PartitionStyle = $Disk.PartitionStyle
|
||||||
|
if($PartitionStyle -ne 'MBR'){
|
||||||
|
$Disk | Set-Disk -PartitionStyle MBR
|
||||||
|
}
|
||||||
|
$BootPartition = New-Partition -DiskNumber $DriveNumber -Size 2GB -IsActive -AssignDriveLetter
|
||||||
|
$DeployPartition = New-Partition -DiskNumber $DriveNumber -UseMaximumSize -AssignDriveLetter
|
||||||
|
Format-Volume -Partition $BootPartition -FileSystem FAT32 -NewFileSystemLabel "Boot" -Confirm:$false
|
||||||
|
Format-Volume -Partition $DeployPartition -FileSystem NTFS -NewFileSystemLabel "Deploy" -Confirm:$false
|
||||||
|
}
|
||||||
|
WriteLog "Start job to create BOOT and Deploy partitions on drive number $DriveNumber"
|
||||||
|
Start-Job -ScriptBlock $ScriptBlock -ArgumentList $DriveNumber | Out-Null
|
||||||
|
}
|
||||||
|
writelog "Wait for partitioning jobs to complete"
|
||||||
|
Get-Job | Wait-Job | Out-Null
|
||||||
|
if($DrivesCount -gt 1){
|
||||||
|
writelog "Get file system information for all drives"
|
||||||
|
$Partitions = Get-Partition | Get-Volume
|
||||||
|
}else{
|
||||||
|
writelog "Get file system information for drive number $DiskNumber"
|
||||||
|
$Partitions = Get-Partition -DiskNumber $DriveNumber | Get-Volume
|
||||||
|
}
|
||||||
|
writelog "Get drive letter for all volumes labeled:BOOT"
|
||||||
|
$BootDrives = ($Partitions | Where-Object { $_.FileSystemLabel -eq "BOOT"}).DriveLetter
|
||||||
|
writelog "Get drive letter for all volumes labeled:Deploy"
|
||||||
|
$DeployDrives = ($Partitions | Where-Object { $_.FileSystemLabel -eq "Deploy"}).DriveLetter
|
||||||
|
writelog "Mount Deployment .iso image"
|
||||||
|
$ISOMountPoint = (Mount-DiskImage -ImagePath "$DeployISOPath" -PassThru | Get-Volume).DriveLetter + ":\"
|
||||||
|
writelog "Copying boot files to all drives labeled BOOT concurrently"
|
||||||
|
foreach ($Drive in $BootDrives) {
|
||||||
|
$Destination = $Drive + ":\"
|
||||||
|
$jobScriptBlock = {
|
||||||
|
param (
|
||||||
|
[string]$SFolder,
|
||||||
|
[string]$DFolder
|
||||||
|
)
|
||||||
|
Robocopy $SFolder $DFolder /E /COPYALL /R:5 /W:5 /J
|
||||||
|
}
|
||||||
|
WriteLog "Start job to copy all boot files to $Destination"
|
||||||
|
Start-Job -ScriptBlock $jobScriptBlock -ArgumentList $ISOMountPoint, $Destination | Out-Null
|
||||||
|
}
|
||||||
|
if($Images){
|
||||||
|
writelog "Copying FFU image files to all drives labeled deploy concurrently"
|
||||||
|
foreach ($Drive in $DeployDrives) {
|
||||||
|
$Destination = $Drive + ":\"
|
||||||
|
$jobScriptBlock = {
|
||||||
|
param (
|
||||||
|
[string]$SFolder,
|
||||||
|
[string]$DFolder
|
||||||
|
)
|
||||||
|
Robocopy $SFolder $DFolder /E /COPYALL /R:5 /W:5 /J
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLog "Start job to copy all FFU files to $Destination"
|
||||||
|
Start-Job -ScriptBlock $jobScriptBlock -ArgumentList $FFUPath, $Destination | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($Drivers){
|
||||||
|
writelog "Copying driver files to all drives labeled deploy concurrently"
|
||||||
|
foreach ($Drive in $DeployDrives) {
|
||||||
|
$Destination = $Drive + ":\Drivers"
|
||||||
|
$jobScriptBlock = {
|
||||||
|
param (
|
||||||
|
[string]$SFolder,
|
||||||
|
[string]$DFolder
|
||||||
|
)
|
||||||
|
New-Item -Path $DFolder -ItemType Directory -Force -Confirm: $false | Out-Null
|
||||||
|
Robocopy $SFolder $DFolder /E /COPYALL /R:5 /W:5 /J
|
||||||
|
}
|
||||||
|
WriteLog "Start job to copy all drivers to $Destination"
|
||||||
|
Start-Job -ScriptBlock $jobScriptBlock -ArgumentList $DriversPath, $Destination | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!($Drivers)){
|
||||||
|
foreach ($Drive in $DeployDrives) {
|
||||||
|
WriteLog "Create drivers directory"
|
||||||
|
$drivepath = $Drive + ":\"
|
||||||
|
New-Item -Path "$drivepath" -Name Drivers -ItemType Directory -Force -Confirm: $false | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($DrivesCount -gt 1){
|
||||||
|
Writelog "Building $DrivesCount drives concurrently...Please be patient..."
|
||||||
|
}else{
|
||||||
|
Writelog "Building the imaging tool on $model...Please be patient..."
|
||||||
|
}
|
||||||
|
Get-Job | Wait-Job | Out-Null
|
||||||
|
|
||||||
|
Dismount-DiskImage -ImagePath $DeployISOPath | Out-Null
|
||||||
|
Writelog "Drive creation jobs completed..."
|
||||||
|
}
|
||||||
|
|
||||||
|
Function New-DeploymentUSB {
|
||||||
|
param(
|
||||||
|
[Array]$Drives,
|
||||||
|
[int]$Count,
|
||||||
|
[String]$FFUPath = "$DevelopmentPath\FFU",
|
||||||
|
[String]$DriversPath = "$DevelopmentPath\Drivers"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
$Drivelist = @()
|
||||||
|
writelog "Creating a USB drive selection list"
|
||||||
|
for($i=0;$i -le $Count -1;$i++){
|
||||||
|
$DriveModel = $Drives[$i].Model
|
||||||
|
$DriveSize = [math]::round($Drives[$i].size/1GB, 2)
|
||||||
|
$DiskNumber = $Drives[$i].DeviceID.Replace("\\.\PHYSICALDRIVE", "")
|
||||||
|
$Properties = [ordered]@{Number = $i + 1 ; DriveNumber = $DiskNumber ; DriveModel = $driveModel ; 'Size (GB)' = $DriveSize}
|
||||||
|
|
||||||
|
$Drivelist += New-Object PSObject -Property $Properties
|
||||||
|
}
|
||||||
|
if($Count -gt 1){
|
||||||
|
$Last = $Count+1
|
||||||
|
$Drivelist += New-Object -TypeName PSObject -Property @{ Number = "$last"; DriveModel = "Select this option to use all ($count) inserted USB Drives" }
|
||||||
|
}
|
||||||
|
$Drivelist | Format-Table -AutoSize -Property Number, DriveModel , 'Size (GB)'
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
$var = $true
|
||||||
|
$DriveSelected = Read-Host 'Enter the drive number to apply the .iso to'
|
||||||
|
$DriveSelected = ($DriveSelected -as [int]) -1
|
||||||
|
if($Last){
|
||||||
|
writelog "All drives selected"
|
||||||
|
}else{
|
||||||
|
writelog "Drive $DriveSelected selected"}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host 'Input was not in correct format. Please enter a valid FFU number'
|
||||||
|
$var = $false
|
||||||
|
}
|
||||||
|
} until (($DriveSelected -le $Count -1 -or $last) -and $var)
|
||||||
|
|
||||||
|
$DisableAutoPlayCurrentSetting = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers" -Name DisableAutoplay).DisableAutoplay
|
||||||
|
if($DisableAutoPlay -and $DisableAutoPlayCurrentSetting -ne 1){
|
||||||
|
writelog "Disable autoPlay current setting is $DisableAutoPlayCurrentSetting"
|
||||||
|
WriteLog "Setting the registry key to disable autoplay for all drives"
|
||||||
|
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers" -Name "DisableAutoplay" -Value 1 -Type DWORD
|
||||||
|
}
|
||||||
|
WriteLog "Closing all MMC windows to prevent drive lock errors"
|
||||||
|
Stop-Process -Name mmc -ErrorAction SilentlyContinue
|
||||||
|
WriteLog "Closing all Diskpart windows to prevent drive lock errors"
|
||||||
|
Stop-Process -Name diskpart -ErrorAction SilentlyContinue
|
||||||
|
$Selection = $Drivelist[$DriveSelected].Number
|
||||||
|
$totalSteps = 5
|
||||||
|
if($Selection -eq $last){
|
||||||
|
Read-Host -Prompt "ALL DRIVES SELECTED! WILL ERASE ALL CURRENTLY CONNECTED USB DRIVES!! Press ENTER to continue"
|
||||||
|
Build-DeploymentUSB -Drives $Drives
|
||||||
|
}else{
|
||||||
|
Read-Host -Prompt "Drive number $Selection was selected. Press ENTER to continue"
|
||||||
|
Build-DeploymentUSB -Drives $Drives[$DriveSelected]
|
||||||
|
}
|
||||||
|
WriteLog "Setting the registry key to re-enable autoplay for all drives"
|
||||||
|
if($DisableAutoPlay){
|
||||||
|
Writelog "Setting disable autoplay setting back to $DisableAutoPlayCurrentSetting"
|
||||||
|
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AutoplayHandlers" -Name "DisableAutoplay" -Value $DisableAutoPlayCurrentSetting -Type DWORD
|
||||||
|
}
|
||||||
|
Writelog "Completed!"
|
||||||
|
}
|
||||||
|
#Get USB Drive and create log file
|
||||||
|
if(Test-Path "$DevelopmentPath\Script.log"){
|
||||||
|
Remove-Item -Path "$DevelopmentPath\Script.log" -Force -Confirm:$false
|
||||||
|
New-item -Path $DevelopmentPath -Name 'Script.log' -ItemType "file" -Force | Out-Null
|
||||||
|
}
|
||||||
|
WriteLog 'Begin Logging'
|
||||||
|
WriteLog 'Getting USB drive information and usb drive count'
|
||||||
|
$USBDrives,$USBDrivesCount = Get-USBDrive
|
||||||
|
New-DeploymentUSB -Drives $USBDrives -Count $USBDrivesCount
|
||||||
|
read-host -Prompt "USB drive creation complete. Press ENTER to exit"
|
||||||
|
|
||||||
|
Exit
|
||||||
|
}else{
|
||||||
|
Write-Host "No .ISO file selected..."
|
||||||
|
read-host "Press ENTER to Exit..."
|
||||||
|
Exit
|
||||||
|
}
|
||||||
@@ -495,10 +495,12 @@ $WinRE = $USBDrive + "WinRE\winre.wim"
|
|||||||
If (Test-Path -Path $WinRE)
|
If (Test-Path -Path $WinRE)
|
||||||
{
|
{
|
||||||
WriteLog 'Copying modified WinRE to Recovery directory'
|
WriteLog 'Copying modified WinRE to Recovery directory'
|
||||||
|
Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object Type -eq Recovery | Set-Partition -NewDriveLetter R
|
||||||
Invoke-Process xcopy.exe "/h $WinRE R:\Recovery\WindowsRE\ /Y"
|
Invoke-Process xcopy.exe "/h $WinRE R:\Recovery\WindowsRE\ /Y"
|
||||||
WriteLog 'Copying WinRE to Recovery directory succeeded'
|
WriteLog 'Copying WinRE to Recovery directory succeeded'
|
||||||
WriteLog 'Registering location of recovery tools'
|
WriteLog 'Registering location of recovery tools'
|
||||||
Invoke-Process W:\Windows\System32\Reagentc.exe "/Setreimage /Path R:\Recovery\WindowsRE /Target W:\Windows"
|
Invoke-Process W:\Windows\System32\Reagentc.exe "/Setreimage /Path R:\Recovery\WindowsRE /Target W:\Windows"
|
||||||
|
Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object Type -eq Recovery | Remove-PartitionAccessPath -AccessPath R:
|
||||||
WriteLog 'Registering location of recovery tools succeeded'
|
WriteLog 'Registering location of recovery tools succeeded'
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
|
|||||||
Reference in New Issue
Block a user