PowerShell関数

このエントリは、PowerShellを学ぶシリーズの13のうちのパート12です

PowerShellを学ぶシリーズのこのエピソードでは、PowerShell関数について考察します。 前回のエピソードでは、PowerShell スクリプトを取り上げ、PowerShell を使用してソリューションを作成し、問題を解決することを開始しました。 PowerShell スクリプトは素晴らしく、多くの人が PowerShell を学習する際にこの段階でかなりの時間を費やしています。 スクリプトを使えば、物事をかなりシンプルに保つことができ、タスクを素早く自動化するのに役立ちます。 もっとPowerShellを書けるようになったら、PowerShell関数の作成も視野に入れるようにしましょう

ビデオ

文書よりもビデオ形式がお好みでしたら、次の TechThoughts ビデオでこのトピックについて説明しています。

PowerShell 関数を記述すべきとき

The end of the day is a set of code that perform a task, PowerShell script is the powerShell. それは PowerShell 関数が行うことでもあります! では、なぜスクリプトではなく関数を書くことを選択するのでしょうか。 以下にその理由を説明します。 一般的に言って、スクリプトは自分のためのものです。 コードを共有したり、チームメイトに使ってもらったりする場合は、関数が提供する機能を使い始めるとよいでしょう。 確固たる線引きはありません。 ワークステーションで一度だけ実行するような簡単なタスクであれば、スクリプトを使用するのがよいでしょう。

  • 単一目的 – 関数は通常、狭いタスクを実行するために使用され、「1 つのことを行い、それを素晴らしくする」ものです。 このため、関数は非常に再利用しやすくなっています。 たとえば、ロギング関数を書いた場合、その PowerShell ロギング関数を他の関数やスクリプトで使用できます。
  • ヘルプ – 関数はヘルプ ベースのコメントをサポートします。
  • パラメータ – 単純および高度なパラメータ宣言と制御のサポートにより、関数は動的で、さまざまな形式のユーザー入力を受け取ることができます。
  • テスト可能 – 関数はテストおよびモック化でき、コードの品質を大幅に向上させます。 以下、それぞれのセクションに飛び込み、詳しく見ていきます。
    # function help - (optional but strongly encouraged)# function name# CmdletBinding - (optional)# parameters - (optional)# function logic (optional Begin / Process / End)# return - (optional)function Verb-Noun { param ( ) begin { } process { } end { }}

    関数ヘルプ

    関数のトップにヘルプを含めると、関数に対して Get-Help を実行したときにそれが表示されます。 これは、他の人があなたのコードを調査しているときに、強力な機能です。

    すべてのヘルプ フィールドはオプションであり、お好みで追加または削除できます。

    <#.SYNOPSIS Short description.DESCRIPTION Long description.EXAMPLE C:\PS> Example of how to use this cmdlet.EXAMPLE C:\PS> Another example of how to use this cmdlet.PARAMETER InputObject Specifies the object to be processed. You can also pipe the objects to this command..OUTPUTS Output from this cmdlet (if any).NOTES General notes.COMPONENT The component this cmdlet belongs to#>

    CmdletBinding

    
    

    優れた機能を書いて Get-AllFileInformation という名前をつけた場合、コマンドレットのように見えますし動作もします。 しかし、PowerShell 関数はコマンドレットではないということは、重要な違いです。

    CmdletBinding は関数の属性で、関数をよりコンパイルされたコマンドレットのように動作させる機能を有効にするものです。

    • Write-Verbose – ユーザーが -Verbose スイッチを使用して、関数が何をしているかを確認できるようにします。
    • PositionalBinding – 関数が各パラメーター名を明示的に提供することなく実行されることを可能にします。 値は、関数に提供される順序によって推測されます

    parameters

    param ( $City, $Units = 'USCS', $Language = 'en', $Short)

    パラメーターは、ユーザーが関数と動的に対話する方法を提供する役割を担います。

    非常に基本的なままで、パラメーターの名前のみを宣言することもできます。

    非常に基本的なままで、パラメータの名前だけを宣言することもできますし、パラメータに何が必要かを非常に具体的にすることもできます。

    • パラメーターが必須であるかどうか
    • パラメーターの位置 (順序)
    • パラメーター タイプ (string/int/bool/etc)
    • デフォルト値の設定
    • Input validation
    • Parameter sets
    • Much more

    この投稿ですべての考えられるパラメーター構成はカバーしきれないと思います。 何年も PowerShell を書いていても、すべてのパラメーター設定と構文を記憶することは困難だと思います。 パラメーターの宣言は、関数への入力を受け取る方法であることを知っておいてください。 パラメータ宣言には多くの詳細や制御を与えることができますが、ニーズに応じてシンプルに保つこともできます。 この記事の下にあるパラメータのリンクをブックマークしてください。

    Begin Process End

    これらの 3 つのキーワードは、関数内で宣言できるフェーズです。

    • Begin は開始時にいくつかの手順を初期化します
    • Process は受け取ったオブジェクトを処理します
    • End はクリーンアップを実行できます。

    これは、パイプラインからの入力の処理をサポートする関数を作成したい場合に特に便利です。

    これは理論的に把握するのが難しいので、ここではその使用法を示す例を示します。 Process は渡された各項目に対して実行され、Process はパイプラインの現在のオブジェクトにアクセスできます。

    関数のロジック

    PowerShell 関数内に含まれるロジックは、スクリプトのそれと変わりません。 ここでは、関数が意図するタスクを実行するためのコア ロジックを記述します。 これは、このコースの第1話から第10話までで説明しました。 また、PowerShell スクリプトのエピソードで完全なライブ例を見ることができます。

    Function return

    すべての関数が、実行時に何かを返すわけではありません。 関数が何かを返す場合は、オプションで return を使用できます。 return を使用すると、関数内のそれ以降のすべての動作が停止し、関数が終了することを覚えておいてください。

    function Get-Total { param ( $Number1, $Number2 ) $total = $Number1 + $Number2 return $total}Get-Total -Number1 2 -Number2 2

    上記の例では、この単純な関数には整数型の 2 つのパラメーターが含まれています。 関数のロジックは 2 つの数値を足し合わせて、整数をユーザーに返します。

    初めての PowerShell 関数

    以下の PowerShell 関数を見てみましょう。 レイアウトは以前に説明したものと同じであることに注意してください。

    <#.SYNOPSIS Returns your public IP address..DESCRIPTION Queries the ipify Public IP Address API and returns your public IP..EXAMPLE Get-PublicIP Returns the public IP..OUTPUTS System.String.NOTES https://github.com/rdegges/ipify-api#>function Get-PublicIP { $uri = 'https://api.ipify.org' try { $invokeRestMethodSplat = @{ Uri = $uri ErrorAction = 'Stop' } $publicIP = Invoke-RestMethod @invokeRestMethodSplat } catch { Write-Error $_ } return $publicIP}#Get-PublicIP

    この関数の実際のロジックはかなり単純なので、スクリプトとして残しておきたくなるかもしれません。 しかし、これは 1 つの特定のことを行い、それをうまく行うことに注意してください。 スクリプトを参照またはインポートする代わりに、この関数を他の高度なロジックに組み入れることができます。

    関数のスコープ

    ほとんどの言語と同様に、PowerShell には変数に対するスコープ ルールがあります。 変数が関数内にある場合、その値を「見る」ことはできなくなります。

    function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2

    この関数は期待どおりに動作し、正しく数値を 2 倍にします。 しかし、コンソールで、$total の値が何であるかを確認してみてください。 できないでしょう。 これは、$total が関数にスコープされており、アクティブなコンソール セッションにはスコープされていないためです。

    これは PowerShell の初心者にとって混乱しやすく、関数を書くのがより困難になる可能性があります。

    ロジックの大部分をスクリプト形式で記述し、変数をテストしながら進めていくことができます。

    あるいは、Write-Host、Write-Output、またはよりよい Write-Debug を使用して、関数内の変数で何が起こっているかを見ることができます!

    function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 Write-Debug $total return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2 -Debug

    デバッグ スイッチにより、$total 内の値にアクセスでき、論理が意図したとおり行われているか確認できることに注意してください。

    例を閉じる

    以下は、PowerShell を使用して人気のウェブサイト reddit を閲覧できるようにする 2 つの PowerShell 関数の大きな例です!

    以下の GitHub gist リンクでコードにアクセスし、コンソールにロードします。

    https://gist.github.com/techthoughts2/cd2b720c9b291510cbd643e6ca73e05f

    これらの関数を調べながら、次の質問に答えてみてください:

    • 2つの関数のうち、どちらが主機能ですか
    • これらは標準機能ですか
    • パイプライン入力はどちらの関数でサポートされますか?

    Additional Reading

    • Functions
    • Parameters
    • Functions Advanced
    • Functions Advanced Parameters
    • PowerShell Approved Verbs
    • CmdletBindingAttribute

    Series Navigation << PowerShell ScriptsManage Cloud with PowerShell >>