Azure / Azure-Functions

1.12k stars 199 forks source link

Provide Guidance on how customers can upgrade Azure PowerShell Commandlets #124

Open SyntaxC4 opened 7 years ago

SyntaxC4 commented 7 years ago

There was a thread on twitter in which a customer was running into an issue where the version of the Azure PowerShell commandlets on their local machine was a different version than what was in Azure Functions. We should provide some guidance on how customers can update the version of the Azure PowerShell Tools which is available in Azure Functions.

We will want to make a separate topic under the Azure Functions Developer Guide (new language node for PowerShell)

itaysk commented 7 years ago

Just spend a good 5 hours banging my head against the wall on this... You suggested to upload the module to the function folder, can you be more specific? I tried copying all the files from C:\Program Files\WindowsPowerShell\Modules\AzureRM.Resources\3.5.0 to the function's folder (not the function app). It didn't work. At lest I think it didn't because my script still doesn't work. I can verify because for some reason Get-Module also doesn't work in the function...

tohling commented 7 years ago

@itaysk, here is a link to the instructions on SO for bringing your custom modules.

http://stackoverflow.com/questions/37724769/how-to-install-a-powershell-module-in-an-azure-function

I have not tested the experience with regards to bringing your own updated Azure PowerShell modules. Hopefully it would just work for you as well.

By the way, we have plans to upgrade both PowerShell and Azure PowerShell versions soon but do not have a firm ETA.

itaysk commented 7 years ago

Thanks! it works. for future readers, I also had to copy AzureRm.Profile which is a dependency of AzureRm.Resources

itaysk commented 7 years ago

@tohling This worked for a couple of functions now, However trying to use Get-AzureRmLog after loading AzureRm.Resources, AzureRm.Profile, and AzureRm.Insights still doesn't work, getting Get-AzureRmLog : Run Login-AzureRmAccount to login.. Any ideas?

tohling commented 7 years ago

@itaysk, there are 2 possibilities that I know of:

1. Module bits used were not copied from an MSI installation.
Some users mentioned that the error went away after using the MSI version instead. For the modules that you uploaded, how were they installed? Did you use the MSI or just executed Install-Module?

Here's the link to the issue on Azure PowerShell's GitHub repo: https://github.com/Azure/azure-powershell/issues/2688

2. Mismatched module versions. Another possibility is that we now have 2 different versions in your Function's environment, and some of the dependencies that Get-AzureRmLog is using calls modules from the default path installed on the system. This would cause conflicts and also result in the same errors as noted on this link: https://social.msdn.microsoft.com/Forums/azure/en-US/74279d49-229d-4904-bfe0-920e5c8e5fe3/run-loginazurermaccount-to-login?forum=azureautomation

itaysk commented 7 years ago

Is it possible that 2 functions in same function app can affect each other? It's hard to say but a function that used to work, no longer works. Code is unchanged, only thing that changed was module folders inside the functions.

tohling commented 7 years ago

After some investigation, it seems that the issue raised by @itaysk is due to 2. Mismatched module versions. To mitigate this, we can by-pass the auto-loading feature of the modules folder. Here are the steps:

  1. Using the Kudu console, create a new randomly named folder, e.g. azuremodules either inside the Function folder or move it up the directory tree to be shared across Functions.
  2. Copy the contents of the modules folder to the azuremodules folder.
  3. Remove the modules folder from the Function.
  4. In the PowerShell script file, import the modules directly with the -Global parameter. e.g.
Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Profile.psd1" -Global;
Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Resources.psd1" -Global;
Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Tags.psd1" -Global;

Thank you @itaysk for bringing this to our attention and being so responsive in helping us troubleshoot the issue!

Hopefully, we will upgrade to the latest Azure PowerShell soon so you can remove these explicit imports. However, it is still good to keep this approach in our radars as there are always folks out there who needs the latest bits and our updates may still not be able to keep up. :-)

johnnliu commented 7 years ago

In the PowerShell script file, import the modules directly with the -Global parameter. e.g. Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Profile.psd1" -Global; Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Resources.psd1" -Global; Import-Module "D:\home\site\wwwroot\azuremodules\AzureRM.Tags.psd1" -Global;

What is this sorcery.

tohling commented 7 years ago

@johnnliu , I just want to clarify this in case it was not clear to other users.

This approach is used to mitigate the situation where there are multiple versions of the same modules in the system. In the above example, there are 2 sets of Azure PowerShell modules:

Set A. The AzurePowerShell modules (older version) installed on the system. Set B. The Azure PowerShell modules (latest version) the customer uploaded to "D:\home\site\wwwroot\azuremodules"

The -Global flag is used to tell the runspace for the Function execution, that the AzureRM.xxxxx.psd1 files must all be loaded from the path "D:\home\site\wwwroot\azuremodules".

Moving the azmodules folder up the directory tree is just an optimization for @itaysk because his FunctionApp would benefit from having a shared custom modules path.

mattcorr commented 7 years ago

Is there a way uploading newer or external modules could be improved? At the moment external FTP clients are required. It would be more convenient to be able to use the View Files tab and upload multiple folders and files from there. Being able to create folders would also be useful!

tohling commented 7 years ago

@mattcorr Yes, I typically use the Kudu console. Here are the steps that describes the "update" scenario:

  1. Visit the Azure Functions Portal.
  2. Select Platform Features -> Advanced tools (Kudu) to launch the Kudu console.
  3. Select Debug console -> PowerShell to launch the PowerShell console.
  4. Navigate to your Function's modules directory.
  5. Drag and drop 1 or more files from your desktop to the Name column area.

You may also use a similar workflow to upload a large number of files packaged in a zipped format into the modules folder. To do so, we make a slight alteration with step 5:

  1. Drag and drop the ZIP file from your desktop to the Size column area.

