Enable .Net 4.0 access from PowerShell V2

While working on an update to one of my projects, PoshPAIG, I decided that I wanted to take a look at using a DataGrid as a possible replacement to the use of a ListView. The problem I ran into right out of the gate was that I was unable to use the DataGrid in my WPF test script as it was only available with .Net 4.0.

image

Not looking so good, is it?

After some researching I came across this article from PowerShell MVP Thomas Lee  written back in August 2010 showing how you can enable the .Net 4.0 access by creating a config file, 1 for the console and 1 for the ISE. After the file has been created, a restart of the console/ISE is necessary for PowerShell to read the config file and begin allowing use of the new .Net 4.0 framework.

This is great news! However, not one to just perform a manual update like that, I took up the initiative to write an advanced function that would not only perform the change on my local system, but also my remote systems as well, if needed.  There is not a lot to it other than creating the Here-String listing the data for the config file and then adding some parameters for Computername, Console and ISE to let the user decide what they want to do. Also since this does make a change to the system, the use of –WhatIf is also enabled in the function.

You can see what version PowerShell is using for the .Net Framework by running the following command:

[environment]::Version

image

Currently, PowerShell is running under .Net 2.0.

Now we dot source my advanced function and run a command to enable .Net 4.0 access to PowerShell.

 

. .\Enable-DotNet4Access.ps1
Enable-DotNet4Access -Console -Verbose

image

Pretty simple, now lets restart the console and check the version being used now.

image

Yep, using .Net 4.0 now!

Now lets run that script again and see if it works any better…

image

And there you have it! I can now use a WPF DataGrid with PowerShell!

Download Script:

Enable-DotNet4Access.ps1

Source Code:

Function Enable-DotNet4Access {
    <#
    .SYNOPSIS  
        Enables PowerShell access to the .NET 4.0 framework by creating a configuration file.

    .DESCRIPTION
        Enables PowerShell access to the .NET 4.0 framework by creating a configuration file. You will need to 
        restart PowerShell in order for this to take effect. In a default installation of PowerShell V2, these
        files do not exist.
    
    .PARAMETER Computername
        Name of computer to enable .NET 4 for PowerShell against.
         
    .PARAMETER Console
        Apply configuration change for console only

    .PARAMETER ISE
        Apply configuration change to ISE only

    .NOTES  
        Name: Enable-DotNet4Access
        Author: Boe Prox
        DateCreated: 10JAN2012 
               
    .LINK  
        https://learn-powershell.net
        
    .EXAMPLE
    Enable-DotNet4Access -Console -ISE
    
    Description
    -----------
    Enables .NET 4.0 access for PowerShell on console and ISE
    #>
    
    [cmdletbinding(
        SupportsShouldProcess = $True
    )]
    Param (
        [parameter(Position='0',ValueFromPipeLine = $True,ValueFromPipelineByPropertyName=$True)]
        [Alias('__Server','Computer','Server','CN')]
        [string[]]$Computername,
        [parameter(Position='1')]
        [switch]$Console,
        [parameter(Position='2')]
        [switch]$ISE
    )
    Begin {
    Write-Verbose ("Creating file data")
$file = @'
<?xml version="1.0"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0.30319"/>
        <supportedRuntime version="v2.0.50727"/>
    </startup>
</configuration>
'@ 
    }
    Process {
        If (-Not $PSBoundParameters['Computername']) {
            Write-Warning ("No computername given! Using {0} as computername." -f $Env:Computername)
            $Computername = $Env:Computername
        }
        ForEach ($Computer in $computername) {
            If ($PSBoundParameters['Console']) {
                If ($pscmdlet.ShouldProcess("Console","Enable .NET 4.0 Access")) {
                    Try {
                        $file | Out-file "\\$computer\C$\Windows\System32\WindowsPowerShell\v1.0\PowerShell.Exe.Config" -Force
                        Write-Host ("{0}: Console must be restarted before changes will take effect!" -f $Computer) -fore Green -Back Black
                    } Catch {
                        Write-Warning ("{0}: {1}" -f $computer,$_.Exception.Message)
                    }
                }
            }
            If ($PSBoundParameters['ISE']) {
                If ($pscmdlet.ShouldProcess("ISE","Enable .NET 4.0 Access")) {
                    Try {
                        $file | Out-file "\\$computer\C$\Windows\System32\WindowsPowerShell\v1.0\PowerShellISE.Exe.Config" -Force
                        Write-Host ("{0}: ISE must be restarted before changes will take effect!" -f $Computer) -fore Green -Back Black
                    } Catch {
                        Write-Warning ("{0}: {1}" -f $computer,$_.Exception.Message)
                    }
                }
            }
        }
    }
}

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell, scripts and tagged , . Bookmark the permalink.

3 Responses to Enable .Net 4.0 access from PowerShell V2

  1. Mike says:

    I just ran across this article and it worked beautifully. I appreciate the effort on your part. Thank you.

  2. That is a very good initiative and thanks for putting everything together.
    I would like to make a small suggestion in your code.

    I see that you are using below code to validate if a value is specified for the parameter or not.

    If (-Not $PSBoundParameters[‘Computername’]) {
    Write-Warning (“No computername given! Using {0} as computername.” -f $Env:Computername)
    $Computername = $Env:Computername
    }

    Instead, you can do like below which gives you same functionality and saves some execution time.

    Param (
    [parameter(Position=’0′,ValueFromPipeLine = $True,ValueFromPipelineByPropertyName=$True)]
    [Alias(‘__Server’,’Computer’,’Server’,’CN’)]
    [ValidateNotNullOrEmpty()]
    [string[]]$Computername = $env:ComputerName,
    [parameter(Position=’1′)]
    [switch]$Console,
    [parameter(Position=’2′)]
    [switch]$ISE
    )

    I just added [ValidateNotNullOrEmpty()] to $computername variable so that if the parameter value is left black it will throw error. I also assigned $env:computername to $computername so that when -ComputerName parameter is not specified it assumes the local computer. That is standard most people in PS world are using.

    Hope this helps…

    Sitaram Pamarthi
    http://techibee.com

    • Boe Prox says:

      Nice catch Sitaram! Although the execution time would probably be minimal, it does save about 4 lines of unneeded code which is always a good thing and a good practice to get into. The [ValidateNotNullOrEmpty()] is also a nice touch as you say to prevent someone giving a null value!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s