Deploying PowerShell 4 with Group Policy

-1+1 (No Ratings Yet)

PowerShell 4 includes some pretty powerful new features including Desired State Configuration. If your clients are still running Windows 7, you won’t natively have these features. To take advantage of these improvements, your clients must run PowerShell 4. Getting your computers to PowerShell 4 isn’t as easy as you would think – especially if your Windows 7 clients are still running PowerShell 2.

Joseph MoodyMVP By Joseph Moody - Tue, November 19, 2013 - 17 comments google+ icon

Joseph Moody is an admin for a public school and helps manage 5,500 PCs. He is a Microsoft Most Valuable Professional (MVP) in Software Packaging, Distribution, and Servicing. He blogs at DeployHappiness.com.

There are several ways to deploy PowerShell 4. You could build it into your image, use SCCM, or Group Policy scripts. Because Group Policy scripts are universally accessible and free, we will use them to deploy PowerShell 4.

In the Group Policy Management Console, create a new GPO named APP Windows Management Framework 4. Create a security group with the same name and scope it to the GPO. Populate this group with a few test computers.

The WMF4 Deployment GPO

The WMF4 Deployment GPO

PowerShell 4, part of the Windows Management Framework (WMF), has one application dependency. It requires .Net Framework 4.5 to be installed first. If .Net Framework 4.5 is not installed beforehand, clients will successfully process part of the update but will not completely install PowerShell 4.

Deploying .Net Framework 4.5 ^

Before we go any further, download the offline installer for .Net Framework 4.5. Save the installer to a network share accessible to your domain computers. When .Net Framework 4.5 is installed, it will register itself in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs as .NETFramework,Version=v4.5”. We can use REG QUERY to check to see if this key exists.

If this registry key exist, %errorlevel% will equal zero. To prevent installing .Net Framework 4.5 over and over again, we can use: IF %errorlevel%==1 GOTO INSTALLNET

Finally, we just need to insert our silent install command and tie the first script together:

Save this script as a batch file and add it as a shutdown script to your GPO.

GPO shutdown script

GPO shutdown script

Deploying Windows Management Framework 4 ^

As we stated above, PowerShell 4 is installed when Windows Management Framework 4 is installed. WMF can be downloaded from here. The update comes in both architecture flavors; be sure to pick the one that matches your environment.

Download Windows Management Framework 4

Downloading the X64 version of WMF 4

Because the package is a .MSU, we will use the Windows Update Standalone Installer (WUSA.exe). A quiet and passive restart install would look like this:

When PowerShell 4 is completely installed, we can query HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine for the PowerShellVersion string. The value of this string should be 4.0

PowerShell version in Registry

PowerShell version in Registry

Like before, we can use REG QUERY to check this key and then check %errorlevel% to ensure a value was found.

Save this batch file and add it to your GPO as a shutdown script.

Shutdown script

Shutdown script

Shutdown script always run synchronously so .Net Framework will install before Windows Management Framework. By using these two scripts, you can deploy PowerShell 4 with Group Policy scripts.

Disclaimer
Your question wasn't answered? Please ask in the new 4sysops forum!

