質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

1回答

284閲覧

Zabbix4.0.7をwindows2008に入れる際logファイルがC直下に配置される。

zazabi

総合スコア24

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

0クリップ

投稿2019/06/12 01:54

編集2019/06/12 04:49

Zabbixバージョン:4.0.7
PC:windows2008(リモート接続)
PowerSellバージョン:2.0
※自社で使っているので、変更不可

■やりたいこと
自動インストールのスクリプトを作成しましたが、一部のconfファイルの変更コマンドが反映されないので反映させたい。
■問題
下記のコマンドをスクリプトで使用した際、logファイルだけが変更されず、C直下に置かれてしまう。

#■コマンド
###引数
#####ユーザーが設定する
$IP = "..."
$log_path = "c:\zabbix\zabbix_agentd.log"
$Metadata = "windows2008"

#####以下本文
フォルダパス
$folder = @("C:\zabbix","C:\zabbix\bin","C:\zabbix\conf")
フォルダ作成
New-Item $folder[0] -ItemType Directory

位置パス定義
現在のスクリプトパス
$file_path = (Convert-Path .)
標準出力に表示
Write-Host $file_path

スクリプト出力ログ
Start-Transcript -Path ($file_path+"\zabbixAgentインストール.log")

ファイルパス
zipファイル
$zip = @(($file_path+"\Desktop\zabbix_agents.zip"),"C:\zabbix\zabbix_agents.zip")
exe:移動前/移動後
$exe_path = @("C:\zabbix\bin\zabbix_agentd.exe","C:\zabbix\zabbix_agentd.exe")
conf:移動前/移動後
$conf_path = @("C:\zabbix\conf\zabbix_agentd.conf","C:\zabbix\zabbix_agentd.conf")

#####confファイル用
log
$LogFile = @("LogFile=c:\zabbix_agentd.log",("LogFile="+$log_path))

zabbixIPアドレス
$Server = @("Server=127.0.0.1",("Server="+$IP))
$ServerActive =@("ServerActive=127.0.0.1",("ServerActive="+$IP))

hostname
$Hostname = "Hostname=Windows host"

メタデータ
$HostMetadata = @("# HostMetadata=",("# HostMetadata=rnrnHostMetadata="+$Metadata))

#####処理開始
zipファイル移動
Move-Item $zip[0] $zip[1]

解凍
$file = $zip[1]
$shell = New-Object -ComObject shell.application
$zip_file = $shell.NameSpace($file)
$dest = $shell.NameSpace((Split-Path $file -Parent))
$dest.CopyHere($zip_file.Items())

exeファイル配置
Move-Item $exe_path[0] $exe_path[1]
confフォルダ配置
Move-Item $conf_path[0] $conf_path[1]

confファイル書き換え
-Encoding UTF8
$conf= Get-Content $conf_path[1] -Encoding UTF8

zabbixサーバ設定
$conf = $(Get-Content $conf_path[1]) -replace $Server[0],$Server[1]
$conf > $conf_path[1]

Zabbixアクティブサーバ設定
$conf = $(Get-Content $conf_path[1]) -replace $ServerActive[0],$ServerActive[1]
$conf > $conf_path[1]

Logファイル設定
$conf = $(Get-Content $conf_path[1]) -replace $LogFile[0],$LogFile[1]
$conf > $conf_path[1]

ホスト名
$result = hostname
$conf = $(Get-Content $conf_path[1]) -replace $Hostname,("Hostname="+$result)
$conf > $conf_path[1]

Zabbixサーバ自動登録をするためのメタデータ
$conf = $(Get-Content $conf_path[1]) -replace $HostMetadata[0], $HostMetadata[1]
$conf > $conf_path[1]

エンコード
-Encoding default
$conf | Out-file $conf_path[1] -Encoding default

#####ZabbixAgentサービス開始
exe実行
cd $folder[0]
.\zabbix_agentd.exe -i -c $conf_path[1]

スタートアップの種類:手動
Get-Service -DisplayName 'Zabbix Agent' | Set-Service -StartupType Manual

サービス開始
cd $folder[0]
.\zabbix_agentd.exe -s -c $conf_path[1]

スタートアップの種類:自動
Set-Service -Name 'Zabbix Agent' -StartupType Automatic

