• このエントリーをはてなブックマークに追加

複数のサーバでコマンドを実行するTeratermマクロ

  • このエントリーをはてなブックマークに追加

Teraterm
zaco muraです。

私が担当しているサービスでは運用しているサーバが約40台ほどあります。
普段はその台数を意識することは意外と少ないですが、アカウント管理とか脆弱性対応など、全サーバに同じコマンドを打つ必要がある時はけっこう大変です。

ということで何か便利な方法はないかと考えたところ、結局は身近なTeratermマクロで解決することにしました。
(世の中的にはchefとかserverspec使う流れだと思いますが、田舎出身アナログエンジニアの私はそんなオシャレな技術は使えません)

スポンサーリンク
Sponsords Link

なんとなくの要求仕様

作るにあたって以下の仕様を考えました。

・複数のサーバに対して同じコマンドを実行するためのマクロ
・汎用的に使いまわせるよう、極力固定パラメータは使わない
・rootでも実行できる
・実行結果を確認できる

で、作った結果が以下です。

複数のサーバでコマンドを実行するTeratermマクロ(ソース)

;;#
;;# ツール名 : command_exec.ttl
;;#
;;# 目    的 : 複数のサーバに対して同じコマンドを実行するためのツール
;;#
;;# 動作概要 : (1) ログイン対象のサーバ一覧を読み込む
;;#            (2) ログインID / ログインPW / 入力したいコマンド をinputboxに入力させる
;;#            (3) 各サーバにログインし、コマンドを実行する
;;#
;;# 仕    様 : ・一般ユーザ or rootでの実行が可能
;;#          : ・対話的なコマンドは実行できない
;;#          : ・複数コマンド実行したい場合は、コマンドを ";" で区切る
;;#          : ・コマンドの実行結果をファイルで取得可能(c:\"ユーザ名"\Desktop\ttl実行結果_YYYYMMDD_HHMMSS\配下に格納)
;;#
;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;#;; (1) サーバのリストを読み込む
;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;# ファイルを選択させる
filenamebox 'サーバのリストを選択' 0

;;# 途中でキャンセルが押されたらexit
if result=0 then
	exit
endif

;;# 変数SERVER_LIST にファイルのパスを格納
SERVER_LIST = inputstr

;;# 選択されたファイルが存在しない場合、exit
filesearch SERVER_LIST
if result=0 then
	messagebox 'File not found.' 'error'
	exit
endif



;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;#;; (2) ログインID / ログインPW / 入力したいコマンド をinputboxに入力させる
;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;#ユーザ入力
inputbox 'サーバへのログインユーザ名を入力してください。' 'command_exec'
USERNAME = inputstr

;;#パスワード入力
passwordbox 'ログインパスワードを入力してください' 'command_exec'
PASSWORD = inputstr

;;#rootでの実行が必要か確認
yesnobox '一般ユーザで実行しますか?(いいえの場合はrootで実行)' 'command_exec'
ROOT_FLAG = result

;;#rootの場合はrootのpwも入力させる
if ROOT_FLAG == 0 then
	passwordbox 'rootのパスワードを入力してください' 'command_exec'
	ROOT_PASSWORD = inputstr
endif

;;#実行したいコマンドを入力させる
inputbox '実行したいコマンドを入力してください。' 'command_exec'
COMMAND = inputstr

;;#実行結果をファイルとして取得したいか確認する
yesnobox '実行結果を取得しますか?(サーバ上のホームディレクトリにttl_log.txtというファイルが作成されます)' 'command_exec'
GET_RESULT = result
if GET_RESULT=1 then
	
	;;#受信元のパスを指定
	SOURCE_PATH = '/home/'
	strconcat SOURCE_PATH USERNAME
	strconcat SOURCE_PATH '/ttl_log.txt'

	;;# 実行するコマンドの最後にリダイレクト先を指定する
	strconcat COMMAND ' > '
	strconcat COMMAND SOURCE_PATH

	;;#現在時刻を取得(ファイル名に利用)
	getdate NOWDATE '%Y%m%d_%H%M%S'

	;;#SCPを受信するパスを指定
	RECV_PATH = 'c:\Users\'
	strconcat RECV_PATH USERNAME
	strconcat RECV_PATH '\Desktop\ttl実行結果_'
	strconcat RECV_PATH NOWDATE
	strconcat RECV_PATH '\'

	;;#実行結果受信用のフォルダをデスクトップ上に作成
	foldercreate RECV_PATH
	
	;;#受信ファイル名に時刻を付与
	strconcat NOWDATE '.txt'
endif


