実世界のPowerShellモジュールの作成:スキャフォールディング関数

あなたは、独自のシナリオに最適なPowerShellモジュールを見つけるのに苦労していますか?数千ものモジュールが利用可能な中、あきらめるべきだと感じるかもしれません。しかし、それでは解決策が不完全であったり非効率になる可能性があります。では、モジュールの作成を始めてみませんか?

このガイドでは、ニーズに合わせた堅牢で再利用可能なソリューションを構築するためのモジュールの作成方法を紹介します。

スクリプトを異なるプロジェクトで再利用できる強力な構築ブロックに変えてみましょう!

コンピュータインベントリモジュールの構築

このガイドでは、コンピュータのハードウェア情報を収集するためのPowerShellモジュールを作成します。このモジュールは、システム管理者が複数のシステムでメモリ、ストレージ、およびプロセッサの詳細を収集してレポートするのに役立ちます。

当社のモジュールには次の機能があります:

  • 特定のハードウェア情報を収集するための機能
  • PowerShellセッションを使用したリモートシステムサポート
  • 一貫したレポート作成のための標準化された出力形式

この実践的な例は、システム管理向けの便利なツールを作成しながら、モジュール開発の基本的な概念を示しています。

PowerShellモジュールの設定

複数のシステムでスクリプトを管理することはすぐに混沌としてしまうかもしれません。しかし、ワークフローが困難になったときには、PowerShellモジュールが役立ちます。モジュールは、スクリプトをグループ化して再利用し、時間を節約し、エラーを減らすための構造化された方法です。

PowerShellモジュールを構築するために重要な概念を組み合わせてみましょう。

まず、モジュールディレクトリを作成し、モジュール自体を定義して作業を整理します。

## Create the module directory in the all-user location
mkdir 'C:\Program Files\PowerShell\Modules\ComputerInventory'

## Create the module to hold the module functions
Set-Content -Path 'C:\Program Files\PowerShell\Modules\ComputerInventory\ComputerInventory.psm1' -Value ''

Set-Contentコマンドは、すべてのユーザーパスにComputerInventoryという名前のモジュールを作成します。この場所は、マシンにログインするすべてのユーザーがモジュールにアクセスできるようにするために選択されています。これは、同じPowerShell機能にアクセスする必要がある複数のユーザーがいるエンタープライズ環境で重要です。ユーザー固有の場所とは異なり、この中央化されたパスは一貫したモジュールの利用可能性とシステム全体での管理を容易にします。

モジュールの利用可能性を確認します:

## The module is already showing up as available
Get-Module ComputerInventory -ListAvailable

現在はシェルですが、後で適切に読み込まれることを確認します。

ファンクションの足場

よく構築されたモジュールは重要ですが、中身がそれを本当に使いやすくします。作業的でなくても各部分が何をしているのかを理解する時間を無駄にする代わりに、モジュールのファンクションのために足場を作成して生産的になります。

VS Codeのようなテキストエディターでモジュールを開き、ファンクションの足場を作成します。

記述的な名前のプレースホルダー・ファンクションを作成することから始めます。

function Get-MemoryInfo {
    [CmdletBinding()]
    param()

}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

}

ファンクション名は一貫した動詞-名前の命名規則に従います。

PowerShellのファンクション名は動詞-名前の命名規則に従います。これは標準化された命名パターンです。この場合、ファンクションは次のように名前が付けられています:

  • Get-MemoryInfo
  • Get-StorageInfo
  • Get-ProcessorInfo

各ファンクション名は「Get」という動詞(情報を取得することを示す)で始まり、それに続く名詞が何の情報を取得するかを示しています(Memory、Storage、またはProcessor)。

この命名規則は、PowerShellにおいて重要です。なぜなら、関数を予測可能で理解しやすくするために役立つからです – ユーザーは名前を見るだけで関数が何を行うのかを素早く把握できます。

以下を実行してその存在を確認してください:

Get-Command -Module ComputerInventory

次のコマンドを実行すると、Get-Command -Module ComputerInventoryというコマンドを実行すると、次のような出力が表示されます:

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-MemoryInfo                                     1.0.0      ComputerInventory
Function        Get-ProcessorInfo                                  1.0.0      ComputerInventory
Function        Get-StorageInfo                                    1.0.0      ComputerInventory

このコマンドは、ComputerInventoryモジュールで利用可能なすべての関数をリストアップします。このモジュールには、作成した3つの関数:Get-MemoryInfo、Get-StorageInfo、Get-ProcessorInfoが含まれています。

この段階では、モジュールには関数の殻が含まれています。これらの関数をカスタムオブジェクトを使用して一貫した出力を定義することで強化しましょう。

