Skip to content

Connect-EXOPSSession Unavailable in Azure Functions #503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
luckerby opened this issue Jul 29, 2020 · 6 comments
Open

Connect-EXOPSSession Unavailable in Azure Functions #503

luckerby opened this issue Jul 29, 2020 · 6 comments
Labels
enhancement New feature or request feature
Milestone

Comments

@luckerby
Copy link

Azure CloudShell has been offering for some time now the ability of using Connect-EXOPSSession, without importing any module manually.

However trying to use the Connect-EXOPSSession cmdlet within an Azure Function results in the error below. Is there anything extra required to have this working - along with other Exchange Online cmdlets - or it's simply not supported for now ?

2020-07-29T20:15:03Z   [Error]   ERROR: The term 'Connect-EXOPSSession' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Exception             : 
    Type        : System.Management.Automation.CommandNotFoundException
    ErrorRecord : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : The term 'Connect-EXOPSSession' is not recognized as the name of a cmdlet, function, script file, or operable program.
                      Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
            HResult : -2146233087
        TargetObject          : Connect-EXOPSSession
        CategoryInfo          : ObjectNotFound: (Connect-EXOPSSession:String) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : CommandNotFoundException
        InvocationInfo        : 
            ScriptLineNumber : 12
            OffsetInLine     : 1
            HistoryId        : 1
            ScriptName       : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1
            Line             : Connect-EXOPSSession
                               
            PositionMessage  : At D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1:12 char:1
                               + Connect-EXOPSSession
                               + ~~~~~~~~~~~~~~~~~~~~
            PSScriptRoot     : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage
            PSCommandPath    : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1
            InvocationName   : Connect-EXOPSSession
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1: line 12
    CommandName : Connect-EXOPSSession
    TargetSite  : 
        Name          : LookupCommandInfo
        DeclaringType : System.Management.Automation.CommandDiscovery, System.Management.Automation, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    StackTrace  : 
   at System.Management.Automation.CommandDiscovery.LookupCommandInfo(String commandName, CommandTypes commandTypes, SearchResolutionOptions searchResolutionOptions, CommandOrigin commandOrigin, ExecutionContext context)
   at System.Management.Automation.CommandDiscovery.LookupCommandProcessor(String commandName, CommandOrigin commandOrigin, Nullable`1 useLocalScope)
   at System.Management.Automation.ExecutionContext.CreateCommand(String command, Boolean dotSource)
   at System.Management.Automation.PipelineOps.AddCommand(PipelineProcessor pipe, CommandParameterInternal[] commandElements, CommandBaseAst commandBaseAst, CommandRedirection[] redirections, ExecutionContext context)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
    Message     : The term 'Connect-EXOPSSession' is not recognized as the name of a cmdlet, function, script file, or operable program.
                  Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    Data        : System.Collections.ListDictionaryInternal
    Source      : System.Management.Automation
    HResult     : -2146233087
TargetObject          : Connect-EXOPSSession
CategoryInfo          : ObjectNotFound: (Connect-EXOPSSession:String) [], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException
InvocationInfo        : 
    ScriptLineNumber : 12
    OffsetInLine     : 1
    HistoryId        : 1
    ScriptName       : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1
    Line             : Connect-EXOPSSession
                       
    PositionMessage  : At D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1:12 char:1
                       + Connect-EXOPSSession
                       + ~~~~~~~~~~~~~~~~~~~~
    PSScriptRoot     : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage
    PSCommandPath    : D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1
    InvocationName   : Connect-EXOPSSession
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, D:\home\site\wwwroot\RetrieveO365PhotosAndInjectToStorage\run.ps1: line 12
@ghost ghost assigned gzuber Jul 29, 2020
@fabiocav fabiocav transferred this issue from Azure/azure-functions-host Jul 29, 2020
@Francisco-Gamino
Copy link
Contributor

HI @luckerby -- By default, the only cmdlets available in the Azure Functions Service is whatever ships with PowerShell Core 6.2 or 7 (depending on the version you are using in your function app). However, you can install additional modules for your function app using Managed Dependencies. For more information, please see https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#dependency-management.

Here is what the requirements.psd1 file will look like:

# This file enables modules to be automatically managed by the Functions service.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{
    'MSApiConnect'= '1.0.0' 
}

Please keep in mind that the module needs to be PowerShell Core compliant. If this is not the case, we can provide you with a potential work around. Let us know.

Cheers,
Francisco

@luckerby
Copy link
Author

luckerby commented Aug 7, 2020

Hi @Francisco-Gamino,

There's currently 2 versions of the Exchange Online modules. Each consists of a limited set of cmdlets. Upon using a Connect-* type of cmdlet (Connect-EXOPSSession for V1 and Connect-ExchangeOnline for V2) and successfully connecting, an implicit remoting module is downloaded, and the majority of cmdlets for operating against Exchange objects are made available.

For the Exchange Online V1 module (which Microsoft no longer recommends using in favor of V2), it's explicitly stated that "The Exchange Online Remote PowerShell Module is not supported in PowerShell Core (macOS, Linux, or Windows Nano Server)". You mentioned a workaround for this, but since V1 is not the preferred way anymore, let's look at the next version.

For V2 - which contains both 9 new cmdlets as well as the old ones in V1, the Connect-ExchangeOnline cmdlet resides in the ExchangeOnlineManagement module. The .psm1 for this module references 2 assemblies:

  • Microsoft.Exchange.Management.RestApiClient.dll (I believe new V2 cmdlets are in here)
  • Microsoft.Exchange.Management.ExoPowershellGalleryModule.dll (this probably contains the old V1 cmdlets)
    Using a decompiler (Jetbrains dotPeek) to check the target framework shows .Net Framework v4.7.2. So again there's no .NET Core targeting.

Can you let me know more details around the workaround ?

@luckerby
Copy link
Author

luckerby commented Aug 7, 2020

One more thing that could affect us - trying to run V2 module's Connect-ExchangeOnline in a Cloud Shell eventually throws the error below.

New-ExoPSSession: /home/mihai/.local/share/powershell/Modules/ExchangeOnlineManagement/1.0.1/ExchangeOnlineManagement.psm1:449
Line |
 449 |  … PSSession = New-ExoPSSession -ExchangeEnvironmentName $ExchangeEnviro …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The type initializer for 'Microsoft.Exchange.Management.AdminApiProvider.Authentication.UserTokenProvider' threw an exception.

@Francisco-Gamino
Copy link
Contributor

Hello @luckerby ,

Here is the potential workaround for the V2 module which might have some dependencies that are not Core CLR compliant.

  1. Install PowerShell Core 7 locally. Install module + dependencies (if any). Then, import the module in PowerShell 7 using the -UseWindowsPowerShell flag, e.g., Import-Module <moduleName> -UseWindowsPowerShell
    If the module imports with no errors, run the commands you need for your script. If everything works correctly, then it is possible that it will run in the Azure Functions service.

    To install PowerShell 7, go to https://github.com/PowerShell/PowerShell/releases/, or just run this in PowerShell: iex "& { $(irm 'https://aka.ms/install-powershell.ps1')} -UseMSI"

  2. If (1) did not work, try to reach out to the team that owns the module to see if there are any plans to make the module + dependencies Core CLR complaint.

  3. Alternatively, you could try to use Functions V1 + PowerShell experimental support (for Windows PowerShell 5.1). Please keep in mind that this is just experimental support and there are no plans to improve this offering.

@AnatoliB AnatoliB added enhancement New feature or request feature labels Aug 18, 2020
@AnatoliB AnatoliB added this to the Backlog milestone Aug 18, 2020
@AnatoliB
Copy link
Contributor

AnatoliB commented Sep 1, 2020

Another workaround is to spawn a powershell.exe process from the function: #232 (comment).

@haneef95
Copy link

For those still experiencing this issue, this might do the trick

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feature
Projects
None yet
Development

No branches or pull requests

5 participants