【问题标题】:How to install a PowerShell module in an Azure Function如何在 Azure 函数中安装 PowerShell 模块
【发布时间】:2017-12-14 19:49:49
【问题描述】:

我需要从 PS-Gallery 获得的 AWS 模块,但是当我尝试在 Azure Function 中运行安装步骤时,它不起作用。 -verbose 参数标志没有向控制台写入任何内容。

在 Azure 函数中获取和使用其他 PowerShell 模块的正确方法是什么?

功能代码

[Console]::WriteLine("PowerShell Timer trigger function executed at:$(get-date)");
if (-not (Get-Module -Name "AWSPowerShell")) {
[Console]::WriteLine("AWSPowerShell not installed");
Install-Module -Name AWSPowerShell -Scope CurrentUser -ErrorAction Continue -Verbose
}
if (-not (Get-Module -Name "AWSPowerShell")){
[Console]::WriteLine("AWSPowerShell install step failed");
}

功能日志

2016-06-09T11:24:31.108 Function started (Id=e09be687-2e13-4754-942e-eab75c8516e5)
2016-06-09T11:24:32.788 Powershell Timer trigger function executed at:06/09/2016 11:24:32
AWSPowerShell not installed
AWSPowerShell install step failed
2016-06-09T11:24:32.788 Function completed (Success, Id=e09be687-2e13-4754-942e-eab75c8516e5)

更新

根据@travis 的回答,我添加了建议的代码,包括 nuget 包管理器行。这仍然没有奏效。我添加了另一个调试行,发现没有模块提供程序,即使在尝试添加 nuget 之后!

修改代码

[Console]::WriteLine("Powershell Timer trigger function executed at:$(get-date)");

Get-PackageProvider -Name nuget -ForceBootstrap

$pkg=Get-PackageProvider -ListAvailable
if ($pkg.Count -lt 1){ [Console]::WriteLine("No providers")}

if (-not (Get-Module -listavailable -Name "AWSPowerShell")) {
    [Console]::WriteLine("AWSPowerShell not installed");
    Install-Module -Name AWSPowerShell -Scope CurrentUser -ErrorAction Continue -Verbose -force
}

if (-not (Get-Module -listavailable -Name "AWSPowerShell")){
    [Console]::WriteLine("AWSPowerShell install step failed");
}

Import-Module AWSPowerShell

修改日志

2016-06-09T17:54:03.859 Powershell Timer trigger function executed at:06/09/2016 17:54:02
No providers
AWSPowerShell not installed
AWSPowerShell install step failed
2016-06-09T17:54:03.859 Function completed (Success, Id=80efb9fc-5e91-45f9-ab58-3b71fcd764af)

