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 Moody

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.

@ECHO OFF
REM Check to see if .Net Framework 4.5 is installed
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5"

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:

@ECHO OFF
REM Check to see if .Net Framework 4.5 is installed
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.5"
IF %errorlevel%==1 GOTO INSTALLNET
IF %errorlevel%==0 GOTO EXIT
:INSTALLNET
Start /wait dotNetFx45_Full_setup.exe /CEIPconsent /norestart /q
:EXIT
exit

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:

wusa.exe "Windows6.1-KB2819745-x64-MultiPkg.msu" /quiet /norestart

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.

@ECHO OFF
REG QUERY "HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine" /f 4.0
IF %errorlevel%==1 GOTO INSTALLWMF
IF %errorlevel%==0 GOTO EXIT
:INSTALLWMF
Start /wait wusa.exe "Windows6.1-KB2819745-x64-MultiPkg.msu" /quiet /norestart
:EXIT
Exit

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.

18 Comments
  1. Avatar
    Brian Clark 10 years ago

    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. Avatar Author
    Joseph Moody 10 years ago

    Hey Brian,

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

  3. Avatar
    Michael Pietroforte 10 years ago

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

  4. Avatar
    Brian Clark 10 years ago

    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. Avatar Author
    Joseph Moody 10 years ago

    That should be fixed soon as well! Sorry again!

  6. Avatar
    Michael Pietroforte 10 years ago

    Yeah, embarrassing. 🙁

  7. Avatar
    Daniel 10 years ago

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

  8. Avatar
    Ben 10 years ago

    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.

  9. Avatar Author
    Joseph Moody 10 years ago

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

  10. Avatar Author
    Joseph Moody 10 years ago

    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?

  11. Avatar
    Jorgen Norman 10 years ago

    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

  12. Avatar
    Frank 10 years ago

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

  13. Avatar
    Sam 9 years ago

    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?

  14. Avatar
    Saptarshi 9 years ago

    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.

  15. Avatar Author
    Joseph Moody 9 years ago

    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)

  16. Avatar
    Stewart Mcknight 9 years ago

    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).

  17. Avatar Author
    Joseph Moody 9 years ago

    Thanks for the feedback Stewart and your detection method!

  18. Avatar
    Herman 8 years ago

    This was the detection method we ended up using in System Center 2012.

    $PSVersionTable is not updated before the computer is rebooted. Same with the registry. So we ended up checking for the existence of the KB or the right $PSVersionTable.

    IF ((Get-hotfix -id “KB2819745” -ErrorAction SilentlyContinue) -or ($PSVersionTable.psversion.Major -ge “4”))
    {
    Write-Host True
    }

Leave a reply

Please enclose code in pre tags: <pre></pre>

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2024

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending
WindowsUpdatePreventer

Log in with your credentials

or    

Forgot your details?

Create Account