;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;#;; (3) 各サーバにログインし、コマンドを実行する
;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;# ログインのタイムアウトを設定(20秒)
timeout = 20

;;# サーバ一覧を読み込む
fileopen FILE_HANDLE SERVER_LIST 0

;;# サーバ一覧を1行ずつ読み込み、ループする
:loop
filereadln FILE_HANDLE SERVER_NAME

	;;#最終行かどうかを判定
	if result goto fclose

	;;#;;ログインするコマンドを作成
	;;# バックグラウンド実行
	LOGIN_COMMAND = '/I /V '
	;;# ログインオプションを設定
	strconcat LOGIN_COMMAND SERVER_NAME
	strconcat LOGIN_COMMAND ' /ssh /2 /auth=password /user='
	strconcat LOGIN_COMMAND USERNAME
	strconcat LOGIN_COMMAND ' /passwd='
	strconcat LOGIN_COMMAND PASSWORD
	
	;;# 実行結果を取得する場合はその設定をする
	if GET_RESULT=1 then

		;;#受信パス指定
		RECV_PATH_CUR = RECV_PATH
		strconcat RECV_PATH_CUR SERVER_NAME
		strconcat RECV_PATH_CUR '_'
		strconcat RECV_PATH_CUR NOWDATE
	endif
		
	;;#ログインし、コマンドを実行
	connect LOGIN_COMMAND
	wait '~]$'
		
	;;# タイムアウトの場合は異常終了させる
	if result=0 then
		goto timeout
	endif

	;;# root実行の場合はrootにsu - する
	if ROOT_FLAG == 0 then
		sendln 'LANG=C su -'
		wait 'Password:'
		sendln ROOT_PASSWORD
		wait '~]#'
	endif

	;;# それ以外ならコマンド実行
	sendln COMMAND
	wait '~]$' '~]#'

	;;# タイムアウトの場合は異常終了させる
	if result=0 then
		goto timeout
	endif

	;;# 実行結果を取得する場合は、SCPを実行
	if GET_RESULT=1 then

		;;# rootの場合はログファイルの権限を変更
		if ROOT_FLAG == 0 then
			CHANGE_OWNER_COMMAND = 'chown '
			strconcat CHANGE_OWNER_COMMAND USERNAME
			strconcat CHANGE_OWNER_COMMAND '. '
			strconcat CHANGE_OWNER_COMMAND SOURCE_PATH
			sendln CHANGE_OWNER_COMMAND
			wait '~]#'
		endif

		;;# scp受信を実行
		scprecv SOURCE_PATH RECV_PATH_CUR

		;;#受信が完了したことを確認するため、1秒毎に受信ファイルのサイズ変化を確認
		mpause 1100
		BEFORE_SIZE = 0

		;;#確認のループ
		:scp_check

			;;# ファイルのサイズを確認
			filestat RECV_PATH_CUR CUR_SIZE

			;;# 現在のサイズと前回のサイズが一致すれば終了
			if CUR_SIZE == BEFORE_SIZE then
				goto scp_finish
			else
				mpause 1100
			endif

			;;# 現在のサイズをBEFORE_SIZEに代入
			BEFORE_SIZE = CUR_SIZE
			goto scp_check
		:scp_finish
	endif

	;;# root実行の場合はここでrootを抜ける
	if ROOT_FLAG == 0 then
		sendln 'exit'
		wait '~]$'
	endif

	;;# サーバから抜ける
	sendln 'exit'
	unlink

;;#繰り返しの先頭(loop)に戻る
goto loop

;;#timeoutのエラー処理
goto fclose

;;# 最終行まで読み込んだ場合、ファイルを閉じて終了
:fclose
fileclose FILE_HANDLE

使い方

1. ファイルをダブルクリックしてマクロを起動
2. ファイルを選択する画面が起動するので、ログインするサーバのリストを読み込む。(IPアドレス or ホスト名を羅列したファイルを用意すればOK)
3. ログインする一般ユーザ名を入力し、OKをクリック
4. パスワードを入力し、OKをクリック
5. 実行ユーザを確認されるので、一般ユーザなら「はい」を、rootなら「いいえ」を選択
6. (rootを選んだ場合のみ) rootパスワードを入力
7. 実行したいコマンドを入力
8. 実行結果を取得する場合は「はい」をクリック

注意点

・もちろん自己責任での使用をお願いします。
・エラー処理はあまりちゃんと入れていません。
・あまりに時間がかかるコマンドを実行すると失敗するかもしれません。timeout値を調整してください。

スポンサーリンク
Sponsords Link
  • このエントリーをはてなブックマークに追加

ZacoDesign

スポンサーリンク
Sponsords Link