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

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

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

Takashi Shinohara

February 20, 2020
Tweet

More Decks by Takashi Shinohara

Other Decks in Programming

Transcript

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

    MVP for Office Development (2018-) Twitter @karamem0 Facebook t.shinohara.56 Blog https://blog.karamem0.jp Bio 紅生姜ジャンキー 2
  2. PowerShell とは .NET をベースとしたスクリプト言語 Window 7 以降の Windows に標準搭載 .NET

    のクロスプラットフォーム化に伴い PowerShell もバージョン 6 から .NET Core をターゲットにしたものに Windows PowerShell (~5.1) PowerShell Core (6.0~) バージョン 7 以降は名称が "PowerShell" に統合される 5
  3. 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
  4. 公開されているモジュールの例 モジュール名 説明 SpeculationControl 脆弱性に対するパッチおよび軽減策の対応状況を確認する ためのモジュール Az Azure を操作するためのモジュール (旧名:

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

    CurrentUser Register-PSRepository コマンドレットでリポジトリを追加すること でプライベートなリポジトリからもインストール可能 10
  6. PowerShell モジュールの要素 名前 説明 コマンドレット PowerShell で動作するコマンド (命令文)。標準で提供さ れるもののほかに C#

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

    PowerShell コード を記述する バイナリ モジュール .NET アセンブリ (.dll) に PowerShell コードを記述 する マニフェスト モジュール マニフェスト ファイル (.psd1) で単一または複数のモ ジュールを定義する ダイナミック モジュール ファイルとして保持せずインメモリ内で展開する この形式で作ることがほとんど 14
  8. マニフェスト ファイル (.psd1) モジュールに関するメタ データを記述するためのファイル マニフェストに関連付けられたモジュール モジュールのバージョン モジュールの作成者 サポートする PowerShell

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

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

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

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

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

    public class HelloWorld : PSCmdlet { protected override void ProcessRecord() { this.WriteObject("Hello World!"); } } 23
  14. バイナリ モジュール: 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
  15. Pester の構文 名前 説明 Describe 複数の Context または It をグループ化する

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

    BeLessThan 指定した値より小さいことを検証する BeLessOrEqual 指定した値より等しいか小さいことを検証する BeOfType 指定した型であることを検証する Match 正規表現に一致することを検証する Throw 例外を発生させることを検証する Not 他のアサーションの意味を反転させる 29
  17. 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
  18. 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
  19. 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
  20. C# からの PowerShell の実行 Windows PowerShell と PowerShell Core で書き方が異なる

    Windows PowerShell の場合: PowerShell オブジェクトにコマン ド名やパラメーターの情報を設定して実行する PowerShell Core の場合: Runspace と Pipeline を作成し、 Pipeline オブジェクトにコマンド名やパラメーターの情報を設定し て実行する 実行結果は PSObject (PowerShell の汎用オブジェクト) として取得 できる 33
  21. 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
  22. 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
  23. Azure DevOps を使った CI/CD Azure Repos GitHub Git Server Azure

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

    Release Pipeline: 作成された Artifacts を 環境にデプロイする Multi-stage Pipeline: Build Pipeline と Release Pipeline に代わって新しく提供され るパイプラインの形式 38
  25. PowerShell Gallery への発行 コマンドレットの実行 Publish-Module -Name <Path> -NuGetApiKey <Key> Marketplace

    から Azure DevOps 向けの拡張機能を入手可能 PowerShell Gallery Publisher https://marketplace.visualstudio.com/items?itemName=k enakamu.PSGalleryPublisher 42
  26. 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
  27. 参考リンク 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