Powershellでサーバ情報を自動収集してみよう

スポンサードリンク



こんにちは。sinyです。

この記事では、Powershellを使った情報収集の活用方法について説明していきます。

Powershellはまったくの初心者という方は、以下の記事もチェックしてみてください。

さて、PowerShellはもともとWindowsサーバ管理のためのオブジェクト指向プログラミング的な位置づけでした。
現在は、Windowsに限らずLinux、MAC等様々な環境で利用できる言語になっています。

仕事柄、Windowsサーバを管理する場面が多かったこともあり、サーバ情報を収集するためにPowerShellをよく利用しています。

今回は、業務でも実際に活用しているサーバ情報をPowerShellで自動収集する事例についてご紹介します。

Powershellでサーバ情報を自動収集する

PowerShellは、実行するPCやサーバだけでなく、リモートにあるサーバ上(社内のサーバ、AWS等のパブリックサーバ問わず)でも実行することができます。

このリモート機能を利用することで、膨大にあるリモートサーバの情報を自動収集することができます。

全体図を示すと、以下のような流れになります。

処理フロー概要
①PowerShellをリモート実行
 →管理サーバ上においてある自動収集用のPowerShellスクリプトをリモートサバ上で動作させることができます
②処理結果を受け取る。
 →処理結果は非同期で受け取ることができます。
③Excelへ出力(csv形式)
 →収集した全サーバ分の情報をcsv形式で出力します。
 
  • この構成のポイントは、必要なシェルはすべて管理サーバ側上に存在していればよく、管理される側のサーバには一切モジュールを配置する必要がないという点です。
  • 管理するサーバ数が何百台というケースではこの構成の利点が大きく効いてきます。
 今回の事例はWindows2012サーバ以降を前提として記載しています。

実装の3ステップ

上記で説明したような仕組みを実装するには、具体的に以下のような3ステップで実装していきます。

実装の3ステップ
①サーバ情報を収集するPSシェルを作成する。
②リモートサーバに対して①で作成したPSシェルをリモート実行する機能をPSシェルで作成する。
③環境設定周りの設定(管理サーバ側、管理対象サーバ側)

具体的な実装方法

それでは、具体的な実装方法のサンプル例を解説していきます。

①サーバ情報を収集するPSシェルを作成

サーバ情報を取得するPSシェルですが、これは比較的簡単です。
参考に、基本的なサーバ情報を取得するサンプルコードを挙げておきますが、この辺は取得したい情報によって適宜スクリプトを書き換えればOKです。
#サーバ名の取得
$hostname = hostname

#OSバージョン取得
$os_version = @(wmic os get Caption)[2]

#OS SPレベル取得
$os_sp_version = @(wmic os get ServicePackMajorVersion)[2]

#メモリサイズ(GB表示)取得
$Total = 0
Get-WmiObject Win32_PhysicalMemory | % {$Total += $_.Capacity}
$memory = [int]($Total/1GB)

②環境設定周りの設定

環境回りの設定としては、管理サーバ側と管理対象サーバ側双方で作業が必要になります。

管理対象サーバ側で必要な作業

 
管理対象サーバ側で必要な作業は基本的には1つだけです。
それは、「管理サーバから管理対象サーバへアクセスする際に利用するOSユーザの作成」です。

注意点は、WindowsサーバではPowerShellをリモート実行するには管理者権限が必要ということです。

 

管理サーバ側で必要な作業

管理サーバ側では、以下の2点を事前に設定しておきます。
  • TrustedHostsを設定する。
  • 接続先ユーザの認証パスワード暗号化ファイルを生成しておく。
  • TrustedHostsの設定

    接続先のサーバを信頼リストに追加することでPowershellをリモート実行させることができるようになります。

    Powershellコンソール画面上で、以下のようなコマンドを実行することで設定できます。

    Set-Item WSMan:\localhost\Client\TrustedHosts -Value (ホスト名 または IPアドレス または *)

  • 接続先ユーザの認証パスワード暗号化ファイルを生成

    以下のコマンドで、事前に作成しておいたアクセス先サーバ上のOSユーザのパスワードを暗号化ファイル化します。

$cred = get-credential

以下の画面が表示されるので、接続先サーバのユーザ名、パスワードを入力してOKを押します。

続いて、以下のコマンドを実行して暗号化ファイルを生成します。

$cred.password | ConvertFrom-SecureString | Set-Content "[暗号化ファイルのパス]\Credential_[サーバ名].txt"

③リモートサーバに対してPSシェルをリモート実行する機能を作成

リモートサーバに対してPSシェルを発行するには、Powershell標準のInvoke-Commandコマンドを利用します。
具体的には、以下の流れでInvoke-Commandを実行します。
  • 認証情報(credential)の生成

    サンプルコード(認証オブジェクトを生成する関数)

    function Create_Credential([string]$servername,[string]$username,[string]$filepath)
    {
    
    	#対象サーバにアクセスするための認証情報を取得
            $filepath = $filepath + "\Credential_" + $serverName + ".txt"
    
    	$passwordfile = $filepath
    	$securePassWord = Get-Content $passwordfile | ConvertTo-SecureString
    	$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassWord)
    	$password = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR)
    	$credential = New-Object PSCredential $username, (ConvertTo-SecureString $password -AsPlainText -Force)
    
        return $credential
    
    }

    上記の関数を使って以下のように認証オブジェクトを生成します。

        #認証情報(credential)の生成
        $credential = Create_Credential $ServerName $username $CredentialDir
  • PSセッションの確立

    PSセッションはNew-PSSessionコマンドを利用します。
    (引数にサーバ名と認証オブジェクトを指定)
    先ほど生成したCredentialオブジェクトを利用します。

        #対象サーバに対するPSセッションを確立
        $session = New-PSSession -ComputerName $Servername -Credential $credential
  • PSシェルのリモート実行


    最後にInvode-Commandを利用してリモートサーバに対してPSシェルを実行します。

        #情報収集シェルのリモート実行
        Invoke-Command -Session $session -AsJob -FilePath $PS_FILE
  
引数には「セッション情報、実行するPSシェルのパスを指定します。
  -Asjobというオプションをつけると非同期ジョブとしてPSシェルを実行してくれます。
 以上、ざっと実装に必要な作業についての解説でした。

実際には、複数サーバに対して動的に認証→リモートアクセス→PSシェルを非同期で実行という形で実装するのが望ましいので、もう少しPSシェルスクリプトを作りこんでいく必要がありますが、PowerShellの知見がある人であれば十分実装できるのではないかと思います。

需要があれば、実運用レベルの実装コーディングについて技術ノートなどにしようかなと思います。
おすすめの記事