I am in the beginning stages of creating a Windows 10 build. One of the first things I needed to do was to install and set the Windows 10 features. Before, I used a batch script that executed DISM to set each feature. I know there is the Install-WindowsFeatures cmdlet, but I also wanted to incorporate verification and other features into a single script. With the help of Sapien's PowerShell Studio, this script was a breeze to write.
This script allows you to set windows features while also verifying each feature was set correctly by querying the feature for the status. It then outputs the feature name and status to the display. I have also included the option to run a report of all available features and their state. Here are the four features the script provides:
You will need to use the -command when executing this at the command line instead of -file. This is because the -ListFeatures is a boolean value. I have also included code that identifies an error 50 and returns a status that you must include the parent feature before activating the specified feature. I have also made the additional command line window be minimized when running the DISM.exe.
This script allows you to set windows features while also verifying each feature was set correctly by querying the feature for the status. It then outputs the feature name and status to the display. I have also included the option to run a report of all available features and their state. Here are the four features the script provides:
- Set an individual feature via command line:
powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -Feature 'RSATClient-Features' -Setting 'disable' - Set multiple features by reading a text file located in the same directory as the script. You can name the text file any name you want. The format for the file is: RSATClient,enable for example. Here is the command line:
powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -FeaturesFile 'FeaturesList.txt'
- Hard code a feature setting at the bottom of the script:
Set-WindowsFeature -Name 'RSATClient-Features' -State 'disable' - Display a list of windows features:
powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -ListFeatures $true
You will need to use the -command when executing this at the command line instead of -file. This is because the -ListFeatures is a boolean value. I have also included code that identifies an error 50 and returns a status that you must include the parent feature before activating the specified feature. I have also made the additional command line window be minimized when running the DISM.exe.
You can download the script from here.
1: <#
2: .SYNOPSIS
3: Process Windows Features
4:
5: .DESCRIPTION
6: This script can return a list of online windows features and/or set specific windows features.
7:
8: .PARAMETER ListFeatures
9: Return a list of all Windows Features
10:
11: .PARAMETER Feature
12: A description of the Feature parameter.
13:
14: .PARAMETER Setting
15: A description of the Setting parameter.
16:
17: .PARAMETER FeaturesFile
18: Name of the features file that contains a list of features with their corresponding settings for this script to process through. The files resides in the same directory as this script.
19:
20: .EXAMPLE
21: Return a list of all available online Windows Features
22: powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -ListFeatures $true
23:
24: Set one Windows Feature from the command line
25: powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -Feature 'RSATClient-Features' -Setting 'disable'
26:
27: Set multiple features by reading contents of a text file
28: powershell.exe -executionpolicy bypass -command WindowsFeatures.ps1 -FeaturesFile 'FeaturesList.txt'
29:
30: .NOTES
31: You must use -command instead of -file in the command line because of the use of boolean parameters
32:
33: An error code 50 means you are trying to enable a feature in which the required parent feature is disabled
34:
35: I have also included two commented out lines at the bottom of the script as examples if you want to hardcode the features within the script.
36: ===========================================================================
37: Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.122
38: Created on: 5/27/2016 2:46 PM
39: Created by: Mick Pletcher
40: Organization:
41: Filename: WindowsFeatures.ps1
42: ===========================================================================
43: #>
44: [CmdletBinding()]
45: param
46: (
47: [boolean]$ListFeatures = $false,
48: [string]$Feature,
49: [ValidateSet('enable', 'disable')][string]$Setting,
50: [String]$FeaturesFile
51: )
52:
53: function Confirm-Feature {
54: <#
55: .SYNOPSIS
56: Confirm the feature setting
57:
58: .DESCRIPTION
59: Confirm the desired change took place for a feature
60:
61: .PARAMETER FeatureName
62: Name of the feature
63:
64: .PARAMETER FeatureState
65: Desired state of the feature
66:
67: .EXAMPLE
68: PS C:\> Confirm-Feature
69:
70: .NOTES
71: Additional information about the function.
72: #>
73:
74: [CmdletBinding()][OutputType([boolean])]
75: param
76: (
77: [ValidateNotNull()][string]$FeatureName,
78: [ValidateSet('Enable', 'Disable')][string]$FeatureState
79: )
80:
81: $WindowsFeatures = Get-WindowsFeaturesList
82: $WindowsFeature = $WindowsFeatures | Where-Object { $_.Name -eq $FeatureName }
83: switch ($FeatureState) {
84: 'Enable' {
85: If (($WindowsFeature.State -eq 'Enabled') -or ($WindowsFeature.State -eq 'Enable Pending')) {
86: Return $true
87: } else {
88: Return $false
89: }
90: }
91: 'Disable' {
92: If (($WindowsFeature.State -eq 'Disabled') -or ($WindowsFeature.State -eq 'Disable Pending')) {
93: Return $true
94: } else {
95: Return $false
96: }
97: }
98: default {
99: Return $false
100: }
101: }
102:
103: }
104:
105: function Get-WindowsFeaturesList {
106: <#
107: .SYNOPSIS
108: List Windows Features
109:
110: .DESCRIPTION
111: This will list all available online windows features
112:
113: .NOTES
114: Additional information about the function.
115: #>
116:
117: [CmdletBinding()]
118: param ()
119:
120: $Temp = dism /online /get-features
121: $Temp = $Temp | Where-Object { ($_ -like '*Feature Name*') -or ($_ -like '*State*') }
122: $i = 0
123: $Features = @()
124: Do {
125: $FeatureName = $Temp[$i]
126: $FeatureName = $FeatureName.Split(':')
127: $FeatureName = $FeatureName[1].Trim()
128: $i++
129: $FeatureState = $Temp[$i]
130: $FeatureState = $FeatureState.Split(':')
131: $FeatureState = $FeatureState[1].Trim()
132: $Feature = New-Object PSObject
133: $Feature | Add-Member noteproperty Name $FeatureName
134: $Feature | Add-Member noteproperty State $FeatureState
135: $Features += $Feature
136: $i++
137: } while ($i -lt $Temp.Count)
138: $Features = $Features | Sort-Object Name
139: Return $Features
140: }
141:
142: function Set-WindowsFeature {
143: <#
144: .SYNOPSIS
145: Configure a Windows Feature
146:
147: .DESCRIPTION
148: Enable or disable a windows feature
149:
150: .PARAMETER Name
151: Name of the windows feature
152:
153: .PARAMETER State
154: Enable or disable windows feature
155:
156: .NOTES
157: Additional information about the function.
158: #>
159:
160: [CmdletBinding()]
161: param
162: (
163: [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$Name,
164: [Parameter(Mandatory = $true)][ValidateSet('enable', 'disable')][string]$State
165: )
166:
167: $EXE = $env:windir + "\system32\dism.exe"
168: Write-Host $Name"....." -NoNewline
169: If ($State -eq "enable") {
170: $Parameters = "/online /enable-feature /norestart /featurename:" + $Name
171: } else {
172: $Parameters = "/online /disable-feature /norestart /featurename:" + $Name
173: }
174: $ErrCode = (Start-Process -FilePath $EXE -ArgumentList $Parameters -Wait -PassThru -WindowStyle Minimized).ExitCode
175: If ($ErrCode -eq 0) {
176: $FeatureChange = Confirm-Feature -FeatureName $Name -FeatureState $State
177: If ($FeatureChange -eq $true) {
178: If ($State -eq 'Enable') {
179: Write-Host "Enabled" -ForegroundColor Yellow
180: } else {
181: Write-Host "Disabled" -ForegroundColor Yellow
182: }
183: } else {
184: Write-Host "Failed" -ForegroundColor Red
185: }
186: } elseif ($ErrCode -eq 3010) {
187: $FeatureChange = Confirm-Feature -FeatureName $Name -FeatureState $State
188: If ($FeatureChange -eq $true) {
189: If ($State -eq 'Enable') {
190: Write-Host "Enabled & Pending Reboot" -ForegroundColor Yellow
191: } else {
192: Write-Host "Disabled & Pending Reboot" -ForegroundColor Yellow
193: }
194: } else {
195: Write-Host "Failed" -ForegroundColor Red
196: }
197: } else {
198: If ($ErrCode -eq 50) {
199: Write-Host "Failed. Parent feature needs to be enabled first." -ForegroundColor Red
200: } else {
201: Write-Host "Failed with error code "$ErrCode -ForegroundColor Red
202: }
203: }
204: }
205:
206: function Set-FeaturesFromFile {
207: <#
208: .SYNOPSIS
209: Set multiple features from a text file
210:
211: .DESCRIPTION
212: This function reads the comma separated features and values from a text file and executes each feature.
213:
214: .NOTES
215: Additional information about the function.
216: #>
217:
218: [CmdletBinding()]
219: param ()
220:
221: $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + '\'
222: $FeaturesFile = $RelativePath + $FeaturesFile
223: If ((Test-Path $FeaturesFile) -eq $true) {
224: $FeaturesFile = Get-Content $FeaturesFile
225: foreach ($Item in $FeaturesFile) {
226: $Item = $Item.split(',')
227: Set-WindowsFeature -Name $Item[0] -State $Item[1]
228: }
229: }
230: }
231:
232: Clear-Host
233: If ($ListFeatures -eq $true) {
234: $WindowsFeatures = Get-WindowsFeaturesList
235: $WindowsFeatures
236: }
237: If ($FeaturesFile -ne '') {
238: Set-FeaturesFromFile
239: }
240: If ($Feature -ne '') {
241: Set-WindowsFeature -Name $Feature -State $Setting
242: }
243:
0 comments:
Post a Comment