From 5796bfb7ec4f9dfd9667c0058709800e999c432b Mon Sep 17 00:00:00 2001 From: skycommand Date: Thu, 24 Sep 2020 11:50:11 +0330 Subject: [PATCH 1/6] Script improvements - Script: Marked each snippet as "PowerShell" instead of plain text. Both GitHub and Microsoft Docs can highlight PowerShell syntax. - Script: Added `#Requires -RunAsAdministrator` because the `Mount-WindowsImage` cmdlet needs it. - Script: Eliminated the path-concatenating code-spaghetti. A mixture of different string-concatenating features was used alongside `Join-Path`! As a result, reading, interpreting, and adopting the path section of the script was a total nightmare. - Script: Replaced all instances of "Write-Host" with "Write-Output". This is a serious change, as PowerShell scripts do not always run attended. Per PowerShell guidelines, `Write-Host` is a last-resort cmdlet. Where possible, `Write-Output` should be used instead. - Script: Changed `"{0:HH:mm:ss}" -f (Get-Date)` into `return "{0:HH:mm:ss}" -f [DateTime]::Now`. It seems not everyone knows that Get-Date's output can be customized, and not always via its parameters. Hence, the former could have unintended consequences. It is also possible to write `Get-Date -Format "HH:mm:ss"` which is neither superior nor inferior. (Well, maybe it costs a few more CPU ticks.) - Markdown Linter: Replaced inline HTML with Markdown - Markdown Linter: Inserted the missing line breaks before each heading --- .../deployment/update/media-dynamic-update.md | 158 +++++++++--------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/windows/deployment/update/media-dynamic-update.md b/windows/deployment/update/media-dynamic-update.md index 8af36e4df1..15715aaf19 100644 --- a/windows/deployment/update/media-dynamic-update.md +++ b/windows/deployment/update/media-dynamic-update.md @@ -18,7 +18,7 @@ ms.topic: article **Applies to**: Windows 10 -This topic explains how to acquire and apply Dynamic Update packages to existing Windows 10 images prior to deployment and includes Windows PowerShell scripts you can use to automate this process. +This topic explains how to acquire and apply Dynamic Update packages to existing Windows 10 images *prior to deployment* and includes Windows PowerShell scripts you can use to automate this process. Volume-licensed media is available for each release of Windows 10 in the Volume Licensing Service Center (VLSC) and other relevant channels such as Windows Update for Business, Windows Server Update Services (WSUS), and Visual Studio Subscriptions. You can use Dynamic Update to ensure that Windows 10 devices have the latest feature update packages as part of an in-place upgrade while preserving language pack and Features on Demand (FODs) that might have been previously installed. Dynamic Update also eliminates the need to install a separate quality update as part of the in-place upgrade process. @@ -42,8 +42,7 @@ You can obtain Dynamic Update packages from the [Microsoft Update Catalog](https ![Table with columns labeled Title, Products, Classification, Last Updated, Version, and Size and four rows listing various dynamic updates and associated KB articles](images/update-catalog.png) -The various Dynamic Update packages might not all be present in the results from a single search, so you might have to search with different keywords to find all of the updates. And you'll need to check various parts of the results to be sure you've identified the needed files. This table shows in bold the key items to search for or look for in the results. For example, to find the relevant "Setup Dynamic Update," you'll have to check the detailed description for the download by selecting the link in the **Title** column of the search results. - +The various Dynamic Update packages might not all be present in the results from a single search, so you might have to search with different keywords to find all of the updates. And you'll need to check various parts of the results to be sure you've identified the needed files. This table shows in **bold** the key items to search for or look for in the results. For example, to find the relevant "Setup Dynamic Update," you'll have to check the detailed description for the download by selecting the link in the **Title** column of the search results. |To find this Dynamic Update packages, search for or check the results here--> |Title |Product |Description (select the **Title** link to see **Details**) | |---------|---------|---------|---------| @@ -96,7 +95,6 @@ Optional Components, along with the .Net feature, can be installed offline, howe These examples are for illustration only, and therefore lack error handling. The script assumes that the following packages is stored locally in this folder structure: - |Folder |Description | |---------|---------| |C:\mediaRefresh | Parent folder that contains the PowerShell script | @@ -107,50 +105,52 @@ These examples are for illustration only, and therefore lack error handling. The The script starts by declaring global variables and creating folders to use for mounting images. Then, make a copy of the original media, from \oldMedia to \newMedia, keeping the original media in case there is a script error and it's necessary to start over from a known state. Also, it will provide a comparison of old versus new media to evaluate changes. To ensure that the new media updates, make sure they are not read-only. -``` -function Get-TS { return "{0:HH:mm:ss}" -f (Get-Date) } +``` PowerShell +#Requires -RunAsAdministrator -Write-Host "$(Get-TS): Starting media refresh" +function Get-TS { return "{0:HH:mm:ss}" -f [DateTime]::Now } -# Declare media for FOD and LPs -$FOD_ISO_PATH = "C:\mediaRefresh\packages\FOD-PACKAGES_OEM_PT1_amd64fre_MULTI.iso" -$LP_ISO_PATH = "C:\mediaRefresh\packages\CLIENTLANGPACKDVD_OEM_MULTI.iso" +Write-Output "$(Get-TS): Starting media refresh" # Declare language for showcasing adding optional localized components -$LANG = "ja-jp" +$LANG = "ja-jp" $LANG_FONT_CAPABILITY = "jpan" +# Declare media for FOD and LPs +$FOD_ISO_PATH = "C:\mediaRefresh\packages\FOD-PACKAGES_OEM_PT1_amd64fre_MULTI.iso" +$LP_ISO_PATH = "C:\mediaRefresh\packages\CLIENTLANGPACKDVD_OEM_MULTI.iso" + # Declare Dynamic Update packages -$LCU_PATH = "C:\mediaRefresh\packages\LCU.msu" -$SSU_PATH = "C:\mediaRefresh\packages\SSU_DU.msu" -$SETUP_DU_PATH = "C:\mediaRefresh\packages\Setup_DU.cab" +$LCU_PATH = "C:\mediaRefresh\packages\LCU.msu" +$SSU_PATH = "C:\mediaRefresh\packages\SSU_DU.msu" +$SETUP_DU_PATH = "C:\mediaRefresh\packages\Setup_DU.cab" $SAFE_OS_DU_PATH = "C:\mediaRefresh\packages\SafeOS_DU.cab" -$DOTNET_CU_PATH = "C:\mediaRefresh\packages\DotNet_CU.msu" +$DOTNET_CU_PATH = "C:\mediaRefresh\packages\DotNet_CU.msu" # Declare folders for mounted images and temp files -$WORKING_PATH = "C:\mediaRefresh\temp" -$MEDIA_OLD_PATH = "C:\mediaRefresh\oldMedia" -$MEDIA_NEW_PATH = "C:\mediaRefresh\newMedia" -$MAIN_OS_MOUNT = $WORKING_PATH + "\MainOSMount" -$WINRE_MOUNT = $WORKING_PATH + "\WinREMount" -$WINPE_MOUNT = $WORKING_PATH + "\WinPEMount" +$MEDIA_OLD_PATH = "C:\mediaRefresh\oldMedia" +$MEDIA_NEW_PATH = "C:\mediaRefresh\newMedia" +$WORKING_PATH = "C:\mediaRefresh\temp" +$MAIN_OS_MOUNT = "C:\mediaRefresh\temp\MainOSMount" +$WINRE_MOUNT = "C:\mediaRefresh\temp\WinREMount" +$WINPE_MOUNT = "C:\mediaRefresh\temp\WinPEMount" # Mount the language pack ISO -Write-Host "$(Get-TS): Mounting LP ISO" +Write-Output "$(Get-TS): Mounting LP ISO" $LP_ISO_DRIVE_LETTER = (Mount-DiskImage -ImagePath $LP_ISO_PATH -ErrorAction stop | Get-Volume).DriveLetter # Declare language related cabs -$WINPE_OC_PATH = Join-Path $LP_ISO_DRIVE_LETTER":" -ChildPath "Windows Preinstallation Environment" | Join-Path -ChildPath "x64" | Join-Path -ChildPath "WinPE_OCs" -$WINPE_OC_LANG_PATH = Join-Path $WINPE_OC_PATH $LANG -$WINPE_OC_LANG_CABS = Get-ChildItem $WINPE_OC_LANG_PATH -name -$WINPE_OC_LP_PATH = Join-Path $WINPE_OC_LANG_PATH "lp.cab" -$WINPE_FONT_SUPPORT_PATH = Join-Path $WINPE_OC_PATH "WinPE-FontSupport-$LANG.cab" -$WINPE_SPEECH_TTS_PATH = Join-Path $WINPE_OC_PATH "WinPE-Speech-TTS.cab" -$WINPE_SPEECH_TTS_LANG_PATH = Join-Path $WINPE_OC_PATH "WinPE-Speech-TTS-$LANG.cab" -$OS_LP_PATH = $LP_ISO_DRIVE_LETTER + ":\x64\langpacks\" + "Microsoft-Windows-Client-Language-Pack_x64_" + $LANG + ".cab" +$WINPE_OC_PATH = "$LP_ISO_DRIVE_LETTER`:\Windows Preinstallation Environment\x64\WinPE_OCs" +$WINPE_OC_LANG_PATH = "$WINPE_OC_PATH\$LANG" +$WINPE_OC_LANG_CABS = Get-ChildItem $WINPE_OC_LANG_PATH -Name +$WINPE_OC_LP_PATH = "$WINPE_OC_LANG_PATH\lp.cab" +$WINPE_FONT_SUPPORT_PATH = "$WINPE_OC_PATH\WinPE-FontSupport-$LANG.cab" +$WINPE_SPEECH_TTS_PATH = "$WINPE_OC_PATH\WinPE-Speech-TTS.cab" +$WINPE_SPEECH_TTS_LANG_PATH = "$WINPE_OC_PATH\WinPE-Speech-TTS-$LANG.cab" +$OS_LP_PATH = "$LP_ISO_DRIVE_LETTER`:\x64\langpacks\Microsoft-Windows-Client-Language-Pack_x64_$LANG.cab" # Mount the Features on Demand ISO -Write-Host "$(Get-TS): Mounting FOD ISO" +Write-Output "$(Get-TS): Mounting FOD ISO" $FOD_ISO_DRIVE_LETTER = (Mount-DiskImage -ImagePath $FOD_ISO_PATH -ErrorAction stop | Get-Volume).DriveLetter $FOD_PATH = $FOD_ISO_DRIVE_LETTER + ":\" @@ -161,10 +161,11 @@ New-Item -ItemType directory -Path $WINRE_MOUNT -ErrorAction stop | Out-Null New-Item -ItemType directory -Path $WINPE_MOUNT -ErrorAction stop | Out-Null # Keep the original media, make a copy of it for the new, updateed media. -Write-Host "$(Get-TS): Copying original media to new media path" +Write-Output "$(Get-TS): Copying original media to new media path" Copy-Item -Path $MEDIA_OLD_PATH"\*" -Destination $MEDIA_NEW_PATH -Force -Recurse -ErrorAction stop | Out-Null Get-ChildItem -Path $MEDIA_NEW_PATH -Recurse | Where-Object { -not $_.PSIsContainer -and $_.IsReadOnly } | ForEach-Object { $_.IsReadOnly = $false } ``` + ### Update WinRE The script assumes that only a single edition is being updated, indicated by Index = 1 (Windows 10 Education Edition). Then the script mounts the image, saves Winre.wim to the working folder, and mounts it. It then applies servicing stack Dynamic Update, since its s are used for updating other s. Since the script is optionally adding Japanese, it adds the language pack to the image, and installs the Japanese versions of all optional packages already installed in Winre.wim. Then, it applies the Safe OS Dynamic Update package. @@ -174,27 +175,27 @@ It finishes by cleaning and exporting the image to reduce the image size. > [!NOTE] > Skip adding the latest cumulative update to Winre.wim because it contains unnecessary s in the recovery environment. The s that are updated and applicable are contained in the safe operating system Dynamic Update package. This also helps to keep the image small. -``` +``` PowerShell # Mount the main operating system, used throughout the script -Write-Host "$(Get-TS): Mounting main OS" +Write-Output "$(Get-TS): Mounting main OS" Mount-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\install.wim" -Index 1 -Path $MAIN_OS_MOUNT -ErrorAction stop| Out-Null # # update Windows Recovery Environment (WinRE) # Copy-Item -Path $MAIN_OS_MOUNT"\windows\system32\recovery\winre.wim" -Destination $WORKING_PATH"\winre.wim" -Force -Recurse -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Mounting WinRE" +Write-Output "$(Get-TS): Mounting WinRE" Mount-WindowsImage -ImagePath $WORKING_PATH"\winre.wim" -Index 1 -Path $WINRE_MOUNT -ErrorAction stop | Out-Null # Add servicing stack update -Write-Host "$(Get-TS): Adding package $SSU_PATH" +Write-Output "$(Get-TS): Adding package $SSU_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SSU_PATH -ErrorAction stop | Out-Null # # Optional: Add the language to recovery environment # # Install lp.cab cab -Write-Host "$(Get-TS): Adding package $WINPE_OC_LP_PATH" +Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_OC_LP_PATH -ErrorAction stop | Out-Null # Install language cabs for each optional package installed @@ -210,7 +211,7 @@ Foreach ($PACKAGE in $WINRE_INSTALLED_OC) { $OC_CAB = $PACKAGE.PackageName.Substring(0, $INDEX) + "_" + $LANG + ".cab" if ($WINPE_OC_LANG_CABS.Contains($OC_CAB)) { $OC_CAB_PATH = Join-Path $WINPE_OC_LANG_PATH $OC_CAB - Write-Host "$(Get-TS): Adding package $OC_CAB_PATH" + Write-Output "$(Get-TS): Adding package $OC_CAB_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $OC_CAB_PATH -ErrorAction stop | Out-Null } } @@ -219,7 +220,7 @@ Foreach ($PACKAGE in $WINRE_INSTALLED_OC) { # Add font support for the new language if ( (Test-Path -Path $WINPE_FONT_SUPPORT_PATH) ) { - Write-Host "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_FONT_SUPPORT_PATH -ErrorAction stop | Out-Null } @@ -227,35 +228,36 @@ if ( (Test-Path -Path $WINPE_FONT_SUPPORT_PATH) ) { if (Test-Path -Path $WINPE_SPEECH_TTS_PATH) { if ( (Test-Path -Path $WINPE_SPEECH_TTS_LANG_PATH) ) { - Write-Host "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_SPEECH_TTS_PATH -ErrorAction stop | Out-Null - Write-Host "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH" Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_SPEECH_TTS_LANG_PATH -ErrorAction stop | Out-Null } } # Add Safe OS -Write-Host "$(Get-TS): Adding package $SAFE_OS_DU_PATH" -Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SAFE_OS_DU_PATH -ErrorAction stop | Out-Null +Write-Output "$(Get-TS): Adding package $SAFE_OS_DU_PATH" +Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SAFE_OS_DU_PATH -ErrorAction stop | Out-Null # Perform image cleanup -Write-Host "$(Get-TS): Performing image cleanup on WinRE" +Write-Output "$(Get-TS): Performing image cleanup on WinRE" DISM /image:$WINRE_MOUNT /cleanup-image /StartComponentCleanup | Out-Null # Dismount Dismount-WindowsImage -Path $WINRE_MOUNT -Save -ErrorAction stop | Out-Null # Export -Write-Host "$(Get-TS): Exporting image to $WORKING_PATH\winre2.wim" +Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\winre2.wim" Export-WindowsImage -SourceImagePath $WORKING_PATH"\winre.wim" -SourceIndex 1 -DestinationImagePath $WORKING_PATH"\winre2.wim" -ErrorAction stop | Out-Null Move-Item -Path $WORKING_PATH"\winre2.wim" -Destination $WORKING_PATH"\winre.wim" -Force -ErrorAction stop | Out-Null ``` + ### Update WinPE This script is similar to the one that updates WinRE, but instead it mounts Boot.wim, applies the packages with the latest cumulative update last, and saves. It repeats this for all images inside of Boot.wim, typically two images. It starts by applying the servicing stack Dynamic Update. Since the script is customizing this media with Japanese, it installs the language pack from the WinPE folder on the language pack ISO. Additionally, add font support and text to speech (TTS) support. Since the script is adding a new language, it rebuilds lang.ini, used to identify languages installed in the image. Finally, it cleans and exports Boot.wim, and copies it back to the new media. -``` +``` PowerShell # # update Windows Preinstallation Environment (WinPE) # @@ -266,15 +268,15 @@ $WINPE_IMAGES = Get-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\boot.wim" Foreach ($IMAGE in $WINPE_IMAGES) { # update WinPE - Write-Host "$(Get-TS): Mounting WinPE" + Write-Output "$(Get-TS): Mounting WinPE" Mount-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\boot.wim" -Index $IMAGE.ImageIndex -Path $WINPE_MOUNT -ErrorAction stop | Out-Null # Add SSU - Write-Host "$(Get-TS): Adding package $SSU_PATH" + Write-Output "$(Get-TS): Adding package $SSU_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $SSU_PATH -ErrorAction stop | Out-Null # Install lp.cab cab - Write-Host "$(Get-TS): Adding package $WINPE_OC_LP_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_OC_LP_PATH -ErrorAction stop | Out-Null # Install language cabs for each optional package installed @@ -291,7 +293,7 @@ Foreach ($IMAGE in $WINPE_IMAGES) { $OC_CAB = $PACKAGE.PackageName.Substring(0, $INDEX) + "_" + $LANG + ".cab" if ($WINPE_OC_LANG_CABS.Contains($OC_CAB)) { $OC_CAB_PATH = Join-Path $WINPE_OC_LANG_PATH $OC_CAB - Write-Host "$(Get-TS): Adding package $OC_CAB_PATH" + Write-Output "$(Get-TS): Adding package $OC_CAB_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $OC_CAB_PATH -ErrorAction stop | Out-Null } } @@ -300,7 +302,7 @@ Foreach ($IMAGE in $WINPE_IMAGES) { # Add font support for the new language if ( (Test-Path -Path $WINPE_FONT_SUPPORT_PATH) ) { - Write-Host "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_FONT_SUPPORT_PATH -ErrorAction stop | Out-Null } @@ -308,39 +310,40 @@ Foreach ($IMAGE in $WINPE_IMAGES) { if (Test-Path -Path $WINPE_SPEECH_TTS_PATH) { if ( (Test-Path -Path $WINPE_SPEECH_TTS_LANG_PATH) ) { - Write-Host "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_SPEECH_TTS_PATH -ErrorAction stop | Out-Null - Write-Host "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH" + Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_SPEECH_TTS_LANG_PATH -ErrorAction stop | Out-Null } } # Generates a new Lang.ini file which is used to define the language packs inside the image if ( (Test-Path -Path $WINPE_MOUNT"\sources\lang.ini") ) { - Write-Host "$(Get-TS): Updating lang.ini" + Write-Output "$(Get-TS): Updating lang.ini" DISM /image:$WINPE_MOUNT /Gen-LangINI /distribution:$WINPE_MOUNT | Out-Null - } + } # Add latest cumulative update - Write-Host "$(Get-TS): Adding package $LCU_PATH" + Write-Output "$(Get-TS): Adding package $LCU_PATH" Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null # Perform image cleanup - Write-Host "$(Get-TS): Performing image cleanup on WinPE" + Write-Output "$(Get-TS): Performing image cleanup on WinPE" DISM /image:$WINPE_MOUNT /cleanup-image /StartComponentCleanup | Out-Null # Dismount Dismount-WindowsImage -Path $WINPE_MOUNT -Save -ErrorAction stop | Out-Null #Export WinPE - Write-Host "$(Get-TS): Exporting image to $WORKING_PATH\boot2.wim" + Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\boot2.wim" Export-WindowsImage -SourceImagePath $MEDIA_NEW_PATH"\sources\boot.wim" -SourceIndex $IMAGE.ImageIndex -DestinationImagePath $WORKING_PATH"\boot2.wim" -ErrorAction stop | Out-Null } Move-Item -Path $WORKING_PATH"\boot2.wim" -Destination $MEDIA_NEW_PATH"\sources\boot.wim" -Force -ErrorAction stop | Out-Null ``` + ### Update the main operating system For this next phase, there is no need to mount the main operating system, since it was already mounted in the previous scripts. This script starts by applying the servicing stack Dynamic Update. Then, it adds Japanese language support and then the Japanese language features. Unlike the Dynamic Update packages, it leverages `Add-WindowsCapability` to add these features. For a full list of such features, and their associated capability name, see [Available Features on Demand](https://docs.microsoft.com/windows-hardware/manufacture/desktop/features-on-demand-non-language-fod). @@ -349,42 +352,42 @@ Now is the time to enable other Optional Components or add other Features on Dem You can install Optional Components, along with the .Net feature, offline, but that will require the device to be restarted. This is why the script installs .Net and Optional Components after cleanup and before export. -``` +``` PowerShell # # update Main OS # # Add servicing stack update -Write-Host "$(Get-TS): Adding package $SSU_PATH" +Write-Output "$(Get-TS): Adding package $SSU_PATH" Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $SSU_PATH -ErrorAction stop | Out-Null # Optional: Add language to main OS -Write-Host "$(Get-TS): Adding package $OS_LP_PATH" +Write-Output "$(Get-TS): Adding package $OS_LP_PATH" Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $OS_LP_PATH -ErrorAction stop | Out-Null # Optional: Add a Features on Demand to the image -Write-Host "$(Get-TS): Adding language FOD: Language.Fonts.Jpan~~~und-JPAN~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD: Language.Fonts.Jpan~~~und-JPAN~0.0.1.0" Add-WindowsCapability -Name "Language.Fonts.$LANG_FONT_CAPABILITY~~~und-$LANG_FONT_CAPABILITY~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Adding language FOD: Language.Basic~~~$LANG~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD: Language.Basic~~~$LANG~0.0.1.0" Add-WindowsCapability -Name "Language.Basic~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Adding language FOD: Language.OCR~~~$LANG~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD: Language.OCR~~~$LANG~0.0.1.0" Add-WindowsCapability -Name "Language.OCR~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Adding language FOD: Language.Handwriting~~~$LANG~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD: Language.Handwriting~~~$LANG~0.0.1.0" Add-WindowsCapability -Name "Language.Handwriting~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Adding language FOD: Language.TextToSpeech~~~$LANG~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD: Language.TextToSpeech~~~$LANG~0.0.1.0" Add-WindowsCapability -Name "Language.TextToSpeech~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Adding language FOD:Language.Speech~~~$LANG~0.0.1.0" +Write-Output "$(Get-TS): Adding language FOD:Language.Speech~~~$LANG~0.0.1.0" Add-WindowsCapability -Name "Language.Speech~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null # Note: If I wanted to enable additional Features on Demand, I'd add these here. # Add latest cumulative update -Write-Host "$(Get-TS): Adding package $LCU_PATH" +Write-Output "$(Get-TS): Adding package $LCU_PATH" Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null # Copy our updated recovery image from earlier into the main OS @@ -393,7 +396,7 @@ Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH -ErrorAction stop Copy-Item -Path $WORKING_PATH"\winre.wim" -Destination $MAIN_OS_MOUNT"\windows\system32\recovery\winre.wim" -Force -Recurse -ErrorAction stop | Out-Null # Perform image cleanup -Write-Host "$(Get-TS): Performing image cleanup on main OS" +Write-Output "$(Get-TS): Performing image cleanup on main OS" DISM /image:$MAIN_OS_MOUNT /cleanup-image /StartComponentCleanup | Out-Null # @@ -402,18 +405,18 @@ DISM /image:$MAIN_OS_MOUNT /cleanup-image /StartComponentCleanup | Out-Null # the image to be booted, and thus if we tried to cleanup after installation, it would fail. # -Write-Host "$(Get-TS): Adding NetFX3~~~~" +Write-Output "$(Get-TS): Adding NetFX3~~~~" Add-WindowsCapability -Name "NetFX3~~~~" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null # Add .Net Cumulative Update -Write-Host "$(Get-TS): Adding package $DOTNET_CU_PATH" +Write-Output "$(Get-TS): Adding package $DOTNET_CU_PATH" Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $DOTNET_CU_PATH -ErrorAction stop | Out-Null # Dismount Dismount-WindowsImage -Path $MAIN_OS_MOUNT -Save -ErrorAction stop | Out-Null # Export -Write-Host "$(Get-TS): Exporting image to $WORKING_PATH\install2.wim" +Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\install2.wim" Export-WindowsImage -SourceImagePath $MEDIA_NEW_PATH"\sources\install.wim" -SourceIndex 1 -DestinationImagePath $WORKING_PATH"\install2.wim" -ErrorAction stop | Out-Null Move-Item -Path $WORKING_PATH"\install2.wim" -Destination $MEDIA_NEW_PATH"\sources\install.wim" -Force -ErrorAction stop | Out-Null ``` @@ -422,20 +425,21 @@ Move-Item -Path $WORKING_PATH"\install2.wim" -Destination $MEDIA_NEW_PATH"\sourc This part of the script updates the Setup files. It simply copies the individual files in the Setup Dynamic Update package to the new media. This step brings an updated Setup.exe as needed, along with the latest compatibility database, and replacement component manifests. -``` +``` PowerShell # # update remaining files on media # # Add Setup DU by copy the files from the package into the newMedia -Write-Host "$(Get-TS): Adding package $SETUP_DU_PATH" +Write-Output "$(Get-TS): Adding package $SETUP_DU_PATH" cmd.exe /c $env:SystemRoot\System32\expand.exe $SETUP_DU_PATH -F:* $MEDIA_NEW_PATH"\sources" | Out-Null ``` + ### Finish up As a last step, the script removes the working folder of temporary files, and unmounts our language pack and Features on Demand ISOs. -``` +``` PowerShell # # Perform final cleanup # @@ -444,9 +448,9 @@ As a last step, the script removes the working folder of temporary files, and un Remove-Item -Path $WORKING_PATH -Recurse -Force -ErrorAction stop | Out-Null # Dismount ISO images -Write-Host "$(Get-TS): Dismounting ISO images" +Write-Output "$(Get-TS): Dismounting ISO images" Dismount-DiskImage -ImagePath $LP_ISO_PATH -ErrorAction stop | Out-Null Dismount-DiskImage -ImagePath $FOD_ISO_PATH -ErrorAction stop | Out-Null -Write-Host "$(Get-TS): Media refresh completed!" +Write-Output "$(Get-TS): Media refresh completed!" ``` From 893db2910c80f7fb96dfd3aa1212a92b590002db Mon Sep 17 00:00:00 2001 From: skycommand Date: Sun, 4 Oct 2020 09:33:10 +0330 Subject: [PATCH 2/6] Update windows/deployment/update/media-dynamic-update.md Co-authored-by: JohanFreelancer9 <48568725+JohanFreelancer9@users.noreply.github.com> --- windows/deployment/update/media-dynamic-update.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/deployment/update/media-dynamic-update.md b/windows/deployment/update/media-dynamic-update.md index 2c0a78e280..ea81420b8b 100644 --- a/windows/deployment/update/media-dynamic-update.md +++ b/windows/deployment/update/media-dynamic-update.md @@ -93,7 +93,7 @@ Optional Components, along with the .NET feature, can be installed offline, howe ## Windows PowerShell scripts to apply Dynamic Updates to an existing image -These examples are for illustration only, and therefore lack error handling. The script assumes that the following packages is stored locally in this folder structure: +These examples are for illustration only, and therefore lack error handling. The script assumes that the following packages are stored locally in this folder structure: |Folder |Description | |---------|---------| From 19fe418cbb0427db7819ab1d98b91b65516e5add Mon Sep 17 00:00:00 2001 From: VARADHARAJAN K <3296790+RAJU2529@users.noreply.github.com> Date: Fri, 16 Oct 2020 08:58:02 +0530 Subject: [PATCH 3/6] removed broken link added new correct link as per the user report #8473 , so i replaced the broken link to correct link. --- windows/security/threat-protection/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/security/threat-protection/index.md b/windows/security/threat-protection/index.md index b4f683756c..3763417926 100644 --- a/windows/security/threat-protection/index.md +++ b/windows/security/threat-protection/index.md @@ -17,7 +17,7 @@ ms.topic: conceptual --- # Threat Protection -[Microsoft Defender Advanced Threat Protection (Microsoft Defender ATP)](https://go.microsoft.com/fwlink/p/?linkid=2069559) is a unified platform for preventative protection, post-breach detection, automated investigation, and response. Microsoft Defender ATP protects endpoints from cyber threats; detects advanced attacks and data breaches, automates security incidents and improves security posture. +[Microsoft Defender Advanced Threat Protection (Microsoft Defender ATP)](https://docs.microsoft.com/windows/security/threat-protection/microsoft-defender-atp/microsoft-defender-advanced-threat-protection) is a unified platform for preventative protection, post-breach detection, automated investigation, and response. Microsoft Defender ATP protects endpoints from cyber threats; detects advanced attacks and data breaches, automates security incidents and improves security posture. >[!TIP] > Enable your users to access cloud services and on-premises applications with ease and enable modern management capabilities for all devices. For more information, see [Secure your remote workforce](https://docs.microsoft.com/enterprise-mobility-security/remote-work/). From 470c7b461c81f52a684493ae589c090f9a3193d9 Mon Sep 17 00:00:00 2001 From: VARADHARAJAN K <3296790+RAJU2529@users.noreply.github.com> Date: Sat, 17 Oct 2020 16:54:30 +0530 Subject: [PATCH 4/6] Update windows/security/threat-protection/index.md accepted Co-authored-by: Trond B. Krokli <38162891+illfated@users.noreply.github.com> --- windows/security/threat-protection/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/security/threat-protection/index.md b/windows/security/threat-protection/index.md index 3763417926..5873b326d0 100644 --- a/windows/security/threat-protection/index.md +++ b/windows/security/threat-protection/index.md @@ -19,7 +19,7 @@ ms.topic: conceptual # Threat Protection [Microsoft Defender Advanced Threat Protection (Microsoft Defender ATP)](https://docs.microsoft.com/windows/security/threat-protection/microsoft-defender-atp/microsoft-defender-advanced-threat-protection) is a unified platform for preventative protection, post-breach detection, automated investigation, and response. Microsoft Defender ATP protects endpoints from cyber threats; detects advanced attacks and data breaches, automates security incidents and improves security posture. ->[!TIP] +> [!TIP] > Enable your users to access cloud services and on-premises applications with ease and enable modern management capabilities for all devices. For more information, see [Secure your remote workforce](https://docs.microsoft.com/enterprise-mobility-security/remote-work/).

