Mick's IT Blogs

Mick's IT Blogs

Latest Updates

26 May 2016

Windows 10: Windows could not parse or process the unattend answer file for pass [specialize]

Posted By: Mick Pletcher - 2:50 PM
















I am in the beginning stages of working on upgrading the firm I work at to Windows 10. Using MDT, The OS would inject drivers and lay down with no issues. Upon the first reboot, it would pop up the following error message:


The first thing I did was to look at the Unattend.xml file by opening the task sequence properties--->OS Info tab. When I looked under the Specialize--->Microsoft-Windows-Shell-Setup, everything looked normal, except for one thing. The product code was showing the code for Windows 7 and I had entered the code during the task sequence setup phase. I proceeded to change to the correct Windows 10 product code. The same error came up again. At that point, I cleared every field within the Specialize--->Microsoft-Windows-Shell-Setup by right-clicking and selecting Revert Change. The same issue occurred again. I hit Shift-F10 to pull up a command line. I got the c:\windows\panther files copied to a thumb drive and looked at the logs on my other machine. I saw the following errors in the setupact.log file:

At this point, I decided to completely delete the task sequence and start all over. The issue persisted. Finally, I deleted the Microsoft-Windows-Shell-Setup from the Specialize component. I re-imaged the machine and it now goes through the first bootup/setup phase with no problems. I already use PowerShell to set the product code after the image is laid down, so that was not a big deal.

20 May 2016

Initiating SCCM Actions with Verification

Posted By: Mick Pletcher - 2:36 PM









The latest script I am writing requires me to initiate both a software updates scan cycle and a software updates deployment evaluation cycle before continuing with the script. The actions needed to be completed before the script can continue, which is what started me on the path to writing this script. I figured if I was going to write two functions for those actions, I would write functions for the rest of the actions. I do realize there are more actions out there that I could include, but for now, I only included the ones in the Actions tab of the Configuration Manager Properties. Thanks to Eswar Knoeti's blog post, I had a reference to refer to on what log files to scan for the action being taken.

The way these scripts work, they kick off an action and then monitor the log file associated with that action until the completion/failed message appears. I have also included a 5 minute maximum wait time if something goes wrong and the action does not complete successfully, and a new message appears. I have noticed that some actions will not initiate if they have been initiated recently. For those, the status will return as failed.

I was going to originally include parameters so that you could select which functions to execute at command line. I chose not to because I figured that functions will likely be taken from this script to be included in other scripts and it is just as easy to comment out ones you do not want to execute between lines 446 and 456.

This has worked great in my environment. There maybe new messages in the log files that you may encounter that cause the function to not read the log file correctly. If so, please write a comment about that in the blog so that I can update the script. Thanks in advance.

