2018年6月19日,星期二

使用Azure函数,PnP和图形在云中运行PowerShell脚本

众所周知,Azure Functions在许多Office 365方案中都非常有用,而这超出了开发人员的范围。 IT专业人员当然可以从在云中运行脚本的能力中受益– perhaps it’您想按时间表每小时,每天或每周运行一次,也许您想使用 即插即用PowerShell too for its awesome commands around managing Groups/Teams, provisioning of SharePoint sites and more. This post is aimed 在 anyone WHO has such a need – we’重新使用Visual Studio Code( 完整的Visual Studio),但’s just because it’甚至对于非编码人员而言,它也成为了出色的PowerShell编辑器。 其实我’m now convinced that VS Code is the best option for PowerShell scripts regardless of WHO you are. 如果你’re a dev, you’我可能会喜欢VS Code可以将文件部署到Azure Function的方式,但是对于IT专业人员或对此不太满意的人,我’图11还显示了如何将脚本(以及使其作为功能运行的相关文件)拖放到云中。在这两种情况下,我们’将从VS Code中受益’支持创建具有正确文件集的功能,代码格式化/着色和调试脚本的功能。

我们的情况’将用于创建Office 365组(但如果您’对Flow方法感兴趣,也请参阅我的 控制Office 365组的创建–一个简单的无代码解决方案 发布)–我喜欢这种情况,因为在将来进行微小的调整后,就可以创建一个Microsoft团队,这可能会更有用。我们’只需等待该应用程序专用API即可,尽管您今天可以根据需要使用用户上下文进行操作。

这些天来有很多创建Azure函数的方法,’将在以后的文章中介绍。因此,如上所述,IT专业人员不应’不必为此担心,但是我们’ll use:

您 should follow these links to download/install those things if you don’t already have them.

步我们’ll go through

I’我将尝试通过大量屏幕截图在本文中进行全面介绍。这里’s what we’ll cover:

  • PowerShell脚本内容概述
  • 安装PnP PowerShell模块
  • 注册Azure AD应用以与图表对话
    • 通过构建并点击一个同意URL来授予管理员对此应用程序的同意(如果您’ve haven’之前没有看过这个过程)
  • 创造 the Function locally using VS Code, using PowerShell as the language
    • 调试/逐步执行功能
  • 准备在云中运行-将文件从SharePointPnPPowerShellOnline模块复制到本地文件夹
  • 创造 the Azure Function app in the portal
  • 将文件发布到函数:
    • 使用VS代码
    • 在Kudu中使用拖放
  • 测试ing the function
  • 最后一步–安全地存储应用程序ID和客户端机密