カスタムオブジェクトを使用した標準化された出力

スクリプト間の一貫性のない出力は、データ解析やトラブルシューティングを悪夢に変える可能性があります。プロのPowerShell開発では、一貫した出力を確保することが効果的なスクリプトの基本です。

カスタムオブジェクトを使用して出力を標準化することで、関数間の一貫性を維持するのに役立ちます。

次のスクリプトでは:

  • カスタムオブジェクトにはComputerNameHardwareCategoryInfoのプロパティが含まれています。
  • HardwareCategoryプロパティは類似のハードウェアタイプをグループ化し、ComputerNameは複数のコンピュータの拡張性を考慮して設計されています。
function Get-MemoryInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

まず、最新バージョンを確認するためにモジュールを再インポートしましょう:

Import-Module ComputerInventory -Force

これで、関数を実行して出力を確認できます。

PS> Get-MemoryInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  

PS> Get-StorageInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  

PS> Get-ProcessorInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName

各関数は、空のComputerNameとInfoプロパティを持つハッシュテーブルを返しますが、それぞれのハードウェアカテゴリが定義されています。

リモートサポート用のセッションパラメータを追加する

数十台、あるいは数百台のコンピュータでスクリプトを実行する必要があると想像してください。各関数にコンピュータ名を手動で指定する必要があるとすると、手間がかかりエラーが発生しやすくなります。幸いにも、PowerShell Remotingには解決策が用意されています。

ComputerNameパラメータの代わりに、PowerShell Remotingを活用するためにSessionパラメータを使用します:

function Get-MemoryInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

このパラメータは、複数のシステムにスケーリングする際の柔軟性を確保します。

Sessionパラメータは、リモートコンピュータでのコマンドの実行にPowerShell Remotingを使用するように設計されています。これが強力な理由です:

  • これは、PSSessionオブジェクト(具体的にはSystem.Management.Automation.Runspaces.PSSession型)を受け入れる必須パラメータとして定義されています。
  • Sessionパラメータは、$Session.ComputerNameを介してコンピュータ名を自動的に提供し、出力オブジェクトに表示されます。

このアプローチにはいくつかの利点があります:

  • 複数のシステムを操作する際の効率的なスケーリングが可能です
  • 各コマンドごとに新しい接続を作成する代わりに、同じセッションを複数の操作で再利用できます。各関数呼び出しのために個々の接続を確立するよりも効率的です
  • 関数をテストするには、単一の PSSession を作成し、そのセッションをインベントリ関数全体で使用します。テストセッションを作成する例では、次のようにします: $testSession = New-PSSession -ComputerName SRV2

モジュールを保存して再インポートします:

ipmo ComputerInventory -Force

関数のテスト

モジュールを構築した後、そのモジュールが正常に動作することをどのように確認しますか?テストは、モジュールの関数が期待どおりに動作し、正確なデータを返すことを確認するために不可欠です。このステップをスキップすると、本番環境で予期しない問題が発生する可能性があります。

リモートセッションを確立し、モジュールをテストします:

$testSession = New-PSSession -ComputerName SRV2

Get-MemoryInfo -Session $testSession
Get-StorageInfo -Session $testSession
Get-ProcessorInfo -Session $testSession

各関数は、期待されるプロパティと正しいコンピュータ名を持つオブジェクトを返すはずです。これらの関数は、堅牢なインベントリツールの基盤を形成します。

表示されたコードに基づいて、これらの関数をリモートセッションでテストすると、出力は次のようになります:

PS> $testSession = New-PSSession -ComputerName SRV2
PS> Get-MemoryInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  SRV2

PS> Get-StorageInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  SRV2

PS> Get-ProcessorInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName                  SRV2

各関数は、コンピュータ名(セッションから)、特定のハードウェアカテゴリ、および情報フィールド(現在は null ですが、実際のハードウェア情報を保持するように設計されています)を含むハッシュテーブルを返します。

結論

この記事では、独自の PowerShell モジュールを作成することが重要であり、オフシェルフのモジュールでは対処できないユニークな課題に取り組むために必要であることを学びました。カスタムモジュールが、環境内の特定の構成やプロセスにおいてゲームチェンジャーとなる方法についても探求しました。

これはComputerInventoryモジュールとの旅の始まりに過ぎません。今後のブログ投稿では、実際のハードウェア情報収集機能、エラーハンドリング、高度なリモート管理機能を追加して、この基盤を拡張していきます。

システム管理者向けの強力なツールにこの基本的なフレームワークを変換する過程にご期待ください!

Source:
https://adamtheautomator.com/powershell-module-functions/