New RelicのInfrastructure agentのインストールコマンドからPowershellの挙動を理解する

記事タイトルとURLをコピーする

こんにちは。マネージドサービス部の塩野です。

New Relicでは、デフォルトで用意されているインストールコマンドで簡単に監視エージェントのインストールができます。

実際、New Relicの画面上ではコマンドラインが1行で記載されていますが、実際は複数のコマンドが結合されて1つのコマンドになっています。 今回はこのインストールコマンドを分解して、なぜこのようなコマンドラインになっているのか深堀してみたいと思います。

想定読者

  • Powershell初学者
  • Powershellを学びたい人

参考にしたコマンドの入手

インストールコマンドの入手元について

今回使用するコマンドは、Add Dataから Infrastructure & OS を開き、一覧の中からWindowsを選択した先にあります。

インストールコマンドについて

上記画面で表示されたインストールコマンドは下記の通りです。
※下記コマンドラインは、実際のものと比較するとライセンスキーとNew RelicのアカウントIDは別のものに差し替えてあります。

[Net.ServicePointManager]::SecurityProtocol = 'tls12, tls'; $WebClient = New-Object System.Net.WebClient; 
$WebClient.DownloadFile("https://download.newrelic.com/install/newrelic-cli/scripts/install.ps1",
"$env:TEMP\install.ps1"); & PowerShell.exe -ExecutionPolicy Bypass -File $env:TEMP\install.ps1; 
$env:NEW_RELIC_API_KEY='NRAK-XXXXXXXXXX'; $env:NEW_RELIC_ACCOUNT_ID='1234567'; 
& 'C:\Program Files\New Relic\New Relic CLI\newrelic.exe' install

コマンドの解説

このWindows用のインストールコマンドはPowershellで書かれており、Powershellを理解する上での様々なエッセンスが含まれています。今回はそういった点にフォーカスした記事になります。

複数コマンドの結合

まず、冒頭で複数のコマンドが結合されていることをお伝えさせて頂きました。上記のインストールコマンドの中をみるといくつかの ; の文字が見つかると思います。 Powershellではコマンドとコマンドを結合する場合に2つ方法があり、前のコマンドと後ろのコマンドを完全に別ものとして扱う場合に ; を分割文字として使用することで複数コマンドを1行にまとめることができます。 また、上記インストールコマンドには含まれていませんが、コマンドの実行結果を元に別のコマンドを実行する場合は | を分割文字として使用します。

詳細は下記ページに記載されていますが、簡単な例をご紹介させて頂きます。

learn.microsoft.com

まずは、複数コマンドを1行にまとめる例です。 下記コードはどちらも変数に test という文字を代入して、コンソール画面に変数の内容を表示するコマンドになります。

▼複数行に分かれたコマンド
$test = 'test'
Write-host $test

▼1行に結合させたコマンド
$test = 'test' ; Write-host $test

New Relicのインストールコマンドには使用されていませんが、コマンドを連結して実行結果を元に別のコマンドを実行する例です。 まずは連結していない状態を確認してから、連結した後の挙動を見てみましょう。

PS C:\> Get-ChildItem -Path C:\

    ディレクトリ: C:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024/01/15  AM 10:37                Microsoft
d-----        2022/05/07   PM 2:24                PerfLogs
d-r---        2024/05/01  AM 10:27                Program Files
d-r---        2024/03/22   PM 6:17                Program Files (x86)
d-r---        2024/01/09   PM 1:10                Users
d-----        2024/04/10  PM 11:41                Windows

Cドライブ直下の一覧を表示するコマンドです。次に、コマンドを連結して出力結果に対してフィルタをかけます。 下記の出力結果の通り、出力結果に対してフィルタを書けることができました。 下記例のようにコマンドで得た結果を元に別の出力結果を求める場合には、パイプ | を使用してコマンドを実行します。

PS C:\> Get-ChildItem -Path C:\ | Where-Object{$_.Name -like 'Microsoft'}

    ディレクトリ: C:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024/01/15  AM 10:37                Microsoft

ファイルのダウンロード

先頭行に書かれているこの部分ですが、.Netの「System.Net.WebClient」クラスがTLSで通信するために必要なコマンドになります。 このコマンドがないとTLSで通信ができずにエラーとなります。

[Net.ServicePointManager]::SecurityProtocol = 'tls12, tls'

次にファイルダウンロードの部分を見ていきましょう。

$WebClient = New-Object System.Net.WebClient; 
$WebClient.DownloadFile("https://download.newrelic.com/install/newrelic-cli/scripts/install.ps1",
"$env:TEMP\install.ps1")

