powershell vs GPO for installation, configuration, maintenance

My question is about using powershell scripts to install, configure, update and maintain Windows 7 Pro/Ent workstations in a 2008R2 domain, versus using GPO/ADMX/msi.

Here's the situation:

Because of a comedy of cumulative corporate bumpfuggery we suddenly found ourselves having to design, configure and deploy a full Windows Server 2008R2 and Windows 7 Pro/Enterprise on very short notice and delivery schedule. Of course, I'm not a windows expert by any means, and we're so understaffed that our buzzword bingo includes 'automate' and 'one-button' and 'it needs to Just Work'. (FWIW, I started with DEC, then on to solaris and cisco, then linux of various flavors with a smattering of BSD nowadays. I use Windows for email and to fill out forms).

So we decided to bring in a contractor to do this for us. and they met the deadline. The system is up and mostly usable, and this is good. We would not have been able to do this. But it's the 'mostly' part that is proving to be the PIMA now, and I'm having to learn Microsoft stuff anyway until/if we can get a new contract with these guys for ongoing operations.

Here's my question. The contractor used powershell almost exclusively for deployment, configuration and updating. My intensive reading over the last week leads me to think that the generally accepted practices for deployment, configuration and updating microsoft stuff uses elements of GPOs and ADMX templates, along with maybe some third party stuff like PolicyPak.

Are there solid reasons that I've not found yet that powershell scripts would be preferred over the GPO methods?

I'm going to discuss this with the contractor lead when he gets back from his vacation, and he'll be straight with me (nor do I think they set us up). But I can also see this might be a religious issue, so I would still like some background on this.

Thoughts? or weblinks?

Thanks!


There is no "right" answer here. My personal preference would be use Group Policy for settings/policies, but for application deployment use PowerShell (or even legacy WSH scripts or batch files), assuming you have a single domain with no complex trust issues. However, there are tradeoffs. Doing everything in PowerShell is certainly legal.

Application Deployment (GPO vs Script):

With GPO based software deployment, you are limited to MSI packages. This can be annoying for products that are not distributed via MSI (e.g. setup.exe). In that case, you have to package it up as an MSI. Enjoy Adobe Reader's MSI+MSP distribution (gotta make an AIP). If you need to customize the install, you need to mess with MSI transforms. Something that could be a single line in a script can become a complicated multi-step process.

When everything you are deploying is readily available as an MSI, and you can install it with no special customizations, GPO deployment is pretty smooth. You can use WMI targeting and automatically uninstall stuff that is out of policy. But as soon as you step out of the confines of that box, things get more complicated. Also, when something does go wrong, it can be difficult to figure out what happened from the Event Viewer.

With a script, you can install or uninstall pretty much anything, MSI, EXE, whatever. If you need to do some cleanup work before installing (e.g. purging old registry keys from a previous version that did not uninstall cleanly), you can do it. If something goes wrong, you can add as much debug/retry/workaround code as you need, and you can run msixec with logging enabled.

You script will generally need some conditional logic to check if the software is already installed (and what version), and then invoke the installer if needed. If you do not have a programming background, this can be intimidating. It is no longer a point-and-click solution. There is also more opportunity for you to screw something up since you wrote it yourself.

We switched from GPO to PowerShell for our application deployment, and it made things a lot easier. When a new version comes out, all we need to do is drop the new installer files in our AppDeployment share and update the $expected_version variable in our script. Takes like 1/10th the time.

You can also do a hybrid approach where you use GPO for MSI stuff and scripts for everything else. I am not a fan of this because I like to have one place to go to see what is installed.

Note that with Group Policy, application deployment does not happen until a reboot. If you are using Startup Scripts, this is also true. However if you use PowerShell Remoting or a Scheduled Task you might be able to pull it off without a reboot (could get messy though).

Settings and Configuration (GPO vs Script):

Group Policy Preferences is really simple to use to do things like create registry values, map network drives, create shortcuts, etc. The fact that Group Policy has background refresh is slick because you can apply settings without forcing users to reboot. Item level targeting gives you a lot of flexibility (and this is in addition to the WMI and Security filtering at the GPO level).

However, Group Policy Preferences is far from perfect. Some of my peeves:

  1. There are way too many methods to manage Internet Explorer, some of them deprecated, some don't work with the latest IE. I always end up just managing the registry settings directly.

  2. Random Errors in the Event Viewer that are stupid. Example: I created an item to delete a Scheduled Task. Great, it's gone from all my workstations. Now the Event Viewer starts filling with Errors "I couldn't delete the task because it doesn't exist". Duh!

  3. Apply Once and do not Reapply will screw you at least once in your career.

  4. Update vs Replace. Pay attention because you will probably pick the wrong one.

  5. There are limits to what you can do with Item Level Targeting. If you need a for() loop or string manipulation (trim characters, adjust case), you will be back to a script.

  6. GPP file operations always happen, even if the files has not been changed. Your workstations will keep copying the same file off of the server over and over again, even if they don't need it. This can unexpectedly hammer your server and network. Item level targeting can help mitigate this, but watch if you have the Remove if Not Applied checked.

  7. Many of the GPP Errors in the Event Viewer contain no useful information to actually fix the problem. You have to turn on tracing.

