Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PowerShell モジュール開発入門 / Introduction to PowerShell module development

PowerShell モジュール開発入門 / Introduction to PowerShell module development

9cdd446fb259ec93e52d4388f60197f8?s=128

Takashi Shinohara

February 20, 2020
Tweet

Transcript

  1. PowerShell モジュール開発入門 篠原敬志 (@karamem0)

  2. 自己紹介 Name 篠原敬志 (Takashi Shinohara) Company アバナード株式会社 シニアコンサルタント Award Microsoft

    MVP for Office Development (2018-) Twitter @karamem0 Facebook t.shinohara.56 Blog https://blog.karamem0.jp Bio 紅生姜ジャンキー 2
  3. アジェンダ PowerShell モジュールの概要 PowerShell モジュールの開発 PowerShell モジュールのテスト PowerShell モジュールの CI/CD

    3
  4. PowerShell モジュールの概要

  5. PowerShell とは .NET をベースとしたスクリプト言語 Window 7 以降の Windows に標準搭載 .NET

    のクロスプラットフォーム化に伴い PowerShell もバージョン 6 から .NET Core をターゲットにしたものに Windows PowerShell (~5.1) PowerShell Core (6.0~) バージョン 7 以降は名称が "PowerShell" に統合される 5
  6. PowerShell の歴史 '06 '07 '08 '09 '10 '11 '12 '13

    '14 '15 '16 '17 '18 '19 '20 XP Vista 7 8 8.1 10 2003 2008 2008 R2 2012 2012 R2 2016 2019 1.0 2.0 3.0 4.0 5.0 5.1 6.0 6.1 6.2 7.0 6
  7. PowerShell モジュールとは PowerShell の再利用可能なライブラリ 一連のコマンドレット/関数/変数/エイリアス等をパッケージ化 モジュールごとに厳密に管理されたバージョン 作成したモジュールは NuGet リポジトリに公開可能 PowerShell

    Gallery MyGet Azure DevOps Artifacts 7
  8. PowerShell Gallery 5,900 個 以上の 固有なパッケージ 12 億回 以上の ダウンロード

    40,000 個 以上の 総パッケージ 8
  9. 公開されているモジュールの例 モジュール名 説明 SpeculationControl 脆弱性に対するパッチおよび軽減策の対応状況を確認する ためのモジュール Az Azure を操作するためのモジュール (旧名:

    AzureRM) AzureAD Azure Active Directory を操作するためのモジュール IISAdministration IIS を管理するためのモジュール AWSPowerShell AWS を操作するためのモジュール 9
  10. PowerShell モジュールのインストール Install-Module コマンドレット (1 回のみ実行) Install-Module -Name <Module> -Scope

    CurrentUser Register-PSRepository コマンドレットでリポジトリを追加すること でプライベートなリポジトリからもインストール可能 10
  11. PowerShell モジュールのインポート Import-Module コマンドレット (プロンプトの起動ごとに実行) Import-Module -Name <Module> 事前にモジュールをインポートしておきたい場合はプロファイルにイ ンポートを記述しておく

    PowerShell 3.0 からはモジュールの暗黙的なインポートがサポートさ れているためいきなりコマンドレットを記述してもOK 11
  12. PowerShell モジュールの開発

  13. PowerShell モジュールの要素 名前 説明 コマンドレット PowerShell で動作するコマンド (命令文)。標準で提供さ れるもののほかに C#

    で独自に作成することもできる。 関数 PowerShell スクリプトで記述される一連の操作を実行し 値を返すための機能。一般的なプログラミング言語の関数 とほとんど同じ。 変数 コマンドレットの結果などを格納するための領域。一般的 なプログラミング言語の変数とほとんど同じ。 エイリアス コマンドレットを短く記述するために付けられる別名。 13
  14. PowerShell モジュールの種類 モジュールの種類 説明 スクリプト モジュール モジュール ファイル (.psm1) に

    PowerShell コード を記述する バイナリ モジュール .NET アセンブリ (.dll) に PowerShell コードを記述 する マニフェスト モジュール マニフェスト ファイル (.psd1) で単一または複数のモ ジュールを定義する ダイナミック モジュール ファイルとして保持せずインメモリ内で展開する この形式で作ることがほとんど 14
  15. PowerShell モジュールの概念 マニフェスト モジュール (.psd1) スクリプト モジュール (.psm1) バイナリ モジュール

    (.dll) ダイナミック モジュール 15
  16. マニフェスト ファイル (.psd1) モジュールに関するメタ データを記述するためのファイル マニフェストに関連付けられたモジュール モジュールのバージョン モジュールの作成者 サポートする PowerShell

    のバージョン 依存関係のあるモジュールやライブラリ エクスポートするコマンドレット/関数/変数/エイリアス コマンドレットで操作可能 New-ModuleManifest Update-ModuleMafinest 16
  17. モジュールの形式の比較 項目 スクリプト モジュール バイナリ モジュール 言語 PowerShell C# または

    VB 規模 小~中規模 大規模 速度 低速 高速 コマンドレット 可能 難しい (不可能ではない) マネージ DLL 問題になることがある 可能 アンマネージ DLL (P/Invoke) 難しい (不可能ではない) 可能 17
  18. スクリプト モジュールの開発 モジュール ファイル (.psm1) に関数/変数/エイリアスを記述する 関数/変数/エイリアスは Export-ModuleMember およびマニフェ スト

    ファイル (.psd1) で公開するかどうかを指定する モジュール ファイル (.psm1) にすべての関数/変数/エイリアスを 記述するとソースの可読性が下がるため、複数のスクリプト ファイル (.ps1) をドットソース読み込みする方法もある 18
  19. スクリプト モジュール: Hello World モジュール ファイル (HelloWorld.psm1) function HelloWorld {

    [CmdletBinding()] param ( ) process { Write-Output 'Hello World!' } } 19
  20. スクリプト モジュール: Hello World マニフェスト ファイル (Helloworld.psd1) @{ RootModule =

    'HelloWorld.psm1' ModuleVersion = '1.0' } 20
  21. スクリプト モジュール: Hello World モジュールのインポート PS C:¥HelloWorld> Import-Module '.¥HelloWorld.psd1' -PassThru

    ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Script 1.0 HelloWorld HelloWorld 21
  22. バイナリ モジュールの開発 以下のターゲットでプロジェクトを作成する Windows PowerShell の場合: .NET Framework 4.7.2 PowerShell

    Core の場合: .NET Core 2.1 PowerShellStandard.Library を NuGet から参照する コマンドレットは PSCmdlet クラスを継承し CmdletAttribute 属性 を付ける 22
  23. バイナリ モジュール: Hello World ソース コード (HelloWorld.cs) [Cmdlet("Write", "HelloWorld")] [Alias("helloworld")]

    public class HelloWorld : PSCmdlet { protected override void ProcessRecord() { this.WriteObject("Hello World!"); } } 23
  24. バイナリ モジュール: Hello World マニフェスト ファイル (HelloWorld.psd1) @{ RootModule =

    'HelloWorld.dll' ModuleVersion = '1.0' } 24
  25. バイナリ モジュール: Hello World モジュールのインポート PS C:¥HelloWorld> Import-Module '.¥bin¥Debug¥net472¥HelloWorld.psd1' -PassThru

    ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Binary 1.0 HelloWorld {Write-HelloWorld, helloworld} 25
  26. PowerShell モジュールのテスト

  27. Pester とは PowerShell 標準でインストールされている PowerShell スクリプト の単体テストのためのモジュール https://github.com/pester/Pester 27

  28. Pester の構文 名前 説明 Describe 複数の Context または It をグループ化する

    Context Context の中で複数の It をグループ化する It 実行されるテスト スクリプトを定義する BeforeEach 各 It の実行前に実行されるスクリプトを定義する AfterEach 各 It の実行後に実行されるスクリプトを定義する Should テストの実行結果を比較し失敗をスローする Mock 既存のコマンドレットをモックする Invoke-Pester テストを実行する 28
  29. Pester のアサーションの例 名前 説明 Be 指定した値と等しいことを検証する BeGreaterThan 指定した値より大きいことを検証する BeGreaterOrEqual 指定した値より等しいか大きいことを検証する

    BeLessThan 指定した値より小さいことを検証する BeLessOrEqual 指定した値より等しいか小さいことを検証する BeOfType 指定した型であることを検証する Match 正規表現に一致することを検証する Throw 例外を発生させることを検証する Not 他のアサーションの意味を反転させる 29
  30. Pester によるテスト: Hello World テスト スクリプト (HelloWorld.Tests.ps1) Import-Module './HelloWorld.psd1' -Force

    Describe 'Tests HelloWorld' { Context 'Positive Test' { It 'Returns HelloWorld' { HelloWorld | Should -Be 'Hello World!' } } } 30
  31. Pester によるテスト: Hello World テストの実行 PS C:¥HelloWorld> Import-Module Pester PS

    C:¥HelloWorld> Invoke-Pester Executing script C:¥HelloWorld¥HelloWorld.Tests.ps1 Describing Tests HelloWorld Context Positive Test [+] Returns HelloWorld 90ms Tests completed in 505ms Tests Passed: 1, Failed: 0, Skipped: 0, Pending: 0, Inconclusive: 0 31
  32. MSTest によるテスト 単体テスト プロジェクトで NuGet からパッケージを参照する Windows PowerShell の場合: PowerShellStandard.Library

    PowerShell Core の場合: Microsoft.PowerShell.SDK Microsoft.PowerShell.Commands.Diagnostics Microsoft.PowerShell.Commands.Management Microsoft.PowerShell.Commands.Utility Microsoft.PowerShell.ConsoleHost Microsoft.WSMan.Management Microsoft.WSMan.Runtime 32
  33. C# からの PowerShell の実行 Windows PowerShell と PowerShell Core で書き方が異なる

    Windows PowerShell の場合: PowerShell オブジェクトにコマン ド名やパラメーターの情報を設定して実行する PowerShell Core の場合: Runspace と Pipeline を作成し、 Pipeline オブジェクトにコマンド名やパラメーターの情報を設定し て実行する 実行結果は PSObject (PowerShell の汎用オブジェクト) として取得 できる 33
  34. Windows PowerShell からの実行 ソース コード var powershell = PowerShell.Create(); powershell.Commands.Clear();

    powershell.AddCommand("Import-Module"); powershell.AddParameter("Name", "./HelloWorld.psd1"); powershell.Invoke(); powershell.Commands.Clear(); powershell.AddCommand("helloworld"); var outputs = powershell.Invoke(); var result = outputs[0].BaseObject; Assert.AreEqual("Hello World!", result); 34
  35. PowerShell Core からの実行 ソース コード var runspace = RunspaceFactory.CreateRunspace(); runspace.Open();

    var pipeline1 = runspace.CreatePipeline(); var command1 = new Command("Import-Module"); command1.Parameters.Add("Name", "./HelloWorld.psd1"); pipeline1.Commands.Add(command1); pipeline1.Invoke(); var pipeline2 = runspace.CreatePipeline(); var command2 = new Command("helloworld"); pipeline2.Commands.Add(command2); var outputs = pipeline2.Invoke(); var result = outputs[0].BaseObject; Assert.AreEqual("Hello World!", result); 35
  36. PowerShell モジュールの CI/CD

  37. Azure DevOps を使った CI/CD Azure Repos GitHub Git Server Azure

    Pipelines Azure Artifacts PowerShell Gallery 37
  38. Azure Pipelines ビルドとデプロイのプロセスを自動化するため の機能 Build Pipeline: ビルドと自動テストを実行 し Artifacts を作成する

    Release Pipeline: 作成された Artifacts を 環境にデプロイする Multi-stage Pipeline: Build Pipeline と Release Pipeline に代わって新しく提供され るパイプラインの形式 38
  39. Azure Artifacts 作成した NuGet や npm などのパッケージを 管理するためのリポジトリとパッケージを公開 するためのフィードを提供 作成したパッケージを

    Azure Pipelines に組み 込むことが可能 39
  40. PowerShell Gallery への発行 PowerShell Gallery へのログ イン https://www.powershellgall ery.com 40

  41. PowerShell Gallery への発行 API キーの発行 41

  42. PowerShell Gallery への発行 コマンドレットの実行 Publish-Module -Name <Path> -NuGetApiKey <Key> Marketplace

    から Azure DevOps 向けの拡張機能を入手可能 PowerShell Gallery Publisher https://marketplace.visualstudio.com/items?itemName=k enakamu.PSGalleryPublisher 42
  43. Azure Artifacts への発行 NuGet パッケージの作成 43

  44. Azure Artifacts への発行 NuGet パッケージの発行 44

  45. Azure Artifacts への発行 Azure Artifacts のフィードに 発行されたパッケージ 45

  46. Azure Artifacts への発行 Azure Artifacts のリポジトリを PowerShell に追加 Register-PSRepository -Name

    'PowershellAzureDevopsS ervices' -SourceLocation 'https://<OrgName>.pkgs.vi sualstudio.com/_packaging/<FeedName>/nuget/v2' -Pub lishLocation 'https://<OrgName>.pkgs.visualstudio.c om/_packaging/<FeedName>/nuget/v2' -InstallationPol icy Trusted 発行されたパッケージのインストール Install-Module -Name 'HelloWorld' -Repository 'Powe rshellAzureDevopsServices' -Scope CurrentUser 46
  47. まとめ

  48. サンプル コード スクリプト モジュール https://dev.azure.com/karamem0jp/PowerShell-ScriptModul e-HelloWorld バイナリ モジュール https://dev.azure.com/karamem0jp/PowerShell-BinaryModu le-HelloWorld

    48
  49. 参考リンク The Next Release of PowerShell – PowerShell 7 https://devblogs.microsoft.com/powershell/the-next-release

    -of-powershell-powershell-7/ PowerShell モジュールをインポートする https://docs.microsoft.com/ja-jp/powershell/scripting/devel oper/module/importing-a-powershell-module Use Azure Artifacts as a private PowerShell repository https://docs.microsoft.com/en-us/azure/devops/artifacts/tu torials/private-powershell-library 49