The easiest way (it worked for me) is to:
- take a computer where the necessary roles and features are not installed
- go to Add Server Roles and Features (in Server Manager)
- use the wizard to add the necessary roles and features
- on the last screen, before pressing the "Install" button, you will notice the link "Export configuration settings"
Export configuration settings
Save the XML file.
After you have the XML file, you can use the PowerShell script listed below to invoke the "Install-WindowsFeature" cmdlet (Server 2012, 2016).
NOTE1: the PowerShell script was designed to work on Windows Server 2008, 2012 and 2016.
For Windows Server 2008 the cmdlet is Add-WindowsFeature.
NOTE2: The PowerShell script assumes the XML file is in the same folder and it's name is listed inside the script - please see the lines 3 and 4.
Import-Module ServerManager -ErrorAction Stop
$win2k8xml = '.\features-w2k8.xml'
$win2k12xml = '.\RolesAndFeatures.xml'
$minOSVersion = [version] "6.1.7600" # Windows Server 2008 R2 RTM version
$os = Get-WmiObject Win32_OperatingSystem
$currentVersion = [version]$os.Version
if($currentVersion -lt $minOSVersion)
{
throw "OS version equal or greater than ${minOSVersion} is required to run this script"
}
elseif($currentVersion.ToString().substring(0,3) -eq $minOSVersion.ToString().substring(0,3))
{
If (!(Test-Path $win2k8xml)) {Write-Host "For Windows Server 2008 R2 server make sure that you have Features-W2K8.xml in the current folder" -ForegroundColor Yellow; Pause}
}
elseif($currentVersion -gt $minOSVersion){
If (!(Test-Path $win2k12xml)) {Write-Host "For Windows Server 2012/2016 make sure that you have RolesAndFeatures.xml in the current folder" -ForegroundColor Yellow; Pause}
}
$OSVersionName = (get-itemproperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName).ProductName
Write-Host "Your OS version is:$OSVersionName" -ForegroundColor Green
$defaultComputerName = $env:computername
$ComputerName = Read-Host "Computername (Press Enter for current computer - $defaultComputerName)"
if ([string]::IsNullOrEmpty($ComputerName))
{
$ComputerName = $defaultComputerName;
}
Write-host "Installation will take place on the following computers: $ComputerName"
function Invoke-WindowsFeatureBatchDeployment {
param (
[parameter(mandatory)]
[string] $ComputerName,
[parameter(mandatory)]
[string] $ConfigurationFilePath
)
# Deploy the features on multiple computers simultaneously.
$jobs = @()
if(Test-Connection -ComputerName $ComputerName -Quiet){
Write-Host "Connection succeeded to: " $ComputerName
if ($currentVersion.ToString().substring(0,3) -eq $minOSVersion.ToString().substring(0,3)) {
$jobs += Start-Job -Command {
#Add-WindowsFeature -ConfigurationFilePath $using:ConfigurationFilePath -ComputerName $using:ComputerName -Restart
$import = Import-Clixml $using:ConfigurationFilePath
$import | Add-WindowsFeature
}
}
elseif ($currentVersion -gt $minOSVersion) {
$jobs += Start-Job -Command {
Install-WindowsFeature -ConfigurationFilePath $using:ConfigurationFilePath -ComputerName $using:ComputerName -Restart
}
}
}
else{
Write-Host "Configuration failed for: "+ $ComputerName + "! Check computer name and execute again"
}
Receive-Job -Job $jobs -Wait | Select-Object Success, RestartNeeded, ExitCode, FeatureResult
}
if ($currentVersion.ToString().substring(0,3) -eq $minOSVersion.ToString().substring(0,3)) {$FilePath = Resolve-Path $win2k8xml}
elseif ($currentVersion -gt $minOSVersion) {$FilePath = Resolve-Path $win2k12xml}
Invoke-WindowsFeatureBatchDeployment $ComputerName $FilePath