You can use PowerShell for settings, but it has some drawbacks too:

  1. Managing registry settings with PowerShell gets messy (at least with the native Registry provider). In my opinion Microsoft screwed up when they made registry values "properties" instead of actual items. It makes things way more complex than it needs to be. You need a bunch of conditional logic to test for the registry keys and create them before you create the values. Group Policy is much simpler in this area.

  2. There are a lot of "basic" sysadmin tasks that you cannot do natively in PowerShell (e.g. creating a shortcut, managing a scheduled task). You have to invoke Wsh, the .Net Framework, or use a third party module.

  3. Scripts run at startup/logon only. No background refresh (unless you setup a Scheduled Task).

  4. If you have to call legacy Window commands utilities (net.exe, schtasks.exe), it can be tricky to call the command, and even more "tricky" to get its screen output to play nicely with PowerShell's output. You may have a command that fails and you don't know it.

Some other general comments on scripts (PowerShell or otherwise) vs GPO:

  1. Scripts are pretty much programming projects. The code will grow and become more complex over time. If you do not treat it like a "real" programming project, with comments, version history, subroutines, etc, it will grow into an unmaintainable mess that your successor will end up scrapping because he didn't understand it.

  2. Sysadmins are (generally) not programmers. They don't know proper programming disciplines (see point #1). Even well-structured code can be intimidating and unreadable for an admin with no programming background. Be mindful of the skillset of your current and future staff.

  3. Scripts have an advantage in that they can be checked into version control and diffed. With GPOs this is a little harder to do.

  4. Scripts are easier to copy onto a USB key and take with you. That was probably the case for your contractor. He probably had some existing scripts from previous projects that he was able to recycle for your project. In my environment I have two networks that are air-gapped (don't ask), but have similar configurations, so we use PowerShell scripts wherever possible so we can re-cycle code between the two networks.

  5. GPOs have an advantage in that you can use tools like RSoP to get a report of all settings applied to a particular workstation/user. This can be important for auditing and troubleshooting.

  6. GPOs are more "discoverable". I can come into an unfamiliar environment and pretty quickly get up to speed on what policies and settings are applied. With a script, I have to start studying code and hope it is well commented.

  7. PowerShell Remoting can be really handy for a one-off command that you want to run on a bunch of systems, and you don't want it to be a "permanent" policy (e.g. everybody delete this one temp file).

Regardless of the approach you use, make sure things are well-documented. You should be documenting things at the micro-level ("Implemented setting x for all accounting workstations to resolve problem with application y"), and also at the macro-level ("All of our workstation settings are stored in the GPO called x").

FOLLOW-UP EDIT: PowerShell 4 adds a new feature called Desired State Configuration. This looks like it can be used to achieve some of what Group Policy Preferences does. It could be a game changer. Have not worked with it yet but it looks really cool.

FOLLOW-UP EDIT 2: One thing I realized is that I did not properly differentiate between Group Policy Policies vs Preferences. Preferences are pretty much analogous to a PowerShell script. Policies are a little more "rigid", and are trickier to implement in a script. To do so, you have to have your script populate HKLM\Software\Policies, but you have to be mindful of collisions with GPOs. In that case, do one or the other, not both.


Obviously Microsoft believes (and most everyone agrees) that Group Policy is the best way to handle the majority of client configuration. The interface is straight-forward and for most of the settings, you don't even need to touch your keyboard. It even has built-in reporting functionality.

The only reason I can see for someone to strike out on their own and use a PowerShell login script is some kind of custom reporting or a proprietary function that GP won't handle.

Also, PowerShell scripts are disabled by default when Windows is installed. But don't worry, there's a Group Policy option to change that.


For overall configuration, Group Policy, that is what is was designed for.

For software installs, I would pick PowerShell 100%. I have been told that publishing/assigning software packages via GPO is a poor practice, and I don't really like doing the logon/logoff script ting. Have a PowerShell script that can either be launched from an intranet location by the user, or you PSRemoting to launch the install yourself. PSRemoting allows you to invoke a command (Invoke-Command or icm) and then send the command to one, many, or all computers in the domain.

For maintenance, I would use PowerShell scripts, but then, I'm not sure what you mean by maintenance.

The use of PowerShell for deployment is because it's easier if you've done it before, and have a template for the scripts. You can just use that instead of fudging through the GUI for every user/computer/role/feature that you need to set up.