Use PowerShell to Install Windows Features and Reboot
Recently, I installed the Windows Subsystem for Linux (WSL) feature on my Windows 10 computer. Microsoft has an installation guide that walks you through the entire process, but I thought I'd share a few PowerShell tricks when it comes to installing Windows features.
The system used throughout this blog article runs Windows 10 version 1803 which ships with Windows PowerShell version 5.1. Your mileage may vary if you're using a different version of Windows and/or PowerShell.
Run Windows PowerShell elevated as an administrator. Add the Windows Subsystem for Linux feature.
1Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online
A reboot is required and I thought this was kind of a bummer until I discovered that the Enable-WindowsOptionalFeature cmdlet doesn't have a parameter to make it go ahead and automatically reboot if one is needed. That's the real bummer :-(. Well, not really, because PowerShell can be used to solve that problem.
Specify the NoRestart
parameter to make it give your prompt back. Luckily, the RestartNeeded
property is returned as an object-oriented result and not just output to the screen. Yes, there's a
difference. This allows you to store the results in a variable and perform logic on them to
automatically reboot if needed. By the way, this will work with any feature added with
Enable-WindowsOptionalFeature
, not just the one shown in this blog article.
1Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -NoRestart -OutVariable results
2if ($results.RestartNeeded -eq $true) {
3 Restart-Computer -Force
4}
Well, that's nice and all, but some of the command output as shown in the previous example is still displayed on the screen along with this progress information shown in the following example.
How can you silence all of that and just make it so without displaying any results? Most people
don't know about the $ProgressPreference
global variable and while it's generally not considered
to be a best practice to change the value of these types of global preference variables, it's what
must be done in this scenario if you want to silence the progress information. I always like to say
best practices are a starting point, not an ending one. Anytime you're going to change the values of
these types of global preference variables, store the current value in a variable, change it, run
the command, and then change it back to it's previous value immediate after the command finishes.
It's also worth noting that changes to these types of preference variables only affects the current
PowerShell session.
The second part of the puzzle is that when the OutVariable
parameter is used to store the results
in a variable, it returns the results and stores them in the specified variable. To perform this
functionality silently, simply store the results of the command in a variable instead of using the
OutVariable
parameter.
Set the global $ProgressPreference
variable to silently continue (the default is continue), store
the results of the command in a variable, and perform logic on the contents of the variable to
determine if a reboot is needed.
1$ProgPref = $ProgressPreference
2$ProgressPreference = 'SilentlyContinue'
3$results = Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -NoRestart
4$ProgressPreference = $ProgPref
5if ($results.RestartNeeded -eq $true) {
6 Restart-Computer -Force
7}
Last, but not least, the warning about the restart being suppressed needs to be silenced in the
previous example. This is a scenario where there's no need to change the value of the global
$WarningPreference
variable because the command has a WarningPreference
parameter that only
affects this single command this one time.
1$ProgPref = $ProgressPreference
2$ProgressPreference = 'SilentlyContinue'
3$results = Enable-WindowsOptionalFeature -FeatureName Microsoft-Windows-Subsystem-Linux -Online -NoRestart -WarningAction SilentlyContinue
4$ProgressPreference = $ProgPref
5if ($results.RestartNeeded -eq $true) {
6 Restart-Computer -Force
7}
As you've seen in this blog article, it seems as if something is missing from the
Enable-WindowsOptionalFeature
cmdlet when trying to automate the installation of Windows features
with it, but when you know how to harness the power of PowerShell, there's almost always a solution
to every problem.
µ