2

I am new to PowerShell and trying to accomplish few things here:

  1. I have a zabbix agent configuration file and I want to be able to change the zabbix_agent_win.conf.
    • Hostname
    • ServerActive
    • HostMetaDataItem

My ultimate goal is to be have a powershell script that will change the Hostname based on "$env:ComputerName" and ServerActive is to change with given parameter, HostMetaData with given parameter either env variable that can be populated with given cmdlet. I started playing around and came across with the following script:

$path = "C:\test.conf"
$word = $(Hostname) 
$replacement = $("$env:ComputerName")
$text = get-content $path 
$newText = $text -replace $word,$replacement
$newText > $path

However this script is not working for me and different combination which I have tried is not changing the value of hostname based on ("$env:ComputerName”).

I found another suggested option:

(Get-Content C:\test.conf -Raw).Replace('\$Hostname$\','\"$env:ComputerName"\') | 
Set-Content C:\test.conf

No luck yet,

Any help appreciated.

Thanks, Katherine

mjsqu
  • 5,151
  • 1
  • 17
  • 21
Katherine
  • 33
  • 1
  • 4
  • I'm trying to understand the context you're running this under, because I've attempted this with both local and remote PowerShell and $(Hostname) and "$env:ComputerName" resolve to the same value. I can only think it might be different if the environment variable had been modified somehow. Test by adding `$word -eq $replacement` to your script, which for me always returns `True`. – mjsqu Sep 16 '18 at 21:19
  • 1
    I have a config file that has Parameters such as: Hostname={MyCompName}, ServerActive={zabbix server hostname}, HostMetaData={system.uname}. I am trying to change these parameters using PowerShell script, the script should be able to find these parameters inside the config file and change according to the env variables. I hope it is clear now. – Katherine Sep 16 '18 at 21:29

1 Answers1

0

The problem with your script is that it looks for the actual hostname value in the file and then replaces it. If your config file contains HOSTNAME=MyComputer and you run it on a computer called MyComputer then it will look up MyComputer in the file and replace it with the value of the COMPUTERNAME variable which is also MyComputer, resulting in no change to the file. If you put a placeholder like Hostname={replace this text} then $(Hostname) still resolves to 'MyComputer', not {replace this text}, the replace does not find or replace anything.

To find Hostname=SOMETHINGELSE and replace SOMETHINGELSE with $env:COMPUTERNAME requires a little more work.

Regular Expression

This approach uses -replace rather than .Replace(), which allows use of regular expressions. It uses regular expression capture groups to find lines where 'Hostname=' appears. Because this is in brackets, it is called capture group 1, which is retained and stored in an automatic variable $1. This is kept by the processor and then repeated in the replace. Anything else on the line, represented by dot-asterisk (.*) (any character repeating 0 or more times, is then replaced by $env:COMPUTERNAME

(Get-Content "C:\test.conf" -Raw) -replace '(Hostname=).*',"`$1$($env:ComputerName)" | 
Set-Content "C:\test.conf"

If you do use this approach I would recommend reading up a bit more about regular expression capture groups so you know what this code is doing.

Testing and replacing different parameters

Use this approach to test the logic. You can edit the bit between @''@ to represent values in your config file:

$zabbixserver='zabbix123'

@'
Hostname={MyCompName}
ServerActive={zabbix server hostname}
HostMetaData={system.uname}
'@ -replace '(ServerActive=).*',"`$1$zabbixserver" `
-replace '(Hostname=).*',"`$1$($env:ComputerName)"

Note the use of the 'backtick' to put the -replace lines on separate lines

Community
  • 1
  • 1
mjsqu
  • 5,151
  • 1
  • 17
  • 21
  • `(Get-Content "C:\test.conf" -Raw) -replace `'(Hostname=).*',"`$1$($env:ComputerName)" | `Set-Content "C:\test.conf"` this worked and get the value of the comp name, however it get rid off the `Hostname` parameter. My goal is to have Hostname=MyServerName. How can I make sure that Hostname remains in the config file? – Katherine Sep 16 '18 at 22:21
  • Did you miss out the backtick before `$1`? It's very important, it asks the processor to retain the text "Hostname=", without the backtick, the interpreter ignores the special purpose of `$1`. It should go, double-quote, backtick, dollar, one, dollar, open-bracket etc. – mjsqu Sep 16 '18 at 22:34
  • Somehow I missed backtick. Thanks so much! You saved tons of time for me. I will look at second part now. – Katherine Sep 16 '18 at 22:48
  • No problem, if you feel my answer was correct, please close your question by clicking the checkmark next to the answer. It helps people know the question is already answered and gives feedback to the answerer. – mjsqu Sep 16 '18 at 22:58