With the help of Sapien's PowerShell Studio, I wrote the following script. You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            Initiate SCCM actions  
4:         
5:       .DESCRIPTION  
6:            This script will initiate SCCM actions and wait until the action is complete before continuing.   
7:         
8:       .EXAMPLE  
9:            powershell.exe -executionpolicy bypass -file SCCMActions.ps1  
10:         
11:       .NOTES  
12:       ===========================================================================  
13:        Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.122  
14:        Created on:       5/20/2016 2:28 PM  
15:        Created by:       Mick Pletcher  
16:        Organization:         
17:        Filename:         SCCMActions.ps1  
18:       ===========================================================================  
19:  #>  
20:  [CmdletBinding()]  
21:  param ()  
22:    
23:  function Get-CurrentDate {  
24:  <#  
25:       .SYNOPSIS  
26:            Get the current date and return formatted value  
27:         
28:       .DESCRIPTION  
29:            Return the current date in the following format: mm-dd-yyyy  
30:         
31:       .NOTES  
32:            Additional information about the function.  
33:  #>  
34:         
35:       [CmdletBinding()][OutputType([string])]  
36:       param ()  
37:         
38:       $CurrentDate = Get-Date  
39:       $CurrentDate = $CurrentDate.ToShortDateString()  
40:       $CurrentDate = $CurrentDate -replace "/", "-"  
41:       If ($CurrentDate[2] -ne "-") {  
42:            $CurrentDate = $CurrentDate.Insert(0, "0")  
43:       }  
44:       If ($CurrentDate[5] -ne "-") {  
45:            $CurrentDate = $CurrentDate.Insert(3, "0")  
46:       }  
47:       Return $CurrentDate  
48:  }  
49:    
50:  function Invoke-ApplicationDeploymentEvaluationCycle {  
51:       $Completed = $false  
52:       $StartTime = Get-Date -UFormat %R  
53:       $CurrentDate = Get-CurrentDate  
54:       Write-Host "Running Application Deployment Evaluation Cycle....." -NoNewline  
55:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000121"  
56:       Do {  
57:            Start-Sleep -Seconds 1  
58:            $CurrentTime = Get-Date -UFormat %R  
59:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
60:            $Log = Get-Content $env:windir"\ccm\logs\DCMReporting.log"  
61:            $Count = $Log.count  
62:            $Count = $Count - 1  
63:            $Log = $Log[$Count]  
64:            $LogTable = $Log.split("<")[-1]  
65:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
66:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
67:            $LogTime = $LogTable.time.Substring(0, 5)  
68:            [datetime]$StringTime = $LogTable.time  
69:            If (($Log -like "*FinalRelease*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
70:                 Write-Host "Completed" -ForegroundColor Yellow  
71:                 $Completed = $true  
72:            }  
73:            If ($TimeDifference.Minutes -ge 5) {  
74:                 Write-Host "Failed" -ForegroundColor Yellow  
75:                 $Completed = $true  
76:            }  
77:       } while ($Completed -eq $false)  
78:  }  
79:    
80:  function Invoke-DiscoveryDataCollectionCycle {  
81:       $Completed = $false  
82:       $StartTime = Get-Date -UFormat %R  
83:       $CurrentDate = Get-CurrentDate  
84:       Write-Host "Running Discovery Data Collection Cycle....." -NoNewline  
85:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000003"  
86:       Do {  
87:            Start-Sleep -Seconds 1  
88:            $CurrentTime = Get-Date -UFormat %R  
89:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
90:            $Log = Get-Content $env:windir"\ccm\logs\InventoryAgent.log"  
91:            $Count = $Log.count  
92:            $Count = $Count - 1  
93:            $Log = $Log[$Count]  
94:            $LogTable = $Log.split("<")[-1]  
95:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
96:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
97:            $LogTime = $LogTable.time.Substring(0, 5)  
98:            [datetime]$StringTime = $LogTable.time  
99:            If (($Log -like "*End of message processing*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
100:                 Write-Host "Completed" -ForegroundColor Yellow  
101:                 $Completed = $true  
102:            }  
103:            If ($TimeDifference.Minutes -ge 5) {  
104:                 Write-Host "Failed" -ForegroundColor Yellow  
105:                 $Completed = $true  
106:            }  
107:       } while ($Completed -eq $false)  
108:  }  
109:    
110:  function Invoke-FileCollectionCycle {  
111:       $Completed = $false  
112:       $StartTime = Get-Date -UFormat %R  
113:       $CurrentDate = Get-CurrentDate  
114:       Write-Host "Running File Collection Cycle....." -NoNewline  
115:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000010"  
116:       Do {  
117:            Start-Sleep -Seconds 1  
118:            $CurrentTime = Get-Date -UFormat %R  
119:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
120:            $Log = Get-Content $env:windir"\ccm\logs\InventoryAgent.log"  
121:            $Count = $Log.count  
122:            $Count = $Count - 1  
123:            $Log = $Log[$Count]  
124:            $LogTable = $Log.split("<")[-1]  
125:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
126:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
127:            $LogTime = $LogTable.time.Substring(0, 5)  
128:            [datetime]$StringTime = $LogTable.time  
129:            If ((($Log -like "*Action completed*") -or ($Log -like "*Exiting as no items to collect*")) -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
130:                 Write-Host "Completed" -ForegroundColor Yellow  
131:                 $Completed = $true  
132:            }  
133:            If ($TimeDifference.Minutes -ge 5) {  
134:                 Write-Host "Failed" -ForegroundColor Yellow  
135:                 $Completed = $true  
136:            }  
137:       } while ($Completed -eq $false)  
138:  }  
139:    
140:  function Invoke-HardwareInventoryCycle {  
141:       $Completed = $false  
142:       $StartTime = Get-Date -UFormat %R  
143:       $CurrentDate = Get-CurrentDate  
144:       Write-Host "Running Hardware Inventory Cycle....." -NoNewline  
145:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000001"  
146:       Do {  
147:            Start-Sleep -Seconds 1  
148:            $CurrentTime = Get-Date -UFormat %R  
149:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
150:            $Log = Get-Content $env:windir"\ccm\logs\InventoryAgent.log"  
151:            $Count = $Log.count  
152:            $Count = $Count - 1  
153:            $Log = $Log[$Count]  
154:            $LogTable = $Log.split("<")[-1]  
155:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
156:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
157:            $LogTime = $LogTable.time.Substring(0, 5)  
158:            [datetime]$StringTime = $LogTable.time  
159:            If (($Log -like "*End of message processing*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
160:                 Write-Host "Completed" -ForegroundColor Yellow  
161:                 $Completed = $true  
162:            }  
163:            If (($Log -like "*already in queue. Message ignored.*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
164:                 Write-Host "Ignored" -ForegroundColor Red  
165:                 $Completed = $true  
166:            }  
167:            If ($TimeDifference.Minutes -ge 5) {  
168:                 Write-Host "Failed" -ForegroundColor Yellow  
169:                 $Completed = $true  
170:            }  
171:       } while ($Completed -eq $false)  
172:  }  
173:    
174:  function Invoke-MachinePolicyEvaluationCycle {  
175:       $Completed = $false  
176:       $StartTime = Get-Date -UFormat %r  
177:       $StartTime = $StartTime.Split(' ')  
178:       $StartTime = $StartTime[0]  
179:       $StartTime = $StartTime.Substring(0, $StartTime.Length - 3)  
180:       $CurrentDate = Get-CurrentDate  
181:       Write-Host "Running Machine Policy Evaluation Cycle....." -NoNewline  
182:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000022"  
183:       Do {  
184:            Start-Sleep -Seconds 1  
185:            $CurrentTime = Get-Date -UFormat %R  
186:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
187:            $Log = Get-Content $env:windir"\ccm\logs\PolicyEvaluator.log"  
188:            $Count = $Log.count  
189:            $LogTime = $Log[$Count - 6]  
190:            $LogTime = $LogTime.Split('"')  
191:            $LogTime = $LogTime[1]  
192:            $LogTime = [management.managementdatetimeconverter]::ToDateTime($LogTime)  
193:            $LogDate = $LogTime  
194:            $LogTime = $LogTime.ToShortTimeString()  
195:            $LogTime = $Logtime.Split(' ')  
196:            $LogTime = $LogTime[0]  
197:            If ($LogTime[2] -ne ":") {  
198:                 $LogTime = $LogTime.Insert(0, "0")  
199:            }  
200:            $LogDate = $LogDate.ToShortDateString()  
201:            $LogDate = Get-CurrentDate  
202:            $LogStatus = $Log[$Count - 9]  
203:            If (($LogStatus -like "*instance of CCM_PolicyAgent_PolicyEvaluationComplete*") -and ($CurrentDate -eq $LogDate) -and ($LogTime -ge $StartTime)) {  
204:                 Write-Host "Completed" -ForegroundColor Yellow  
205:                 $Completed = $true  
206:            }  
207:            If ($TimeDifference.Minutes -ge 5) {  
208:                 Write-Host "Failed" -ForegroundColor Yellow  
209:                 $Completed = $true  
210:            }  
211:       } while ($Completed -eq $false)  
212:  }  
213:    
214:  function Invoke-MachinePolicyRetrievalCycle {  
215:       $Completed = $false  
216:       $StartTime = Get-Date -UFormat %r  
217:       $StartTime = $StartTime.Split(' ')  
218:       $StartTime = $StartTime[0]  
219:       $StartTime = $StartTime.Substring(0, $StartTime.Length - 3)  
220:       $CurrentDate = Get-CurrentDate  
221:       Write-Host "Running Machine Policy Retrieval Cycle....." -NoNewline  
222:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000021"  
223:       Do {  
224:            Start-Sleep -Seconds 1  
225:            $CurrentTime = Get-Date -UFormat %R  
226:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
227:            $Log = Get-Content $env:windir"\ccm\logs\PolicyEvaluator.log"  
228:            $Count = $Log.count  
229:            $LogTime = $Log[$Count - 6]  
230:            $LogTime = $LogTime.Split('"')  
231:            $LogTime = $LogTime[1]  
232:            $LogTime = [management.managementdatetimeconverter]::ToDateTime($LogTime)  
233:            $LogDate = $LogTime  
234:            $LogTime = $LogTime.ToShortTimeString()  
235:            $LogTime = $Logtime.Split(' ')  
236:            $LogTime = $LogTime[0]  
237:            If ($LogTime[2] -ne ":") {  
238:                 $LogTime = $LogTime.Insert(0, "0")  
239:            }  
240:            $LogDate = $LogDate.ToShortDateString()  
241:            $LogDate = Get-CurrentDate  
242:            $LogStatus = $Log[$Count - 9]  
243:            If (($LogStatus -like "*instance of CCM_PolicyAgent_PolicyEvaluationComplete*") -and ($CurrentDate -eq $LogDate) -and ($LogTime -ge $StartTime)) {  
244:                 Write-Host "Completed" -ForegroundColor Yellow  
245:                 $Completed = $true  
246:            }  
247:            If ($TimeDifference.Minutes -ge 5) {  
248:                 Write-Host "Failed" -ForegroundColor Yellow  
249:                 $Completed = $true  
250:            }  
251:       } while ($Completed -eq $false)  
252:  }  
253:    
254:  function Invoke-SoftwareInventoryCycle {  
255:       $Completed = $false  
256:       $StartTime = Get-Date -UFormat %R  
257:       $CurrentDate = Get-CurrentDate  
258:       Write-Host "Running Software Inventory Cycle....." -NoNewline  
259:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000002"  
260:       Do {  
261:            Start-Sleep -Seconds 1  
262:            $CurrentTime = Get-Date -UFormat %R  
263:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
264:            $Log = Get-Content $env:windir"\ccm\logs\InventoryAgent.log"  
265:            $Count = $Log.count  
266:            $Count = $Count - 1  
267:            $Log = $Log[$Count]  
268:            $LogTable = $Log.split("<")[-1]  
269:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
270:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
271:            $LogTime = $LogTable.time.Substring(0, 5)  
272:            [datetime]$StringTime = $LogTable.time  
273:            If (($Log -like "*Initialization completed in*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
274:                 Write-Host "Completed" -ForegroundColor Yellow  
275:                 $Completed = $true  
276:            }  
277:            If ($TimeDifference.Minutes -ge 5) {  
278:                 Write-Host "Failed" -ForegroundColor Yellow  
279:                 $Completed = $true  
280:            }  
281:       } while ($Completed -eq $false)  
282:  }  
283:    
284:  function Invoke-SoftwareMeteringUsageReportCycle {  
285:       $Completed = $false  
286:       $StartTime = Get-Date -UFormat %R  
287:       $CurrentDate = Get-CurrentDate  
288:       Write-Host "Running Software Metering Usage Report Cycle....." -NoNewline  
289:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000031"  
290:       Do {  
291:            Start-Sleep -Seconds 1  
292:            $CurrentTime = Get-Date -UFormat %R  
293:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
294:            $Log = Get-Content $env:windir"\ccm\logs\SWMTRReportGen.log"  
295:            $Count = $Log.count  
296:            $Count = $Count - 1  
297:            $Log = $Log[$Count]  
298:            $LogTable = $Log.split("<")[-1]  
299:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
300:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
301:            $LogTime = $LogTable.time.Substring(0, 5)  
302:            [datetime]$StringTime = $LogTable.time  
303:            If ((($Log -like "*No usage data found to generate software metering report*") -or ($Log -like "*Successfully generated report header*") -or ($Log -like "*Message ID of sent message*")) -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
304:                 Write-Host "Completed" -ForegroundColor Yellow  
305:                 $Completed = $true  
306:            }  
307:            If ($TimeDifference.Minutes -ge 5) {  
308:                 Write-Host "Failed" -ForegroundColor Yellow  
309:                 $Completed = $true  
310:            }  
311:       } while ($Completed -eq $false)  
312:  }  
313:    
314:  function Invoke-SoftwareUpdatesDeploymentEvaluationCycle {  
315:  <#  
316:       .SYNOPSIS  
317:            Scan for software updates that are out of compliance  
318:         
319:       .DESCRIPTION  
320:            Initiates a scan for software updates compliance. Before client computers can scan for software update compliance, the software updates environment must be configured.  
321:         
322:       .NOTES  
323:            Additional information about the function.  
324:  #>  
325:         
326:       [CmdletBinding()]  
327:       param ()  
328:         
329:       $Completed = $false  
330:       $StartTime = Get-Date -UFormat %R  
331:       $CurrentDate = Get-CurrentDate  
332:       Write-Host "Running Software Updates Deployment Evaluation Cycle....." -NoNewline  
333:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000108"  
334:       Do {  
335:            Start-Sleep -Seconds 1  
336:            $CurrentTime = Get-Date -UFormat %R  
337:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
338:            $Log = Get-Content $env:windir"\ccm\logs\ScanAgent.log"  
339:            $Count = $Log.count  
340:            $Count = $Count - 1  
341:            $Log = $Log[$Count]  
342:            $LogTable = $Log.split("<")[-1]  
343:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
344:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
345:            $LogTime = $LogTable.time.Substring(0, 5)  
346:            [datetime]$StringTime = $LogTable.time  
347:            If (($Log -like "*Calling back to client on Scan request complete*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
348:                 Write-Host "Completed" -ForegroundColor Yellow  
349:                 $Completed = $true  
350:            }  
351:            If ($TimeDifference.Minutes -ge 5) {  
352:                 Write-Host "Failed" -ForegroundColor Yellow  
353:                 $Completed = $true  
354:            }  
355:       } while ($Completed -eq $false)  
356:  }  
357:    
358:  function Invoke-SoftwareUpdatesScanCycle {  
359:       $Completed = $false  
360:       $StartTime = Get-Date -UFormat %R  
361:       $CurrentDate = Get-CurrentDate  
362:       Write-Host "Running Software Updates Scan Cycle....." -NoNewline  
363:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000113"  
364:       Do {  
365:            Start-Sleep -Seconds 1  
366:            $CurrentTime = Get-Date -UFormat %R  
367:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
368:            $Log = Get-Content $env:windir"\ccm\logs\scanagent.log"  
369:            $Count = $Log.count  
370:            $Count = $Count - 1  
371:            $Log = $Log[$Count]  
372:            $LogTable = $Log.split("<")[-1]  
373:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
374:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
375:            $LogTime = $LogTable.time.Substring(0, 5)  
376:            [datetime]$StringTime = $LogTable.time  
377:            If (($Log -like "*scan completion received*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
378:                 Write-Host "Completed" -ForegroundColor Yellow  
379:                 $Completed = $true  
380:            }  
381:            If ($TimeDifference.Minutes -ge 5) {  
382:                 Write-Host "Failed" -ForegroundColor Yellow  
383:                 $Completed = $true  
384:            }  
385:       } while ($Completed -eq $false)  
386:  }  
387:    
388:  function Invoke-WindowsInstallerSourceListUpdateCycle {  
389:       $Completed = $false  
390:       $StartTime = Get-Date -UFormat %R  
391:       $CurrentDate = Get-CurrentDate  
392:       Write-Host "Running Windows Installer Source List Update Cycle....." -NoNewline  
393:       Start-ConfigurationManagerClientScan -ScheduleID "00000000-0000-0000-0000-000000000032"  
394:       Do {  
395:            Start-Sleep -Seconds 1  
396:            $CurrentTime = Get-Date -UFormat %R  
397:            $TimeDifference = New-TimeSpan -Start $StartTime -End $CurrentTime  
398:            $Log = Get-Content $env:windir"\ccm\logs\SrcUpdateMgr.log"  
399:            $Count = $Log.count  
400:            $Count = $Count - 1  
401:            $Log = $Log[$Count]  
402:            $LogTable = $Log.split("<")[-1]  
403:            $LogTable = $LogTable.Substring(0, $LogTable.length - 1) -replace ' ', ';'  
404:            $LogTable = "@{$($LogTable)}" | Invoke-Expression  
405:            $LogTime = $LogTable.time.Substring(0, 5)  
406:            [datetime]$StringTime = $LogTable.time  
407:            If (($Log -like "*MSI update source list task finished successfully*") -and ($CurrentDate -eq $LogTable.date) -and ($LogTime -ge $StartTime)) {  
408:                 Write-Host "Completed" -ForegroundColor Yellow  
409:                 $Completed = $true  
410:            }  
411:            If ($TimeDifference.Minutes -ge 5) {  
412:                 Write-Host "Failed" -ForegroundColor Yellow  
413:                 $Completed = $true  
414:            }  
415:       } while ($Completed -eq $false)  
416:  }  
417:    
418:  function Start-ConfigurationManagerClientScan {  
419:  <#  
420:       .SYNOPSIS  
421:            Initiate Configuration Manager Client Scan  
422:         
423:       .DESCRIPTION  
424:            This will initiate an SCCM action  
425:         
426:       .PARAMETER ScheduleID  
427:            GUID ID of the SCCM action  
428:         
429:       .NOTES  
430:            Additional information about the function.  
431:  #>  
432:         
433:       [CmdletBinding()]  
434:       param  
435:       (  
436:                 [ValidateSet('00000000-0000-0000-0000-000000000121', '00000000-0000-0000-0000-000000000003', '00000000-0000-0000-0000-000000000010', '00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000021', '00000000-0000-0000-0000-000000000022', '00000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000031', '00000000-0000-0000-0000-000000000108', '00000000-0000-0000-0000-000000000113', '00000000-0000-0000-0000-000000000111', '00000000-0000-0000-0000-000000000026', '00000000-0000-0000-0000-000000000027', '00000000-0000-0000-0000-000000000032')]$ScheduleID  
437:       )  
438:         
439:       $WMIPath = "\\" + $env:COMPUTERNAME + "\root\ccm:SMS_Client"  
440:       $SMSwmi = [wmiclass]$WMIPath  
441:       $Action = [char]123 + $ScheduleID + [char]125  
442:       [Void]$SMSwmi.TriggerSchedule($Action)  
443:  }  
444:    
445:  Clear-Host  
446:  Invoke-SoftwareUpdatesScanCycle  
447:  Invoke-SoftwareUpdatesDeploymentEvaluationCycle  
448:  Invoke-ApplicationDeploymentEvaluationCycle  
449:  Invoke-DiscoveryDataCollectionCycle  
450:  Invoke-FileCollectionCycle  
451:  Invoke-HardwareInventoryCycle  
452:  Invoke-MachinePolicyEvaluationCycle  
453:  Invoke-MachinePolicyRetrievalCycle  
454:  Invoke-SoftwareInventoryCycle  
455:  Invoke-SoftwareMeteringUsageReportCycle  
456:  Invoke-WindowsInstallerSourceListUpdateCycle  
457:    

18 May 2016

Configure PowerShell Settings

Posted By: Mick Pletcher - 12:50 PM










Recently, we needed to start building select machines off of our domain for special projects. This meant that group policies would not be applied. I use GPOs to set PowerShell settings on all of the machines. With these machines no longer getting GPOs applied, PowerShell scripts would no longer execute correctly because some of my scripts also use a module I push via GPO and the execution policy was not updated. This lead me to write, with the help and ease of Sapien's PowerShell Studio, the script below that will set the execution policy, configure the RunAs Administrator, configure additional paths for PowerShell modules, and copies PowerShell modules over. This gets executed after the first windows updates are applied in the task sequencing. If the script is executed manually, there is an output screen that shows if each setting is a success or failure.

To use this script, you will need to update/verify lines 212, 217, 224, and 225. Of course, if you don't want all of those things to change, you can comment some of them out.

You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            Configure PowerShell  
4:         
5:       .DESCRIPTION  
6:            Configure PowerShell execution policy and install PowerShell modules.  
7:         
8:       .DESCRIPTION  
9:            A description of the file.  
10:         
11:       .PARAMETER PSConsoleTitle  
12:            Title of the PowerShell Console  
13:         
14:       .EXAMPLE  
15:            powershell.exe -executionpolicy bypass -file ConfigurePowerShell.ps1  
16:         
17:       .NOTES  
18:            ===========================================================================  
19:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.122  
20:            Created on:       5/18/2016 12:12 PM  
21:            Created by:       Mick Pletcher  
22:            Organization:  
23:            Filename:         ConfigurePowerShell.ps1  
24:            ===========================================================================  
25:  #>  
26:  [CmdletBinding()]  
27:  param  
28:  (  
29:            [string]$PSConsoleTitle = 'PowerShell Configuration'  
30:  )  
31:    
32:  function Set-ConsoleTitle {  
33:  <#  
34:       .SYNOPSIS  
35:            Console Title  
36:         
37:       .DESCRIPTION  
38:            Sets the title of the PowerShell Console  
39:         
40:       .PARAMETER ConsoleTitle  
41:            Title of the PowerShell Console  
42:         
43:       .NOTES  
44:            Additional information about the function.  
45:  #>  
46:         
47:       [CmdletBinding()]  
48:       param  
49:       (  
50:                 [Parameter(Mandatory = $true)][String]$ConsoleTitle  
51:       )  
52:         
53:       $host.ui.RawUI.WindowTitle = $ConsoleTitle  
54:  }  
55:    
56:  function Get-RelativePath {  
57:  <#  
58:       .SYNOPSIS  
59:            Get the relative path  
60:         
61:       .DESCRIPTION  
62:            Returns the location of the currently running PowerShell script  
63:         
64:       .NOTES  
65:            Additional information about the function.  
66:  #>  
67:         
68:       [CmdletBinding()][OutputType([string])]  
69:       param ()  
70:         
71:       $Path = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
72:       Return $Path  
73:  }  
74:    
75:  function Set-RegistryKeyValue {  
76:  <#  
77:       .SYNOPSIS  
78:            Test if a registry value exists  
79:         
80:       .DESCRIPTION  
81:            This tests to see if a registry value exists by using the get-itemproperty and therefore returning a boolean value if the cmdlet executes successfully.  
82:         
83:       .PARAMETER RegKeyName  
84:            Registry key name  
85:         
86:       .PARAMETER RegKeyValue  
87:            Value within the registry key  
88:         
89:       .PARAMETER RegKeyData  
90:            The data pertaining to the registry key value  
91:         
92:       .PARAMETER DisplayName  
93:            Name to be used to display on the status window  
94:         
95:  #>  
96:         
97:       [CmdletBinding()]  
98:       param  
99:       (  
100:                 [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$RegKeyName,  
101:                 [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$RegKeyValue,  
102:                 [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$RegKeyData,  
103:                 [string]$DisplayName = $null  
104:       )  
105:         
106:       If ($DisplayName -ne $null) {  
107:            Write-Host "Setting"$DisplayName"....." -NoNewline  
108:       }  
109:       $NoOutput = New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT  
110:       $Key = Get-Item -LiteralPath $RegKeyName -ErrorAction SilentlyContinue  
111:       If ($Key -ne $null) {  
112:            If ($RegKeyValue -eq '(Default)') {  
113:                 $Value = Get-ItemProperty $RegKey '(Default)' | Select-Object -ExpandProperty '(Default)'  
114:            } else {  
115:                 $Value = $Key.GetValue($RegKeyValue, $null)  
116:            }  
117:            If ($Value -ne $RegKeyData) {  
118:                 Set-ItemProperty -Path $RegKeyName -Name $RegKeyValue -Value $RegKeyData -Force  
119:            }  
120:              
121:       } else {  
122:            $NoOutput = New-Item -Path $RegKeyName -Force  
123:            $NoOutput = New-ItemProperty -Path $RegKeyName -Name $RegKeyValue -Value $RegKeyData -Force  
124:       }  
125:       If ($RegKeyValue -eq '(Default)') {  
126:            $Value = Get-ItemProperty $RegKey '(Default)' | Select-Object -ExpandProperty '(Default)'  
127:       } else {  
128:            $Value = $Key.GetValue($RegKeyValue, $null)  
129:       }  
130:       If ($DisplayName -ne $null) {  
131:            If ($Value -eq $RegKeyData) {  
132:                 Write-Host "Success" -ForegroundColor Yellow  
133:            } else {  
134:                 Write-Host "Failed" -ForegroundColor Red  
135:                 Write-Host $Value  
136:                 Write-Host $RegKeyData  
137:            }  
138:       }  
139:  }  
140:    
141:  function Copy-Files {  
142:  <#  
143:       .SYNOPSIS  
144:            Copy-Files  
145:         
146:       .DESCRIPTION  
147:            This will copy specified file(s)  
148:         
149:       .PARAMETER SourceDirectory  
150:            Directory containing the source file(s)  
151:         
152:       .PARAMETER DestinationDirectory  
153:            Directory where the source file(s) will be copied to  
154:         
155:       .PARAMETER FileFilter  
156:            Either a specific filename or a wildcard specifying what to copy  
157:         
158:       .EXAMPLE  
159:            Copy-Files -SourceDirectory 'c:\windows' -DestinationDirectory 'd:\windows' -FileFilter '*.exe'  
160:            Copy-Files -SourceDirectory 'c:\windows' -DestinationDirectory 'd:\windows' -FileFilter 'INSTALL.LOG'  
161:         
162:       .NOTES  
163:            Additional information about the function.  
164:  #>  
165:         
166:       [CmdletBinding()]  
167:       param  
168:       (  
169:                 [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$SourceDirectory,  
170:                 [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$DestinationDirectory,  
171:                 [ValidateNotNullOrEmpty()][String]$FileFilter  
172:       )  
173:         
174:       $Dest = $DestinationDirectory  
175:       If ((Test-Path $DestinationDirectory) -eq $false) {  
176:            $NoOutput = New-Item -Path $DestinationDirectory -ItemType Directory -Force  
177:       }  
178:       $Files = Get-ChildItem $SourceDirectory -Filter $FileFilter  
179:       If ($Files.Count -eq $null) {  
180:            Write-Host "Copy"$Files.Name"....." -NoNewline  
181:            Copy-Item $Files.FullName -Destination $Dest -Force  
182:            $Test = $Dest + "\" + $Files.Name  
183:            If (Test-Path $Test) {  
184:                 Write-Host "Success" -ForegroundColor Yellow  
185:            } else {  
186:                 Write-Host "Failed" -ForegroundColor Red  
187:            }  
188:       } else {  
189:            For ($i = 0; $i -lt $Files.Count; $i++) {  
190:                 $File = $Files[$i].FullName  
191:                 Write-Host "Copy"$Files[$i].Name"....." -NoNewline  
192:                 Copy-Item $File -Destination $Dest -Force  
193:                 $Test = $Dest + "\" + $Files[$i].Name  
194:                 If (Test-Path $Test) {  
195:                      Write-Host "Success" -ForegroundColor Yellow  
196:                 } else {  
197:                      Write-Host "Failed" -ForegroundColor Red  
198:                 }  
199:            }  
200:       }  
201:  }  
202:    
203:  Clear-Host  
204:  #Set the title of the PowerShell console  
205:  Set-ConsoleTitle -ConsoleTitle $PSConsoleTitle  
206:    
207:  #Define the relative path   
208:  $RelativePath = Get-RelativePath  
209:    
210:  #Configure additional paths for PowerShell modules  
211:  $RegKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'  
212:  $RegValue = $env:SystemRoot + '\system32\WindowsPowerShell\v1.0\Modules\;' + $env:ProgramFiles + '\windowspowershell\modules'  
213:  Set-RegistryKeyValue -DisplayName "PSModulePath" -RegKeyName $RegKey -RegKeyValue 'PSModulePath' -RegKeyData $RegValue  
214:    
215:  #Set the PowerShell execution policy  
216:  $RegKey = 'HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'  
217:  Set-RegistryKeyValue -DisplayName "ExecutionPolicy" -RegKeyName $RegKey -RegKeyValue 'ExecutionPolicy' -RegKeyData 'RemoteSigned'  
218:    
219:  #Configure PowerShell RunAs Administrator  
220:  $RegKey = 'HKCR:\Microsoft.PowerShellScript.1\Shell\runas\command'  
221:  Set-RegistryKeyValue -DisplayName "RunAs Administrator" -RegKeyName $RegKey -RegKeyValue '(Default)' -RegKeyData '"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit "%1"'  
222:    
223:  #Copy PowerShell Modules  
224:  $ModuleFolder = $env:ProgramFiles + "\WindowsPowerShell\Modules\Deployment"  
225:  Copy-Files -SourceDirectory $RelativePath -DestinationDirectory $ModuleFolder -FileFilter "Deployment.psm1"  
226:    

03 May 2016

Install Dell Command Update and Flash BIOS in WinPE

Posted By: Mick Pletcher - 12:44 PM














I have wanted to get the process of flashing the BIOS into the WinPE environment for quite a while. With the help of Sapien's PowerShell Studio, I finally wrote the script to make this possible. The purpose is that it can flash it much quicker in the WinPE environment and it also gives two opportunities for he BIOS to be flashed during the build process. On some Dell machines, if the BIOS version is too far behind, there is an intermediary BIOS update that must be applied before the latest update can be. This gives the build the opportunity to get past that intermediary and apply the latest update before the build is completed.

To use this script, you will need to first install the Dell Command | Update on a system. If you are using the x86 version of WinPE, then install it on an x86 PC. The same on an x64 machine. Copy all of the contents of the %PROGRAMFILES%\Dell\CommandUpdate folder to a folder on a network share. Next, copy the msi.dll file from the %WINDIR%\System32 folder to the same folder share.

I created a task sequence folder and then put three task sequences underneath it.

Now it's time to create the Run Command Line task sequence. The first is to map to the folder share where you copied the CommandUpdate folder to. I used T: as my drive letter and used the following command: net use t: \\<NetworkShareFolder> /USER:<domain>\<username> <Password>. This is not recorded in any of the logs, so you don't risk the password being seen by unwanted eyes so long as they cannot access the task sequence.

The second task sequence is to install and update the Dell BIOS. This is also a Run Command Line sequence. The command line I use is: powershell.exe -executionpolicy bypass -file t:\install.ps1.

The final task sequence is unmapping the network drive via a Run Command Line sequence. The command line for this is net use t: /delete

I have also included in the script the ability to apply an XML file to the dcu-cli.exe. The XML file specifies what driver types to apply to the system. It looks for the XML file in the same directory as the PowerShell script. I found that if I execute the dcu-cli.exe with no switches, it does try to install one driver update to the WinPE environment, but it fails and continues to install the BIOS update with no issues.

Here is a video of the tool in action during the initial phase of the build process:


You can download the script from here.



UpdateBIOSWinPE.ps1

1:  <#  
2:       .SYNOPSIS  
3:            Install Dell Command | Update and Update the BIOS  
4:         
5:       .DESCRIPTION  
6:            Copy over the Dell Command | Update and install the BIOS  
7:         
8:       .PARAMETER Source  
9:            Source folder containing the Dell Command | Update files  
10:         
11:       .PARAMETER Destination  
12:            Location to copy the Dell Command | Update files to  
13:         
14:       .PARAMETER XMLFile  
15:            XML file that limits the Dell Command | Update to only scan for a BIOS update  
16:         
17:       .NOTES  
18:            ===========================================================================  
19:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.120  
20:            Created on:       4/27/2016 10:17 AM  
21:            Created by:       Mick Pletcher  
22:            Organization:  
23:            Filename:         UpdateBIOSWinPE.ps1  
24:            ===========================================================================  
25:  #>  
26:  [CmdletBinding()]  
27:  param  
28:  (  
29:            [string]$Source = 't:\',  
30:            [string]$Destination = 'x:\DCU',  
31:            [string]$XMLFile  
32:  )  
33:    
34:  function Copy-Folder {  
35:  <#  
36:       .SYNOPSIS  
37:            Copy Folder  
38:         
39:       .DESCRIPTION  
40:            Copy folder to destination  
41:         
42:       .PARAMETER SourceFolder  
43:            Folder to copy contents from  
44:         
45:       .PARAMETER DestinationFolder  
46:            Folder to copy contents to  
47:         
48:       .PARAMETER Subfolders  
49:            Include all subfolders  
50:         
51:       .PARAMETER Mirror  
52:            Mirror the destination folder with the source folder. Contents that exist in the destination folder, but not in the source folder, will be deleted.  
53:         
54:       .EXAMPLE  
55:            PS C:\> Copy-Folder -SourceFolder 'Value1' -DestinationFolder 'Value2'  
56:         
57:       .NOTES  
58:            Additional information about the function.  
59:  #>  
60:         
61:       [CmdletBinding()]  
62:       param  
63:       (  
64:                 [string]$SourceFolder,  
65:                 [string]$DestinationFolder,  
66:                 [ValidateSet($true, $false)][boolean]$Subfolders = $false,  
67:                 [ValidateSet($true, $false)][boolean]$Mirror = $false  
68:       )  
69:         
70:       $Executable = $env:windir + "\system32\Robocopy.exe"  
71:       $Switches = $SourceFolder + [char]32 + $DestinationFolder + [char]32 + "/eta"  
72:       If ($Subfolders -eq $true) {  
73:            $Switches = $Switches + [char]32 + "/e"  
74:       }  
75:       If ($Mirror -eq $true) {  
76:            $Switches = $Switches + [char]32 + "/mir"  
77:       }  
78:       Write-Host "Copying "$SourceFolder"....." -NoNewline  
79:       $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Switches -Wait -Passthru).ExitCode  
80:       If (($ErrCode -eq 0) -or ($ErrCode -eq 1)) {  
81:            Write-Host "Success" -ForegroundColor Yellow  
82:       } else {  
83:            Write-Host "Failed with error code"$ErrCode -ForegroundColor Red  
84:       }  
85:  }  
86:    
87:  function Update-BIOS {  
88:  <#  
89:       .SYNOPSIS  
90:            Update to the latest BIOS Version  
91:         
92:       .DESCRIPTION  
93:            Execute the DCU-CLI.exe to query Dell for the latest BIOS version  
94:         
95:       .NOTES  
96:            Additional information about the function.  
97:  #>  
98:         
99:       [CmdletBinding()]  
100:       param ()  
101:         
102:       $Executable = $Destination + "\dcu-cli.exe"  
103:       If ($XMLFile -eq "") {  
104:            $Switches = " "  
105:       } else {  
106:            $XMLFile = $Destination + "\" + $XMLFile  
107:            $Switches = "/policy" + [char]32 + $XMLFile  
108:       }  
109:       #$Switches = " "  
110:       Write-Host "Updating BIOS....." -NoNewline  
111:       $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Switches -Wait -Passthru).ExitCode  
112:       If ($ErrCode -eq 0) {  
113:            Write-Host "Success" -ForegroundColor Yellow  
114:       } else {  
115:            Write-Host "Failed with error code"$ErrCode -ForegroundColor Red  
116:       }  
117:  }  
118:    
119:  #Copy contents of the Dell Command | Update folder to the WinPE directory  
120:  Copy-Folder -SourceFolder $Source -DestinationFolder $Destination -Subfolders $true -Mirror $true  
121:  #Copy msi.dll to the WinPE system32 folder to make msiexec.exe functional  
122:  Copy-Item -Path $Destination"\msi.dll" -Destination "x:\windows\system32" -Force  
123:  #Execute the dcu-cli.exe to update the BIOS  
124:  Update-BIOS  
125:    

21 April 2016

NIC Advanced Properties

Posted By: Mick Pletcher - 6:59 PM










Recently, we started having issues with our new Dell Latitude E7450 laptops. They would be put to sleep and then they could not restore the network connection once the laptop was docked again. The problem came from the Energy Efficient Ethernet setting in the advanced properties of the NIC. That is what lead me to writing this script so that we could set it during the build process. With the help of Sapien Technology's PowerShell Studio, this was pretty easy to write and it made writing the code very thorough.

I wrote the script so that all entries are there, at least for the Dell models we use. You may need to manually add or delete some values if the systems you have differ, which they likely will. I set the script up so that unless there are values that need to be entered, everything can be done from command line. If you do not define a parameter, then it is skipped over. I entered the exact values from the drop-down menus for each value. The script translates that into the required value to enter into the registry. I also put the possible values within the comments of each parameter.

You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            NIC Advanced Properties  
4:         
5:       .DESCRIPTION  
6:            Configure NIC Advanced Properties by modifying the values in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318} registry key.  
7:         
8:       .PARAMETER ConsoleTitle  
9:            Title displayed in the PowerShell Console  
10:         
11:       .PARAMETER EnergyEfficientEthernet  
12:            RegValue: EEELinkAdvertisement  
13:            0 - Off  
14:            1 - On  
15:         
16:       .PARAMETER FlowControl  
17:            RegValue: *FlowControl  
18:            0 - Disabled  
19:            1 - Tx Enabled  
20:            2 - Rx Enabled  
21:            3 - Rx & Tx Enabled  
22:         
23:       .PARAMETER JumboPacket  
24:            RegValue: *JumboPacket  
25:            1514 - Disabled  
26:            4088 - 4088 Bytes  
27:            9014 - 9014 Bytes  
28:         
29:       .PARAMETER LegacySwitchCompatibilityMode  
30:            RegValue: LinkNegotiationProcess  
31:            1 - Disabled  
32:            2 - Enabled  
33:         
34:       .PARAMETER LinkSpeedBatterySaver  
35:            RegValue: AutoPowerSaveModeEnabled  
36:            0 - Disabled  
37:            1 - Enabled  
38:         
39:       .PARAMETER PriorityVLAN  
40:            RegValue: *PriorityVLANTag  
41:            0 - Priority & VLAN Disabled  
42:            1 - Priority Enabled  
43:            2 - VLAN Enabled  
44:            3 - Priority & VLAN Enabled  
45:         
46:       .PARAMETER ProtocolARPOffload  
47:            RegValue: *PMARPOffload  
48:            0x00000000 - Enabled  
49:            0x00000001 - Disabled  
50:         
51:       .PARAMETER ProtocolNSOffload  
52:            RegValue: *PMNSOffload  
53:            0x00000000 - Enabled  
54:            0x00000001 - Disabled  
55:         
56:       .PARAMETER SpeedDuplex  
57:            RegValue: *SpeedDuplex  
58:            0 - Auto Negotiation  
59:            1 - 10 Mbps Half Duplex  
60:            2 - 10 Mbps Full Duplex  
61:            3 - 100 Mbps Half Duplex  
62:            4 - 100 Mbps Full Duplex  
63:            6 - 1.0 Gbps Full Duplex  
64:         
65:       .PARAMETER SystemIdlePowerSaver  
66:            RegValue: SipsEnabled  
67:            0 - Disabled  
68:            1 - Enabled  
69:         
70:       .PARAMETER WakeOnMagicPacket  
71:            RegValue: *WakeOnMagicPacket  
72:            0x00000000 - Enabled  
73:            0x00000001 - Disabled  
74:         
75:       .PARAMETER WakeOnPatternMatch  
76:            RegValue: *WakeOnPattern  
77:            0x00000000 - Enabled  
78:            0x00000001 - Disabled  
79:         
80:       .NOTES  
81:            ===========================================================================  
82:            Created with:      SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.119  
83:            Created on:       4/20/2016 11:20 AM  
84:            Created by:          Mick Pletcher  
85:            Organization:  
86:            Filename:          NICAdvancedProperties  
87:            ===========================================================================  
88:  #>  
89:  [CmdletBinding()]  
90:  param  
91:  (  
92:            [string]$ConsoleTitle = 'NIC Advanced Properties',  
93:            [ValidateSet('Off', 'On')][string]$EnergyEfficientEthernet,  
94:            [ValidateSet('Disabled', 'Tx Enabled', 'Rx Enabled', 'Rx & Tx Enabled')][string]$FlowControl,  
95:            [ValidateSet('Disabled', '4088 Bytes', '9014 Bytes')][string]$JumboPacket,  
96:            [ValidateSet('Disabled', 'Enabled')][string]$LegacySwitchCompatibilityMode,  
97:            [ValidateSet('Disabled', 'Enabled')][string]$LinkSpeedBatterySaver,  
98:            [ValidateSet('Priority & VLAN Disabled', 'Priority Enabled', 'VLAN Enabled', 'Priority & VLAN Enabled')][string]$PriorityVLAN,  
99:            [ValidateSet('Disabled', 'Enabled')][string]$ProtocolARPOffload,  
100:            [ValidateSet('Disabled', 'Enabled')][string]$ProtocolNSOffload,  
101:            [ValidateSet('Auto Negotiation', '10 Mbps Half Duplex', '10 Mbps Full Duplex', '100 Mbps Half Duplex', '100 Mbps Full Duplex', '1.0 Gbps Full Duplex')][string]$SpeedDuplex,  
102:            [ValidateSet('Disabled', 'Enabled')][string]$SystemIdlePowerSaver,  
103:            [ValidateSet('Disabled', 'Enabled')][string]$WakeOnMagicPacket,  
104:            [ValidateSet('Disabled', 'Enabled')][string]$WakeOnPatternMatch  
105:  )  
106:    
107:  function Get-PhysicalNICs {  
108:  <#  
109:       .SYNOPSIS  
110:            Retrieve the Physical NICs  
111:         
112:       .DESCRIPTION  
113:            Find the physical NICs that are currently being used and return the information from the function  
114:         
115:       .EXAMPLE  
116:            PS C:\> Get-PhysicalNICs  
117:         
118:       .NOTES  
119:            Additional information about the function.  
120:  #>  
121:         
122:       [CmdletBinding()]  
123:       param ()  
124:         
125:       # Get all physical ethernet adaptors  
126:       $NICs = Get-WmiObject Win32_NetworkAdapter -filter "AdapterTypeID = '0' `  
127:       AND PhysicalAdapter = 'true' `  
128:       AND NOT Description LIKE '%Centrino%' `  
129:       AND NOT Description LIKE '%wireless%' `  
130:       AND NOT Description LIKE '%virtual%' `  
131:       AND NOT Description LIKE '%WiFi%' `  
132:       AND NOT Description LIKE '%Bluetooth%'"  
133:       Return $NICs  
134:  }  
135:    
136:  function Get-Platform {  
137:  <#  
138:       .SYNOPSIS  
139:            Determine Platform  
140:         
141:       .DESCRIPTION  
142:            Test if system is a desktop or laptop  
143:         
144:       .NOTES  
145:            Additional information about the function.  
146:  #>  
147:         
148:       [CmdletBinding()][OutputType([string])]  
149:       param ()  
150:         
151:       if (Get-WmiObject -Class win32_battery -ComputerName "localhost") {  
152:            $Platform = "Laptop"  
153:       } else {  
154:            $Platform = "Desktop"  
155:       }  
156:       Return $Platform  
157:  }  
158:    
159:  function Set-NICRegistryKey {  
160:  <#  
161:       .SYNOPSIS  
162:            Get registry key of NIC  
163:         
164:       .DESCRIPTION  
165:            Find the registry key of the physical NIC  
166:         
167:       .PARAMETER NetworkAdapters  
168:            List of physical NIC cards  
169:         
170:       .EXAMPLE  
171:            PS C:\> Set-NICRegistryKey  
172:         
173:       .NOTES  
174:            Additional information about the function.  
175:  #>  
176:         
177:       [CmdletBinding()]  
178:       param  
179:       (  
180:                 $NetworkAdapters  
181:       )  
182:         
183:       $NetworkAdapterKey = "HKLM:\system\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"  
184:       foreach ($NetworkAdapter in $NetworkAdapters) {  
185:            If ([int]$NetworkAdapter.DeviceID -lt 10) {  
186:                 $NetworkAdapterSubKey = $NetworkAdapterKey + "\" + "000" + $NetworkAdapter.DeviceID  
187:            } else {  
188:                 $NetworkAdapterSubKey = $NetworkAdapterKey + "\" + "00" + $NetworkAdapter.DeviceID  
189:            }  
190:            $AdapterProperties = Get-ItemProperty $NetworkAdapterSubKey  
191:            #Energy Efficient Ethernet  
192:            If ($EnergyEfficientEthernet -ne "") {  
193:                 $AdaptorProperty = 'EEELinkAdvertisement'  
194:                 Write-Host "Energy Efficient Ethernet....." -NoNewline  
195:                 If ($EnergyEfficientEthernet -eq "On") {  
196:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
197:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 1  
198:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
199:                      If ($Value.$AdaptorProperty -eq 1) {  
200:                           Write-Host $EnergyEfficientEthernet -ForegroundColor Yellow  
201:                      } else {  
202:                           Write-Host "Failed" -ForegroundColor Red  
203:                      }  
204:                 } else {  
205:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
206:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0  
207:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
208:                      If ($Value.$AdaptorProperty -eq 0) {  
209:                           Write-Host $EnergyEfficientEthernet -ForegroundColor Yellow  
210:                      } else {  
211:                           Write-Host "Failed" -ForegroundColor Red  
212:                      }  
213:                 }  
214:            }  
215:            #Flow Control  
216:            If ($FlowControl -ne "") {  
217:                 $AdaptorProperty = '*FlowControl'  
218:                 Write-Host "Flow Control....." -NoNewline  
219:                 switch ($FlowControl) {  
220:                      "Disabled" {  
221:                           $AdapterPropertyValue = 0  
222:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
223:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
224:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
225:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
226:                                Write-Host $FlowControl -ForegroundColor Yellow  
227:                           } else {  
228:                                Write-Host "Failed" -ForegroundColor Red  
229:                           }  
230:                      }  
231:                      "Tx Enabled" {  
232:                           $AdapterPropertyValue = 1  
233:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
234:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
235:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
236:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
237:                                Write-Host $FlowControl -ForegroundColor Yellow  
238:                           } else {  
239:                                Write-Host "Failed" -ForegroundColor Red  
240:                           }  
241:                      }  
242:                      "Rx Enabled" {  
243:                           $AdapterPropertyValue = 2  
244:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
245:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
246:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
247:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
248:                                Write-Host $FlowControl -ForegroundColor Yellow  
249:                           } else {  
250:                                Write-Host "Failed" -ForegroundColor Red  
251:                           }  
252:                      }  
253:                      "Rx & Tx Enabled" {  
254:                           $AdapterPropertyValue = 3  
255:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
256:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
257:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
258:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
259:                                Write-Host $FlowControl -ForegroundColor Yellow  
260:                           } else {  
261:                                Write-Host "Failed" -ForegroundColor Red  
262:                           }  
263:                      }  
264:                 }  
265:            }  
266:            #Jumbo Packet  
267:            If ($JumboPacket -ne "") {  
268:                 $AdaptorProperty = '*JumboPacket'  
269:                 Write-Host "Jumbo Packet....." -NoNewline  
270:                 switch ($JumboPacket) {  
271:                      "Disabled" {  
272:                           $AdapterPropertyValue = 1514  
273:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
274:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
275:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
276:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
277:                                Write-Host $JumboPacket -ForegroundColor Yellow  
278:                           } else {  
279:                                Write-Host "Failed" -ForegroundColor Red  
280:                           }  
281:                      }  
282:                      "4088 Bytes" {  
283:                           $AdapterPropertyValue = 4088  
284:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
285:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
286:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
287:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
288:                                Write-Host $JumboPacket -ForegroundColor Yellow  
289:                           } else {  
290:                                Write-Host "Failed" -ForegroundColor Red  
291:                           }  
292:                      }  
293:                      "9014 Bytes" {  
294:                           $AdapterPropertyValue = 9014  
295:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
296:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
297:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
298:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
299:                                Write-Host $JumboPacket -ForegroundColor Yellow  
300:                           } else {  
301:                                Write-Host "Failed" -ForegroundColor Red  
302:                           }  
303:                      }  
304:                 }  
305:            }  
306:            #Legacy Switch Compatibility Mode  
307:            If ($LegacySwitchCompatibilityMode -ne "") {  
308:                 $AdaptorProperty = 'LinkNegotiationProcess'  
309:                 Write-Host "Legacy Switch Compatibility Mode....." -NoNewline  
310:                 If ($LegacySwitchCompatibilityMode -eq "Disabled") {  
311:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
312:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 1  
313:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
314:                      If ($Value.$AdaptorProperty -eq 1) {  
315:                           Write-Host $LegacySwitchCompatibilityMode -ForegroundColor Yellow  
316:                      } else {  
317:                           Write-Host "Failed" -ForegroundColor Red  
318:                      }  
319:                 } else {  
320:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
321:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 2  
322:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
323:                      If ($Value.$AdaptorProperty -eq 2) {  
324:                           Write-Host $LegacySwitchCompatibilityMode -ForegroundColor Yellow  
325:                      } else {  
326:                           Write-Host "Failed" -ForegroundColor Red  
327:                      }  
328:                 }  
329:            }  
330:            #Link Speed Battery Saver  
331:            If ($LinkSpeedBatterySaver -ne "") {  
332:                 $Platform = Get-Platform  
333:                 If ($Platform -eq "Laptop") {  
334:                      $AdaptorProperty = 'AutoPowerSaveModeEnabled'  
335:                      Write-Host "Link Speed Battery Saver....." -NoNewline  
336:                      If ($LinkSpeedBatterySaver -eq "Disabled") {  
337:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
338:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0  
339:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
340:                           If ($Value.$AdaptorProperty -eq 0) {  
341:                                Write-Host $LinkSpeedBatterySaver -ForegroundColor Yellow  
342:                           } else {  
343:                                Write-Host "Failed" -ForegroundColor Red  
344:                           }  
345:                      } else {  
346:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
347:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 1  
348:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
349:                           If ($Value.$AdaptorProperty -eq 1) {  
350:                                Write-Host $LinkSpeedBatterySaver -ForegroundColor Yellow  
351:                           } else {  
352:                                Write-Host "Failed" -ForegroundColor Red  
353:                           }  
354:                      }  
355:                 }  
356:            }  
357:            #Priority VLAN  
358:            If ($PriorityVLAN -ne "") {  
359:                 $AdaptorProperty = '*PriorityVLANTag'  
360:                 Write-Host "Priority VLAN....." -NoNewline  
361:                 switch ($PriorityVLAN) {  
362:                      "Priority & VLAN Disabled" {  
363:                           $AdapterPropertyValue = 0  
364:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
365:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
366:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
367:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
368:                                Write-Host $PriorityVLAN -ForegroundColor Yellow  
369:                           } else {  
370:                                Write-Host "Failed" -ForegroundColor Red  
371:                           }  
372:                      }  
373:                      "Priority Enabled" {  
374:                           $AdapterPropertyValue = 1  
375:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
376:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
377:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
378:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
379:                                Write-Host $PriorityVLAN -ForegroundColor Yellow  
380:                           } else {  
381:                                Write-Host "Failed" -ForegroundColor Red  
382:                           }  
383:                      }  
384:                      "VLAN Enabled" {  
385:                           $AdapterPropertyValue = 2  
386:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
387:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
388:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
389:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
390:                                Write-Host $PriorityVLAN -ForegroundColor Yellow  
391:                           } else {  
392:                                Write-Host "Failed" -ForegroundColor Red  
393:                           }  
394:                      }  
395:                      "Priority & VLAN Enabled" {  
396:                           $AdapterPropertyValue = 3  
397:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
398:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
399:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
400:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
401:                                Write-Host $PriorityVLAN -ForegroundColor Yellow  
402:                           } else {  
403:                                Write-Host "Failed" -ForegroundColor Red  
404:                           }  
405:                      }  
406:                 }  
407:            }  
408:            #Protocol ARP Offload  
409:            If ($ProtocolARPOffload -ne "") {  
410:                 $AdaptorProperty = '*PMARPOffload'  
411:                 Write-Host "Protocol ARP Offload....." -NoNewline  
412:                 If ($ProtocolARPOffload -eq "Disabled") {  
413:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
414:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000001  
415:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
416:                      If ($Value.$AdaptorProperty -eq 0x00000001) {  
417:                           Write-Host $ProtocolARPOffload -ForegroundColor Yellow  
418:                      } else {  
419:                           Write-Host "Failed" -ForegroundColor Red  
420:                      }  
421:                 } else {  
422:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
423:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000000  
424:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
425:                      If ($Value.$AdaptorProperty -eq 0x00000000) {  
426:                           Write-Host $ProtocolARPOffload -ForegroundColor Yellow  
427:                      } else {  
428:                           Write-Host "Failed" -ForegroundColor Red  
429:                      }  
430:                 }  
431:            }  
432:            #Protocol NS Offload  
433:            If ($ProtocolNSOffload -ne "") {  
434:                 $AdaptorProperty = '*PMNSOffload'  
435:                 Write-Host "Protocol NS Offload....." -NoNewline  
436:                 If ($ProtocolNSOffload -eq "Disabled") {  
437:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
438:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000001  
439:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
440:                      If ($Value.$AdaptorProperty -eq 0x00000001) {  
441:                           Write-Host $ProtocolNSOffload -ForegroundColor Yellow  
442:                      } else {  
443:                           Write-Host "Failed" -ForegroundColor Red  
444:                      }  
445:                 } else {  
446:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
447:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000000  
448:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
449:                      If ($Value.$AdaptorProperty -eq 0x00000000) {  
450:                           Write-Host $ProtocolNSOffload -ForegroundColor Yellow  
451:                      } else {  
452:                           Write-Host "Failed" -ForegroundColor Red  
453:                      }  
454:                 }  
455:            }  
456:            #Speed Duplex  
457:            if ($SpeedDuplex -ne "") {  
458:                 $AdaptorProperty = '*SpeedDuplex'  
459:                 $AdapterProperties.$AdaptorProperty = $SpeedDuplex  
460:            }  
461:            If ($SpeedDuplex -ne "") {  
462:                 $AdaptorProperty = '*SpeedDuplex'  
463:                 Write-Host "Speed Duplex....." -NoNewline  
464:                 switch ($SpeedDuplex) {  
465:                      "Auto Negotiation" {  
466:                           $AdapterPropertyValue = 0  
467:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
468:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
469:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
470:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
471:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
472:                           } else {  
473:                                Write-Host "Failed" -ForegroundColor Red  
474:                           }  
475:                      }  
476:                      "10 Mbps Half Duplex" {  
477:                           $AdapterPropertyValue = 1  
478:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
479:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
480:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
481:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
482:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
483:                           } else {  
484:                                Write-Host "Failed" -ForegroundColor Red  
485:                           }  
486:                      }  
487:                      "10 Mbps Full Duplex" {  
488:                           $AdapterPropertyValue = 2  
489:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
490:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
491:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
492:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
493:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
494:                           } else {  
495:                                Write-Host "Failed" -ForegroundColor Red  
496:                           }  
497:                      }  
498:                      "100 Mbps Half Duplex" {  
499:                           $AdapterPropertyValue = 3  
500:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
501:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
502:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
503:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
504:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
505:                           } else {  
506:                                Write-Host "Failed" -ForegroundColor Red  
507:                           }  
508:                      }  
509:                      "100 Mbps Full Duplex" {  
510:                           $AdapterPropertyValue = 4  
511:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
512:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
513:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
514:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
515:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
516:                           } else {  
517:                                Write-Host "Failed" -ForegroundColor Red  
518:                           }  
519:                      }  
520:                      "1.0 Gbps Full Duplex" {  
521:                           $AdapterPropertyValue = 6  
522:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
523:                           Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value $AdapterPropertyValue  
524:                           $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
525:                           If ($Value.$AdaptorProperty -eq $AdapterPropertyValue) {  
526:                                Write-Host $SpeedDuplex -ForegroundColor Yellow  
527:                           } else {  
528:                                Write-Host "Failed" -ForegroundColor Red  
529:                           }  
530:                      }  
531:                 }  
532:            }  
533:            #System Idle Power Saver  
534:            If ($SystemIdlePowerSaver -ne "") {  
535:                 $AdaptorProperty = 'SipsEnabled'  
536:                 Write-Host "System Idle Power Saver....." -NoNewline  
537:                 If ($SystemIdlePowerSaver -eq "Enabled") {  
538:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
539:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 1  
540:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
541:                      If ($Value.$AdaptorProperty -eq 1) {  
542:                           Write-Host $SystemIdlePowerSaver -ForegroundColor Yellow  
543:                      } else {  
544:                           Write-Host "Failed" -ForegroundColor Red  
545:                      }  
546:                 } else {  
547:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
548:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0  
549:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
550:                      If ($Value.$AdaptorProperty -eq 0) {  
551:                           Write-Host $SystemIdlePowerSaver -ForegroundColor Yellow  
552:                      } else {  
553:                           Write-Host "Failed" -ForegroundColor Red  
554:                      }  
555:                 }  
556:            }  
557:            #Wake On Magic Packet  
558:            If ($WakeOnMagicPacket -ne "") {  
559:                 $AdaptorProperty = '*WakeOnMagicPacket'  
560:                 Write-Host "Wake On Magic Packet....." -NoNewline  
561:                 If ($WakeOnMagicPacket -eq "Disabled") {  
562:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
563:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000001  
564:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
565:                      If ($Value.$AdaptorProperty -eq 0x00000001) {  
566:                           Write-Host $WakeOnMagicPacket -ForegroundColor Yellow  
567:                      } else {  
568:                           Write-Host "Failed" -ForegroundColor Red  
569:                      }  
570:                 } else {  
571:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
572:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000000  
573:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
574:                      If ($Value.$AdaptorProperty -eq 0x00000000) {  
575:                           Write-Host $WakeOnMagicPacket -ForegroundColor Yellow  
576:                      } else {  
577:                           Write-Host "Failed" -ForegroundColor Red  
578:                      }  
579:                 }  
580:            }  
581:            #Wake On Pattern Match  
582:            If ($WakeOnPatternMatch -ne "") {  
583:                 $AdaptorProperty = '*WakeOnPattern'  
584:                 Write-Host "Wake On Pattern Match....." -NoNewline  
585:                 If ($WakeOnPatternMatch -eq "Disabled") {  
586:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
587:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000001  
588:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
589:                      If ($Value.$AdaptorProperty -eq 0x00000001) {  
590:                           Write-Host $WakeOnPatternMatch -ForegroundColor Yellow  
591:                      } else {  
592:                           Write-Host "Failed" -ForegroundColor Red  
593:                      }  
594:                 } else {  
595:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
596:                      Set-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty -Value 0x00000000  
597:                      $Value = Get-ItemProperty -Path $NetworkAdapterSubKey -Name $AdaptorProperty  
598:                      If ($Value.$AdaptorProperty -eq 0x00000000) {  
599:                           Write-Host $WakeOnPatternMatch -ForegroundColor Yellow  
600:                      } else {  
601:                           Write-Host "Failed" -ForegroundColor Red  
602:                      }  
603:                 }  
604:            }  
605:       }  
606:  }  
607:    
608:  function Set-ConsoleTitle {  
609:  <#  
610:       .SYNOPSIS  
611:            Console Title  
612:         
613:       .DESCRIPTION  
614:            Sets the title of the PowerShell Console  
615:         
616:       .PARAMETER ConsoleTitle  
617:            Title of the PowerShell Console  
618:         
619:       .NOTES  
620:            Additional information about the function.  
621:  #>  
622:         
623:       [CmdletBinding()]  
624:       param  
625:       (  
626:                 [Parameter(Mandatory = $true)][String]$ConsoleTitle  
627:       )  
628:         
629:       $host.ui.RawUI.WindowTitle = $ConsoleTitle  
630:  }  
631:    
632:  Clear-Host  
633:  Set-ConsoleTitle $ConsoleTitle  
634:  $NICs = Get-PhysicalNICs  
635:  Set-NICRegistryKey -NetworkAdapters $NICs  
636:    

20 April 2016

NIC Power Management Properties

Posted By: Mick Pletcher - 12:36 PM












I wrote and published a script that enabled wake on lan two years ago. Since then, I have needed to write new scripts to modify the advanced tab of the NIC properties. I began by looking at my old script to see about adding the new settings to it and I decided to update the old one and republish it here. Thanks to Sapien Technology's PowerShell Studio, I have updated the script with much documentation.

This script will check or uncheck the three boxes in the screenshot below:


To use the script, I have set four parameters which I have set defaults to, which you can easily change:

  • ConsoleTitle - Title displayed in the PowerShell Console
  • TurnOffDeviceAllow the computer to turn off this device to save power. Select true to check this or false to uncheck it
  • WakeComputer - Allow this device to wake the computer. Select true to check this or false to uncheck it
  • AllowMagicPacketsOnly - Only allow a magic packet to wake the computer. Select true to check this or false to uncheck it
You can download the script from here.

Here is the script:


1:  <#  
2:       .SYNOPSIS  
3:            NIC Power Management  
4:         
5:       .DESCRIPTION  
6:            Configure NIC Power Management settings  
7:         
8:       .PARAMETER ConsoleTitle  
9:            Title displayed in the PowerShell Console  
10:         
11:       .PARAMETER TurnOffDevice  
12:            Allow the computer to turn off this device to save power. Select true to check this or false to uncheck it.  
13:         
14:       .PARAMETER WakeComputer  
15:            Allow this device to wake the computer. Select true to check this or false to uncheck it.  
16:         
17:       .PARAMETER AllowMagicPacketsOnly  
18:            Only allow a magic packet to wake the computer. Select true to check this or false to uncheck it.  
19:         
20:       .EXAMPLE  
21:            powershell.exe -executionpolicy bypass -file NICPowerManagement.ps1 -ConsoleTitle "NIC Power Management" -TurnOffDevice $true -WakeComputer $true -AllowMagicPacketsOnly $true  
22:         
23:       .NOTES  
24:            ===========================================================================  
25:            Created with:      SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.119  
26:            Created on:       4/20/2016 11:20 AM  
27:            Created by:       Mick Pletcher  
28:            Organization:  
29:            Filename:        NICPowerManagement.ps1  
30:            ===========================================================================  
31:  #>  
32:  [CmdletBinding()]  
33:  param  
34:  (  
35:            [Parameter(Mandatory = $false)][string]$ConsoleTitle = 'NIC Power Management',  
36:            [bool]$TurnOffDevice = $true,  
37:            [bool]$WakeComputer = $true,  
38:            [bool]$AllowMagicPacketsOnly = $true  
39:  )  
40:    
41:  function Exit-PowerShell {  
42:  <#  
43:       .SYNOPSIS  
44:            Exit PowerShell  
45:         
46:       .DESCRIPTION  
47:            Exit out of the PowerShell script and return an error code 1 if errors were encountered  
48:         
49:       .PARAMETER Errors  
50:            True or false if errors were encountered  
51:         
52:       .NOTES  
53:            Additional information about the function.  
54:  #>  
55:         
56:       [CmdletBinding()]  
57:       param  
58:       (  
59:                 [bool]$Errors  
60:       )  
61:         
62:       If ($Errors -eq $true) {  
63:            Exit 1  
64:       }  
65:  }  
66:    
67:  function Get-RelativePath {  
68:  <#  
69:       .SYNOPSIS  
70:            Get the relative path  
71:         
72:       .DESCRIPTION  
73:            Returns the location of the currently running PowerShell script  
74:         
75:       .NOTES  
76:            Additional information about the function.  
77:  #>  
78:         
79:       [CmdletBinding()][OutputType([string])]  
80:       param ()  
81:         
82:       $Path = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
83:       Return $Path  
84:  }  
85:    
86:  function Get-PhysicalNICs {  
87:  <#  
88:       .SYNOPSIS  
89:            Retrieve the Physical NICs  
90:         
91:       .DESCRIPTION  
92:            Find the physical NICs that are currently being used and return the information from the function  
93:         
94:       .EXAMPLE  
95:            PS C:\> Get-PhysicalNICs  
96:         
97:       .NOTES  
98:            Additional information about the function.  
99:  #>  
100:         
101:       [CmdletBinding()]  
102:       param ()  
103:         
104:       # Get all physical ethernet adaptors  
105:       $NICs = Get-WmiObject Win32_NetworkAdapter -filter "AdapterTypeID = '0' `  
106:       AND PhysicalAdapter = 'true' `  
107:       AND NOT Description LIKE '%Centrino%' `  
108:       AND NOT Description LIKE '%wireless%' `  
109:       AND NOT Description LIKE '%virtual%' `  
110:       AND NOT Description LIKE '%WiFi%' `  
111:       AND NOT Description LIKE '%Bluetooth%'"  
112:       Return $NICs  
113:  }  
114:    
115:  function Set-ConsoleTitle {  
116:  <#  
117:       .SYNOPSIS  
118:            Console Title  
119:         
120:       .DESCRIPTION  
121:            Sets the title of the PowerShell Console  
122:         
123:       .NOTES  
124:            Additional information about the function.  
125:  #>  
126:         
127:       [CmdletBinding()]  
128:       param ()  
129:         
130:       $host.ui.RawUI.WindowTitle = $ConsoleTitle  
131:  }  
132:    
133:  function Set-NICPowerManagement {  
134:  <#  
135:       .SYNOPSIS  
136:            Enable NIC Power Management  
137:         
138:       .DESCRIPTION  
139:            A detailed description of the Set-NICPowerManagement function.  
140:         
141:       .PARAMETER NICs  
142:            Physical NICs  
143:         
144:       .NOTES  
145:            Additional information about the function.  
146:  #>  
147:         
148:       [CmdletBinding()][OutputType([bool])]  
149:       param  
150:       (  
151:                 $NICs  
152:       )  
153:         
154:       foreach ($NIC in $NICs) {  
155:            $Errors = $false  
156:            Write-Host "NIC:"$NIC.Name  
157:            #Allow the computer to turn off this device  
158:            Write-Host "Allow the computer to turn off this device....." -NoNewline  
159:            $NICPowerManage = Get-WmiObject MSPower_DeviceEnable -Namespace root\wmi | Where-Object { $_.instancename -match [regex]::escape($nic.PNPDeviceID) }  
160:            If ($NICPowerManage.Enable -ne $TurnOffDevice) {  
161:                 $NICPowerManage.Enable = $TurnOffDevice  
162:                 $HideOutput = $NICPowerManage.psbase.Put()  
163:            }  
164:            If ($NICPowerManage.Enable -eq $TurnOffDevice) {  
165:                 Write-Host "Success" -ForegroundColor Yellow  
166:            } else {  
167:                 Write-Host "Failed" -ForegroundColor Red  
168:                 $Errors = $true  
169:            }  
170:            # Allow this device to wake the computer  
171:            Write-Host "Allow this device to wake the computer....." -NoNewline  
172:            $NICPowerManage = Get-WmiObject MSPower_DeviceWakeEnable -Namespace root\wmi | Where-Object { $_.instancename -match [regex]::escape($nic.PNPDeviceID) }  
173:            If ($NICPowerManage.Enable -ne $WakeComputer) {  
174:                 $NICPowerManage.Enable = $WakeComputer  
175:                 $HideOutput = $NICPowerManage.psbase.Put()  
176:            }  
177:            If ($NICPowerManage.Enable -eq $WakeComputer) {  
178:                 Write-Host "Success" -ForegroundColor Yellow  
179:            } else {  
180:                 Write-Host "Failed" -ForegroundColor Red  
181:                 $Errors = $true  
182:            }  
183:            # Only allow a magic packet to wake the computer  
184:            Write-Host "Only allow a magic packet to wake the computer....." -NoNewline  
185:            $NICPowerManage = Get-WmiObject MSNdis_DeviceWakeOnMagicPacketOnly -Namespace root\wmi | Where-Object { $_.instancename -match [regex]::escape($nic.PNPDeviceID) }  
186:            If ($NICPowerManage.EnableWakeOnMagicPacketOnly -ne $AllowMagicPacketsOnly) {  
187:                 $NICPowerManage.EnableWakeOnMagicPacketOnly = $AllowMagicPacketsOnly  
188:                 $HideOutput = $NICPowerManage.psbase.Put()  
189:            }  
190:            If ($NICPowerManage.EnableWakeOnMagicPacketOnly -eq $AllowMagicPacketsOnly) {  
191:                 Write-Host "Success" -ForegroundColor Yellow  
192:            } else {  
193:                 Write-Host "Failed" -ForegroundColor Red  
194:                 $Errors = $true  
195:            }  
196:       }  
197:       Return $Errors  
198:  }  
199:    
200:  Clear-Host  
201:  Set-ConsoleTitle  
202:  $PhysicalNICs = Get-PhysicalNICs  
203:  $Errors = Set-NICPowerManagement -NICs $PhysicalNICs  
204:  Start-Sleep -Seconds 5  
205:  Exit-PowerShell -Errors $Errors  
206:    

18 April 2016

Apple QuickTime Uninstaller

Posted By: Mick Pletcher - 2:55 PM










As we have all seen recently, it is time we get rid of Apple QuickTime from PCs as they are no longer going to update the software. I had a few ask me to publish a blanket uninstaller for QuickTime. With the help of Sapien's PowerShell Studio, I wrote this script to uninstall it from all of the machines in my firm. This uninstaller will query the Add/Remove programs for any applications named quicktime. It will uninstall any version of QuickTime. I have pre-configured the script parameters to search for apps name 'QuickTime' and use the msi switches '/qb- /norestart'.

You can download the script from here.


1:  <#  
2:       .SYNOPSIS  
3:            Apple Quicktime  
4:         
5:       .DESCRIPTION  
6:            Uninstall Apple Quicktime  
7:         
8:       .PARAMETER ApplicationName  
9:            A description of the ApplicationName parameter.  
10:         
11:       .PARAMETER WindowTitle  
12:            Title of the PowerShell window  
13:         
14:       .PARAMETER MSI_Switches  
15:            The switches used when executing the uninstallation of the MSI  
16:         
17:       .EXAMPLE  
18:            powershell.exe -executionpolicy bypass -file uninstall.ps1  
19:         
20:       .NOTES  
21:            ===========================================================================  
22:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.119  
23:            Created on:       4/18/2016 1:44 PM  
24:            Created by:       Mick Pletcher  
25:            Organization:  
26:            Filename:         UninstallQuicktime.ps1  
27:            ===========================================================================  
28:  #>  
29:  param  
30:  (  
31:            [string]$ApplicationName = 'quicktime',  
32:            [string]$WindowTitle = 'Uninstall Apple Quicktime',  
33:            [string]$MSI_Switches = '/qb- /norestart'  
34:  )  
35:    
36:  function Set-ConsoleTitle {  
37:  <#  
38:       .SYNOPSIS  
39:            Console Title  
40:         
41:       .DESCRIPTION  
42:            Sets the title of the PowerShell Console  
43:         
44:       .PARAMETER Title  
45:            Title of the PowerShell console  
46:         
47:       .NOTES  
48:            Additional information about the function.  
49:  #>  
50:         
51:       [CmdletBinding()]  
52:       param  
53:       (  
54:                 [Parameter(Mandatory = $true)][String]$Title  
55:       )  
56:         
57:       $host.ui.RawUI.WindowTitle = $Title  
58:  }  
59:    
60:    
61:  Function InitializeVariables {  
62:       $Global:BuildLog = $Env:windir + "\Waller\Logs\BuildLogs\Build.csv"  
63:       $Global:Errors = $null  
64:       $Global:LogFile = $Env:windir + "\Waller\Logs\BuildLogs\AppleQuicktime.log"  
65:       $Global:Phase = "Software Deployment"  
66:       $Global:RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
67:  }  
68:    
69:  function Uninstall-MSIByName {  
70:  <#  
71:       .SYNOPSIS  
72:            Uninstall-MSIByName  
73:         
74:       .DESCRIPTION  
75:            Uninstalls an application that was installed using the MSI installer. This function will query the 32-bit and 64-bit add/remove programs entries to match a what is defined in the ApplicationName parameter. You do not have to enter the entire name. This allows you to uninstall multiple versions of an application by entering just a portion of the name that is displayed amoung all versions.  
76:         
77:       .EXAMPLE  
78:            Uninstall-MSIByName "Adobe Reader" "/qb- /norestart"  
79:         
80:       .NOTES  
81:            Additional information about the function.  
82:  #>  
83:         
84:       [CmdletBinding()]  
85:       param ()  
86:         
87:       $Uninstall = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall -Recurse -ErrorAction SilentlyContinue  
88:       $Uninstall += Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall -Recurse -ErrorAction SilentlyContinue  
89:       $SearchName = "*" + $ApplicationName + "*"  
90:       $Executable = $Env:windir + "\system32\msiexec.exe"  
91:       Foreach ($Key in $Uninstall) {  
92:            $TempKey = $Key.Name -split "\\"  
93:            If ($TempKey[002] -eq "Microsoft") {  
94:                 $Key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $Key.PSChildName  
95:            } else {  
96:                 $Key = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" + $Key.PSChildName  
97:            }  
98:            If ((Test-Path $Key) -eq $true) {  
99:                 $KeyName = Get-ItemProperty -Path $Key  
100:                 If ($KeyName.DisplayName -like $SearchName) {  
101:                      $TempKey = $KeyName.UninstallString -split " "  
102:                      If ($TempKey[0] -eq "MsiExec.exe") {  
103:                           Write-Host "Uninstall"$KeyName.DisplayName"....." -NoNewline  
104:                           $Parameters = "/x " + $KeyName.PSChildName + [char]32 + $MSI_Switches  
105:                           $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Parameters -Wait -Passthru).ExitCode  
106:                           If (($ErrCode -eq 0) -or ($ErrCode -eq 3010) -or ($ErrCode -eq 1605)) {  
107:                                Write-Host "Success" -ForegroundColor Yellow  
108:                           } else {  
109:                                Write-Host "Failed with error code "$ErrCode -ForegroundColor Red  
110:                           }  
111:                      }  
112:                 }  
113:            }  
114:       }  
115:  }  
116:    
117:  Clear-Host  
118:  Set-ConsoleTitle -Title $WindowTitle  
119:  Uninstall-MSIByName  
120:  Exit-PowerShell  
121:    

Copyright © 2013 Mick's IT Blogs™ is a registered trademark.