大きく分けると2つのコマンドに分かれていて、まず最初の「 $WebClient = New-Object System.Net.WebClient 」の部分で HTTP通信を行うクラスをオブジェクトとして変数に割り当てています。 このHTTP通信をおこなうクラスの「System.Net.WebClient」ですが、かなり昔のOSで使用されていたバージョンの .Net 1.1.Net 2.0 でサポートされているクラスとなります。

詳細はMicrosoftのページに委ねますが、実は最新のOSの場合では「System.Net.WebClient」を使わなくても、 他のPowershellコマンドが充実しているため、同じことを別コマンドで実現することはできます。 しかしながら、現在も「System.Net.WebClient」が使われていることを加味すると、 古いOSでもインストールコマンドが通るように後方互換を持たせていると解釈する方が自然かもしれません。

learn.microsoft.com

ちなみに、これを1つのコマンドで実現する場合は下記のようなコマンドになります。

▼ パターン1
New-Object System.Net.WebClient | Where-Object { $_.DownloadFile("https://download.newrelic.com/install/newrelic-cli/scripts/install.ps1","$env:TEMP\install.ps1") }

▼ パターン2
(New-Object System.Net.WebClient).DownloadFile("https://download.newrelic.com/install/newrelic-cli/scripts/install.ps1","$env:TEMP\install.ps1")

オプション部分として指定されているのは、「ダウンロード元URL」と「保存先」で、それぞれダウンロード元URLは https://download.newrelic.com/install/newrelic-cli/scripts/install.ps1 と保存先は一時フォルダ「$env:TEMP」直下に 「install.ps1」 というファイル名で保存するような構成となっています。

ダウンロードしたファイルの実行

次のコマンドは下記になります。

& PowerShell.exe -ExecutionPolicy Bypass -File $env:TEMP\install.ps1

頭についている & は呼び出し演算子で、任意のネイティブコマンドやpowershellのコマンドを実行できます。 ここで指定されているのは「PowerShell.exe」 で、実行しようとしているのは ダウンロードした インストール用ファイル $env:TEMP\install.ps1 です。

これをそのまま実行すると権限の問題でインストール用ファイルが動かないので、「-ExecutionPolicy Bypass」 を使って エラーを回避しているのがこのコマンドのポイントになります。 ちなみにここでインストールされるのは「New Relic CLI」であって、監視データを送信するためのInfrastructure agentではありません。

※呼び出し演算子については下記マイクロソフトのサイトに詳細が記載されています。

他のコマンドを実行する PowerShell コマンド

learn.microsoft.com

監視エージェントのインストール

最後の部分のコマンドは下記の2つになります。
まずは、下記の部分で環境変数にAPIキーとNew Relicのアカウントをセットします。

$env:NEW_RELIC_API_KEY='NRAK-XXXXXXXXXX'
$env:NEW_RELIC_ACCOUNT_ID='1234567'; 

次に下記のコマンドを使用して実際のエージェントをインストールします。

& 'C:\Program Files\New Relic\New Relic CLI\newrelic.exe' install

Powershellコードの解説は以上となりますが、New Relicではインストールの際に一部カスタマイズできるように下記のオプションが用意されています。

「Automatically answer "yes" to all install prompts. We'll stop the installer if there's an error.」を有効にすると、下記のようにインストールコマンドの後ろに -y オプションが付きます。 インストールプログラム実行中に、追加モジュールのインストールやGoldenSignalの設定をするかどうか確認されますが、このオプションを有効化することで追加モジュールやGoldenSignalなどが全てインストールされます。

& 'C:\Program Files\New Relic\New Relic CLI\newrelic.exe' install -y

「Use a proxy」を有効にすると、下記のように環境変数にPROXYの設定が追加されてインストールコマンドがPROXY経由でNew Relicに通信を行います。

$env:HTTPS_PROXY='https://example.com:3128/'

New Relic CLIの詳細については下記に公式ドキュメントがありますので、興味があればご確認ください。

docs.newrelic.com

まとめ

今回はNew Relicのお話というより、New Relicのインストールコマンドを深堀してみたらこんなことになっていましたという記事になります。PowershellはWindowsを少し深く使う際に必ず必要になるスキルではありますが、個人的には若干クセ強めの言語と理解していましたので、こちらの記事がどなたかの参考になれば幸いです。

◆ 塩野 正人
◆ マネージドサービス部 所属
◆ X(Twitter):@shioccii
◆ 過去記事はこちら

前職ではオンプレミスで仮想化基盤の構築や運用に従事。現在は運用部隊でNew Relicを使ってサービス改善に奮闘中。