zipファイル削除
Remove-Item $zip[1] -Recurse
binファイル削除
Remove-Item $folder[1] -Recurse
confファイル削除
Remove-Item $folder[2] -Recurse

起動確認
Get-service "Zabbix Agent" | select-object displayname,status,starttype,PathName

ポーズ
Read-Host "続けるには Enter キーを押してください..."

結果を出力する
Stop-Transcript

不明瞭なことがあれば追加で記述しますので、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mitarai

2019/06/12 04:40 編集

おそらく省略されていると思うのですが、$log_pathという変数にはどういう値が入っているのでしょうか? 無関係の部分は省いて構いませんので、必要な部分は省略せずに再現可能な形のコードを提示されたら回答しやすくなります。質問は編集できます。
zazabi

2019/06/12 04:49

アドバイスありがとうございます。 どこが原因で上記の事が起こるのか知りたかったため、全文掲載させていただきました。
mitarai

2019/06/12 04:57

質問の編集ありがとうございます。
guest

回答1

0

ベストアンサー

-replace演算子は正規表現によって置換します。
正規表現においてカンマ.やバックスラッシュ\などは特別な意味をもつので文字通りにマッチしなかったのが原因かと思われます。

例として以下のようにしても置換されませんが

PowerShell

1"c:\test.txt" -replace "c:\test.txt", "Matched!" 2c:\test.txt

特別な意味をもつ記号をエスケープしてやればマッチします。

PowerShell

1"c:\test.txt" -replace "c:\test.txt", "Matched!" 2Matched!

もしくはregexクラスのEscape()メソッドを使います。

PowerShell

1"c:\test.txt" -replace [regex]::Escape("c:\test.txt"), "Matched!" 2Matched! 3

ただしこのような正規表現が必要ない場合は-replace演算子を使うと無駄にコストがかかるので
"文字列".Replace("置換前", "置換後")メソッドを使って単純な置換を行うのが普通です。

PowerShell

1"c:\test.txt".Replace("c:\test.txt", "Matched!")

今回の例では複数の置換が必要なので例えばハッシュテーブルを使って以下のようにも書けます。

PowerShell

1$h = @{ 2 "LogFile=c:\zabbix_agentd.log" = "LogFile=$logPath" 3 "Server=127.0.0.1" = "Server=$ip" 4 "ServerActive=127.0.0.1" = "ServerActive=$ip" 5 "Hostname=Windows host" = "Hostname=" + [Net.Dns]::GetHostName() 6 "# HostMetadata=" = "# HostMetadata=rnrnHostMetadata=$metaData" 7} 8 9$conf = Get-Content sample.conf -Encoding utf8 10$h.GetEnumerator() | foreach { $conf = $conf.Replace($_.Key, $_.Value) } 11$conf | Out-File sample.conf -Encoding utf8

この辺りはいろいろなやり方があると思うので自分が良いと思う方法でやってください。単純に
"abcde".Replace("a","x").Replace("b","y")・・・とつなげてもいいです。

あと置換の度にファイルに保存して、また読み込んで、を繰り返すのは無駄なので変数内で繰り返し置換したあとに最後に保存するとよいと思います。

追記

上記の配列に対してその要素のメソッドを呼び出す方法はPowerShell version 2ではできない方法でしたので、一括して読み込む方法を使うとよいです。

PowerShell

1# これを 2$conf = Get-Content sample.conf -Encoding utf8 34# こっちに変更 5$conf = [IO.File]::ReadAllText(sample.conf, [Text.Encoding]::UTF8)

こうすることで文字列の配列ではなく一つの文字列としてファイルを読み込みます。

最後に全体的に手直しして少し見通しをよくしたコードを置いて置きます。まったくテストしてないのでバグがあったらすみません。ご参考までに。(こちらも修正しました)

PowerShell

