Parameters and Intellisence

A colleague of mine sent me an email asking if I could explain what he sees in his console:

You might be interested in as well so here are the answers:

For the 1rst screenshot, it’s the Intellisense feature that proposes this list of values that the MemberType parameter accepts.
If you use the help either online or interactively, you can’t unfortunately find the answer.
As you can see the help on PowerShell 5.0 doesn’t really help.

I knew the answer and replied that property is actually an alias of the properties parametername.
Yes, parameters can have aliases 🙂
To uncover it, you should use the Get-Command cmdlet:

(gcm Get-ADUser | Select -Expand Parameters)['Properties']

And when I tested on PowerShell 5.1, it appears that the alias is displayed

First mistery solved 😀

Now the 2nd one. Why there’s a difference in the count?

Can you notice the addtional “Select * ” in the second command invocation ?

Well, using the Select-Object cmdlet changes an object, including its type, methods and properties.

To find out what are the exact differences, you can do

$User = 'A random UserName'
Compare-Object (Get-ADUser $User -Pro *| gm).Name -Diff (Get-ADUser $User -Pro *| select *| gm).Name

The native ADUser object has a Contains and GetEnumerator methods, a Item ParameterizedProperty whereas its “Selected” ADuser doesn’t…
2nd Mystery solved 😎

Speeding up the Windows 7 installation with slipstreaming

At work, one of our hardware supplier was supposed to ship the exact same model we bought last year but they actually delivered a serie of laptops with M2 SATA based SSD disk. What a surprise!

We discovered that our immutable architecture approach was broken by this internal recent hardware component. M2 SATA and NVMe didn’t exist when Windows 7 SP1 was released in 2009.
An engineer provided two links to the following knowledge base articles:

The first link is very interesting because it exposes a way to slipstream (you may remember the Update rollup 1 for Windows XP released in 2003) hotfixes directly into the Windows 7 ISO image.
Now that Windows 7 shifted to the same “servicing” model as Window 10 (see Simplified servicing for Windows 7 and Windows 8.1: the latest improvements), it’s also a huge opportunity to reduce the number of updates required for a vanilla Windows 7 SP1 ISO image.

First, please don’t strictly follow what’s written in KB2990941, you may have some difficulties to get the Windows 8.1 ADK that was relevant and current when they released this article in September 2015. This version of ADK isn’t strictly required. Your brave old Windows 7 WAIK can do all the steps.
I’ll show below the steps using a combination of The Windows® Automated Installation Kit (AIK) for Windows® 7 + The Windows® Automated Installation Kit (AIK) Supplement for Windows® 7 SP1.

There’s a 2nd reason why you should not strictly follow what’s written.
There are two errors in the various dism commands in step 9.
The compression mentioned in the notes can only work for an online image and cannot be used for an offline image which is what we work with in method 1.

Do you have the Windows 7 WAIK installed in its default location?

What do I need?

What’s next? What’s the plan?

  • We inject first the servicing stack from April 2015 that is a requirement for the convenience update
  • We inject the convenience update right after
  • Then we only inject the July 2016 rollup into the install.wim because it contains the latest version of the Window Update Agent (WUA)
  • We inject the two M2 hotfixes
  • Finally we inject the drivers

With the little script I provided, the steps are less cumbersome and error prone.
They look like this:

.\inject.bat 3020369
.\inject.bat 3125574

:: inject only July 2016 rollup (contains latest WUA) into install.wim and not boot.wim and winre.wim
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\install.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Package /PackagePath:c:\temp\hotfix\Windows6.1-KB3172605-x64.cab
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

.\inject.bat 2990941
.\inject.bat 3087873

:: add the drivers
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\boot.wim /Index:2 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\src\sources\install.wim /Index:1 /MountDir:c:\temp\mount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:C:\temp\mount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Mount-WIM /WimFile:c:\temp\mount\windows\system32\recovery\winre.wim /Index:1 /MountDir:c:\temp\winremount
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /Image:c:\temp\winremount /Add-Driver /Driver:c:\temp\drivers /Recurse
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"c:\temp\winremount" /Commit
"%_WAIKLOCATION%\Tools\Servicing\Dism.exe" /unmount-Wim /MountDir:"C:\temp\mount" /Commit