Nonetheless, I do agree with your suggestions on providing a similar experience in the Azure Functions Portal as well. Kindly open an issue on our Portal GitHub page, https://github.com/projectkudu/AzureFunctionsPortal

KirkMunro commented 7 years ago

@tohling You mention a few times in this thread that you hope to upgrade the default version of Azure PowerShell "soon". It's been 8 months since you first mentioned that on this thread. Can you please try to get this prioritized higher so that it actually happens?

StephenFerrero commented 7 years ago

@tohling I just tried your work-around consisting of importing the latest Azure powershell modules. I pulled the latest modules from the Azure Powershell MSI installer and copied them into a new folder one-level above my function. I am attempting to import the AzureRM.Profile module using the following:

Import-Module "D:\Home\site\wwwroot\azuremodules\AzureRM.Profile.psd1" -Global;

And receiving the following error:

2017-10-28T00:34:22.086 Import-Module : D:\local\Temporary ASP.NET Files\root\b6bf3c4a\589448ba\assembly\dl3\86e47096\81251d36_824fd301\AzureRmProfileStartup.ps1
at run.ps1: line 1
+ Import-Module
+ _____________
    + CategoryInfo          : NotSpecified: (:) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand
2017-10-28T00:34:22.134 Exception while executing function: Functions.QueryLogAnalytics. Microsoft.Azure.WebJobs.Script: PowerShell script error. Microsoft.WindowsAzure.Commands.Common: D:\local\Temporary ASP.NET Files\root\b6bf3c4a\589448ba\assembly\dl3\86e47096\81251d36_824fd301\AzureRmProfileStartup.ps1.
2017-10-28T00:34:22.181 Function completed (Failure, Id=ec11cd86-c651-4199-8afe-b142ca7630e9, Duration=1273ms)

I've confirmed the AzureRmProfileStartup.ps1 file is present in the azuremodules folder.

In fact, if I create a new function and attempt to use the built-in Azure modules:

Import-Module AzureRM.Profile

I get a similar error:

2017-10-28T01:05:00.626 Import-Module : D:\local\Temporary ASP.NET Files\root\b6bf3c4a\589448ba\assembly\dl3\86e47096\81251d36_824fd301\AzureRmProfileStartup.ps1
at run.ps1: line 2
+ Import-Module
+ _____________
    + CategoryInfo          : NotSpecified: (:) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand
2017-10-28T01:05:00.689 Exception while executing function: Functions.TimerTriggerPowerShell1. Microsoft.Azure.WebJobs.Script: PowerShell script error. Microsoft.WindowsAzure.Commands.Common: D:\local\Temporary ASP.NET Files\root\b6bf3c4a\589448ba\assembly\dl3\86e47096\81251d36_824fd301\AzureRmProfileStartup.ps1.
2017-10-28T01:05:00.720 Function completed (Failure, Id=2985ad9a-1d00-4544-b0a6-cf62effdac0d, Duration=696ms)
StephenFerrero commented 7 years ago

After stopping the function on Friday and starting it again today, I am able to import the built-in Azure Powershell modules as well as the updated modules I uploaded with no errors... No idea what changed here.

mimckitt commented 6 years ago

Is there any update on this issue? I have a customer reaching out via MSDN what seems to have a similar issue:

https://social.msdn.microsoft.com/Forums/azure/en-US/3b19d319-6ba5-41fe-8283-8c68de33542e/how-to-resolve-the-azure-powershell-session-has-not-been-properly-initialized-please-import-the?forum=AzureFunctions

4c74356b41 commented 6 years ago

@tohling this doesnt really work, doesnt it?

Agazoth commented 6 years ago

I think I found a solution that works. Please try it out: https://agazoth.github.io/blogpost/2018/07/22/Powershell-Modules-in-Azure-Fuctions.html

pebre77 commented 6 years ago

@tohling Could you please provide some help? I created an Azure Function that will receive a PS Script as a parameter, but the problem is that "The term 'Connect-AzureRMAccount' is not recognized as the name of a cmdlet, function, script file, or operable program" I created a folder "modules" and copied "AzureRM.Profile" folder and "AzureRM.Resource" folder into it and it's not working, change from 32 to 64 bits, same.....What else needs to be changed on the Azure function? Do you have some basic script to share?

KirkMunro commented 6 years ago

@pebre77 Add-AzureRmAccount was renamed as Connect-AzureRmAccount in recent builds of the AzureRM module package. If you're seeing that error, then it would seem that update hasn't made it into the Azure function runtime yet. You should be able to work around that by adding this to the top of your Azure Function script:

if (-not (Get-Command -Name Connect-AzureRmAccount -ErrorAction Ignore)) {
    New-Alias -Name Connect-AzureRmAccount -Value Add-AzureRmAccount
}
pollardsg commented 6 years ago

To solve the Login-AzureRmAccount issue due to multiple versions AzureRM loaded after imported newer versions I chose to use remove-module before loading my newer versions. This removes the references for current powershell session. I just removed all the Azure modules:


foreach ($m in $s) 
{
    Remove-Module  -ModuleInfo $m
}

Import-Module "D:\home\site\wwwroot\psmodules\AzureRM.profile\5.5.1\AzureRM.profile.psd1" -Global;
Import-Module "D:\home\site\wwwroot\psmodules\AzureRM.Network\6.5.0\AzureRM.Network.psd1" -Global;
Import-Module "D:\home\site\wwwroot\psmodules\AzureRM.Compute\4.6.0\AzureRM.Compute.psd1" -Global;```
eamonoreilly commented 5 years ago

We are currently working on supporting PowerShell using the v2 runtime. As part of this work, we are also making it easier to include and managed modules.