1$ip = "..." 2$logPath = "c:\zabbix\zabbix_agentd.log" 3$metaData = "windows2008" 4 5##### ここから本文 ###### 6 7$zipPath = Join-Path ([Environment]::GetFolderPath("Desktop")) "zabbix_agents.zip" 8$destDir = "C:\zabbix" 9$exeName = "zabbix_agentd.exe" 10$confName = "zabbix_agentd.conf" 11 12#confファイル置換用ハッシュテーブル 13$h = @{ 14 "LogFile=c:\zabbix_agentd.log" = "LogFile=$logPath" 15 "Server=127.0.0.1" = "Server=$ip" 16 "ServerActive=127.0.0.1" = "ServerActive=$ip" 17 "Hostname=Windows host" = "Hostname=" + (hostname) 18 "# HostMetadata=" = "# HostMetadata=rnrnHostMetadata=$metaData" 19} 20 21#スクリプト出力ログ 22$scriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 23Start-Transcript -Path "$scriptRoot/zabbixAgentインストール.log" 24 25#### 処理開始 #### 26 27#フォルダ作成 28New-Item $destDir -ItemType Directory > $null 29 30#解凍 31$shell = New-Object -ComObject shell.application 32$srcNS = $shell.NameSpace($zipPath) 33$destNS = $shell.NameSpace($destDir) 34$destNS.CopyHere($srcNS.Items()) 35 36#exeファイル配置 37$exeFile = Move-Item "$destDir/bin/$exeName" $destDir -PassThru 38#confフォルダ配置 39$confFile = Move-Item "$destDir/conf/$confName" $destDir -PassThru 40 41#confファイル書き換え 42$conf = [IO.File]::ReadAllText($confFile, [Text.Encoding]::UTF8) 43$h.GetEnumerator() | foreach { $conf = $conf.Replace($_.Key, $_.Value) } 44$conf | Out-File $confFile -Encoding utf8 45 46#ZabbixAgentサービス開始 47& $exeFile -i -c $confFile 48#スタートアップの種類:手動 49Get-Service -DisplayName 'Zabbix Agent' | Set-Service -StartupType Manual 50 51#サービス開始 52& $exeFile -s -c $confFile 53#スタートアップの種類:自動 54Set-Service -Name 'Zabbix Agent' -StartupType Automatic 55 56#zipファイル,binフォルダ,confフォルダ削除 57$zipPath,"$destDir/bin","$destDir/conf" | Remove-Item -Recurse 58 59#起動確認 60Get-Service "Zabbix Agent" | Select-Object DisplayName,Status,StartType,PathName 61 62Read-Host "続けるには Enter キーを押してください..." 63Stop-Transcript

投稿2019/06/12 08:40

編集2019/06/13 12:58
mitarai

総合スコア223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zazabi

2019/06/12 23:38

丁寧な回答ありがとうございます! regexクラス や ハッシュテーブル は知らなかったので、勉強になります。特に後者は使いどころが多そうなので、覚えておきます。
zazabi

2019/06/13 06:31 編集

追記 少し修正してやってみましたが、ハッシュテーブルだとlogファイルがC直下に置かれてしまうようです…。 別のものを試してみます。 →confファイル内を置換する際、下記のようなエラーが出るため上げていただいたコマンドを使用するのは難しそうです。 エラー:[System.Object[]] に 'Replace' という名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。
mitarai

2019/06/13 12:59

失礼しました。Powershell v2だとできない方法だったようです。回答に追記、修正しまたした。
zazabi

2019/06/13 23:37

手直しありがとうございます。参考にさせていただきます。 色々試してみて困っていた事は無事解決しました。原因は特殊文字だったようです。 「\z」が特殊文字として認識され、文字列として認識されていなかったので置換できなかったのかと思います。「"LogFile=c:\zabbix_agentd.log"」を「"LogFile=c:\zabbix_agentd.log"」としたら正しく置換されました。どうしてこの部分だけなのかは不明ですが……。
mitarai

2019/06/14 08:37 編集

問題が解決してなによりです。 正規表現では「\」はエスケープの役割を持ち、他の文字と組み合わせることで様々な意味が形成されます。例えば「\z」は文字列の末尾にマッチします。他にも「\d」は数字にマッチしたり「\n」は改行文字にマッチしたりと予め決められています。「¥」そのものはエスケープをつかって「\」と表します。 また、カンマ「.」は改行文字以外の全ての一文字にマッチします。当然カンマそのものにもマッチするのでこの場合は問題なかったかもしれませんが、カンマそのものだけにマッチさせるなら「.」としてください。 正規表現は入門サイトがたくさんあるので一度眺めてみることをおすすめします。言語を問わず、またプログラミングに限らず様々な場面で使えるので知っておく価値があると思います。 環境によって差異があるのでPowershell(.NET)の正規表現について正確に知りたい場合は以下のリンクあたりにまとまっています。 https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問