mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d4b66851a | |||
| 3ba0da19f8 | |||
| 6826f854ae | |||
| afa524091c | |||
| f14c7f2b00 |
+5
-3
@@ -16,7 +16,7 @@ To support the newly released Copilot+ PCs, we now support the creation and depl
|
||||
* The host machine you're building the FFU from must be ARM64
|
||||
* Office/M365 apps don't currently support installing the ARM64 native bits from an offline system. If you pass `-InstallOffice $true` the script will change the value to false. You can install office after the fact when connected to the internet. I'm investigating this behavior and will issue a fix if/when this gets resolved. I still don't recommend building the FFU VM on the internet.
|
||||
* The [Defender Updates Site](https://www.microsoft.com/en-us/wdsi/defenderupdates) provides download links for Defender definitions. The ARM link doesn't work for ARM64 and mpam-fe.exe fails to install. However there might be an undocumented ARM64 URL that may work. I've included it, but haven't tested it as I'm writing these notes. So we'll see if that works out.
|
||||
* Drivers - I know Surface Laptop 7 and Pro
|
||||
* Drivers - Surface Laptop 7 and Pro 11 don't have ARM64 drivers available yet (there are entries, but they just point to a .txt file). Other OEMs may have drivers available.
|
||||
|
||||
In all, testing has gone very well.
|
||||
|
||||
@@ -24,7 +24,7 @@ In all, testing has gone very well.
|
||||
|
||||
Big thanks to [Zehadi Alam](https://github.com/zehadialam) for his contributions to get this added to the project. You can now add any application in the msstore or winget source via the Winget command line utility. In the 1.8 Winget release the ability to download apps from the msstore source was added, which means being able to download apps like the Company Portal. For those of you that have been asking for Company Portal to be inbox in Windows, this is the next best thing. The script will check if Winget 1.8 is installed and if not, it'll install it.
|
||||
|
||||
The way this works is if `-InstallApps $true` and the FFUDevelopment\Apps\AppList.json file exists, whatever apps defined in that json file will be downloaded via Winget and will be installed in the FFU VM prior to capture. We've included two files: AppList_InboxAppsSample.json and AppList_Sample.json. The AppList_InboxAppsSample.json contains all of the apps that are installed in Windows by default and are searchable via `winget search AppID` . Some of these apps do not download and we're investigating why they come up via search, but fail to download. The AppList_Sample.json has Company Portal and New Teams.
|
||||
The way this works is if `-InstallApps $true` and the FFUDevelopment\Apps\AppList.json file exists, whatever apps defined in that json file will be downloaded via Winget and will be installed in the FFU VM prior to capture. We've included two files: AppList_InboxAppsSample.json and AppList_Sample.json. The AppList_InboxAppsSample.json contains all of the apps that are installed in Windows by default and are searchable via `winget search AppID` . Some of these apps do not download and we're investigating why they come up via search, but fail to download. The AppList_Sample.json has Company Portal and New Teams.
|
||||
|
||||

|
||||
|
||||
@@ -37,12 +37,14 @@ In sticking with the idea of having the most up to date Windows build, inbox sto
|
||||
|
||||
Updated means latest .NET, Defender (definition and platform updates), Edge, OneDrive, and all updates available via Winget for Store Apps have been provisioned in the FFU. The numbers in the table are cumulative, meaning the FFU was laid down, store apps were updated via running Get Apps from the Microsoft Store app and data usage was gathered from Settings, then Windows Update was manually kicked off via Settings and data usage was gathered.
|
||||
|
||||
In order to get apps to help build your AppList.json file, just run `winget search "AppName"`
|
||||
In order to get apps to help build your AppList.json file, just run `winget search "AppName"`
|
||||
|
||||

|
||||
|
||||
In this example we see that Firefox is published to both the msstore and winget sources. It's up to you which one you'd like to pick (I assume the msstore and the 128 version from the winget source are both the same version, but that may not be the case). You'll want to use the Name, ID, and Source values to help create your AppList.json file.
|
||||
|
||||
When downloading msstore apps, it does require an Entra ID. If you're building your FFUs from a machine that is not signed in with an Entra ID, you will be prompted for credentials for each app you download AND for the license file for each app (2 prompts per app). If downloading many store apps is something you plan on doing, I highly recommend signing in with an Entra ID to prevent the authentication prompts.
|
||||
|
||||
Other improvements
|
||||
|
||||
* [mhaley](https://github.com/mhaley) made their first contribution to [assign the drive letter to the recovery partition when copying in a custom WinRE.wim](https://github.com/rbalsleyMSFT/FFU/pull/35)
|
||||
|
||||
@@ -903,69 +903,54 @@ function Get-LenovoDrivers {
|
||||
[int]$WindowsRelease
|
||||
)
|
||||
|
||||
# Parse the Lenovo PSREF search page for machine types
|
||||
function Get-LenovoPSREF {
|
||||
param (
|
||||
[string]$ModelName
|
||||
)
|
||||
|
||||
$url = "https://psref.lenovo.com/search"
|
||||
WriteLog "Getting Lenovo PSREF page for model: $ModelName"
|
||||
$url = "https://psref.lenovo.com/api/search/DefinitionFilterAndSearch/Suggest?kw=$ModelName"
|
||||
WriteLog "Querying Lenovo PSREF API for model: $ModelName"
|
||||
$OriginalVerbosePreference = $VerbosePreference
|
||||
$VerbosePreference = 'SilentlyContinue'
|
||||
$webContent = Invoke-WebRequest -Uri $url
|
||||
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers $Headers -UserAgent $UserAgent
|
||||
$VerbosePreference = $OriginalVerbosePreference
|
||||
WriteLog "Complete"
|
||||
|
||||
# Access the parsed HTML
|
||||
WriteLog "Parsing content"
|
||||
$parsedHtml = $webContent.ParsedHtml
|
||||
|
||||
# Select the nodes you are interested in
|
||||
$productNameNodes = $parsedHtml.getElementsByTagName("li") | Where-Object { $_.className -contains "productname_li" }
|
||||
$jsonResponse = $response.Content | ConvertFrom-Json
|
||||
|
||||
$products = @()
|
||||
# Iterate through the nodes
|
||||
foreach ($product in $productNameNodes) {
|
||||
$productA = $product.getElementsByTagName("a") | Where-Object { $_.tagName -eq "a" }
|
||||
$innertext = @($productA.innertext) # Ensure innertext is treated as an array
|
||||
$productName = $innertext[0]
|
||||
|
||||
#if $productname contains 'Chromebook', skip the product
|
||||
if ($productName -like '*Chromebook*') {
|
||||
continue
|
||||
}
|
||||
$machineTypes = $innertext[1..($innertext.Count - 1)]
|
||||
|
||||
if ($innertext -match $ModelName) {
|
||||
foreach ($machineType in $machineTypes) {
|
||||
If ($machineType -eq $modelName) {
|
||||
WriteLog "Model name entered is a matching machine type"
|
||||
$products = @()
|
||||
$products += [pscustomobject]@{
|
||||
ProductName = $productName
|
||||
MachineType = $machineType
|
||||
}
|
||||
WriteLog "Product Name: $productName Machine Type: $machineType"
|
||||
continue
|
||||
}
|
||||
foreach ($item in $jsonResponse.data) {
|
||||
$productName = $item.ProductName
|
||||
$machineTypes = $item.MachineType -split " / "
|
||||
|
||||
foreach ($machineType in $machineTypes) {
|
||||
if ($machineType -eq $ModelName) {
|
||||
WriteLog "Model name entered is a matching machine type"
|
||||
$products = @()
|
||||
$products += [pscustomobject]@{
|
||||
ProductName = $productName
|
||||
MachineType = $machineType
|
||||
}
|
||||
WriteLog "Product Name: $productName Machine Type: $machineType"
|
||||
return $products
|
||||
}
|
||||
$products += [pscustomobject]@{
|
||||
ProductName = $productName
|
||||
MachineType = $machineType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ,$products
|
||||
}
|
||||
|
||||
# Parse the Lenovo PSREF page for the model
|
||||
$machineTypes = Get-LenovoPSREF -ModelName $Model
|
||||
if ($machineTypes.Count -eq 0) {
|
||||
if ($machineTypes.ProductName.Count -eq 0) {
|
||||
WriteLog "No machine types found for model: $Model"
|
||||
WriteLog "Enter a valid model or machine type in the -model parameter"
|
||||
exit
|
||||
} elseif ($machineTypes.Count -eq 1) {
|
||||
} elseif ($machineTypes.ProductName.Count -eq 1) {
|
||||
$machineType = $machineTypes[0].MachineType
|
||||
$model = $machineTypes[0].ProductName
|
||||
} else {
|
||||
@@ -973,7 +958,7 @@ function Get-LenovoDrivers {
|
||||
Write-Output "Multiple machine types found for model: $Model"
|
||||
}
|
||||
WriteLog "Multiple machine types found for model: $Model"
|
||||
for ($i = 0; $i -lt $machineTypes.Count; $i++) {
|
||||
for ($i = 0; $i -lt $machineTypes.ProductName.Count; $i++) {
|
||||
if ($VerbosePreference -ne 'Continue'){
|
||||
Write-Output "$($i + 1). $($machineTypes[$i].ProductName) ($($machineTypes[$i].MachineType))"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ While we use this in Education at Microsoft, other industries can use it as well
|
||||
|
||||
# Updates
|
||||
|
||||
2406.1 has been released! Check out the changes in the new [Change Log](ChangeLog.md)
|
||||
2407.1 has been released! Check out the changes in the new [Change Log](ChangeLog.md)
|
||||
|
||||
# Getting Started
|
||||
|
||||
|
||||
Reference in New Issue
Block a user