Conclusion

Congratulations, you’ve successfully slipsteamed updates into a Windows 7 image 😀

What’s else did you get?

Well, you’ve a larger image… that’s a fact and definitely a drawback.

You also have an image that requires less post-installation updates and that can immediately, rapidly and successfully scan for missing updates against Windows Update.
That makes two benefits

In my work environment, the above slipstreamed image allowed me to divide by at least 3 the time it takes to install from scratch a fully up-to-date Windows 7 box 😎

My immutable architecture approach is repaired and performs faster like it did in 2009 when Windows 7 SP1 was RTM.

ETW provider security – fix event id 30

In february 2016, Robin ten Berge posted the following on the PM.org mailing list



The whole thread is archived here

I’ve also encountered this behavior (2 events) after rebooting and having patched 2012 R2 Hyper-V servers.
The event logging service encountered an error (5) while enabling publisher {0bf2fb94-7b60-4b4d-9766-e82f658df540} to channel Microsoft-Windows-Kernel-ShimEngine/Operational. This does not affect channel operation, but does affect the ability of the publisher to raise events to the channel. One common reason for this error is that the Provider is using ETW Provider Security and has not granted enable permissions to the Event Log service identity.

I was also able to reproduce the error by just enabling and disabling the Microsoft-Windows-Kernel-ShimEngine/Operational log when the server is running 🙂

To fix it, my google fu found this http://www.geoffchappell.com/studies/windows/win32/services/scm/events/diagnostic.htm and I just added the LOCAL SERVICE as suggested.

