|
| 1 | +# Windows Patching Extension |
| 2 | + |
| 3 | +This extension will install Windows Server patches, including prerelease hotfixes. It's useful for the following cases: |
| 4 | + |
| 5 | +1. Microsoft support has provided a pre-release hotfix for your testing |
| 6 | +2. Installing additional Windows update packages (MSU) that are not yet included in the default Windows Server with Containers VM on the Azure Marketplace. |
| 7 | + |
| 8 | +## Configuration |
| 9 | + |
| 10 | +|Name |Required| Acceptable Value | |
| 11 | +|-------------------|--------|----------------------| |
| 12 | +|name |yes | windows-patches | |
| 13 | +|version |yes | v1 | |
| 14 | +|rootURL |optional| `https://raw.githubusercontent.com/Azure/acs-engine/master/` or any repo with the same extensions/... directory structure | |
| 15 | +|extensionParameters|yes | comma-delimited list of URIs enclosed with ' such as `'https://privateupdates.domain.ext/Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe', 'https://privateupdates.domain.ext/Windows10.0-KB123456-x64-InstallForTestingPurposesOnly.exe'` | |
| 16 | + |
| 17 | +## Example |
| 18 | + |
| 19 | +```json |
| 20 | + ... |
| 21 | + "agentPoolProfiles": [ |
| 22 | + { |
| 23 | + "name": "windowspool1", |
| 24 | + "extensions": [ |
| 25 | + { |
| 26 | + "name": "windows-patches" |
| 27 | + } |
| 28 | + ] |
| 29 | + } |
| 30 | + ], |
| 31 | + ... |
| 32 | + "extensionProfiles": [ |
| 33 | + { |
| 34 | + "name": "windows-patches", |
| 35 | + "version": "v1", |
| 36 | + "rootURL": "https://raw.githubusercontent.com/Azure/acs-engine/master/", |
| 37 | + "extensionParameters": "'https://mypatches.blob.core.windows.net/hotfix3692/Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe?sp=r&st=2018-08-17T00:25:01Z&se=2018-09-17T08:25:01Z&spr=https&sv=2017-11-09&sig=0000000000%3D&sr=b', 'http://download.windowsupdate.com/c/msdownload/update/software/secu/2018/08/windows10.0-kb4343909-x64_f931af6d56797388715fe3b0d97569af7aebdae6.msu'" |
| 38 | + } |
| 39 | + ] |
| 40 | + ... |
| 41 | +``` |
| 42 | + |
| 43 | +## Supported Orchestrators |
| 44 | + |
| 45 | +This has been tested with Kubernetes clusters, and does not depend on any specific version. |
| 46 | + |
| 47 | +## Selecting Patches |
| 48 | + |
| 49 | +### Cumulative Updates |
| 50 | + |
| 51 | +If you would like to include a cumulative update as part of your deployment that isn't in the Windows Server with Containers image, then follow these steps. |
| 52 | + |
| 53 | +1. Browse to [Windows 10 Update History](https://support.microsoft.com/en-us/help/4099479), and follow the link to the right version (1709 or 1803) in the left. This page should be titled "Windows 10 and Windows Server update history" because the links also lead you to Windows Server updates. |
| 54 | +2. Next, look for the latest patch in the lower left such as ["August 14, 2018—KB4343909 (OS Build 17134.228)"](https://support.microsoft.com/en-us/help/4343909), and click that link. |
| 55 | +3. Scroll down to "How to get this update", and click on the ["Microsoft Update Catalog"](http://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB4343909) link. |
| 56 | +4. Find the row for `(year)-(month) Cumulative Update for Windows Server 2016 ((1709 or 1803)) for x64-based Systems (KB######)`, and click the "Download" button. |
| 57 | +5. This will pop up a new window with a hyperlink such as `windows10.0-kb4343909-x64_f931af6d56797388715fe3b0d97569af7aebdae6.msu`. Copy that link. |
| 58 | +6. Include that link in the `extensionParameters` as shown in the [Example](#Example) |
| 59 | + |
| 60 | +### Supplied by Microsoft support |
| 61 | + |
| 62 | +Once you have downloaded a private hotfix from Microsoft support, it needs to be put in an Azure-accessible location. The easiest way to do this is to create an [Azure Blob Storage](https://docs.microsoft.com/en-us/azure/storage/common/storage-create-storage-account#blob-storage-accounts) account. Once uploaded, you can create a private link with a key to access it that will work with this extension. |
| 63 | + |
| 64 | +1. If you haven't already, install the [Azure CLI](https://docs.microsoft.com/cli/azure/get-started-with-az-cli2), and run `az login` to log in to Azure |
| 65 | +2. Copy the sample below for either bash (Linux, Mac, or WSL), or PowerShell (Windows), and modify the variables at the top. |
| 66 | + |
| 67 | + |
| 68 | +#### Using az cli and bash to upload the patch |
| 69 | + |
| 70 | +```bash |
| 71 | +#!/bin/bash |
| 72 | +export resource_group=patchgroup |
| 73 | +export storage_location=westus2 |
| 74 | +export storage_account_name=privatepatches |
| 75 | +export container_name=hotfix |
| 76 | +export blob_name=Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe |
| 77 | +export file_to_upload=Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe |
| 78 | + |
| 79 | +echo "Creating the group..." |
| 80 | +az group create --location $storage_location --resource-group $resource_group |
| 81 | + |
| 82 | +echo "Creating the storage account..." |
| 83 | +az storage account create --location $storage_location --name $storage_account_name --resource-group $resource_group --sku Standard_LRS |
| 84 | + |
| 85 | +echo "Getting the connection string..." |
| 86 | +export AZURE_STORAGE_CONNECTION_STRING="`az storage account show-connection-string --name $storage_account_name --resource-group $resource_group`" |
| 87 | + |
| 88 | +echo "Creating the container..." |
| 89 | +az storage container create --name $container_name |
| 90 | + |
| 91 | +echo "Uploading the file..." |
| 92 | +az storage blob upload --container-name $container_name --file $file_to_upload --name $blob_name |
| 93 | + |
| 94 | +echo "Getting a read-only SAS token, good for 30 days..." |
| 95 | +export EXPIRY=`date +"%Y-%m-%dT%H:%M:%SZ" -d '30 days'` |
| 96 | +export TEMPORARY_SAS=`az storage blob generate-sas --container-name $container_name --name $blob_name --permissions r --expiry $EXPIRY` |
| 97 | + |
| 98 | +echo "Getting a URL to the file..." |
| 99 | +export ABSURL=`az storage blob url --container-name $container_name --name $blob_name --sas-token $TEMPORARY_SAS` |
| 100 | + |
| 101 | +echo "Full URL including access token:" |
| 102 | +echo "$ABSURL?$TEMPORARY_SAS" | sed "s/\"//g" |
| 103 | +``` |
| 104 | + |
| 105 | +#### Using az cli and PowerShell to upload the patch |
| 106 | + |
| 107 | +```powershell |
| 108 | +$resource_group="patchgroup" |
| 109 | +$storage_location="westus2" |
| 110 | +$storage_account_name="privatepatches" |
| 111 | +$container_name="hotfix" |
| 112 | +$blob_name="Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe" |
| 113 | +$file_to_upload="Windows10.0-KB999999-x64-InstallForTestingPurposesOnly.exe" |
| 114 | +
|
| 115 | +Write-Host "Creating the group..." |
| 116 | +az group create --location $storage_location --resource-group $resource_group |
| 117 | +
|
| 118 | +Write-Host "Creating the storage account..." |
| 119 | +az storage account create --location $storage_location --name $storage_account_name --resource-group $resource_group --sku Standard_LRS |
| 120 | +
|
| 121 | +Write-Host "Getting the connection string..." |
| 122 | +$ENV:AZURE_STORAGE_CONNECTION_STRING = az storage account show-connection-string --name $storage_account_name --resource-group $resource_group |
| 123 | +
|
| 124 | +Write-Host "Creating the container..." |
| 125 | +az storage container create --name $container_name |
| 126 | +
|
| 127 | +Write-Host "Uploading the file..." |
| 128 | +az storage blob upload --container-name $container_name --file $file_to_upload --name $blob_name |
| 129 | +
|
| 130 | +Write-Host "Getting a read-only SAS token, good for 30 days..." |
| 131 | +$EXPIRY = ([DateTime]::Now + [timespan]::FromDays(30)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") |
| 132 | +$TEMPORARY_SAS = az storage blob generate-sas --container-name $container_name --name $blob_name --permissions r --expiry $EXPIRY |
| 133 | +
|
| 134 | +Write-Host "Getting a URL to the file..." |
| 135 | +$ABSURL = az storage blob url --container-name $container_name --name $blob_name --sas-token $TEMPORARY_SAS |
| 136 | +
|
| 137 | +Write-Host "Full URL including access token:" |
| 138 | +$full_url = "$($ABSURL)?$($TEMPORARY_SAS)".Replace("""","") |
| 139 | +$full_url | Write-Host |
| 140 | +$full_url | Set-Clipboard |
| 141 | +``` |
| 142 | + |
| 143 | +The last line of the script will output a URL, and also put it on the Windows clipboard. Copy it into `extensionParameters` as shown in the sample above. Do not share this URL, keep it private. |
| 144 | + |
| 145 | +## Troubleshooting |
| 146 | + |
| 147 | +Extension execution output is logged to files found under the following directory on the target virtual machine. |
| 148 | + |
| 149 | +```powershell |
| 150 | +C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension |
| 151 | +``` |
| 152 | + |
| 153 | +The specified files are downloaded into the following directory on the target virtual machine. |
| 154 | + |
| 155 | +```powershell |
| 156 | +C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.*\Downloads\<n> |
| 157 | +``` |
0 commit comments