Microsoft Defender ATP

From d73e0a401052b2abd11f49532e9a37d76f33dbc5 Mon Sep 17 00:00:00 2001 From: VARADHARAJAN K <3296790+RAJU2529@users.noreply.github.com> Date: Sat, 17 Oct 2020 19:59:34 +0530 Subject: [PATCH 5/6] added simplifying deployment of SSU link as per the user feedback #8478, so i added a simplifying-on-premises-deployment-of-SSU link. --- windows/deployment/update/servicing-stack-updates.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/windows/deployment/update/servicing-stack-updates.md b/windows/deployment/update/servicing-stack-updates.md index 49d29f4d8a..3ad8432738 100644 --- a/windows/deployment/update/servicing-stack-updates.md +++ b/windows/deployment/update/servicing-stack-updates.md @@ -28,6 +28,8 @@ Servicing stack updates provide fixes to the servicing stack, the component that Servicing stack updates improve the reliability of the update process to mitigate potential issues while installing the latest quality updates and feature updates. If you don't install the latest servicing stack update, there's a risk that your device can't be updated with the latest Microsoft security fixes. +See this [Simplifing Deployment of Servicing Stack Updates](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/simplifying-on-premises-deployment-of-servicing-stack-updates/ba-p/1646039) + ## When are they released? Servicing stack update are released depending on new issues or vulnerabilities. In rare occasions a servicing stack update may need to be released on demand to address an issue impacting systems installing the monthly security update. Starting in November 2018 new servicing stack updates will be classified as "Security" with a severity rating of "Critical." From 0184e9d6e04f13a5419d1c437341152795b55f21 Mon Sep 17 00:00:00 2001 From: Jaime Ondrusek Date: Mon, 19 Oct 2020 09:44:23 -0700 Subject: [PATCH 6/6] Update servicing-stack-updates.md Tweaking language. --- windows/deployment/update/servicing-stack-updates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/deployment/update/servicing-stack-updates.md b/windows/deployment/update/servicing-stack-updates.md index 3ad8432738..e5a1395289 100644 --- a/windows/deployment/update/servicing-stack-updates.md +++ b/windows/deployment/update/servicing-stack-updates.md @@ -28,7 +28,7 @@ Servicing stack updates provide fixes to the servicing stack, the component that Servicing stack updates improve the reliability of the update process to mitigate potential issues while installing the latest quality updates and feature updates. If you don't install the latest servicing stack update, there's a risk that your device can't be updated with the latest Microsoft security fixes. -See this [Simplifing Deployment of Servicing Stack Updates](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/simplifying-on-premises-deployment-of-servicing-stack-updates/ba-p/1646039) +For information about some changes to servicing stack updates, see [Simplifing Deployment of Servicing Stack Updates](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/simplifying-on-premises-deployment-of-servicing-stack-updates/ba-p/1646039) on the Windows IT Pro blog. ## When are they released?