Here are the steps I used to fix it:

  • Launch an elevated perfmon: C:\windows\system32\perfmon.exe
  • Expand ‘Data Collector Sets’
  • Expand ‘Event Trace Sessions’
  • Right-click ‘Eventlog-System’ running session and click ‘Properties’
  • In the ‘Trace providers’ list, scroll down to ‘Microsoft-Windows-Kernel-ShimEngine’ and select it.
  • Click on the ‘Security’ button next to it
  • Click ‘Add’, type ‘LOCAL SERVICE’, click ‘Check Names’ (adjust the location if required)
  • Untick all permissions and just leave TRACELOG_GUID_ENABLE
  • Just click “Apply” button in the ‘Security settings for this ETW trace provider’
  • You don’t need to click “Apply” or “Ok” button in the parent (Eventlog-System properties( window or you’ll get an ‘Access Denied’ (normal, you are not allowed to modify a running trace)

WSUS synchronization report

The other day I wondered how to get the equivalent of this WSUS synchronization summary and its details.
More precisely I wanted to get the summary of what you see in the mmc snap-in under the synchronizations node:
wsus-sync-01
and the details that you get when you right-click a synchronization and hit ‘Synchronization report’ but I got instead the following message telling me that the report viewer wasn’t installed
wsus-sync-02

After a few minutes, I found the following MSDN page about Reporting Newly Synchronized Updates
I first looked at the GetUpdates method that has many ways to call it.
wsus-sync-03
The msdn article proposes to use the 2nd one where you specify all the 5 arguments:

  • Microsoft.UpdateServices.Administration.ApprovedStates approvedStates,
  • datetime fromArrivalDate,
  • datetime toArrivalDate,
  • Microsoft.UpdateServices.Administration.UpdateCategoryCollection updateCategories,
  • Microsoft.UpdateServices.Administration.UpdateClassificationCollection updateClassifications

where both the updatecategories and updateclassifications are set to $null
I gave it a try but I couldn’t get reliable results 😦 even when the two collections (UpdateCategoryCollection and UpdateClassificationCollection) were properly defined and not set to null.
Forget that method, it’s too unpredictable.

I switched to the 3rd method where you just use a single updateScope object as argument instead of the above 5 arguments and finally got the expected reliability 😀

# Get the last sync info (start and end times)
$lastSync = (Get-WsusServer).GetSubscription().GetLastSynchronizationInfo()

# Create an updatescope object
$UpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope

# Set the start time
$UpdateScope.FromArrivalDate = $lastSync.StartTime
# Set the end time
$UpdateScope.ToArrivalDate = $lastSync.EndTime

# Invoke the getupdates method using the update scope object
$SyncUpdates = (Get-WsusServer).GetUpdates($UpdateScope)

Now to get the summary, I just do

$SyncUpdates | 
Group-Object -Property publicationstate -NoElement

wsus-sync-04
To view the details of what was synchronized I do:

$SyncUpdates | Out-GridView
# or 
$SyncUpdates | 
Select Title,SecurityBulletins,UpdateClassificationTitle,PublicationState | 
Sort PublicationState | 
Format-Table -AutoSize

wsus-sync-05

Easy-peasy and as always PowerShell rocks 😎

Get-GPPrefRegistryValue or Get-GPRegistryValue

Someone at work recently asked me to provide the list of (web) sites assigned to an IE zone, so that he could tell me what sites are obsolete and can be removed. Yeah, we need that because IE11 intranet automatic detection mechanism doesn’t work with an httpstunnel interface and an NRPT table for those who are familiar with Direct Access scenario.

I jumped on a PowerShell console and couldn’t immediately get the answer because I got confused by the Get-GPPrefRegistryValue cmdlet. I couldn’t easily get the answer because I actually used the wrong cmdlet (my bad) 😦
I should have used the Get-GPRegistryValue cmdlet instead 🙂 . Do you see the difference between the two cmdlets?

I could actually have had my answer in less than 2 seconds by doing:

Get-GPO -Name "myGPOName" | 
Get-GPRegistryValue -Key 'HKCU\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey' |
Select ValueName,Value

Instead, I went the hard way and did the following:

# 1. Export the GPO to an XML file
Get-GPO -Name "myGPOName" | 
Get-GPOReport -ReportType Xml -Path "C:\myGPOName.xml"

# 2. Read the XML file
(
 ([xml](Get-Content "C:\myGPOName.xml")).GPO.User.ExtensionData.Extension.Policy | 
 Where Name -eq 'Site to Zone Assignment List'
).ListBox.Value.Element

Even if you’re confused, PowerShell always provides many ways to skin the cat 😀

Add missing WinRMRemoteWMIUsers__ group in Active Directory

I’ve seen this morning a post in French about the WinRMRemoteWMIUsers__ group missing from Active Directory Domain Services. The post references the following kb3118385 page about Svchost.exe uses excessive CPU resources on a single-core Windows Server 2012 domain controller

The only missing part in the blog post is the properties of this group that I actually found on this technet page winrmremotewmiusers__

Of course, you can add the missing group like this

if (-not(Get-ADGroup -Filter { Name -eq 'WinRMRemoteWMIUsers__' })) {
 New-ADGroup -GroupScope DomainLocal -GroupCategory Security -Name 'WinRMRemoteWMIUsers__'
}

…but, it won’t have the well-known SID documented above.

And its Description is:

Members of this group can access WMI resources over management protocols (such as WS-Management via the Windows Remote Management service). This applies only to WMI namespaces that grant access to the user.

Stop telemetry

Some people noticed Windows 7 computers talking to some IP addresses on port TCP:80 since the November Quality Rollup while Woody Leonhard warned mid-October that there’ll be a new telemetry being pushed to downlevel OS like Windows 7 and 8.1 .

A few days before Christmas, abbodi86 provided a less aggressive way of stopping telemetry on a computer on the PM.org mailing list:
abbodii-telemetry-v2

Here’s how to do this on Windows 10 using PowerShell

At the end in the Perfmon snap-in you shouldn’t have any active event trace sessions (right-click refresh if necessary)
autologger-diagtrack-listener-tracesession
and the the Autologger session should be set to Disabled so that it doesn’t start at the next computer restart
autologger-diagtrack-listener-provider

On Windows 7, you cannot use PowerShell and here is the “legacy” way to achieve the same thing: