In order to speed up the installation phase of a ConfigMgr 2012 environment, I’ve created a PowerShell script that will install all necessary prerequisites for different site roles. This blog post will cover the different scenarios in where you can utilize the script. The script has been tested on Windows Server 2012, and are using some PowerShell v3 only cmdlets, so if you’re gonna install ConfigMgr 2012 SP1 on a Windows Server 2008 R2 SP1 server, the script would have to be modified a bit or you could install the WMF 3.0 on the server. Grab WMF 3.0 here. Remember to install .NET Framework 4.x, as it’s a prerequisite to WMF 3.0.
Update – Check out the latest version for ConfigMgr 2012 R2 – here.
Overview
- Prerequisites
- Download the prerequisites script
- Install prerequisites for a CAS or Primary site
- Install prerequisites for a Secondary site
- Install prerequisites for the Application Catalog
- Extend the Active Directory schema
- Install Windows ADK
- Install and configure WSUS
Prerequisites
The script used in this blog post will need to have access to some files on the ConfigMgr 2012 SP1 source ISO. Depending on your environment, mount or insert the ISO to the host that you’ll be running the script from.
Download the prerequisites script
Save the script below to C:\Scripts and name it Install-SCCMPrereqs.ps1.
Download the script there: Install-SCCMPrereqs.ps1
################################################# # # Author: Nickolaj Andersen # Blog: https://msendpointmgr.com # Twitter: @NickolajA # Date: 2013-07-08 # Version: 1.5.0 # # Examples: # # .\Install-SCCMPrereqs.ps1 -SiteType CAS # .\Install-SCCMPrereqs.ps1 -SiteType Primary # .\Install-SCCMPrereqs.ps1 -SiteType Secondary # .\Install-SCCMPrereqs.ps1 -SystemRole ApplicationCatalog # .\Install-SCCMPrereqs.ps1 -ExtendSchema # .\Install-SCCMPrereqs.ps1 -InstallWADK # .\Install-SCCMPrereqs.ps1 -InstallWSUS # ################################################# [CmdletBinding()] param( [ValidateSet("CAS","Primary","Secondary")] [string]$SiteType, [ValidateSet("ApplicationCatalog")] [string]$SystemRole, [switch]$ExtendSchema, [switch]$InstallWADK, [switch]$InstallWSUS ) $WarningPreference = "SilentlyContinue" function Install-NETFramework3.5 { $a = 0 $NETFeature = @("NET-Framework-Core") $NETFeaturesCount = $NETFeature.Count $NETFeature | ForEach-Object { $a++ Write-Progress -id 1 -Activity "Installing Windows Features" -Status "Windows Feature $($a) of $($NETFeaturesCount)" -PercentComplete (($a / $NETFeaturesCount)*100) Write-Host "Installing: $_" Add-WindowsFeature $_ | Out-Null } } function Install-WindowsFeatures { $i = 0 $WinFeatures = @("BITS","BITS-IIS-Ext","BITS-Compact-Server","RDC","WAS-Process-Model","WAS-Config-APIs","WAS-Net-Environment","Web-Server","Web-ISAPI-Ext","Web-ISAPI-Filter","Web-Net-Ext","Web-Net-Ext45","Web-ASP-Net","Web-ASP-Net45","Web-ASP","Web-Windows-Auth","Web-Basic-Auth","Web-URL-Auth","Web-IP-Security","Web-Scripting-Tools","Web-Mgmt-Service","Web-Stat-Compression","Web-Dyn-Compression","Web-Metabase","Web-WMI","Web-HTTP-Redirect","Web-Log-Libraries","Web-HTTP-Tracing","UpdateServices-RSAT","UpdateServices-API","UpdateServices-UI") $WinFeaturesCount = $WinFeatures.Count $WinFeatures | ForEach-Object { $i++ Write-Progress -id 1 -Activity "Installing Windows Features" -Status "Windows Feature $($i) of $($WinFeaturesCount)" -PercentComplete (($i / $WinFeaturesCount)*100) Write-Host "Installing:" $_ Add-WindowsFeature $_ | Out-Null } Write-Host "Windows Features successfully installed" Write-Host "" } function Install-WindowsFeaturesSecondary { $c = 0 $SecFeatures = @("BITS","BITS-IIS-Ext","BITS-Compact-Server","RDC","WAS-Process-Model","WAS-Config-APIs","WAS-Net-Environment","Web-Server","Web-ISAPI-Ext","Web-Windows-Auth","Web-Basic-Auth","Web-URL-Auth","Web-IP-Security","Web-Scripting-Tools","Web-Mgmt-Service","Web-Metabase","Web-WMI") $SecFeaturesCount = $SecFeatures.Count $SecFeatures | ForEach-Object { $c++ Write-Progress -id 1 -Activity "Installing Windows Features" -Status "Windows Feature $($c) of $($SecFeaturesCount)" -PercentComplete (($c / $SecFeaturesCount)*100) Write-Host "Installing:" $_ Add-WindowsFeature $_ | Out-Null } Write-Host "Windows Features successfully installed" } function Install-WSUSFeatures { $d = 0 $WSUSFeatures = @("UpdateServices","UpdateServices-WidDB","UpdateServices-Services","UpdateServices-RSAT","UpdateServices-API","UpdateServices-UI") $WSUSFeaturesCount = $WSUSFeatures.Count $WSUSFeatures | ForEach-Object { $d++ Write-Progress -id 1 -Activity "Installing WSUS Features" -Status "WSUS Feature $($d) of $($WSUSFeaturesCount)" -PercentComplete (($d / $WSUSFeaturesCount)*100) Write-Host "Installing:" $_ Add-WindowsFeature $_ | Out-Null } Write-Host "WSUS Features successfully installed" Write-Host "" } function Configure-WSUS { $WSUSContentFolder = Read-Host "Enter the path where you want to store the WSUS content, e.g. 'C:\WSUS'" if (!(Test-Path -Path $WSUSContentFolder)) { New-Item $WSUSContentFolder -ItemType Directory | Out-Null } $WSUSUtil = "$Env:ProgramFiles\Update Services\Tools\WsusUtil.exe" $WSUSUtilArgs = "POSTINSTALL CONTENT_DIR=$WSUSContentFolder" Write-Host "" Write-Host "Starting the WSUS PostInstall configuration" Start-Process -FilePath $WSUSUtil -ArgumentList $WSUSUtilArgs -NoNewWindow -Wait Write-Host "" Write-Host -ForegroundColor Green "Successfully installed and configured WSUS" } function Set-ExtendADAchema { if ($ExtendSchema -eq $true) { $RegExp = "^[A-Z]*\:$" $DriveLetter = Read-Host "Enter drive (e.g. 'D:') letter for ConfigMgr source files" if ($DriveLetter -match $RegExp) { $Schema = $true } else { Write-Warning "Wrong drive letter specified" -ErrorAction Stop } } if ($Schema) { $DC = Read-Host "Enter a Domain Controller NetBIOS name" $GetPath = Get-ChildItem -Recurse -Filter "EXTADSCH.EXE" -Path $DriveLetter\SMSSETUP\BIN\X64 $Path = $GetPath.DirectoryName + "\EXTADSCH.EXE" $Destination = "\\" + $DC + "\C$" Copy-Item $Path $Destination -Force Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "C:\EXTADSCH.EXE" -ComputerName $DC | Out-Null } $Content = Get-Content -Path "\\$DC\C$\extadsch.log" if ($Content -match "Successfully extended the Active Directory schema") { Write-Host "Active Directory was successfully extended" } else { Write-Warning "Active Directory was not extended successfully, refer to C:\ExtADSch.log on domain controller" } } function Get-PrereqFiles { $RegExp = "^[A-Z]*\:$" $DriveLetter = Read-Host "Enter drive letter (e.g. 'D:') for ConfigMgr source files" if ($DriveLetter -match $RegExp) { $Prereq = $true } else { Write-Warning "Wrong drive letter specified. Enter drive letter like 'D:'" -ErrorAction Stop } if ($Prereq) { $dldest = "C:\ConfigMgr_Prereq" if (!(Test-Path -Path $dldest)) { New-Item $dldest -ItemType Directory | Out-Null } try { if (Test-Path "$DriveLetter\SMSSETUP\BIN\X64\setupdl.exe") { $Download = $true } } catch { Write-Warning "$DriveLetter\SMSSETUP\BIN\X64\setupdl.exe is not found" -ErrorAction Stop } if ($Download) { Write-Host "Downloading Configuration Manager prerequisites to $($dldest), this may take a couple of minutes" Start-Process -FilePath "$DriveLetter\SMSSETUP\BIN\X64\setupdl.exe" -ArgumentList "$dldest" -Wait Write-Host "Successfully downloaded Configuration Manager prerequisites" } } } function Install-WindowsADK { $ADKInstalledFeatures = @() $ComputerName = $env:COMPUTERNAME $UninstallKey = "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" $Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$ComputerName) $RegistryKey = $Registry.OpenSubKey($UninstallKey) $SubKeys = $RegistryKey.GetSubKeyNames() ForEach ($Key in $SubKeys) { $CurrentKey = $UninstallKey + "\\" + $Key $CurrentSubKey = $Registry.OpenSubKey($CurrentKey) $DisplayName = $CurrentSubKey.GetValue("DisplayName") if ($DisplayName -like "Windows PE x86 x64") { $ADKInstalledFeatures += $DisplayName } elseif ($DisplayName -like "User State Migration Tool") { $ADKInstalledFeatures += $DisplayName } elseif ($DisplayName -like "Windows Deployment Tools") { $ADKInstalledFeatures += $DisplayName } } Write-Host "" Write-Host "# Choose how you'd like to install Windows ADK" Write-Host "# " Write-Host "# ----------------------------------------------------------------------------------" Write-Host "# 1. Online install - Download and silent install" Write-Host "# 2. Offline install - Silent install of previously downloaded Windows ADK files" Write-Host "# ----------------------------------------------------------------------------------" Write-Host "" $Answer = Read-Host "Please enter your selection [1,2] and press Enter" switch ($Answer) { 1 {$SelectedOption = "Online"} 2 {$SelectedOption = "Offline"} } if (($SelectedOption -like "Online") -AND ($ADKInstalledFeatures.Length -ne 3)) { $dlfolder = "C:\Downloads" if (!(Test-Path -Path $dlfolder)) { New-Item $dlfolder -ItemType Directory | Out-Null } Write-Host "" $ADKURL = "https://download.microsoft.com/download/9/9/F/99F5E440-5EB5-4952-9935-B99662C3DF70/adk/adksetup.exe" $ADKObject = New-Object System.Net.WebClient $Global:DownloadComplete = $False $EventDataComplete = Register-ObjectEvent $ADKObject DownloadFileCompleted -SourceIdentifier WebClient.DownloadFileComplete -Action {$Global:DownloadComplete = $True} $EventDataProgress = Register-ObjectEvent $ADKObject DownloadProgressChanged -SourceIdentifier WebClient.DownloadProgressChanged -Action { $Global:DPCEventArgs = $EventArgs } Write-Progress -Activity "Downloading Windows ADK Setup" -Status $ADKURL $ADKObject.DownloadFileAsync($ADKURL, "$dlfolder\adksetup.exe") while (!($Global:DownloadComplete)) { $PercentComplete = $Global:DPCEventArgs.ProgressPercentage if ($PercentComplete -ne $null) { Write-Progress -Activity "Downloading Windows ADK Setup" -Status $ADKURL -PercentComplete $PercentComplete } } Write-Progress -Activity "Downloading Windows ADK Setup" -Status $ADKURL -Complete Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged Unregister-Event -SourceIdentifier WebClient.DownloadFileComplete $ADKOnArguments = "/norestart /q /ceip off /features OptionId.WindowsPreinstallationEnvironment OptionId.DeploymentTools OptionId.UserStateMigrationTool" Write-Host "Windows ADK is now being installed from the web, which will take time depending on your internet connection" Write-Host "" Start-Process -FilePath "$dlfolder\adksetup.exe" -ArgumentList $ADKOnArguments do { $ADKProcess = Get-WmiObject -Class Win32_Process -Filter 'Name="adksetup.exe"' Write-Host "." -NoNewline Start-Sleep -s 5 } while ($ADKProcess) Write-Host "`n`n" Write-Host -ForegroundColor Green "Windows ADK has been successfully installed" } elseif (($SelectedOption -like "Offline") -AND ($ADKInstalledFeatures.Length -ne 3)) { Write-Host "" $SetupLocation = Read-Host "Please enter a path for the Windows ADK setup (e.g. C:\WindowsADK)" $ADKOffArguments = "/norestart /q /ceip off /features OptionId.WindowsPreinstallationEnvironment OptionId.DeploymentTools OptionId.UserStateMigrationTool" Write-Host "Windows ADK is now installing in the background, give it a few minutes to complete" Write-Host "" Start-Process -FilePath "$SetupLocation\adksetup.exe" -ArgumentList $ADKOffArguments do { $ADKProcess = Get-WmiObject -Class Win32_Process -Filter 'Name="adksetup.exe"' Write-Host "." -NoNewline Start-Sleep -s 5 } while ($ADKProcess) Write-Host "`n`n" Write-Host -ForegroundColor Green "Windows ADK has been successfully installed" } else { if ($ADKInstalledFeatures.Length -eq 3) { Write-Host "" Write-Host -ForegroundColor Green "All required Windows ADK features are already installed, skipping install" } } } function Install-AppCatFeatures { $ACWindowsFeatures = @("NET-Framework-Features","NET-Framework-Core","NET-HTTP-Activation","NET-Non-HTTP-Activ","NET-WCF-Services45","NET-WCF-HTTP-Activation45","RDC","RSAT","RSAT-Role-Tools","WAS","WAS-Process-Model","WAS-NET-Environment","WAS-Config-APIs","Web-Server","Web-WebServer","Web-Common-Http","Web-Static-Content","Web-Default-Doc","Web-App-Dev","Web-ASP-Net","Web-ASP-Net45","Web-Net-Ext","Web-Net-Ext45","Web-ISAPI-Ext","Web-ISAPI-Filter","Web-Security","Web-Windows-Auth","Web-Filtering","Web-Mgmt-Tools","Web-Mgmt-Console","Web-Scripting-Tools","Web-Mgmt-Compat","Web-Metabase","Web-Lgcy-Mgmt-Console","Web-Lgcy-Scripting","Web-WMI") $ACWindowsFeaturesCount = $ACWindowsFeatures.Count $i = 0 $ACWindowsFeatures | ForEach-Object { $i++ Write-Progress -id 1 -Activity "Windows Features Installation" -Status "Installing Windows Feature $($_), $($i) of $($ACWindowsFeaturesCount)" -PercentComplete (($i / $ACWindowsFeaturesCount)*100) Write-Host "Installing: $($_)" Add-WindowsFeature $_ | Out-Null } Write-Host "" Write-Host -ForegroundColor Green "Prerequisites for the Application Catalog has successfully been installed" } $WarningPreference = "SilentlyContinue" $ScriptBeginning = Get-Date function Install-SitePrereq { Install-NETFramework3.5 Install-WindowsFeatures Get-PrereqFiles } function Install-SecondaryPrereq { Install-NETFramework3.5 Install-WindowsFeaturesSecondary } if ($InstallWADK) { Install-WindowsADK } if ($ExtendSchema) { Set-ExtendADAchema } if ($InstallWSUS) { Install-WSUSFeatures Configure-WSUS } if (($SiteType -like "CAS") -OR ($SiteType -like "Primary")) { Install-SitePrereq Write-Host "" Write-Host -ForegroundColor Green "Prerequisites installed successfully" } elseif ($SiteType -like "Secondary") { Install-SecondaryPrereq Write-Host "" Write-Host -ForegroundColor Green "Prerequisites installed successfully" } elseif ($SiteType -eq $null) { Write-Warning "The parameter SiteType was not defined" } if ($SystemRole -like "ApplicationCatalog") { Install-AppCatFeatures } $ScriptEnding = Get-Date $Measure = $ScriptEnding - $ScriptBeginning Write-Host "" Write-Host -ForegroundColor Green "Execution time: $([math]::round($Measure.TotalSeconds)) seconds"
Install prerequisites for a CAS or Primary site
1. Mount your ConfigMgr 2012 SP1 source ISO.
2. Open an elevated PowerShell console.
3. Browse to C:\Scripts.
4. Run the command below and press Enter. During this phase the required Windows Features for a Primary site server is installed.
.\Install-SCCMPrereqs.ps1 -SiteType Primary
5. When asked to enter a drive letter, type D: and press Enter (the ISO is mounted as D: in my lab environment). The setupdl.exe executable of the source ISO will now be launched and download all necessary files to C:\ConfigMgr_Prereq.
6. Once the download of all files has successfully completed, the script terminates and shows that everything was successfully installed.
Install prerequisites for a Secondary site
1. Open an elevated PowerShell console.
2. Browse to C:\Scripts.
3. Run the command below and press Enter.
.\Install-SCCMPrereqs.ps1 -SiteType Secondary
4. The necessary Windows Features will now be installed. When the installation is completed, you’ll see a message in green that the prerequisites was successfully installed.
Install prerequisites for the Application Catalog
1. Open an elevated PowerShell console.
2. Browse to C:\Scripts.
3. Run the command below and press Enter.
.\Install-SCCMPrereqs.ps1 -SystemRole ApplicationCatalog
4. All the necessary Windows Features will now be installed. When the installation is completed, you’ll see a message in green that the prerequisites was successfully installed.
Extend the Active Directory schema
1. Mount your ConfigMgr 2012 SP1 source ISO.
2. Open an elevated PowerShell console (the logged on user needs to be a member of the Schema Admins and Domain Admins AD groups).
3. Browse to C:\Scripts.
4. Run the command below and press Enter.
.\Install-SCCMPrereqs.ps1 -ExtendSchema
5. When asked to enter a drive letter, type D: and press Enter.
6. Enter the NetBIOS name of your domain controller that’s running the Schema Master FSMO role, and press Enter. In my lab environment DC01 is the Schema Master.
Install Windows ADK
1. Open an elevated PowerShell console.
2. Browse to C:\Scripts.
3. Run the command below and press Enter. The script will check if the three required components of Windows ADK is installed. If none are found, the script will continue and you’ll be given two options.
- Online install – the script downloads the adksetup.exe and installs it silently
- Offline install – the script will ask for a folder where the adksetup.exe and it’s setup files have been downloaded in advance
.\Install-SCCMPrereqs.ps1 -InstallWADK
4. Select option 1 or 2 and press Enter.
5. The picture below shows the progress of the online installation. Since the setup files are downloaded from the web, depending on your internet connection it will take some time.
6. If you chose the offline installation method, you’ll be asked to point out a folder where the adksetup.exe is located together with it’s setup files.
Install and configure WSUS
1. Open an elevated PowerShell console.
2. Browse to C:\Scripts.
3. Run the command below and press Enter. The necessary Windows Features for WSUS (Update Services in Windows 2012) will now be installed.
.\Install-SCCMPrereqs.ps1 -InstallWSUS
4. When asked to enter the WSUS content location, type C:\WSUS and press Enter. You could of course choose your own location.
5. At this stage, wsusutil.exe will be launched and run the PostInstall configuration and set the WSUS content location to the folder you specified.
Please let me know if you find any bugs in the script, that would be very much appreciated!
PS C:\Scripts> .\Install-SCCMPrereqs.ps1 -SiteType Primary
Au caractère C:\Scripts\Install-SCCMPrereqs.ps1:21 : 1
+ [CmdletBinding()]
+ ~~~~~~~~~~~~~~~~~
Attribut inattendu « CmdletBinding ».
Au caractère C:\Scripts\Install-SCCMPrereqs.ps1:22 : 1
+ param(
+ ~~~~~
Jeton inattendu « param » dans l’expression ou l’instruction.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedAttribute
hi, thanks for this script very helpful and time saver, but why the WDS Role is not handled ?
thanks in advance.
Run as Admin…
start cmd.exe as admin and then :
cd XXX\xxx\prerequisites
.\Install_prerequisite.ps1
Everytime when I run the prere script it keep saying insufficient rights detedcted even after adding the user in the local admin group, please advise?
Will this script also work for SCCM 2012 R2? Or can you modify it to get the prereqs for SCCM 2012 R2?
Fantastic script!
Hi Cris!
I recommend you to check out this tool instead:
https://msendpointmgr.com/2013/12/18/configmgr-2012-r2-prerequisites-installation-tool/
I’m currently working on a PowerShell module that will have all the functionality of this tool, but it’s not ready yet (time is a precious thing!)
Regards,
Nickolaj
Got this error
Downloading: adksetup.exe
Exception calling “DownloadFile” with “2” argument(s): “Unable to connect to the remote server”
At E:\Script\Install-SCCMPrereqs.ps1:195 char:9
+ $ADKObject.DownloadFile($ADKUrl, “$dlfolder\adksetup.exe”)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
Installing: Windows ADK
This may take 10 minutes or more, since the adksetup.exe downloads components from the internet
Start-Process : This command cannot be run due to the error: The system cannot find the file specified.
At E:\Script\Install-SCCMPrereqs.ps1:199 char:9
+ Start-Process -FilePath “$dlfolder\adksetup.exe” -ArgumentList $ADKargum …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
_______________________________________________________________________
We have already downloaded the ConfigMgr 2012 SP1 updates and WADK
They are saved on our file server
is there anyway you can suggest how the script can use already downloaded files and not download them again.
Hi Kitaab,
I’ll look into that and post an update to the script. I’m currently traveling, so it’s gonna take a couple of days. I hope that’s ok.
Have a great weekend!
/Nickolaj
Hi Kitaab,
The current version 1.5.0 of the script will now allow you to choose how you’d like to install Windows ADK. I hope it helps.
/Nickolaj
Many thanks going to try this now in lab and will update.. :0)
Cool! Looking forward to hear about the results.
/Nickolaj
What a time saver this script is! It works perfectly and makes doing all the groundwork for an SCCM 2012 server effortless. Thank you so much for sharing this! I also just found your SCOM 2012 script that does the same thing! BRILLIANT!
Hey Noel,
Thanks for the feedback! I’m glad that the script was able to save you some time. I’m currently working on extending it so that it can install prereqs for different site system roles. The work for an application catalog is now done. Will post about that in a bit.
Regards,
Nickolaj