Pages

Bulk Hostname and IP Updates in RHEL 7, 8, 9 & 10

Managing hostnames and IP addresses across multiple Linux servers is a routine task for system administrators—but doing it manually doesn’t scale. With RHEL 7, 8, 9 & 10, Red Hat standardizes network management through NetworkManager and nmcli, making automation the preferred and safest approach.

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
Automation helps you:
  • Eliminate human error
  • Apply consistent configuration
  • Save time on repetitive tasks
  • Follow Red Hat best practices
Prerequisites:

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:
          ens192 – primary
          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
FieldDescription
           remoteCurrent IP or hostname to SSH into
           hostnameNew hostname
           primary_ipStatic IP for ens192
           primary_gatewayGateway for ens192
           primary_dnsDNS server
           secondary_ipStatic IP for ens224
           secondary_gatewayGateway for ens224
           secondary_dnsDNS 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
Script: rhel-hostname-ip-change.sh

#!/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
Best Practices
  • 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
Conclusion
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