【问题讨论】:

    标签: powershell azure azure-functions


    【解决方案1】:

    Azure Functions 对 PowerShell 脚本的支持目前处于试验阶段。支持以下场景:

    1. Azure Functions 将能够支持客户自带模块。这些模块将驻留在名为 modules 的文件夹中,该文件夹位于 PowerShell 脚本所在的同一目录中。在示例函数的Kudu 控制台中,目录结构如下所示,

    1. 我们不支持客户使用Install-Module cmdlet 安装他们自己的模块,但是,客户可以将他们的模块上传到modules 文件夹中。

    2. modules 文件夹中的所有模块都将自动加载,因此客户不必显式使用 Import-Module cmdlet。

    3. 我们将支持 scriptbinarymanifest 模块。这些模块将驻留在modules 文件夹中的平面结构中。一个示例布局如下:

    根据您要实现的目标,以下是一些建议的步骤,以确保已加载 AWSPowerShell 模块。

    1. 在您的开发机器上本地安装AWSPowerShell。您需要上传\AWSPowerShell\3.3.5.0下的所有内容

    2. 使用 Kudu 界面,将安装的 AWSPowerShell 依赖项上传到位于 Function 目录中的 modules 文件夹中。为此,请打开 Function App 的 Portal UI,然后单击 Function App Settings 按钮。

    3. 接下来,单击转到 Kudu 按钮以启动 Kudu 控制台。您应该会看到类似于以下内容的快照,

    4. 在 cmd 控制台提示符下,导航到 Function 的文件夹,创建 modules 目录并将 \AWSPowerShell\3.3.5.0 中的所有内容上传到 modules 目录。

    您应该最终得到一个 modules 文件夹,其中包含类似于以下快照的文件列表:

    1. 运行你的函数。例如,给定我的函数的以下脚本,

      if (-not (Get-Module -Name "AWSPowerShell")) { Write-Output "AWSPowerShell not installed"; } else { Write-Output "AWSPowerShell installed"; }

    执行时,日志输出如下,

    2016-10-11T18:26:01.486 Function started (Id=582b69aa-6236-436d-81c5-c08ada8ae674)
    2016-10-11T18:26:03.267 Loaded modules:
    /AWSPowerShell/modules/AWSPowerShell.psd1
    /AWSPowerShell/modules/AWSPowerShell.dll
    /AWSPowerShell/modules/AWSSDK.APIGateway.dll
    /AWSPowerShell/modules/AWSSDK.ApplicationAutoScaling.dll
    /AWSPowerShell/modules/AWSSDK.ApplicationDiscoveryService.dll
    /AWSPowerShell/modules/AWSSDK.AutoScaling.dll
    /AWSPowerShell/modules/AWSSDK.AWSMarketplaceCommerceAnalytics.dll
    /AWSPowerShell/modules/AWSSDK.AWSMarketplaceMetering.dll
    /AWSPowerShell/modules/AWSSDK.AWSSupport.dll
    /AWSPowerShell/modules/AWSSDK.CertificateManager.dll
    /AWSPowerShell/modules/AWSSDK.CloudFormation.dll
    /AWSPowerShell/modules/AWSSDK.CloudFront.dll
    /AWSPowerShell/modules/AWSSDK.CloudHSM.dll
    /AWSPowerShell/modules/AWSSDK.CloudSearch.dll
    /AWSPowerShell/modules/AWSSDK.CloudSearchDomain.dll
    /AWSPowerShell/modules/AWSSDK.CloudTrail.dll
    /AWSPowerShell/modules/AWSSDK.CloudWatch.dll
    /AWSPowerShell/modules/AWSSDK.CloudWatchEvents.dll
    /AWSPowerShell/modules/AWSSDK.CloudWatchLogs.dll
    /AWSPowerShell/modules/AWSSDK.CodeCommit.dll
    /AWSPowerShell/modules/AWSSDK.CodeDeploy.dll
    /AWSPowerShell/modules/AWSSDK.CodePipeline.dll
    /AWSPowerShell/modules/AWSSDK.CognitoIdentity.dll
    /AWSPowerShell/modules/AWSSDK.CognitoIdentityProvider.dll
    /AWSPowerShell/modules/AWSSDK.ConfigService.dll
    /AWSPowerShell/modules/AWSSDK.Core.dll
    /AWSPowerShell/modules/AWSSDK.DatabaseMigrationService.dll
    /AWSPowerShell/modules/AWSSDK.DataPipeline.dll
    /AWSPowerShell/modules/AWSSDK.DeviceFarm.dll
    /AWSPowerShell/modules/AWSSDK.DirectConnect.dll
    /AWSPowerShell/modules/AWSSDK.DirectoryService.dll
    /AWSPowerShell/modules/AWSSDK.DynamoDBv2.dll
    /AWSPowerShell/modules/AWSSDK.EC2.dll
    /AWSPowerShell/modules/AWSSDK.ECR.dll
    /AWSPowerShell/modules/AWSSDK.ECS.dll
    /AWSPowerShell/modules/AWSSDK.ElastiCache.dll
    /AWSPowerShell/modules/AWSSDK.ElasticBeanstalk.dll
    /AWSPowerShell/modules/AWSSDK.ElasticFileSystem.dll
    /AWSPowerShell/modules/AWSSDK.ElasticLoadBalancing.dll
    /AWSPowerShell/modules/AWSSDK.ElasticLoadBalancingV2.dll
    /AWSPowerShell/modules/AWSSDK.ElasticMapReduce.dll
    /AWSPowerShell/modules/AWSSDK.Elasticsearch.dll
    /AWSPowerShell/modules/AWSSDK.ElasticTranscoder.dll
    /AWSPowerShell/modules/AWSSDK.GameLift.dll
    /AWSPowerShell/modules/AWSSDK.IdentityManagement.dll
    /AWSPowerShell/modules/AWSSDK.ImportExport.dll
    /AWSPowerShell/modules/AWSSDK.Inspector.dll
    /AWSPowerShell/modules/AWSSDK.IoT.dll
    /AWSPowerShell/modules/AWSSDK.IotData.dll
    /AWSPowerShell/modules/AWSSDK.KeyManagementService.dll
    /AWSPowerShell/modules/AWSSDK.Kinesis.dll
    /AWSPowerShell/modules/AWSSDK.KinesisAnalytics.dll
    /AWSPowerShell/modules/AWSSDK.KinesisFirehose.dll
    /AWSPowerShell/modules/AWSSDK.Lambda.dll
    /AWSPowerShell/modules/AWSSDK.MachineLearning.dll
    /AWSPowerShell/modules/AWSSDK.MobileAnalytics.dll
    /AWSPowerShell/modules/AWSSDK.OpsWorks.dll
    /AWSPowerShell/modules/AWSSDK.RDS.dll
    /AWSPowerShell/modules/AWSSDK.Redshift.dll
    /AWSPowerShell/modules/AWSSDK.Route53.dll
    /AWSPowerShell/modules/AWSSDK.Route53Domains.dll
    /AWSPowerShell/modules/AWSSDK.S3.dll
    /AWSPowerShell/modules/AWSSDK.SecurityToken.dll
    /AWSPowerShell/modules/AWSSDK.ServiceCatalog.dll
    /AWSPowerShell/modules/AWSSDK.SimpleEmail.dll
    /AWSPowerShell/modules/AWSSDK.SimpleNotificationService.dll
    /AWSPowerShell/modules/AWSSDK.SimpleSystemsManagement.dll
    /AWSPowerShell/modules/AWSSDK.SimpleWorkflow.dll
    /AWSPowerShell/modules/AWSSDK.Snowball.dll
    /AWSPowerShell/modules/AWSSDK.SQS.dll
    /AWSPowerShell/modules/AWSSDK.StorageGateway.dll
    /AWSPowerShell/modules/AWSSDK.WAF.dll
    /AWSPowerShell/modules/AWSSDK.WorkSpaces.dll
    /AWSPowerShell/modules/log4net.dll
    /AWSPowerShell/modules/AWSPowerShellCompleters.psm1
    2016-10-11T18:27:21.265 AWSPowerShell installed
    2016-10-11T18:27:21.464 Function completed (Success, Id=582b69aa-6236-436d-81c5-c08ada8ae674)
    

    注意:该函数需要一段时间才能完成,因为所有模块都是在运行时加载的。

    请务必记住,与大多数 IaaS 设置不同,Azure 函数是在多租户环境中执行的。因此,仍然存在以下已知警告:

    1. 我们的基础架构可防止任何执行我们认为存在安全风险的低级 API 的函数(例如交互模式、主机凭据访问、注册表编辑等)。如果您使用的 PowerShell 脚本或模块调用任何这些被阻止的 API,您将无法在 Functions 中执行这些工作负载。尽管如此,我们的目标是支持尽可能多的场景,因此我们会根据客户的需求量优先考虑畅通无阻的场景。

    2. 我们目前在我们的基础架构中安装了 PowerShell 4.0 版和 Azure PowerShell 1.4。我们将尽快升级这些版本。随着我们在 Azure Functions 中添加对 PowerShell 的更多支持,模块套件可能会随着时间的推移而升级或添加。这些预安装的模块极有可能与您现有的模块发生冲突。

    【讨论】:

    • 这有助于获取初始代码设置。然而,它使本地开发成为一种痛苦。在本地运行 ./run.ps1 时,它没有本地加载 DLL 或我的脚本模块。所以我必须想出一些防御性的方法来在本地开发中运行脚本……还没有弄清楚。
    • “modules”文件夹只是一个方便的功能。您可以将其重命名为“模块”或任何其他名称,并将您的 DLL 放在那里。然后在 run.ps1 脚本中使用 Import-Module cmdlet。
    • 此外,您还可以将您的自定义模块目录向上移动,以便在同一个 Function App 内的 Functions 之间共享相同的路径。
    • 我现在确实可以使用if (-not (Get-Module -Name "ScriptName")) 检查脚本模块。我仍在尝试通过模块中的 Add-Type 选择性地加载 DLL。
    【解决方案2】:

    您需要通过将-listavailable 添加到get-module 调用来确保查找所有模块,而不仅仅是加载的模块。

    您可能需要引导 nuget 以使 install-module 在非交互式环境中工作。命令为:Get-PackageProvider -Name nuget -ForceBootstrap

    如果您安装的存储库不受信任,您可能需要强制使用install-module 命令。

    示例

    [Console]::WriteLine("Powershell Timer trigger function executed at:$(get-date)");
    
    if (-not (Get-Module -listavailable -Name "AWSPowerShell")) {
        [Console]::WriteLine("AWSPowerShell not installed");
        Install-Module -Name AWSPowerShell -Scope CurrentUser -ErrorAction Continue -Verbose -force
    }
    
    if (-not (Get-Module -listavailable -Name "AWSPowerShell")){
        [Console]::WriteLine("AWSPowerShell install step failed");
    }
    

    仅供参考:[Console]::WriteLine 在 PowerShell 中不被视为自动化脚本的良好做法。尝试坚持Write-Verbose你可以像这样强制Write-Verbose -message 'my message' -verbose

    【讨论】:

    • 我最初使用的是 write-host,但 WriteLine 是 Microsoft 编写的,所以我采用了他们所做的,假设最佳实践/正确的解决方案路线。我想关于假设的格言在这里发挥了作用! ;)
    • 我不知道这是在哪里使用的。 Console.WriteHost 可能出于特定原因在那里使用,但如果是的话。我想更好地理解。我的推特信息在我的个人资料中。我们应该在这里继续讨论主题。
    • 看起来我可能无法在 Azure Functions 的 powershell 上下文中添加包提供程序:-/
    【解决方案3】:

    更新 azurerm powershell 模块怎么样,有很多模块可以升级到最新版本 4.1.0,如果我们上传这些模块,放在一个平面目录中将是一个问题。

    C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ResourceManager\AzureResourceManager

    包含 46 个文件夹。

    【讨论】:

      【解决方案4】:

      我怀疑原因是您没有指定要从中加载模块的位置。当前$env:PSModulePath 被列为

      WindowsPowerShell\模块;
      D:\Program Files (x86)\WindowsPowerShell\Modules; D:\Windows\system32\WindowsPowerShell\v1.0\Modules\;
      d:\Program Files\Microsoft 安全客户端\MpProvider\;
      D:\Program Files\Microsoft Message Analyzer\PowerShell\;
      D:\Program Files\WindowsPowerShell\Modules\;
      D:\Program Files (x86)\MicrosoftSDKs\Azure\PowerShell\ResourceManager\AzureResourceManager\;
      D:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\;
      D:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\Storage\

      我无法完全弄清楚它从哪里引用第一个,所以我不能把它们放在那里。所以我把它放在一起

      $env:PSModulePath = $env:PSModulePath + ";d:\home\modules\"
      
      import-module azured 
      $out = Deploy-Template
      [Console]::WriteLine($out)
      Out-File -Encoding Ascii $Env:res -inputObject $out
      

      这会加载模块(位于 d:\home\modules)并按预期工作

      Get-PackageProvider -Name nuget -ForceBootstrap 不起作用的原因是没有安装PackageManagement 模块。但是已经安装了nuget。您需要直接与kudu 交互才能以这种方式安装软件包。

      我很高兴看到我不是唯一一个被功能驱动的人;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-18
        • 2020-07-31
        • 1970-01-01
        • 2019-11-14
        • 1970-01-01
        • 2012-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多