Search code examples
powershellews-managed-api

using ews from powershell 2.0


Got an error while trying to execute the following code:

$dll = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"

import-module -Name $dll

$exc = new-object Microsoft.Exchange.WebServices.Data.ExchangeService

Error:

New-Object : Could not load file or assembly 'System.Core, Version=3.5.0.0, Cul
ture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The
system cannot find the file specified.
At D:\scripts\get_mails.ps1:5 char:18
+ $exc = new-object <<<<  Microsoft.Exchange.WebServices.Data.ExchangeService
    + CategoryInfo          : NotSpecified: (:) [New-Object], FileNotFoundExce
   ption
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerS
   hell.Commands.NewObjectCommand

We ran this on a windows server 2008 r2 which has .net framework 4.5.2 (now upgraded to 4.6.1) installed. The version of powershell being used is v2.0

We should be able to use the managed api via powershell 2.0 right?


Solution

  • I think the problem is that you're trying to load an assembly that needs .net runtime of >=3.5. If you run $PSVersionTable in PowerShell 2.0, you'll get something like this:

    Name                           Value
    ----                           -----
    CLRVersion                     2.0.50727.5485
    BuildVersion                   6.1.7601.17514
    PSVersion                      2.0
    WSManStackVersion              2.0
    PSCompatibleVersions           {1.0, 2.0}
    SerializationVersion           1.1.0.1
    PSRemotingProtocolVersion      2.1
    

    It's the CLR version that's causing the EWS assembly to fail loading.

    To fix this, you can create a batch file, which will in turn, create a config file that calls PowerShell 2.0 and uses a newer CLR runtime.

    Here's the batch file:

    @echo off
    :: https://stackoverflow.com/questions/7308586/using-batch-echo-with-special-characters
    if exist %~dp0powershell.exe.activation_config goto :run
    echo.^<?xml version="1.0" encoding="utf-8" ?^>                 > %~dp0powershell.exe.activation_config
    echo.^<configuration^>                                        >> %~dp0powershell.exe.activation_config
    echo.  ^<startup useLegacyV2RuntimeActivationPolicy="true"^>  >> %~dp0powershell.exe.activation_config
    echo.    ^<supportedRuntime version="v4.0"/^>                 >> %~dp0powershell.exe.activation_config
    echo.  ^</startup^>                                           >> %~dp0powershell.exe.activation_config
    echo.^</configuration^>                                       >> %~dp0powershell.exe.activation_config
    :run
    :: point COMPLUS_ApplicationMigrationRuntimeActivationConfigPath to the directory that this cmd file lives in
    :: and the directory contains a powershell.exe.activation_config file which matches the executable name powershell.exe
    set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=%~dp0
    %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe %*
    set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=
    

    Change powershell.exe to powershell_ise.exe to launch ISE with .net 4 CLR runtime.

    Also see my SO answer on using EWS in PowerShell