Installing Windows Features with PowerShell

22 September 2014, by

Previous article in series

I’m a big fan of automating things. A good candidate is provisioning development machines. Everyone who works on your codebase will have to set it up just so – why not make their lives easier by keeping them away from the tedium of the “Turn Windows features on or off” dialog?

Turn Windows Features On Or Off

If you have Windows 8 / Windows Server 2012, which come with PowerShell 3, this is pretty trivial:

Enable-WindowsOptionalFeature -FeatureName IIS-NetFxExtensibility -Online -All

“Online” means that you are modifying your live Windows installation – as opposed to playing around with an offline Windows install image. “All” means enable all dependent features. And the feature name is… Well, it’s obvious if you know it.

Finding the mapping between features in the dialog box and feature names for the PowerShell script is a bit round the houses as I’ve not been able to find a definitive reference. The best approach I’ve found is this:

Get-WindowsOptionalFeature -Online
     | Where-Object { $_.FeatureName -match "Net" }

Play around with some strings you suspect will appear in the name – thus far I’ve always been able to guess which is the right feature after a bit of digging!

Of course, there’s a whole array of additional cmdlets to play around with Windows configuration (mostly focussed on building install images) – see

What if I’m not on Windows Server 2012?

Fortunately, all is not lost. The general theme I’ve found is that PowerShell cmdlets don’t normally add new functionality that wasn’t available previously – they just make it much more conveniently accessible.

In the case of installing optional features, Windows 7 / Windows Server 2008 include the dism.exe tool which will do the same thing.

dism /Enable-Feature /FeatureName:IIS-NetFxExtensibility /Online

dism /Get-Feature /Online | Where-Object { $_ -match “Net” }

Note that I’m still using PowerShell to run these commands (see the Where-Object filter). I would argue strongly in favour of using PowerShell even if you’re on a slightly older version of Windows – it’s good practice, and will make it easier to upgrade your scripts in future. Yes you could run dism from Cygwin Bash (or even DOS Batch…), but why not take advantage of the opportunity to learn a little PowerShell?

To add extra encouragement, here’s a quick PowerShell function I knocked up to make it easier to run dism without getting all the extra-verbose output it normally spews out, but still capturing the logs in case of error. It’s not quite as neat as the PowerShell 3 built-in version, but it might help tide you over.

function InstallWindowsFeature($featureName) {
Write-Host "Installing $featureName..."

$tempFile = [io.path]::GetTempFileName()
dism /Online /Enable-Feature /FeatureName:$featureName > $tempFile

if ($LastExitCode -ne 0) {
cat $tempFile
Remove-Item $tempFile
Write-Error "Error installing $featureName - provisioning was not completed"

Remove-Item $tempFile

InstallWindowsFeature "IIS-WebServerRole"
InstallWindowsFeature "IIS-ManagementScriptingTools"

Next time I’ll take a look at automating IIS configuration using PowerShell.


Categories: Technical


Leave a Reply

* Mandatory fields

eight − 2 =

Submit Comment