Monthly Archives: October 2014

Thoughts and ideas to manage Google Chrome for Work, and some Extensions too…

Recently I was asked to investigate how to manage Google Chrome for Work in a corporate environment. The customer involved is using Google Cloud Services intensively. This means that in order to receive an optimal user experience, the Google Chrome browser is needed. I decided to investigate and come up with some thoughts and ideas on how to do it.

Managing applications consists of two activities:

  • Deployment
  • Configuration

In an ideal scenario, those activities are completely separated. The result will be that the installation of the application can be done using the default settings while the configuration will be taken care of elsewhere. Fortunately, Google provides a few methods of configuring Google Chrome. The most well-known are:

  • Editing the master_preferences file
  • Using Group Policy

For the sake of this blog, the corporate environment consists of Windows 8.1 devices which are domain joined. This means we can consider using Group Policy. Using Group Policy will meet the initial goal of keeping deployment and configuration separate. I was able to use the following reference to see how to use Group Policy to manage Google Chrome:

As we can see, the policies are machine driven. This provides another challenge how Google Chrome for Work needs to be installed. Google has the following deployment guide to get started:

In this guide, I found the following passage critical for my investigation:

Chrome installations from an MSI package are installed at the system level and are available to all users. As a result, any user-level installation of Chrome, (i.e. a user’s own Chrome installation), will be overridden.

It looks like Google has revised the approach of installing Google Chrome quite dramatically since it was possible to install Chrome in the user context. This allowed end users to install Google Chrome without administrator privileges which can be considered a security officer’s true nightmare, not to mention the configuration management and release management processes in a corporate environment.

In order to investigate how to do it, I’ve set up a lab environment with the following machines:

  • 1 Windows Server 2012 R2 domain controller
  • 1 System Center 2012 R2 Configuration Manager site server
  • 1 Windows 8.1 x64 client

Knowing that Google Chrome will always be installed in the system context means we can make it part of an Operating System Deployment Task Sequence. But first an application needs to be made.

To create the application just import googlechromestandaloneenterprise.msi and create a standard Deployment Type, nothing fancy.


Really nothing fancy…

Adding this to a Task Sequence is nothing fancy either…

There you go. I created an MDT 2013 Task Sequence with an unattended Windows 8.1 x64 deployment since it’s not relevant to build a Windows 8.1 x64 image first.

Configuring Google Chrome is a bit more challenging. It really depends on requirements and processes to determine how Google Chrome for Work should be configured. This is what I did first:

  • Create a separate GPO for Google Chrome and link it to a OU where my client machine resides
  • Import the chrome.adm template

I’ve decided to configure just a few settings the GPO provides:

  • Setting Google Chrome as the default browser
  • Configure the start page

Configuring the Start Page requires 2 GPO settings




What about Extensions?

Admittingly, I find it great to manage Extensions by GPO. It does require some detective work before they can be automatically added to Google Chrome. Fortunately, nothing has to be downloaded in advance once you know the Extension ID. In my example I added a list of so called force-installed Extensions.

And here’s the list itself


Once the configuration is in place and the machine is deployed, the result will look this

Starting Google Chrome with my Start Pages

And the Extensions specified are also in place.


Finally, Google frequently updates Chrome. You can manage the update behavior by configuring Google Update by Group Policy, the following website can be used as a reference:

This requires to import the GoogleUpdate.adm template to configure the update behavior.

In this investigation, I configured the following update settings:

  • Automatically check for updates every 60 minutes
  • Enable auto updating of Google Chrome


Here are the GPO’s needed to configure it.


and finally


Updating Google Chrome for Work works great, if you’re an administrator. Unfortunately, when a user accessed the ‘About’ tab in Chrome it will trigger an update check. For a standard user this will immediately trigger User Account Control asking for credentials for elevation in Windows Vista or newer. Because Google Chrome is installed in the system context (installed in the %PROGRAMFILES% directory), administrator rights are required to make changes to the computer initiated by a user. This behavior is by design.

Especially in Windows 8.1, it is absolutely not recommended to turn off UAC since it will break a lot of functionality of Windows itself. Giving users administrator privileges should not be recommended either. To maintain a strict configuration management and release management process, it’s recommended to disable updates to prevent users who do have administrator privileges install updates by themselves.

