{"id":5757,"date":"2024-10-25T15:42:53","date_gmt":"2024-10-25T23:42:53","guid":{"rendered":"https:\/\/jetstreamsoft.com\/portal\/?post_type=ht_kb&#038;p=5757"},"modified":"2024-12-16T10:09:34","modified_gmt":"2024-12-16T18:09:34","slug":"change_drva_addr_new-ps1","status":"publish","type":"ht_kb","link":"https:\/\/jetstreamsoft.com\/portal\/jetstream-knowledge-base\/change_drva_addr_new-ps1\/","title":{"rendered":"change_drva_addr_new.ps1"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/pwsh\n\n#\n#(c) 2023 JetStream Software, Inc &lt; legal @jetstreamsoft.com >\n    #\n# This software is provided under the terms of the\n# JetStream Software Inc.Software Tools License Agreement(STLA).\n# Use of this software constitutes agreement to the terms of the STLA.\n#\n\n# force stop on error\n$ErrorActionPreference = \"Stop\"\n\n# vCenter parameters - fill with caution!\n    $login = \"administrator@vsphere.local\"\n$passwd = \"\"\n$srvaddr = \"10.40.4.101\"\n# vCenter FQDN\n\n$drva_prefix = \"jss-\"\n\n# Expect 4.2 \/ 4.1 .18 compatible extra routing by\ndefault.\n\nclass netConfig {\n    &#91;string] $netName\n        &#91;string] $routes&#91;string] $gw&#91;string] $setup&#91;string] $dns\n}\n\n# rules to fill the configuration:\n    # - only one interface is\ndefault (others are non -\n    default)\n# - All interfaces must exist on the appliance\n$fullConfig = @(\n    #&#91;netConfig] @ {\n        netName = \"VM Network\";\n        gw = \"*\";\n        setup = \"\";\n        routes = \"10.8.0.0\/24 via 10.50.0.11\";\n        dns = \"8.8.8.8, 1.1.1.1\"\n    },\n    #&#91;netConfig] @ {\n        netName = \"VM Network 2\";\n        gw = \"\";\n        setup = \"\";\n        routes = \"10.20.0.0\/24 via 192.168.100.2\";\n        dns = \"\"\n    },\n    #&#91;netConfig] @ {\n        netName = \"VM Network 3\";\n        gw = \"\";\n        setup = \"\";\n        routes = \"10.12.0.0\/24 via 10.5.5.2 metric 500,10.10.0.0\/24 via 10.5.5.2\";\n        dns = \"\"\n    }\n    &#91;netConfig] @ {\n        netName = \"VM Network\";\n        gw = \"10.40.0.1\";\n        setup = \"10.40.2.25#255.255.248.0\";\n        routes = \"\";\n        dns = \"10.40.0.9\"\n    }\n    #&#91;netConfig] @ {\n        netName = \"VM Network\";\n        gw = \"\";\n        setup = \"\";\n        routes = \"\";\n        dns = \"\"\n    },\n    #&#91;netConfig] @ {\n        netName = \"VM Network 2\";\n        gw = \"192.168.100.1\";\n        setup = \"192.168.100.99#255.255.255.0\";\n        routes = \"\";\n        dns = \"\"\n    },\n    #&#91;netConfig] @ {\n        netName = \"VM Network 3\";\n        gw = \"\";\n        setup = \"\";\n        routes = \"10.10.0.0\/24 via 10.5.5.2 metric 666\";\n        dns = \"\"\n    }\n)\n\nfunction check_ip {\n    param(\n        &#91;string] $ipv4_str\n    )\n    $parts = $ipv4_str.Split('.')\n    if ($parts.Length - ne 4) {\n        \"Wrong number of octets in {0}\" - f $ipv4_str | Write - Host\n        return $False\n    }\n    foreach($octet in $parts) {\n        Try {\n            $oval = &#91;int]::Parse($octet)\n            if ($oval - le 0 - or $oval - ge 256) {\n                \"Bad octet {0} in IP address {1}\" - f $octet, $ipv4_str | Write - Host\n                return $False\n            }\n        } catch {\n            \"Bad octet {0} in IP address {1}\" - f $octet, $ipv4_str | Write - Host\n            return $False\n        }\n    }\n    return $True\n}\n\n# sanity check configuration\n# - exactly one def route NIC expected\n$numDflt = 0\nforeach($cfg in $fullConfig) {\n        if (&#91;String]::IsNullOrEmpty($cfg.netName)) {\n            Write - Host \"Network name is not provided in one of the config entries\"\n            exit\n        }\n        if (!&#91;String]::IsNullOrEmpty($cfg.gw)) {\n            $numDflt += 1\n            if ($cfg.gw - eq \"*\") {\n                # DHCP + def GW\n                if ($cfg.setup - ne \"\") {\n                    \"Network {0}, default non-DHCP interface must provide specific default GW\"\n                    `\n                    -f $cfg.NetName  | Write-Host\n                exit\n            }\n        } else { # IP address in GW\n            if ($cfg.setup -eq \"\") {\n                \"Network {0}, default DHCP interface must pick gw from DHCP options\" ` -\n                    f $cfg.NetName | Write - Host\n                    exit\n                }\n            }\n        }\n        if (!&#91;String]::IsNullOrEmpty($cfg.dns)) {\n            &#91;Char&#91;]] $sep = @(' ', ',')\n            $servers = $cfg.dns.Split($sep, &#91;System.StringSplitOptions]::RemoveEmptyEntries)\n            foreach($server in $servers) {\n                if (!(check_ip($server))) {\n                    \"Network {0}, invalid DNS server specified {1}\"\n                    `\n                     -f $cfg.NetName, $server | Write-Host\n                exit\n            }\n        }\n    }\n}\nif ($numDflt -ne 1) {\n    \"Wrong number of default adapters - {0}, expected 1\" -f $numDflt | Write-Host\n    exit\n}\n\n# check vCenter server access credentials\nif (&#91;String]::IsNullOrEmpty($srvaddr)) {\n    $srvaddr = Read-Host -Prompt \"Enter vCenter IP or FQDN\"\n} else {\n    \"Connecting to host {0}\" -f $srvaddr | Write-Host\n}\n\nif (&#91;String]::IsNullOrEmpty($login)) {\n    $login = Read-Host -Prompt \"Enter vCenter user name\"\n} else {\n    \"Username {0}\" -f $login | Write-Host\n}\n\nif (&#91;String]::IsNullOrEmpty($passwd)) {\n    $passwd = Read-Host -Prompt \"Enter password\" -AsSecureString\n    $passwd = $passwd | ConvertFrom-SecureString -AsPlainText\n}\n\n\n$visrv = Connect-VIServer -Server $srvaddr -User $login -Password $passwd\n\n:extloop while ($True) {\n    # choose VM to edit\n    do {\n        $vmlist=Get-VM -Server $visrv | where {$_.Name.StartsWith($drva_prefix)}\n        Write-Host \"Choose VM to reconfigure:\"\n        $idx=0\n        foreach ($jsvm in $vmlist) {\n            $idx += 1\n            \"`\n                    t {\n                        0\n                    }: {\n                        1\n                    }\n                    \" -f $idx, $jsvm.Name | Write-Host\n                }\n                $reply = Read - Host \"index, newline to re-read, Q\/q to exit \"\n                if (&#91;Char]::ToUpper($reply&#91;0]) - eq 'Q') {\n                    break extloop\n                }\n                $reply = $reply - as&#91;int]\n            }\n            while ($null - eq $reply - or $reply - le 0 - or $reply - gt $vmlist.Length)\n\n                $vm = $vmlist&#91;$reply - 1]\n\n            # validate options: all VM networks must be found in config\n            $nic_list = $vm | Get - NetworkAdapter\n            foreach($nic in $nic_list) {\n                $cfg = $fullConfig | Where - Object {\n                    $_.netName - eq $nic.NetworkName\n                }\n                if (!$cfg) {\n                    \"Network {0} of VM {1} not found in config\"\n                    `\n                -f $nic.NetworkName, $vm.Name | Write-Host\n            break extloop\n        }\n    }\n\n    while($True)\n    {\n        # validate options: all config networks muts be configured with VM\n        # print config changes\n        foreach ($cfg in $fullConfig)\n        {\n            $nic = $nic_list | Where-Object { $_.NetworkName -eq $cfg.netName }\n            if (!$nic)\n            {\n                \"Network {0} not found on VM {1}\" -f $cfg.netName, $vm.Name | Write-Host\n                break extloop\n            }\n\n            $ip_setup_param = &#91;String]::Format(\"guestinfo.net.{0}\", $nic.MacAddress)\n            $route_setup_param = &#91;String]::Format(\"guestinfo.net.routes.{0}\", $nic.MacAddress)\n            $gway_setup_param = &#91;String]::Format(\"guestinfo.net.gw.{0}\", $nic.MacAddress)\n            $dns_setup_param = &#91;String]::Format(\"guestinfo.net.dns.{0}\", $nic.MacAddress)\n\n            $ip_setup = $vm | Get-AdvancedSetting -Name $ip_setup_param\n            $route_setup = $vm | Get-AdvancedSetting -Name $route_setup_param\n            $gway_setup = $vm | Get-AdvancedSetting -Name $gway_setup_param\n            $dns_setup = $vm | Get-AdvancedSetting -Name $dns_setup_param\n\n            $msg = \"\"\n            if ($ip_setup.Value -ne $cfg.setup)\n            {\n                $msg += \" config to '{0}';\" -f $cfg.setup\n            }\n            if ($route_setup.Value -ne $cfg.routes)\n            {\n                $msg += \" routes to '{0}';\" -f $cfg.routes\n            }\n            if ($gway_setup.Value -ne $cfg.gw)\n            {\n                $msg += \" gateway to '{0}';\" -f $cfg.gw\n            }\n            if ($dns_setup.Value -ne $cfg.dns)\n            {\n                $msg += \" DNS settings to '{0}';\" -f $cfg.dns\n            }\n            if (! &#91;String]::IsNullOrEmpty($msg)) {\n                \"`\n                    tChanging {\n                        0\n                    }\n                    on network {\n                        1\n                    }\n                    \" -f $msg, $cfg.netName | Write-Host\n                }\n            }\n\n            $reply = Read - Host \"Press enter to continue, Q\/q to exit, N\/n to choose next VM,\"\n            `\n            + \" E\/e to change IP address\"\n        if (&#91;Char]::ToUpper($reply&#91;0]) -eq 'N')\n        {\n            continue extloop\n        }\n        if (&#91;Char]::ToUpper($reply&#91;0]) -eq 'Q')\n        {\n            break extloop\n        }\n        if (&#91;Char]::ToUpper($reply&#91;0]) -eq 'E')\n        {\n            foreach ($cfg in $fullConfig)\n            {\n                if (&#91;String]::IsNullOrEmpty($cfg.setup)) {\n                    \"Interface {0} configured for DHCP\" -f $cfg.netName | Write-Host\n                } else {\n                    do {\n                        $new_ip = Read-Host (\"IP for interface {0}\" -f $cfg.netName)\n                    } while (! $new_ip -or !(check_ip($new_ip)))\n                    $parts = $cfg.setup.Split('#')\n                    $cfg.setup = \"{0}#{1}\" -f $new_ip, $parts&#91;1]\n                }\n            }\n            continue\n        }\n        break\n    }\n\n    # perform GW config changes\n    if ($vm.PowerState -ne &#91;VMware.VimAutomation.ViCore.Types.V1.Inventory.PowerState]::PoweredOff) {\n        Stop-VM -VM $vm -Confirm:$False\n    }\n\n    foreach ($nic in $nic_list) {\n        $cfg = $fullConfig | Where-Object {$_.netName -eq $nic.NetworkName}\n\n        $ip_setup_param = &#91;String]::Format(\"guestinfo.net.{0}\", $nic.MacAddress)\n        $route_setup_param = &#91;String]::Format(\"guestinfo.net.routes.{0}\", $nic.MacAddress)\n        $gway_setup_param = &#91;String]::Format(\"guestinfo.net.gw.{0}\", $nic.MacAddress)\n        $dns_setup_param = &#91;String]::Format(\"guestinfo.net.dns.{0}\", $nic.MacAddress)\n\n        $ip_setup = $vm | Get-AdvancedSetting -Name $ip_setup_param\n        $route_setup = $vm | Get-AdvancedSetting -Name $route_setup_param\n        $gway_setup = $vm | Get-AdvancedSetting -Name $gway_setup_param\n        $dns_setup = $vm | Get-AdvancedSetting -Name $dns_setup_param\n\n        if ($ip_setup.Value -ne $cfg.setup) {\n            $ip_setup | Remove-AdvancedSetting -Confirm:$False\n            if (! &#91;String]::IsNullOrEmpty($cfg.setup)) {\n                $vm | New-AdvancedSetting -Name $ip_setup_param -Value $cfg.setup -Confirm:$False\n            }\n        }\n        if ($route_setup.Value -ne $cfg.routes) {\n            $route_setup | Remove-AdvancedSetting -Confirm:$False\n            if (! &#91;String]::IsNullOrEmpty($cfg.routes)) {\n                $vm | New-AdvancedSetting -Name $route_setup_param -Value $cfg.routes -Confirm:$False\n            }\n        }\n        if ($gway_setup.Value -ne $cfg.gw) {\n            $gway_setup | Remove-AdvancedSetting -Confirm:$False\n            if (! &#91;String]::IsNullOrEmpty($cfg.gw)) {\n                $vm | New-AdvancedSetting -Name $gway_setup_param -Value $cfg.gw -Confirm:$False\n            }\n        }\n        if ($dns_setup.Value -ne $cfg.dns) {\n            $dns_setup | Remove-AdvancedSetting -Confirm:$False\n            if (! &#91;String]::IsNullOrEmpty($cfg.dns)) {\n                $vm | New-AdvancedSetting -Name $dns_setup_param -Value $cfg.dns -Confirm:$False\n            }\n        }\n    }\n\n    Start-VM -VM $vm -Confirm:$False\n}\n\nDisconnect-VIServer -Server $global:DefaultVIServers -Confirm:$False<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"nf_dc_page":"","footnotes":""},"ht-kb-category":[],"ht-kb-tag":[255],"class_list":["post-5757","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_tag-no_search"],"_links":{"self":[{"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb\/5757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb"}],"about":[{"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/comments?post=5757"}],"version-history":[{"count":1,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb\/5757\/revisions"}],"predecessor-version":[{"id":5758,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb\/5757\/revisions\/5758"}],"wp:attachment":[{"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/media?parent=5757"}],"wp:term":[{"taxonomy":"ht_kb_category","embeddable":true,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb-category?post=5757"},{"taxonomy":"ht_kb_tag","embeddable":true,"href":"https:\/\/jetstreamsoft.com\/portal\/wp-json\/wp\/v2\/ht-kb-tag?post=5757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}