1+ [CmdletBinding ()]
2+ param ([Parameter (Mandatory = $true , Position = 0 )]
3+ [string ]$buildNumber ,
4+ [switch ]$desktopCPP = $true )
5+
6+ # Ensure the error action preference is set to the default for PowerShell3, 'Stop'
7+ $ErrorActionPreference = ' Stop'
8+ # from: https://github.com/GuillaumeFalourd/setup-windows10-sdk-action
9+ # Constants
10+ $WindowsSDKOptions = @ (" OptionId.UWPCpp" )
11+ $WindowsSDKRegPath = " HKLM:\Software\Microsoft\Windows Kits\Installed Roots"
12+ $WindowsSDKRegRootKey = " KitsRoot10"
13+ $WindowsSDKVersion = " 10.0.$buildNumber .0"
14+ $WindowsSDKInstalledRegPath = " $WindowsSDKRegPath \$WindowsSDKVersion \Installed Options"
15+ $StrongNameRegPath = " HKLM:\SOFTWARE\Microsoft\StrongName\Verification"
16+ $PublicKeyTokens = @ (" 31bf3856ad364e35" )
17+
18+ if ($buildNumber -notmatch " ^\d{5,}$" )
19+ {
20+ Write-Host " ERROR: '$buildNumber ' doesn't look like a windows build number"
21+ Write-Host
22+ Exit 1
23+ }
24+
25+ function Download-File {
26+ param ([string ] $outDir ,
27+ [string ] $downloadUrl ,
28+ [string ] $downloadName )
29+
30+ $downloadPath = Join-Path $outDir " $downloadName .download"
31+ $downloadDest = Join-Path $outDir $downloadName
32+ $downloadDestTemp = Join-Path $outDir " $downloadName .tmp"
33+
34+ Write-Host - NoNewline " Downloading $downloadName ..."
35+
36+ if ($buildNumber -eq " 17763" ) {
37+ $downloadURL = " https://software-download.microsoft.com/download/pr/17763.132.181022-1834.rs5_release_svc_prod1_WindowsSDK.iso"
38+ }
39+
40+ if ($buildNumber -eq " 18362" ) {
41+ $downloadURL = " https://software-download.microsoft.com/download/pr/18362.1.190318-1202.19h1_release_WIndowsSDK.iso"
42+ }
43+
44+ if ($buildNumber -eq " 19041" ) {
45+ $downloadURL = " https://software-download.microsoft.com/download/pr/19041.685.201201-2105.vb_release_svc_prod1_WindowsSDK.iso"
46+ }
47+
48+ if ($buildNumber -eq " 20348" ) {
49+ $downloadUrl = " https://software-download.microsoft.com/download/pr/20348.1.210507-1500.fe_release_WindowsSDK.iso"
50+ }
51+
52+ if ($buildNumber -eq " 22000" ) {
53+ $downloadUrl = " https://software-static.download.prss.microsoft.com/pr/download/22000.194.210911-1543.co_release_svc_prod1_WindowsSDK.iso"
54+ }
55+
56+ if ($buildNumber -eq " 22621" ) {
57+ $downloadUrl = " https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/22621.1.220506-1250.ni_release_WindowsSDK.iso"
58+ }
59+
60+ try {
61+ $webclient = new-object System.Net.WebClient
62+ $webclient.DownloadFile ($downloadUrl , $downloadPath )
63+ }
64+ catch [System.Net.WebException ] {
65+ Write-Host
66+ Write-Warning " Failed to fetch updated file from $downloadUrl "
67+ if (! (Test-Path $downloadDest )) {
68+ throw " $downloadName was not found at $downloadDest "
69+ }
70+ else {
71+ Write-Warning " $downloadName may be out of date"
72+ }
73+ }
74+
75+ Unblock-File $downloadPath
76+
77+ $downloadDestTemp = $downloadPath ;
78+
79+ # Delete and rename to final dest
80+ if (Test-Path - PathType Container $downloadDest ) {
81+ [System.IO.Directory ]::Delete($downloadDest , $true )
82+ }
83+
84+ Move-Item - Force $downloadDestTemp $downloadDest
85+ Write-Host " Done"
86+
87+ return $downloadDest
88+ }
89+
90+ function Get-ISODriveLetter {
91+ param ([string ] $isoPath )
92+
93+ $diskImage = Get-DiskImage - ImagePath $isoPath
94+ if ($diskImage ) {
95+ $volume = Get-Volume - DiskImage $diskImage
96+
97+ if ($volume ) {
98+ $driveLetter = $volume.DriveLetter
99+ if ($driveLetter ) {
100+ $driveLetter += " :"
101+ return $driveLetter
102+ }
103+ }
104+ }
105+
106+ return $null
107+ }
108+
109+ function Mount-ISO {
110+ param ([string ] $isoPath )
111+
112+ # Check if image is already mounted
113+ $isoDrive = Get-ISODriveLetter $isoPath
114+
115+ if (! $isoDrive ) {
116+ Mount-DiskImage - ImagePath $isoPath - StorageType ISO | Out-Null
117+ }
118+
119+ $isoDrive = Get-ISODriveLetter $isoPath
120+ Write-Verbose " $isoPath mounted to ${isoDrive} :"
121+ }
122+
123+ function Dismount-ISO {
124+ param ([string ] $isoPath )
125+
126+ $isoDrive = (Get-DiskImage - ImagePath $isoPath | Get-Volume ).DriveLetter
127+
128+ if ($isoDrive ) {
129+ Write-Verbose " $isoPath dismounted"
130+ Dismount-DiskImage - ImagePath $isoPath | Out-Null
131+ }
132+ }
133+
134+ function Disable-StrongName {
135+ param ([string ] $publicKeyToken = " *" )
136+
137+ reg ADD " HKLM\SOFTWARE\Microsoft\StrongName\Verification\*,$publicKeyToken " / f | Out-Null
138+ if ($env: PROCESSOR_ARCHITECTURE -eq " AMD64" ) {
139+ reg ADD " HKLM\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,$publicKeyToken " / f | Out-Null
140+ }
141+ }
142+
143+ function Test-Admin {
144+ $identity = [Security.Principal.WindowsIdentity ]::GetCurrent()
145+ $principal = New-Object Security.Principal.WindowsPrincipal $identity
146+ $principal.IsInRole ([Security.Principal.WindowsBuiltInRole ]::Administrator)
147+ }
148+
149+ function Test-RegistryPathAndValue {
150+ param (
151+ [parameter (Mandatory = $true )]
152+ [ValidateNotNullOrEmpty ()]
153+ [string ] $path ,
154+ [parameter (Mandatory = $true )]
155+ [ValidateNotNullOrEmpty ()]
156+ [string ] $value )
157+
158+ try {
159+ if (Test-Path $path ) {
160+ Get-ItemProperty - Path $path | Select-Object - ExpandProperty $value - ErrorAction Stop | Out-Null
161+ return $true
162+ }
163+ }
164+ catch {
165+ }
166+
167+ return $false
168+ }
169+
170+ function Test-InstallWindowsSDK {
171+ $retval = $true
172+
173+ if (Test-RegistryPathAndValue - Path $WindowsSDKRegPath - Value $WindowsSDKRegRootKey ) {
174+ # A Windows SDK is installed
175+ # Is an SDK of our version installed with the options we need?
176+ if (Test-RegistryPathAndValue - Path $WindowsSDKInstalledRegPath - Value " $WindowsSDKOptions " ) {
177+ # It appears we have what we need. Double check the disk
178+ $sdkRoot = Get-ItemProperty - Path $WindowsSDKRegPath | Select-Object - ExpandProperty $WindowsSDKRegRootKey
179+ if ($sdkRoot ) {
180+ if (Test-Path $sdkRoot ) {
181+ $refPath = Join-Path $sdkRoot " References\$WindowsSDKVersion "
182+ if (Test-Path $refPath ) {
183+ $umdPath = Join-Path $sdkRoot " UnionMetadata\$WindowsSDKVersion "
184+ if (Test-Path $umdPath ) {
185+ # Pretty sure we have what we need
186+ $retval = $false
187+ }
188+ }
189+ }
190+ }
191+ }
192+ }
193+
194+ return $retval
195+ }
196+
197+ function Test-InstallStrongNameHijack {
198+ foreach ($publicKeyToken in $PublicKeyTokens ) {
199+ $key = " $StrongNameRegPath \*,$publicKeyToken "
200+ if (! (Test-Path $key )) {
201+ return $true
202+ }
203+ }
204+
205+ return $false
206+ }
207+
208+ Write-Host - NoNewline " Checking for installed Windows SDK $WindowsSDKVersion ..."
209+ $InstallWindowsSDK = Test-InstallWindowsSDK
210+ if ($InstallWindowsSDK ) {
211+ Write-Host " Installation required"
212+ }
213+ else {
214+ Write-Host " INSTALLED"
215+ }
216+
217+ $StrongNameHijack = Test-InstallStrongNameHijack
218+ Write-Host - NoNewline " Checking if StrongName bypass required..."
219+
220+ if ($StrongNameHijack ) {
221+ Write-Host " REQUIRED"
222+ }
223+ else {
224+ Write-Host " Done"
225+ }
226+
227+ if ($StrongNameHijack -or $InstallWindowsSDK ) {
228+ if (! (Test-Admin )) {
229+ Write-Host
230+ throw " ERROR: Elevation required"
231+ }
232+ }
233+
234+ if ($InstallWindowsSDK ) {
235+ # Static(ish) link for Windows SDK
236+ # Note: there is a delay from Windows SDK announcements to availability via the static link
237+ $uri = " https://software-download.microsoft.com/download/sg/Windows_InsiderPreview_SDK_en-us_$ ( $buildNumber ) _1.iso" ;
238+
239+ if ($null -eq $env: TEMP ) {
240+ $env: TEMP = Join-Path $env: SystemDrive ' temp'
241+ }
242+
243+ $winsdkTempDir = Join-Path $env: TEMP " WindowsSDK"
244+
245+ if (! [System.IO.Directory ]::Exists($winsdkTempDir )) {
246+ [void ][System.IO.Directory ]::CreateDirectory($winsdkTempDir )
247+ }
248+
249+ $file = " winsdk_$buildNumber .iso"
250+
251+ Write-Verbose " Getting WinSDK from $uri "
252+ $downloadFile = Download- File $winsdkTempDir $uri $file
253+
254+ # TODO Check if zip, exe, iso, etc.
255+ try {
256+ Write-Host - NoNewline " Mounting ISO $file ..."
257+ Mount-ISO $downloadFile
258+ Write-Host " Done"
259+
260+ $isoDrive = Get-ISODriveLetter $downloadFile
261+
262+ if (Test-Path $isoDrive ) {
263+ Write-Host - NoNewLine " Installing WinSDK..."
264+
265+ $setupPath = Join-Path " $isoDrive " " WinSDKSetup.exe"
266+ Start-Process - Wait $setupPath " /features $WindowsSDKOptions /q"
267+ Write-Host " Done"
268+ }
269+ else {
270+ throw " Could not find mounted ISO at ${isoDrive} "
271+ }
272+ }
273+ finally {
274+ Write-Host - NoNewline " Dismounting ISO $file ..."
275+ # Dismount-ISO $downloadFile
276+ Write-Host " Done"
277+ }
278+ }
279+
280+ if ($StrongNameHijack ) {
281+ Write-Host - NoNewline " Disabling StrongName for Windows SDK..."
282+
283+ foreach ($key in $PublicKeyTokens ) {
284+ Disable-StrongName $key
285+ }
286+
287+ Write-Host " Done"
288+ }
0 commit comments