This means a different method needs to be used to deploy an updated version of Google Chrome for Work. To me, the Application model of Configuration Manager is the most suitable environment since it allows to supersede applications. This also means the Task Sequence may be edited frequently as well. Alternatively, a 3rd party update tool such as Secunia can be used as well if the organization has a license for that.

I can conclude that Google has done the right thing to have Google Chrome for Work installed in the system context and manage it by using Group Policy.





ConfigMgr 2012 R2: a script to create bulk User collections and a nice counterpart…

Recently in one of my projects I was asked to prepare the newly built System Center 2012 R2 Configuration Manager environment to facilitate application deployment for around 400 applications. Even though the applications were not available at the time, the customer requested to have User Collections in place to facilitate automatic deployment and removal once the applications are available.

Together with the customer I suggested to use the following approach:

  • Create User Collections which will target users based on Active Directory Security Group Membership, the User Collection will have the same name as the AD Security Group Name (ie. “APP-Adobe-Reader”)
  • Create User Collections which will target all users except the ones who are member of the corresponding AD Security Group. This User Collection has an “Uninstall ” prefix followed by the AD Security Group Name (ie. “Uninstall APP-Adobe-Reader)

This approach allows the Application Model available in Configuration Manager to be fully utilized. If a user is a member of the group then he or she receives the application. If a user is not a member (anymore), then the application will be uninstalled. This means the User Collection with the AD Security Name will have a required Install deployment targeted (based on company policy) while the other one will have a required Uninstall deployment targeted.

Basically, managing group membership in Active Directory is all you need to have the applications installed or removed. This is particularly useful when users lose the right to use an application and it will also remove unauthorized install by users as well (assuming the Application is the same (ie. by Product Code)).

Since the groups were already created I received a .csv file to use as my input to create the collections. It makes perfect sense that it is no fun whatsoever when this must be done manually so it would be nice if this can be automated. Fortunately we have PowerShell.

NOTE: This script should work in Configuration Manager 2012 SP1 as well, although I haven’t tested in an SP1 environment.

So, here’s the script I created to do the job:


# Script name: Create_User_Collections.ps1


# Purpose: Creates User Collections based on AD Group Name, uses .csv

# as input


# Author: Marc Westerink


# Reference:






#Create the required ‘global’ variables

$ConfigMgrModulePath=“D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1”


#Connecting to site

Import-Module $ConfigMgrModulePath

Set-Location $ConfigMgrSiteCode

