目次
こんにちは。sinyです。
この記事では、Powershellを使った情報収集の活用方法について説明していきます。
Powershellはまったくの初心者という方は、以下の記事もチェックしてみてください。
さて、PowerShellはもともとWindowsサーバ管理のためのオブジェクト指向プログラミング的な位置づけでした。
現在は、Windowsに限らずLinux、MAC等様々な環境で利用できる言語になっています。
仕事柄、Windowsサーバを管理する場面が多かったこともあり、サーバ情報を収集するためにPowerShellをよく利用しています。
今回は、業務でも実際に活用しているサーバ情報をPowerShellで自動収集する事例についてご紹介します。
Powershellでサーバ情報を自動収集する
PowerShellは、実行するPCやサーバだけでなく、リモートにあるサーバ上(社内のサーバ、AWS等のパブリックサーバ問わず)でも実行することができます。
このリモート機能を利用することで、膨大にあるリモートサーバの情報を自動収集することができます。
全体図を示すと、以下のような流れになります。
→管理サーバ上においてある自動収集用のPowerShellスクリプトをリモートサバ上で動作させることができます
②処理結果を受け取る。
→処理結果は非同期で受け取ることができます。
③Excelへ出力(csv形式)
→収集した全サーバ分の情報をcsv形式で出力します。
- この構成のポイントは、必要なシェルはすべて管理サーバ側上に存在していればよく、管理される側のサーバには一切モジュールを配置する必要がないという点です。
- 管理するサーバ数が何百台というケースではこの構成の利点が大きく効いてきます。
実装の3ステップ
上記で説明したような仕組みを実装するには、具体的に以下のような3ステップで実装していきます。
②リモートサーバに対して①で作成したPSシェルをリモート実行する機能をPSシェルで作成する。
③環境設定周りの設定(管理サーバ側、管理対象サーバ側)
具体的な実装方法
①サーバ情報を収集するPSシェルを作成
#サーバ名の取得
$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をリモート実行するには管理者権限が必要ということです。
管理サーバ側で必要な作業
- TrustedHostsを設定する。
- 接続先ユーザの認証パスワード暗号化ファイルを生成しておく。
- TrustedHostsの設定
接続先のサーバを信頼リストに追加することでPowershellをリモート実行させることができるようになります。
Powershellコンソール画面上で、以下のようなコマンドを実行することで設定できます。
Set-Item WSMan:\localhost\Client\TrustedHosts -Value (ホスト名 または IPアドレス または *)
- 接続先ユーザの認証パスワード暗号化ファイルを生成
$cred = get-credential
以下の画面が表示されるので、接続先サーバのユーザ名、パスワードを入力してOKを押します。
続いて、以下のコマンドを実行して暗号化ファイルを生成します。
$cred.password | ConvertFrom-SecureString | Set-Content "[暗号化ファイルのパス]\Credential_[サーバ名].txt"
③リモートサーバに対してPSシェルをリモート実行する機能を作成
- 認証情報(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の知見がある人であれば十分実装できるのではないかと思います。