In this guide, we’ll build a production-ready Bash script that automates hostname and static IP changes across multiple RHEL 7, 8, 9 & 10 servers using a CSV file and SSH.
Why Automate Hostname and IP Changes?
Common use cases include:
- VM cloning and re-IP addressing
- Environment refreshes (DEV / STAGE / PROD)
- Data center migrations
- DR and failover testing
- Eliminate human error
- Apply consistent configuration
- Save time on repetitive tasks
- Follow Red Hat best practices
Before running the script, ensure:
- RHEL 7, 8, 9 & 10 servers
- SSH key-based authentication
- Root access (or passwordless sudo)
- NetworkManager is running
- Network interfaces:
ens224 – secondary
Adjust interface names or subnet sizes as required for your environment.
CSV Input File Format
The script reads server configuration from a CSV file and supports comments.
Example: host_ip_change.txt
#remote,hostname,primary_ip,primary_gateway,primary_dns,secondary_ip,secondary_gateway,secondary_dns
192.168.10.244,indrxltst11,192.168.10.224,192.168.10.1,192.168.10.100,192.168.20.224,192.168.20.1,192.168.20.100
| Field | Description |
|---|---|
| remote | Current IP or hostname to SSH into |
| hostname | New hostname |
| primary_ip | Static IP for ens192 |
| primary_gateway | Gateway for ens192 |
| primary_dns | DNS server |
| secondary_ip | Static IP for ens224 |
| secondary_gateway | Gateway for ens224 |
| secondary_dns | DNS server |
Final Bash Script (RHEL 7, 8, 9 & 10 Compatible)
Script Features
- CSV-driven automation
- Skips empty and commented lines
- Uses nmcli (NetworkManager-compliant)
- Updates hostname and two interfaces
- Reloads connections and reboots
#!/bin/bash
# Automate hostname and IP changes on RHEL 7, 8, 9 & 10 servers using CSV input
# Interfaces: ens192 (primary), ens224 (secondary)
echo "Enter the path to the CSV file:"
read csv_file
if [[ ! -f "$csv_file" ]]; then
echo "CSV file not found!"
exit 1
fi
while IFS=, read -r remote hostname primary_ip primary_gateway primary_dns secondary_ip secondary_gateway secondary_dns; do
# Skip empty lines and comments
[[ -z "$remote" || "$remote" =~ ^# ]] && continue
echo "---------------------------------------------------------"
echo "Processing server: $remote"
echo "---------------------------------------------------------"
ssh -T root@"$remote" << EOF
echo "Updating hostname and network configuration..."
hostnamectl set-hostname "$hostname"
nmcli con mod ens192 \
ipv4.method manual \
ipv4.addresses $primary_ip/24 \
ipv4.gateway $primary_gateway \
ipv4.dns $primary_dns
nmcli con mod ens224 \
ipv4.method manual \
ipv4.addresses $secondary_ip/24 \
ipv4.gateway $secondary_gateway \
ipv4.dns $secondary_dns
nmcli con reload
echo "---------------- Hostname ----------------"
hostnamectl
echo "---------------- ens192 ------------------"
nmcli con show ens192
echo "---------------- ens224 ------------------"
nmcli con show ens224
echo "Rebooting server..."
reboot
EOF
echo "Changes applied to $remote. Waiting for reboot..."
sleep 10
done < "$csv_file"
echo "All servers processed successfully."
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sample Script Output
[root@inddcpppz01 scripts]# ./rhel-hostname-ip-change.sh
Enter the path to the CSV file:
/root/scripts/host_ip_change.txt
---------------------------------------------------------
Processing server: 192.168.10.244
---------------------------------------------------------
*********************************************************
* !!!! WELCOME TO PPC.COM TEST LAB SERVER'S !!!! *
* This server is meant for testing Linux commands and *
* Tools. If you are not associated with ppc.com and *
* Not authorized. Please dis-connect immediately. *
*********************************************************
Updating hostname and network configuration...
---------------- Hostname ----------------
Static hostname: indrxltst11
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: 3b223da7ca514758839fb91ce7f319a9
Boot ID: d20afc3459524d93807b0ba9d9df55eb
Product UUID: 564d79af-6b4e-b4f6-3c9e-9075e3ccb935
AF_VSOCK CID: 3821844789
Virtualization: vmware
Operating System: Red Hat Enterprise Linux 10.0 (Coughlan)
CPE OS Name: cpe:/o:redhat:enterprise_linux:10::baseos
Kernel: Linux 6.12.0-55.9.1.el10_0.x86_64
Architecture: x86-64
Hardware Vendor: VMware, Inc.
Hardware Model: VMware Virtual Platform
Hardware Serial: VMware-56 4d 79 af 6b 4e b4 f6-3c 9e 90 75 e3 cc b9 35
Firmware Version: 6.00
Firmware Date: Mon 2015-09-21
Firmware Age: 10y 4month 1w 5d
---------------- ens192 ------------------
connection.id: ens192
connection.uuid: bf5c3e39-1f0e-3378-8dd7-fbb41fa659af
connection.stable-id: --
connection.type: 802-3-ethernet
connection.interface-name: ens192
connection.autoconnect: yes
connection.autoconnect-priority: -999
connection.autoconnect-retries: -1 (default)
connection.multi-connect: 0 (default)
connection.auth-retries: -1
connection.timestamp: 1769957773
connection.permissions: --
connection.zone: --
connection.controller: --
connection.master: --
connection.slave-type: --
connection.port-type: --
connection.autoconnect-slaves: -1 (default)
connection.autoconnect-ports: -1 (default)
connection.down-on-poweroff: -1 (default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.ip-ping-timeout: 0
connection.ip-ping-addresses: --
connection.ip-ping-addresses-require-all:-1 (default)
connection.metered: unknown
connection.lldp: default
connection.mdns: -1 (default)
connection.llmnr: -1 (default)
connection.dns-over-tls: -1 (default)
connection.mptcp-flags: 0x0 (default)
connection.wait-device-timeout: -1
connection.wait-activation-delay: -1
802-3-ethernet.port: --
802-3-ethernet.speed: 0
802-3-ethernet.duplex: --
802-3-ethernet.auto-negotiate: no
802-3-ethernet.mac-address: --
802-3-ethernet.cloned-mac-address: --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-denylist: --
802-3-ethernet.mtu: auto
802-3-ethernet.s390-subchannels: --
802-3-ethernet.s390-nettype: --
802-3-ethernet.s390-options: --
802-3-ethernet.wake-on-lan: default
802-3-ethernet.wake-on-lan-password: --
802-3-ethernet.accept-all-mac-addresses:-1 (default)
ipv4.method: manual
ipv4.dns: 192.168.10.100
ipv4.dns-search: --
ipv4.dns-options: --
ipv4.dns-priority: 0
ipv4.addresses: 192.168.10.224/24
ipv4.gateway: 192.168.10.1
ipv4.routes: --
ipv4.route-metric: -1
ipv4.route-table: 0 (unspec)
ipv4.routing-rules: --
ipv4.replace-local-rule: -1 (default)
ipv4.dhcp-send-release: -1 (default)
ipv4.routed-dns: -1 (default)
ipv4.ignore-auto-routes: no
ipv4.ignore-auto-dns: no
ipv4.dhcp-client-id: --
ipv4.dhcp-iaid: --
ipv4.dhcp-dscp: --
ipv4.dhcp-timeout: 0 (default)
ipv4.dhcp-send-hostname-deprecated: yes
ipv4.dhcp-send-hostname: -1 (default)
ipv4.dhcp-hostname: --
ipv4.dhcp-fqdn: --
ipv4.dhcp-hostname-flags: 0x0 (none)
ipv4.never-default: no
ipv4.may-fail: yes
ipv4.required-timeout: -1 (default)
ipv4.dad-timeout: -1 (default)
ipv4.dhcp-vendor-class-identifier: --
ipv4.dhcp-ipv6-only-preferred: -1 (default)
ipv4.link-local: 0 (default)
ipv4.dhcp-reject-servers: --
ipv4.auto-route-ext-gw: -1 (default)
ipv4.shared-dhcp-range: --
ipv4.shared-dhcp-lease-time: 0 (default)
ipv6.method: auto
ipv6.dns: --
ipv6.dns-search: --
ipv6.dns-options: --
ipv6.dns-priority: 0
ipv6.addresses: --
ipv6.gateway: --
ipv6.routes: --
ipv6.route-metric: -1
ipv6.route-table: 0 (unspec)
ipv6.routing-rules: --
ipv6.replace-local-rule: -1 (default)
ipv6.dhcp-send-release: -1 (default)
ipv6.routed-dns: -1 (default)
ipv6.ignore-auto-routes: no
ipv6.ignore-auto-dns: no
ipv6.never-default: no
ipv6.may-fail: yes
ipv6.required-timeout: -1 (default)
ipv6.ip6-privacy: -1 (default)
ipv6.temp-valid-lifetime: 0 (default)
ipv6.temp-preferred-lifetime: 0 (default)
ipv6.addr-gen-mode: eui64
ipv6.ra-timeout: 0 (default)
ipv6.mtu: auto
ipv6.dhcp-pd-hint: --
ipv6.dhcp-duid: --
ipv6.dhcp-iaid: --
ipv6.dhcp-timeout: 0 (default)
ipv6.dhcp-send-hostname-deprecated: yes
ipv6.dhcp-send-hostname: -1 (default)
ipv6.dhcp-hostname: --
ipv6.dhcp-hostname-flags: 0x0 (none)
ipv6.auto-route-ext-gw: -1 (default)
ipv6.token: --
proxy.method: none
proxy.browser-only: no
proxy.pac-url: --
proxy.pac-script: --
GENERAL.NAME: ens192
GENERAL.UUID: bf5c3e39-1f0e-3378-8dd7-fbb41fa659af
GENERAL.DEVICES: ens192
GENERAL.IP-IFACE: ens192
GENERAL.STATE: activated
GENERAL.DEFAULT: yes
GENERAL.DEFAULT6: no
GENERAL.SPEC-OBJECT: --
GENERAL.VPN: no
GENERAL.DBUS-PATH: /org/freedesktop/NetworkManager/ActiveConnection/2
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/Settings/1
GENERAL.ZONE: --
GENERAL.MASTER-PATH: --
IP4.ADDRESS[1]: 192.168.10.244/24
IP4.GATEWAY: 192.168.10.1
IP4.ROUTE[1]: dst = 0.0.0.0/0, nh = 192.168.10.1, mt = 100
IP4.ROUTE[2]: dst = 192.168.10.0/24, nh = 0.0.0.0, mt = 100
IP4.DNS[1]: 192.168.10.100
IP6.ADDRESS[1]: fe80::20c:29ff:fecc:b935/64
IP6.GATEWAY: --
IP6.ROUTE[1]: dst = fe80::/64, nh = ::, mt = 1024
---------------- ens224 ------------------
connection.id: ens224
connection.uuid: 4242c0f6-b9ba-39f4-b11e-fb965a79d709
connection.stable-id: --
connection.type: 802-3-ethernet
connection.interface-name: ens224
connection.autoconnect: yes
connection.autoconnect-priority: -999
connection.autoconnect-retries: -1 (default)
connection.multi-connect: 0 (default)
connection.auth-retries: -1
connection.timestamp: 1769957774
connection.permissions: --
connection.zone: --
connection.controller: --
connection.master: --
connection.slave-type: --
connection.port-type: --
connection.autoconnect-slaves: -1 (default)
connection.autoconnect-ports: -1 (default)
connection.down-on-poweroff: -1 (default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.ip-ping-timeout: 0
connection.ip-ping-addresses: --
connection.ip-ping-addresses-require-all:-1 (default)
connection.metered: unknown
connection.lldp: default
connection.mdns: -1 (default)
connection.llmnr: -1 (default)
connection.dns-over-tls: -1 (default)
connection.mptcp-flags: 0x0 (default)
connection.wait-device-timeout: -1
connection.wait-activation-delay: -1
802-3-ethernet.port: --
802-3-ethernet.speed: 0
802-3-ethernet.duplex: --
802-3-ethernet.auto-negotiate: no
802-3-ethernet.mac-address: --
802-3-ethernet.cloned-mac-address: --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-denylist: --
802-3-ethernet.mtu: auto
802-3-ethernet.s390-subchannels: --
802-3-ethernet.s390-nettype: --
802-3-ethernet.s390-options: --
802-3-ethernet.wake-on-lan: default
802-3-ethernet.wake-on-lan-password: --
802-3-ethernet.accept-all-mac-addresses:-1 (default)
ipv4.method: manual
ipv4.dns: 192.168.20.100
ipv4.dns-search: --
ipv4.dns-options: --
ipv4.dns-priority: 0
ipv4.addresses: 192.168.20.224/24
ipv4.gateway: 192.168.20.1
ipv4.routes: --
ipv4.route-metric: -1
ipv4.route-table: 0 (unspec)
ipv4.routing-rules: --
ipv4.replace-local-rule: -1 (default)
ipv4.dhcp-send-release: -1 (default)
ipv4.routed-dns: -1 (default)
ipv4.ignore-auto-routes: no
ipv4.ignore-auto-dns: no
ipv4.dhcp-client-id: --
ipv4.dhcp-iaid: --
ipv4.dhcp-dscp: --
ipv4.dhcp-timeout: 0 (default)
ipv4.dhcp-send-hostname-deprecated: yes
ipv4.dhcp-send-hostname: -1 (default)
ipv4.dhcp-hostname: --
ipv4.dhcp-fqdn: --
ipv4.dhcp-hostname-flags: 0x0 (none)
ipv4.never-default: no
ipv4.may-fail: yes
ipv4.required-timeout: -1 (default)
ipv4.dad-timeout: -1 (default)
ipv4.dhcp-vendor-class-identifier: --
ipv4.dhcp-ipv6-only-preferred: -1 (default)
ipv4.link-local: 0 (default)
ipv4.dhcp-reject-servers: --
ipv4.auto-route-ext-gw: -1 (default)
ipv4.shared-dhcp-range: --
ipv4.shared-dhcp-lease-time: 0 (default)
ipv6.method: auto
ipv6.dns: --
ipv6.dns-search: --
ipv6.dns-options: --
ipv6.dns-priority: 0
ipv6.addresses: --
ipv6.gateway: --
ipv6.routes: --
ipv6.route-metric: -1
ipv6.route-table: 0 (unspec)
ipv6.routing-rules: --
ipv6.replace-local-rule: -1 (default)
ipv6.dhcp-send-release: -1 (default)
ipv6.routed-dns: -1 (default)
ipv6.ignore-auto-routes: no
ipv6.ignore-auto-dns: no
ipv6.never-default: no
ipv6.may-fail: yes
ipv6.required-timeout: -1 (default)
ipv6.ip6-privacy: -1 (default)
ipv6.temp-valid-lifetime: 0 (default)
ipv6.temp-preferred-lifetime: 0 (default)
ipv6.addr-gen-mode: eui64
ipv6.ra-timeout: 0 (default)
ipv6.mtu: auto
ipv6.dhcp-pd-hint: --
ipv6.dhcp-duid: --
ipv6.dhcp-iaid: --
ipv6.dhcp-timeout: 0 (default)
ipv6.dhcp-send-hostname-deprecated: yes
ipv6.dhcp-send-hostname: -1 (default)
ipv6.dhcp-hostname: --
ipv6.dhcp-hostname-flags: 0x0 (none)
ipv6.auto-route-ext-gw: -1 (default)
ipv6.token: --
proxy.method: none
proxy.browser-only: no
proxy.pac-url: --
proxy.pac-script: --
GENERAL.NAME: ens224
GENERAL.UUID: 4242c0f6-b9ba-39f4-b11e-fb965a79d709
GENERAL.DEVICES: ens224
GENERAL.IP-IFACE: ens224
GENERAL.STATE: activated
GENERAL.DEFAULT: no
GENERAL.DEFAULT6: no
GENERAL.SPEC-OBJECT: --
GENERAL.VPN: no
GENERAL.DBUS-PATH: /org/freedesktop/NetworkManager/ActiveConnection/3
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/Settings/2
GENERAL.ZONE: --
GENERAL.MASTER-PATH: --
IP4.ADDRESS[1]: 192.168.20.244/24
IP4.GATEWAY: 192.168.20.1
IP4.ROUTE[1]: dst = 0.0.0.0/0, nh = 192.168.20.1, mt = 101
IP4.ROUTE[2]: dst = 192.168.20.0/24, nh = 0.0.0.0, mt = 101
IP4.DNS[1]: 192.168.20.100
IP6.ADDRESS[1]: fe80::20c:29ff:fecc:b93f/64
IP6.GATEWAY: --
IP6.ROUTE[1]: dst = fe80::/64, nh = ::, mt = 1024
Rebooting server...
Changes applied to 192.168.10.244. Waiting for reboot...
All servers processed successfully.
[root@inddcpppz01 scripts]#
Login in to the server indrxltst11 & check the IP address
Why This Approach Is Recommended for RHEL 9
- Fully NetworkManager-compliant
- No deprecated network-scripts
- Changes persist across reboots
- CSV-based = scalable and repeatable
- Minimal dependencies
- Test on a non-production server first
- Keep console or hypervisor access available
- Avoid changing the IP of your active SSH session
- Maintain a rollback plan
This Bash script provides a safe, scalable, and enterprise-ready solution for managing hostnames and IP addresses across RHEL 7, 8, 9 & 10 servers. By leveraging nmcli and CSV-driven automation, you can eliminate manual configuration errors and standardize network changes across environments.
For sysadmins managing multiple Linux servers, this approach is simple, powerful, and highly effective.
No comments:
Post a Comment