#Creating the User Collections

 Import-CSV E:\Install\CMName.csv | %{

#Create the required ‘local’ variables

$AllUsers=“All Users”




$UCUninstallName=“Uninstall “+$_.CMName

$QueryExpression=‘”select SMS_R_USER.ResourceID,SMS_R_USER.ResourceType,SMS_R_USER.Name,SMS_R_USER.UniqueUserName,SMS_R_USER.WindowsNTDomain from SMS_R_User where SMS_R_User.SecurityGroupName=’

#Create the User Collection with a query rule

New-CMUserCollection -LimitingCollectionName $AllUsers -Name $_.CMName -RefreshType $RefreshType

Add-CMUserCollectionQueryMembershipRule -CollectionName $_.CMName -RuleName $_.CMName -QueryExpression $QueryExpression$UCInstallName

#Create the ‘uninstall’ User Collection with 2 rules: include All Users and exclude the User Collection

New-CMUserCollection -LimitingCollectionName $AllUsers -Name $UCUninstallName -RefreshType $RefreshType

Add-CMUserCollectionIncludeMembershipRule -CollectionName $UCUninstallName -IncludeCollectionName $AllUsers

Add-CMUserCollectionExcludeMembershipRule -CollectionName $UCUninstallName -ExcludeCollectionName $_.CMName


A few things were a bit tricky to get it working. So I worked on this script together with one of my ‘partners in crime’ Robin Verbeek. Robin has his own blog at

Creating a ConfigMgr Collection Query rule is tricky because it contains quite some quotes and two backslash characters. They have a special meaning in PowerShell so a few more must be used to get the correct query expression. I used two variables and stuck them together to get the correct expression

The RefreshType parameter is configure to use incremental updates. This may cause issues when lots of collections are used (explained at Robin suggested the populate the variable to be like this: $RefreshType=“Periodic” He added an additional parameter named RefreshSchedule needed to enable scheduling a full update: $RefreshSchedule=New-CMSchedule -RecurInterval Days -RecurCount 7

I decided to place the required ‘local’ variables in the loop to make sure they’re used where needed

Running this script took around 30 minutes to have 400 User Collections created (and their 400 counterparts). While this may be not really fast I think it’s still considerably faster than creating 800 User Collections Manager manually (and less error prone).

It is possible to replace the .csv import by reading Active Directory but you’re on your own there, I believe lots of people already created something like that.

As usual, please test this before running this in a production environment…


Thoughts on creating PowerShell scripts to automate tasks in Configuration Manager 2012 SP1/R2

More and more I start to appreciate PowerShell instead of the Console, a lot of blog posts are available as well to automate even repetitive tasks. Examples of these repetitive tasks may be:

  • (bulk) import of applications
  • Adding (or removing) a large amount of distribution point

Most of the time, these scripts are the ones I can use by myself for future projects, share with coworkers or peers, or even provide them to my customers so their lives can be easier too. One of the great benefits of these scripts is removing the human element or administrations since humans are not flawless.

Sharing these scripts made me think of something. What I consider most important is keeping your scripts clean but also readable. With this approach I decided to investigate some time in writing them in a certain way so that they’re understandable and reusable.

Looking at the Cmdlet reference for Configuration Manager, available at , we can see that a lot of PowerShell cmdlets are available. These cmdlets are built up in such a way that they more or less follow the steps you would do in a wizard when using the console. I consider these cmdlets very straightforward as well. Most of the parameters require either a string or a Boolean in order to run the cmdlet successfully.

To clarify this, let’s have a look at one of these cmdlets. I chose the cmdlet Add-CMManagementPoint. The reference documentation is available at

To keep things simple, the purpose is to add a management point which uses the site database and HTTP as communication. For our convenience we use the site server’s computer account to install the role. When looking at the reference the cmdlet we need to use the following syntax:

Add-CMManagementPoint -SiteCode <String> -SiteSystemServerName <String> [-GenerateAlert] [-UserName <String> ] [-Confirm] [-WhatIf] [ <CommonParameters>]

Looking at the syntax we can determine that the parameters SiteCode and SiteSystemServerName require strings with the information required to run it successfully. The most common scenario would most likely be that this cmdlet is used in a script. You can use variables to keep the script code clean. So why not using variable names that match the parameter? This would allow you to keep the code clean, but also know to which parameter the variable belongs to.

When I found out what to fill in for each parameter and knowing how to name each variable (and populate it with data), I came up with a script that looks like this:


# Script name: Add_MP.ps1                                                 #

# Purpose: Installs the Management Point role on a single site system     #

#                                                                         #
# Author: Marc Westerink                                                  #

#                                                                         #

# Reference:  #

#                                                                         #


#Create the required ‘global’ variables

$ConfigMgrModulePath=“D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1”


#Create the requied ‘local’ variables



#Connecting to site

Import-Module $ConfigMgrModulePath

cd $ConfigMgrSiteCode

#Adding the Management Point

Add-CMManagementPoint -SiteCode $SiteCode -SiteSystemServerName $SiteSystemServerName


As you can see, I need to create variables. Two types of variables are defined (at least that how I name them):

  • Global variables: these are valid anywhere in the script. In this example, I need the location for the PowerShell module and the site code to browse to
  • Local variables: these are used for the specific purpose. They can defined in the script or they can be imported from a file

To me, this makes the script pretty readable, reusable and clean.

Hope this helps, feel free to come with suggestions you’d like to share.



Steve Thompson [MVP]

The automation specialist

Boudewijn Plomp

Cloud and related stuff...

Anything about IT

by Alex Verboon

Deployment Made Simple

Modern Workplace

Azure, Hybrid Identity & Enterprise Mobility + Security

Daan Weda

This site is all about System Center and PowerShell

IT And Management by Abheek

Microsoft certified Trainer -Abheek

Heading To The Clouds

by Marthijn van Rheenen