-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInstall-SccmPrerequisites.ps1
325 lines (276 loc) · 8.99 KB
/
Install-SccmPrerequisites.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
<#
.SYNOPSIS
Install Sccm prerequisites including Windows Features and ADK components.
.DESCRIPTION
Install Sccm prerequisites including Windows Features and ADK components.
This is best used after running the Save-SccmPrerequisites.ps1 script.
.PARAMETER PrereqPath
Path to the folder containing all the files for prerequisites.
If you ran Save-SccmPrerequisites.ps1, use the same folder specified in -Path.
.PARAMETER WindowsMediaPath
Path to the current version of Windows' sxs store.
This is only required to install .Net 3.5 which is not included in the OS.
If this feature has been installed this parameter is not needed.
.EXAMPLE
Install-SccmPrerequisites.ps1 -PrereqPath . -WindowsMediaSourcePath D:\sources\sxs\
Description
-----------
In this command are using the current directory for the PrereqPath.
By using the -WindowsMediaSourcePath parameter, we are telling the script to install .NetFramework 3.5 using the Windows installer source media under D:\sources\sxs. This would have required us to mount the Windows installer ISO prior to running the script.
.EXAMPLE
Install-SccmPrerequisites.ps1 -PrereqPath C:\temp\sccm -Verbose
Description
-----------
In this example, we specify that the ADK prerequisites are in the C:\temp\sccm folder.
Since we have not specified -WindowsMediaSourcePath, the script will not install .Net Framework 3.5, but it will notify us if it is not installed so we can manually install it later.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,Position=0)]
[String]$PrereqPath,
[Parameter(Position=1)]
[ValidateScript({Test-Path -Path $_})]
[String]$WindowsMediaPath
)
Function isAdministrator {
$wid=[Security.Principal.WindowsIdentity]::GetCurrent()
$principal=New-Object -TypeName Security.Principal.WindowsPrincipal `
-ArgumentList $wid
$adminRole=[Security.Principal.WindowsBuiltInRole]::Administrator
return $principal.IsInRole($adminRole)
}
Function GetADKInstalledFeatures {
[CmdletBinding()]
Param()
$kitsRegPath='HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits'
Try{
$winKitsInstall=Test-Path -Path $kitsRegpath
if(!$winKitsInstall){
Write-Error "[$kitsRegPath] does not exist. ADK not installed." `
-ErrorAction Stop
}
$installRoots=Get-ChildItem -Path "$kitsRegPath\Installed Roots" `
-ErrorAction Stop
if(!$installRoots){
Write-Error "Install Roots key not found. ADK features not installed." `
-ErrorAction Stop
}
$installOptPath="$($installRoots[0].PSPath)\Installed Options"
$installOpt=Get-Item -Path $installOptPath -ErrorAction Stop
$installOptHash=New-Object -TypeName hashtable
foreach($option in $installOpt.Property){
$installOptHash.Add($option,$installOpt.GetValue($option))
}
Write-Output $installOptHash
}Catch{
Write-Error $_
}
}
Function WaitForProcessEnd {
[CmdletBinding()]
Param(
[String]$processName,
[String]$msg
)
$processRunning=$true
Write-Host $msg -NoNewline
Do{
Write-Host '.' -NoNewline
Start-Sleep -Seconds 30
$process=Get-Process -Name $processName `
-ErrorAction SilentlyContinue
if(!$process){
$processRunning=$false
}
}While($processRunning)
}
Try{
Write-Verbose "Admin?"
$isAdmin=isAdministrator
if(!$isAdmin){
Write-Error "Not running as Admin. Run with Administrative permissions" `
-ErrorAction Stop
}
Write-Verbose "Validating PreReq files"
$prereqTest=Test-Path -Path $PrereqPath
if(!$prereqTest){
Write-Error "PreReq Source Path is invalid" `
-ErrorAction Stop
}
$sccmPreReqPath=Join-Path -Path $PrereqPath -ChildPath prereq
$adkPath=Join-Path -Path $PrereqPath -ChildPath adk
$adkPePath=Join-Path -Path $PrereqPath -ChildPath adkPeAddon
$prereqFolders=@(
$sccmPreReqPath,
$adkPath,
$adkPePath
)
$peAddonPresent=$true
$peAddonRequired=$false
[version]$adkVersionNoPE='10.1.17763.1'
foreach($folder in $prereqFolders){
$folderExist=Test-Path -Path $folder
if(!$folderExist){
switch -Wildcard ($folder) {
'*adkPeAddon' {
$peAddonPresent=$false
continue
}
'*adk' {
Write-Error "Required PreReq folder not found [$folder]" `
-ErrorAction Stop
}
Default {
$warn=[String]::Format(
"The folder {0} was not found. {1}. {2}",
$folder,
"This may cause issues during sccm install",
"Install will continue..."
)
Write-Warning $warn
}
} # End switch
} # End folder test
} # End folder loop
### ADK and WinPE Addon Validation
Write-Verbose "Validating ADK Status"
$adkMandatoryFeatureList=@(
'OptionId.DeploymentTools',
'OptionId.UserStateMigrationTool',
'OptionId.WindowsPreinstallationEnvironment'
)
$requiredAdkFeatureList=New-Object -TypeName Collections.ArrayList
$adkInstallHash=GetADKInstalledFeatures -ErrorAction SilentlyContinue
foreach($feature in $adkMandatoryFeatureList){
if($adkInstallHash.$feature -ne 1){
Write-Verbose "[$feature] required"
[void]$requiredAdkFeatureList.Add($feature)
}
}
if($requiredAdkFeatureList){
Write-Verbose "ADK features missing... Validating ADKSetup files"
$adk=Get-Item -Path "$adkPath\adksetup.exe" -ErrorAction Stop
[version]$adkVersion=$adk.VersionInfo.FileVersion
if($adkVersion -ge $adkVersionNoPE){
$peAddonRequired=$true
if(!$peAddonPresent){
$emsg=[String]::Format(
"Your version of ADK requires a WinPE Addon. {0}. {1}.",
"The addon is not present",
"Unable to install ADK"
)
Write-Error $emsg -ErrorAction Stop
}
$adkPeSetupFile=Test-Path -Path "$adkPePath\adkwinpesetup.exe"
if(!$adkPeSetupFile){
$emsg=[String]::Format(
"Your version of ADK requires a WinPE Addon. {0}. {1}.",
"The adkwinpesetup.exe file is not present",
"Unable to install ADK"
)
Write-Error $emsg -ErrorAction Stop
}
}
}else{
Write-Verbose "All mandatory ADK features present"
}
### END of ADK and WinPE Addon Validation
### Windows Feature Validation
if(!(Get-Module -Name ServerManager -ErrorAction SilentlyContinue)){
Import-Module -Name ServerManager -ErrorAction Stop
}
$features=Get-WindowsFeature -ErrorAction Stop
$winFeatureList=@(
'NET-HTTP-Activation',
'NET-Non-HTTP-Activ',
'NET-Framework-45-ASPNET',
'NET-WCF-HTTP-Activation45',
'NET-WCF-TCP-PortSharing45',
'BITS',
'BITS-IIS-Ext',
'RDC',
'Web-Server',
'Web-Common-Http',
'Web-Default-Doc',
'Web-Dir-Browsing',
'Web-Http-Errors',
'Web-Static-Content',
'Web-Http-Redirect',
'Web-Health',
'Web-Http-Logging',
'Web-Request-Monitor',
'Web-Http-Tracing',
'Web-Security',
'Web-Filtering',
'Web-Basic-Auth',
'Web-CertProvider',
'Web-IP-Security',
'Web-Url-Auth',
'Web-Windows-Auth',
'Web-App-Dev',
'Web-Net-Ext',
'Web-Net-Ext45',
'Web-ISAPI-Ext',
'Web-ISAPI-Filter',
'Web-Includes',
'Web-Ftp-Server',
'Web-Ftp-Service',
'Web-Mgmt-Tools',
'Web-Mgmt-Console',
'Web-Mgmt-Compat',
'Web-Metabase',
'Web-Lgcy-Mgmt-Console',
'Web-Lgcy-Scripting',
'Web-WMI',
'Web-Scripting-Tools',
'Web-Mgmt-Service',
'RSAT-Feature-Tools',
'RSAT-Bits-Server'
)
# NET Framework Core is removed from recent OS's.
## Must be installed from Windows install media
$netfxCoreFeature='NET-Framework-Core'
$netfx3=$features | Where-Object {$_.Name -eq $netfxCoreFeature}
if(!($netfx3.Installed)){
if(!($WindowsMediaPath)){
$mediaWarn=[String]::Format(
"WindowsFeature: {0}. {1} is required for this installation. {2}.",
"[$netfxCoreFeature] is not installed",
"You will need to complete this manually before you can install SCCM."
)
Write-Warning $mediaWarn
}else{
Write-Verbose "Installing Windows feature: [$netfxCoreFeature]"
Install-WindowsFeature -Name $netfxCoreFeature `
-Source $WindowsMediaPath `
-ErrorAction Stop
}
}
### END Windows Feature Installation
Write-Verbose "Installing remaining Windows features"
Install-WindowsFeature -Name $winFeatureList -ErrorAction Stop
if(!$requiredAdkFeatureList){
Write-Verbose "ADK Install not required"
return
}
$winPeFeature='OptionId.WindowsPreinstallationEnvironment'
if(!($requiredAdkFeatureList.Contains($winPeFeature))){
$peAddonRequired=$false
}
if($peAddonRequired){
$requiredAdkFeatureList.Remove($winPeFeature)
}
if($requiredAdkFeatureList){
$adkFeature=$($requiredAdkFeatureList -join ' ')
& "$adkPath\adksetup.exe" /ceip off /features $adkFeature /quiet
WaitForProcessEnd -processName adksetup `
-msg "Installing ADK"
}
if($peAddonRequired){
& "$adkPePath\adkwinpesetup.exe" /features $winPeFeature /quiet
WaitForProcessEnd -processName adkwinpesetup `
-msg "Installing ADK PE Addon"
}
}Catch{
Write-Error $_
}