更新资料–考虑将凭据存储在Azure Key Vault中,因为它已达到“常规可用性”
在这篇文章的后面’图11显示了我们如何在AAD中注册一个应用程序以与Graph对话,该图具有以应用程序ID和密码形式出现的凭据。我展示了将这些代码与Azure环境变量中的代码存储在一起,但是在那里’现在是一个更好的选择。 Azure Key Vault提供了在您定义的位置安全地存储这些内容的功能“who”可以访问它们(例如 哪一个 Azure函数或提供服务主体的其他事物)。
我的两个朋友对此有很好的文章:

    PowerShell脚本内容概述

    让’s从脚本开始,只是您可以看到它有多简单。我们赢了’尚未做任何事情,但这是您的信息–注意我们的例子’如果您要重新使用(创建Office 365组)非常简单’能够使用PnP命令(New-PnPUnifiedGroup)并注册一个AAD应用程序。

    这是我使用的脚本内容:

    考虑到这一点,让’s处理先决条件步骤,例如获取PnP PowerShell模块和注册AAD应用程序以能够创建组。    

    安装PnP PowerShell模块

    有两种安装方法,但是PnP PowerShell页面包含您需要的所有内容-完整说明和安装程序链接。看到:

     //docs.microsoft.com/en-us/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps

    注册Azure AD应用以与图表对话

    要是我们’重新使用与图形对话的PnP PowerShell命令(就像我要创建Office 365组一样),那么我们需要AAD应用程序注册,我们的脚本/代码将使用该注册来进行身份验证。我们为我们的操作定义了适当的权限范围’实际表演–以下过程显示了创建网上论坛所需的操作,但是如果您’重新使用执行其他操作的其他脚本,那么很可能是’将需要其他权限范围。

    1. 在Azure门户中,转到“Azure活动目录”部分并找到“App registrations” area:
      SNAGHTML41e995b
    2. 点击“新申请注册” button:
      SNAGHTML41f91c4
    3. 完成细节–请注意,在这种情况下,登录URL可以是唯一标识您的功能的任何内容:
      SNAGHTML42f55f6
    4. 打“Create” button.
    5. 现在,我们需要为此应用注册授予适当的权限:
      1. 进入“Settings” area, and select “Required permissions”:
        SNAGHTML4379a0d
      2. 点击“Add” button, then “Select an API”然后找到并选择“Microsoft Graph”:
        SNAGHTML43a2fcb
      3. 在里面“申请权限”此列表中的部分,选中复选框“读写所有群组”:
        SNAGHTML43bb969
      4. 请点击“Select” and then “Done”保存此配置。
    6. 现在我们需要获取PowerShell脚本的应用程序ID–可以从设置区域复制它。将其存储在安全的地方,以便以后粘贴到我们的PowerShell脚本中:
      SNAGHTML435dc21
    7. 我们还需要获取一个密钥。这可以通过以下方式完成:
      1. 进入“Keys” area:
        SNAGHTML43e1c6f
      2. 给钥匙起个名字– when you click “Save”,键值将出现在框中:
        SNAGHTML4337eb8
        SNAGHTML4346511
      3. 同样,将其存储在安全的位置,以备以后在我们的PowerShell脚本中使用。

    向应用授予管理员同意

    现在我们’定义了我们的AAD应用注册后,租户管理员需要向该应用授予管理员同意。这是安全门,这意味着组织允许此访问Office 365数据。发生的是您以以下形式构造了URL:

    //login.microsoftonline.com/[tenant].onmicrosoft.com/adminconsent?client_id=[App ID]

    因此对于我的应用程序,URL如下所示: //login.microsoftonline.com/chrisobriensp.onmicrosoft.com/adminconsent?client_id=348841f1-6c9d-4044-b014-ed346f2572f2

    当租户管理员点击此URL时,他/她会看到此应用程序的许可要求列表,并可以决定是否授予同意:

    SNAGHTML45a381c

    获得同意后,应用程序可以请求身份验证令牌,该令牌可以执行与所选权限范围相关的操作。在以下位置了解有关此过程的更多信息 承租人 Admin Consent 如果你需要。

      创造 the Function locally, using PowerShell as the language

      好吧,现在已经有了先决条件,我们’准备创建一个Azure函数来运行我们的PS脚本。

      1. 首先,在计算机上创建一个文件夹来托管文件– I named my folder “COB-GroupCreator-Function” to reflect what we’re doing here.
      2. 打开“ VS Code”到该文件夹​​。
      3. 按下CTRL SHIFT + P进入VS Code命令栏,然后开始输入“Azure Functions”拉起那些命令。选择“Create New Project” command:
        SNAGHTMLfff7b5
      4. 按照命令栏中的提示选择文件夹–如果您接受默认值’已经在您之前创建的文件夹中:
        SNAGHTML1568088c
      5. 在选择语言时,请立即选择任何一种–但在这种情况下,我们说我们’d use PowerShell. PowerShell没有’t之所以会出现在列表中,是因为支持仅是实验性的(截至2018年6月),但我们稍后可以切换到它:
        SNAGHTML1569e4bf
      6. 现在让 ’s添加单个功能。再次按CTRL SHIFT + P,然后找到“Create Function” command under Azure功能:
        SNAGHTML156d23fb
      7. 接受我们’ll使用当前文件夹:
        SNAGHTML156f43bf
      8. 在里面next step we can change the language to PowerShell:
        SNAGHTML1572184b
      9. 选择 PowerShell from the list:
        SNAGHTML1574f870
      10. 下一步,我们需要包括“non-verified”模板,而PowerShell支持仍处于试验阶段– select the “更改模板过滤器” option:
        SNAGHTML15764032
      11. 选择 “All” from the list:
        SNAGHTML15778ca8
      12. 现在出现了其他模板–在这种情况下,我们的功能将成为每天运行一次的简单功能,因此我们’ll select “Timer trigger”:
        SNAGHTML159ee9ae
      13. 现在输入函数的名称:
        SNAGHTML15a0bb42
      14. 对于每天上午10点运行的函数,CRON表达式为“0 0 10 * * *”, so let’s enter that when we’顺便问一下功能的时间表’s a good 其他CRON表达式的备忘单):
        SNAGHTML15a49c1e
      15. 现在,一堆新文件将添加到您的文件夹中,包括“run.ps1”该文件是用于函数实现的PowerShell脚本:
        SNAGHTML15a731ad

      We’现在可以为我们的功能实现做准备了。除了说,如果你’re following these steps when PowerShell support is still experimental, you may still have some leftover JavaScript config if you did this. 让’s fix that next.

      使用F5在本地调试我们的PowerShell脚本

      VS Code可以很好地用作PowerShell脚本的调试器。最好的方法是通过本地开发和调试使PowerShell脚本100%正确 之前 将其作为Azure功能发布到云中。您’能够在断点处停止,查看变量等–与在本地进行操作相比,在本地进行操作要容易得多’每天在Azure中重新运行(尽管您也有选择)。

      因此,我们所需要做的就是从launch.json文件中删除JS配置。在.vscode文件夹中找到它:

      SNAGHTML15bee9e2

      删除JS配置部分– 之前:

      SNAGHTML15c009c9

      后:

      SNAGHTML15c08ed7

      VS Code现在非常聪明,可以根据您的.ps1文件扩展名执行正确的操作。您’会发现您可以在脚本中添加一个断点(当前仍只是一行样板代码),然后按F5可以在本地调试:

      SNAGHTML449f5a3

      实际上,您可以做更多的事情来定制按F5时发生的情况–例如,如果您的PowerShell脚本接受参数,并且您想在调试时传递一些值。这是通过将一些特定于PowerShell的配置添加回launch.json文件中来完成的– see 在VS代码中使用launch.json文件进行改进的PowerShell调试 对于这个例子。但是即使没有这个,我们’现在可以在本地单步执行脚本并获得我们进行正确开发和测试所需的反馈。

      准备在云中运行-将文件从SharePointPnPPowerShellOnline模块复制到本地文件夹

      现在,我们需要将文件从SharePoint 即插即用PowerShell模块复制到本地文件夹中。这不是’在本地运行所必需的–文件将从该文件的本地模块路径加载(可以在PS中使用$ Env:PSModulePath找到)–但是当脚本作为Azure函数运行时,这是必需的。所以让’通过运行$ Env:PSModulePath在本地计算机上查找文件–您应该在那里看到一堆路径,但是其中一个将用于SharePointPnPPowerShellOnline模块: 

      SNAGHTML4763bbe

      在计算机上打开该文件夹,然后复制“Modules”子文件夹及其所有’的内容放入包含您的功能PS脚本的文件夹中。

      您r set of files should now look like this:

      SNAGHTMLfd0159

      当您的脚本在云中运行时,Azure Functions运行时现在将加载此文件夹中存储的所有模块,因此您可以成功使用PnP命令。

      将脚本内容粘贴到run.ps1中

      现在,我们准备处理脚本实现。粘贴到我们已经看到的脚本中(为方便起见,在下面重复),或者实现自己的步骤。

      您’将需要用AAD应用ID,AAD应用密钥(密钥)和Office 365租户前缀的值替代脚本中的占位符/变量– for now, let’用硬编码的方式来测试我们的脚本。 后来,我们’将换出这些硬编码的值,然后从Azure中的配置中获取它们。

      提醒一下,这是我使用的脚本内容:

      Once you've pasted those details in, run your script to check it works (by pressing F5 in VS Code). 如果你r AAD app is registered with the right details and permissions, and you have the 即插即用PowerShell module installed properly, things should work just fine when running locally. Hooray! 如果没有,则应解决这些问题,直到在本地成功运行之前,再发布到Azure函数。

      创造 the Azure Function app in the portal

      我们需要一个Azure Function应用程序来将脚本托管在云中。您实际上可以通过VS Code创建此代码(使用命令“Azure函数:在Azure中创建函数应用”),效果很好!但是,为简单起见,让’可以通过Azure门户以常规方式进行操作。即使到那里,我们也有两个选择,但可以带您进入创建功能应用程序流程的一切都很好– for example:

      1. 请点击“Create a resource”:
        SNAGHTMLe7bd811
      2. 开始输入“function app”搜索项目–找到它时选择它,然后按“Create” button:
        SNAGHTMLe7cfece
      3. 然后完成细节–你可以在下面的图片中看到我’重复使用Azure中已有的一些东西(例如资源组,存储帐户等)–但只要有需要就可以创建新的。当然,请注意您所做的选择’在生产中真正做到这一点(尤其是您是否’re 选择消费计划或应用服务计划)。打“Create” button when you’re ready:
        SNAGHTMLe7eade6
      4. 您r 功能应用, as well as an App Insights instance if you selected that option, should now have been created and are ready to host code:

        SNAGHTMLe83a189
      身份验证说明
      在这种情况下,我们的函数实际上不会对调用方进行任何身份验证,因为在这种情况下,我们永远不会通过HTTP调用它(这可能与您创建的其他函数不同)。这纯粹是一个计时器触发功能。

      从VS Code将文件发布到Azure函数:

      下一步,一旦我们’re sure the script is working correctly, is to publish it to an Azure Function. 您 can do this in a variety of ways, but VS Code makes this easy:

      1. 切换到VS Code中的Azure选项卡(底部图标):

        SNAGHTMLbf4881
      2. 查找您之前创建的Function App。右键单击它,然后选择“部署到功能应用”:
        SNAGHTML1ea4112d
      3. 在VS Code命令面板中逐步浏览提示–默认值通常是您需要的:

        SNAGHTMLc1f726
      4. 接受提示:

        图片

      5. VS Code随后将开始发布操作:

        SNAGHTMLc9b489
      6. 您’然后将发现您的文件已作为功能部署到所选的功能应用程序:

        SNAGHTMLe32952

      替代–部署文件的方式不同

      当然,你不 ’*必须*使用VS Code将文件发布到您的功能应用程序中。可以将文件保存在其中的任何文件(FTP,通过Kudu手动复制,Web部署,从源代码管理同步)–您只需要确保文件以正确的结构结尾即可。这是您最终需要得到的:

      SNAGHTMLe3dca72

      SNAGHTMLe3e7ccb

      要使用Kudu部署文件,只需将它们从Windows资源管理器拖放到Kudu中的site / wwwroot文件夹中:

      SNAGHTMLe49905d

        最后一步-安全存储应用程序ID和客户端机密

        此时,您现在应该使您的脚本在云中成功运行。它应按照您为函数定义的时间表执行,或通过使用“Test”Azure门户中的按钮。但是请记住,我们将一些用于应用程序身份验证的值硬编码到了脚本中–我们需要解决该问题。

        与在脚本中对这些值进行硬编码相比,更好的选择是将应用程序设置添加到Azure Function应用程序,然后从那里读取它们。它们由Azure安全地存储,尽管您可以更进一步,并使用Key Vault或类似的工具(如果需要)。两者都比在代码或脚本中包含机密/密码更好!在接下来的步骤中,我们’将它们定义为Azure中的应用设置,并调整脚本以从那里进行选择:

        1. 转到“平台功能”选项卡,然后选择“Application 设定值”:

          SNAGHTMLcdcce0
        2. 向下滚动到“Application 设定值”部分,然后单击“Add new setting” link:

          SNAGHTMLd053c9
        3. 添加具有执行工作权限的Azure AD应用程序注册的应用程序ID和密码(在本例中为创建Office 365组):

          SNAGHTMLd282fd
        4. 还要为您的租户前缀添加一个项目并命名“Tenant”.
        5. 唐’t forget to click “Save”返回页面顶部:

          SNAGHTMLd30906
        Accessing App 设定值 from PowerShell in a Function
        App 设定值 can be retrieved by use of the $ env:[MyAppSetting] PowerShell中的语法,类似于环境变量。因此,在脚本中,我们只需使用以下内容即可与添加配置值的键进行匹配:

        $ env:AppID 
        $ env:AppSecret 
        $ env:租户

        这意味着我们的最终脚本应如下所示:

        瞧!您的脚本现在应该从云中运行,并以应有的方式实现。我赢了’显示此示例(Office 365组)的最终结果,因为您最有可能知道其外观,但是希望您能理解总体思路和涉及的步骤。

        概要

        从云端运行PowerShell脚本的想法非常有用,特别是对于应按计划执行的脚本。我们创建Office 365组的方案是’t 一定 你的东西’d想按计划执行(或者,是否需要每周一次会议或其他定期活动的协作空间?)但是,PnP PowerShell的强大功能意味着 许多 您可以使用这种方法处理的场景。我们展示了如何在Azure函数中运行外部模块(如PnP),以及如何处理对Graph的身份验证– overall, it’这是一种功能强大的方法,对IT专业人员和开发人员均有用。我建议最近将Visual Studio Code与PowerShell一起使用,尤其是因为它可以帮助打包和部署Azure Functions以及提供调试支持。祝您编码愉快!