17 Comments- Leave a Reply

  1. Brian Clark says:

    Can you please post the source for the InstallWMF4.bat? That seems to be missing from this article. I’d like to see it work the same way, where it doesn’t try to install if it is already installed. Since the WMF4.0 installer is an .msu file, It can use the wusa command line arguments, like /quiet. However, I don’t see one related to not installing again if present.

  2. Joseph MoodyJoseph Moody says:

    Hey Brian,

    That script will be updated in a bit. Sorry for the confusion!

  3. I uploaded only half of the article. :( Sorry for that. The article should be complete now.

  4. Brian Clark says:

    It looks like you copied in the wrong Powershell 4 install script (you have the .Net installer script). But I see what you are doing here. Thanks for correcting the article.

  5. Joseph MoodyJoseph Moody says:

    That should be fixed soon as well! Sorry again!

  6. Daniel says:

    Great, but I wonder why it wasn’t packaged in *one* startup script. The commands inside .cmd run synchronously anyway.

  7. Ben says:

    I just followed this article to the ‘T’.. i have the GPO applied to a test OU with test machines within. first shutdown took quite a while longer than normal.. and I got all excited thinking the WMF and Net4.5 were being installed. Once I booted it back up and logged in.. nope. PowerShell version still 2.1 :(

    Cannot figure out what I did wrong when manually running the batch files works.

  8. Joseph MoodyJoseph Moody says:

    It should work fine as one script. I prefer granular setups – just a personal preference.

  9. Joseph MoodyJoseph Moody says:

    Hey Ben – does a GPResult show that the scripts were applied? Are you doing this with startup or shutdown scripts? Do your computers have read/execute to the network shares where the installers are located?

  10. Jorgen Norman says:

    Hi Joseph

    I was wondering about this scenario, i´m trying to deploy UE-V and get stuck on pre-req wmf4. I have .net 4.5 and 4.5.1 already in place and if i run a batch with silent install of wmf4 it goes through and exit with 0. Still i get no powershell update.

    Is the only way to install wmf4 with a restart? If so i will surely run it on log off..but in the best of world i can apply this during computer is logged on.
    Any hints would be most appreciated.
    //Jörgen

  11. Frank says:

    I had to add the complete path to the msu file instead of just the filename, maybe thats an obstacle for some…

  12. Sam says:

    how did you mention the complete path? did you mount the network share to a drive and then mention it or just gave the full netowork share path?

  13. Saptarshi says:

    Hi Joseph,
    How does your wmf install batch script know where to look for the msu file? Does it have to be on a share mounted on every machine in the AD? We do not mount such shares in our AD, so is there an alternate way? I would still like to implement this installation using GPO only since we dont have SCCM in house.

  14. Joseph MoodyJoseph Moody says:

    You can stick it in SYSVOL if you would like or stick it on a share that domain computers have read/execute access to. If you stick it on a separate share, change the path to the MSU to be the complete file path (\\server\share\folder\nameoffile.msu)

  15. Stewart Mcknight says:

    code appears to work but doesnt.. When checking the registry to see if powershell is installed we saw false positives if powershell 3.0 was installed

    Below works better

    REG QUERY “HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine” /v PowerShellVersion |find “4.0”

    This is why..

    echo Checking for powershell v 4.0
    REG QUERY “HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine” /f 4.0
    IF %errorlevel%==1 GOTO WMF
    IF %errorlevel%==0 GOTO EXIT

    Now if I run the reg query on a server which has PSv3 then we get the following:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine
    ApplicationBase REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0
    PSPluginWkrModuleName REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0\pspluginwkr-v3.dll
    PSCompatibleVersion REG_SZ 1.0, 2.0, 3.0
    RuntimeVersion REG_SZ v4.0.30319
    ConsoleHostAssemblyName REG_SZ Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyTo
    ken=31bf3856ad364e35, ProcessorArchitecture=msil
    ConsoleHostModuleName REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell.ConsoleHost.dll
    PowerShellVersion REG_SZ 3.0

    Using get-host and $psversiontable we can see that yes this is PSv3 we are running.

    PS C:\Users\> get-host
    Name : ConsoleHost
    Version : 3.0
    InstanceId : 5207ce93-a273-4784-a029-c67a416d9bad
    UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
    CurrentCulture : en-US
    CurrentUICulture : en-US
    PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
    IsRunspacePushed : False
    Runspace : System.Management.Automation.Runspaces.LocalRunspace

    PS C:\Users\> $psversiontable
    Name Value
    —- —–
    PSVersion 3.0
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.18444
    BuildVersion 6.2.9200.16481
    PSCompatibleVersions {1.0, 2.0, 3.0}
    PSRemotingProtocolVersion 2.2

    This is what we should get if we are running PSv4:

    PS C:\Users\> REG QUERY “HKLM\SOFTWARE\Microsoft\Powershell\3\PowerShellEngine”
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Powershell\3\PowerShellEngine
    ApplicationBase REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0
    PSPluginWkrModuleName REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0\pspluginwkr-v3.dll
    PSCompatibleVersion REG_SZ 1.0, 2.0, 3.0, 4.0
    RuntimeVersion REG_SZ v4.0.30319
    ConsoleHostAssemblyName REG_SZ Microsoft.PowerShell.ConsoleHost, Version=3.0.0.0, Culture=neutral, PublicKeyTo
    ken=31bf3856ad364e35, ProcessorArchitecture=msil
    ConsoleHostModuleName REG_SZ C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell.ConsoleHost.dll
    PowerShellVersion REG_SZ 4.0

    PS C:\Users\> get-host
    Name : ConsoleHost
    Version : 4.0
    InstanceId : 6d6280b8-b5be-4af6-bc7c-684167e934aa
    UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
    CurrentCulture : en-US
    CurrentUICulture : en-US
    PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
    IsRunspacePushed : False
    Runspace : System.Management.Automation.Runspaces.LocalRunspace

    The problem with your query is that it looks for the value “4.0”. It finds this under RunTimeVersion regardless of the PS version. This refers to .net version and is not the version of powershell (which is shows by PowerShellVersion).

  16. Joseph MoodyJoseph Moody says:

    Thanks for the feedback Stewart and your detection method!

Please share your thoughts in a comment!

Login

Lost your password?