VMware Cloud Community
LHBL2003
Contributor
Contributor
Jump to solution

Simply deactivate the second Connect-VIServer.

Hello,

Aim:
I want to rename a port group.
This also works when I do it for one ESXi Server. (Simply deactivate the second Connect-VIServer.)
However, in my constellation not with two ESXi servers.

Guess:
I assume that Get-View will find the same NetworkSystem object for both connections. Although it is specified by a specific ESXi. "$ esx.ConfigManager.NetworkSystem"

Preface:
In this example I am consciously connecting to both ESXi servers.
The connection actually belongs in Menu.ps1.
There I can select a function ps1 in Explorer via the FileDialog.
So I call my function via dot.

. RenamePg.ps1

The function ps1 knows the connections (Connect-VIServer) because I do not write them in any variable.

Problem:

"$esxList" -> contains all connected ESXi servers
"$esx" -> contains only one ESXi server

"$netSys" -> but lists network system information from both.

"$netSys.UpdatePortGroup" -> Does not work because both network system information is included.

Is there a way to prevent this from happening?

What I don't want to do:
I don't want to build a loop in the ps1 menu.
Con Server 1 -> FunctionX
Con Server 2 -> FunctionX

Because if I e.g. want to have all VM names in an Excel list, I would have to pass parameters. And that means that my menu ps1 has to be intelligent.

Thanks for ideas

 

# Subfunction

function RenamePortGroup  ([String] $oldPortGroupName, [String] $newPortGroupName)
{
    $esxList = Get-VMHost | Get-View

    foreach ($esx in $esxList)
    {   
        $netSys = Get-View $esx.ConfigManager.NetworkSystem # <-- netSys Two Entrys not one
        $pg = $esx.Config.Network.Portgroup | where {$_.Spec.Name -eq $oldPortGroupName}

        if($pg -ne $null)
        {
            $spec = $pg.Spec
            $spec.Name = $newPortGroupName
            $netSys.UpdatePortGroup($oldPortGroupName, $spec) # <-- Here then the problem, since netSys lists two servers.
        }
    }

    Write-Host "Portgruppe in VMs ändern"
    Get-VM |Get-NetworkAdapter |Where {$_.NetworkName -eq $oldPortGroupName } |Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
}

# MAIN 

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.13" -User "root" -Password "XYZ" -SaveCredentials # Belongs to Menu File.
Connect-VIServer -Server "10.10.18.30" -User "root" -Password "XYZ" -SaveCredentials # Belongs to Menu File.

$oldPortGroupName = Read-Host "Old Portgroup Name?"
$newPortGroupName = Read-Host "New Portgroup Name?"

RenamePortGroup  -oldPortGroupName $oldPortGroupName -newPortGroupName $newPortGroupName


Disconnect-VIServer -Server * -confirm:$false -Force # Belongs to Menu File.

 

 

 

================================

Original deutsch 😄

Hallo,

Ziel:
ich möchte eine Portgruppe umbenennen.
Das funktioniert auch wenn ich das für one ESXi Server mache. (Einfach den zweiten Connect-VIServer deaktivieren)
Allerdings in meiner Konstelation nicht mit zwei ESXi Server.

Vermutung:
Ich gehe davon aus das Get-View bei beiden Verbindung das selbe NetworkSystem Objekt findet. Obwohl es von einem bestimmten ESXi angegeben ist. "$esx.ConfigManager.NetworkSystem"

Vorwort:
Ich verbinde mich in diesem beispiel Bewust mit beiden ESXi Servern.
Das Verbinden gehört eigentlich in Menu.ps1.
Dort kann ich via FileDialog eine Funktions ps1 im Explorer aussuchen.
Ich rufe meine Funktion also via Dot auf.

. RenamePg.ps1

Die Funktions ps1 kennt also die Verbindungen (Connect-VIServer), weil ich diese in keine Variable schreibe.

Problem:

"$esxList" --> beinhaltet alle Verbundenen ESXi Server
$esx --> beinhaltet nur einen ESXi Server

$netSys --> Listet aber Network System Informationen von beiden.

$netSys.UpdatePortGroup --> Funktioniert nicht, weil beide Network System informationen enthalten sind.

Gibt es einen Weg dies zu verhindern?

Was ich nicht machen möchte:
Ich möchte ungerne im Menü ps1 eine Schleife bauen.
Con Server 1 --> FunktionX
Con Server 2 --> FunktionX

Denn wenn ich z.B. alle VM Namen in einer Excel liste haben möchte, müsste ich parameter übergeben. Und das beeutet das mein Menu ps1 intiligent sein muss.

 

0 Kudos
1 Solution

Accepted Solutions
LHBL2003
Contributor
Contributor
Jump to solution

Hi @LucD

It works now with your version.
But I still had to add Get-VMHost from my version.
Because Get-VMHost returns the name that was used for the connection. This is required for Get-View, Get-VMHost etc. Because with you the FQDN comes back. But the functions expect the name as indicated for the connection. So ServerName, FQDN or IP address.
So your example is similar to my example.

I made a mixed version of both. With the advantages of your version and the correction with Get-VMHost.

Thanks.

Finding:
The server names are still required for both.
The problem with the unsightly "For loop" has been fixed.
The constellation of you will be more resource-friendly.

 

 

# Subfunction
function RenamePortGroup ([String] $oldPortGroupName, [String] $newPortGroupName) 
{
 
    Get-VMHost -PipelineVariable ConViServer | # Hole die Liste der Verbundenen ESXi Server
    Foreach-Object -Process { # Gehe die Liste schleifenweise durch

        $esx =  Get-View -Server $ConViServer.Name -ViewType HostSystem # Hole die HostSystem Informationen zum ESXi
        $netSys = Get-View -Server $ConViServer.Name -ID $esx.ConfigManager.NetworkSystem # Hole die Network System Informationen zum ESXi

        $pg = $esx.Config.Network.Portgroup | where {$_.Spec.Name -eq $oldPortGroupName} # Suche nach der Gruppe mit dem alten Portgruppennamen
        ForEach-Object -Process { # Führe für die gefundene Gruppe folgendes aus

            $spec = $pg.Spec # Hole die Konfiguration zur Portgruppe
            $spec.Name = $newPortGroupName # Neuer name für die Portgruppe
            $netSys.UpdatePortGroup($oldPortGroupName, $spec) # Koniguration aktualisieren

            # Da die Portgruppe umbenannt wurde, werden nun die Netzwerkkarten geprüft und dort auch die Portgruppe umbenannt.
            Get-VM -Server $ConViServer.Name |Get-NetworkAdapter |
            where {$_.NetworkName -eq $oldPortGroupName } |
            Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
        }
    }
}

# MAIN 

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.13" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.39" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.

$oldPortGroupName = Read-Host "Old Portgroup Name?"
$newPortGroupName = Read-Host "New Portgroup Name?"

RenamePortGroup  -oldPortGroupName $oldPortGroupName -newPortGroupName $newPortGroupName


Disconnect-VIServer -Server * -confirm:$false -Force # Belongs to Menu File.

 

 

 

#########################

German:

Es geht jetzt mit deiner Version.
Ich musste aber noch Get-VMHost aus meiner Version hinzufügen.
Denn Get-VMHost gibt den Namen zurück der bei der Verbindung verwendet wurde. Dieser wird für Get-View, Get-VMHost usw. benötigt. Denn bei dir kommt der FQDN zurück. Aber die Funktionen erwarten den namen wie bei der Verbindung angegeben. Also ServerName, FQDN oder IP-Adresse.
Somit ist dein beispiel ähnlich wie mein beispiel.

Ich habe eine Mix version aus beiden erstellt. Mit den vorteilen deiner Version und der korrektur mit Get-VMHost.

Danke.

Feststellung:
Bei beiden sind die angaben der Servernamen weiterhin erforderlich.
Das Problem mit der For unschönen "For-Schleife" wurde behoben.
Die Konstellation von dir wird Recourcen schonender sein.

 

View solution in original post

0 Kudos
6 Replies
LucD
Leadership
Leadership
Jump to solution

Most PowerCLI cmdlets have a Server parameter through which you can indicate against which connected server you want to execute the cmdlet.
Isn't that the easiest solution?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LHBL2003
Contributor
Contributor
Jump to solution

Not quite nice, but it works.

I would like to improve it if it is possible.

Point 1:
I would like to use "foreach" for Get-VMHost and not "for".
However, it does not jump into the foreach even though it contains 2 entries. Do I have to convert it beforehand?

Point 2:
Is there a global possibility to tell Get-VM, Get-View, Get-VMHost that all subsequent calls should first be made on ESXi X without "-Server"?

# Subfunction


function RenamePortGroup ([String] $oldPortGroupName, [String] $newPortGroupName)
{
$HostList = Get-VMHost # Connected servers

for ($i=0; $i -lt $HostList.length; $i++) # <-- Unfortunately, foreach is not possible
{
$VIServer = $HostList[$i].Name # Name as given for Connect

$esx = Get-VMHost -Server $VIServer | Get-View # Network System from selected ESXi

$netSys = Get-View -Server $VIServer -ID $esx.ConfigManager.NetworkSystem # Network System from selected ESXi
$pg = $esx.Config.Network.Portgroup | where {$_.Spec.Name -eq $oldPortGroupName} # Search for port group with old names

# If port group found, then
if($pg -ne $null)
{
$spec = $pg.Spec # Get PG object by defining the name.
$spec.Name = $newPortGroupName # Rename PG
$netSys.UpdatePortGroup($oldPortGroupName, $spec) # Update port group
}

# Adjust the network configurations of the VMs so that the new port group is selected.
Write-Host "Portgruppe in VMs ändern"
Get-VM -Server $VIServer |Get-NetworkAdapter |Where {$_.NetworkName -eq $oldPortGroupName } |Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
}
}

# MAIN

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.13" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.39" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.

$oldPortGroupName = Read-Host "Old Portgroup Name?"
$newPortGroupName = Read-Host "New Portgroup Name?"

RenamePortGroup -oldPortGroupName $oldPortGroupName -newPortGroupName $newPortGroupName


Disconnect-VIServer -Server * -confirm:$false -Force # Belongs to Menu File.

 

------------------
Deutsch

Zwar nicht ganz schön aber es funktioniert.

Ich würde es gerne noch verbessern wenn es möglich ist.

Punkt 1:
Ich möchte für Get-VMHost gerne "foreach" nutzen und nicht "for".
Allerdings springt er dann nicht in die foreach obwohl 2 einträhe enthalten sind. Muss ich es vorher noch Convertieren?

Point 2:
Gibt es eine global möglichkeit Get-VM, Get-View, Get-VMHost mitzuteilen, dass alle volgenden aufrufe zunächst auf ESXi X erfolgen sollen ohne "-Server"?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Why so complicated?
Basically you want to rename the Portgroup on all ESXi nodes to which you are connected.
The function could then just be

 

function RenamePortGroup ([String] $oldPortGroupName, [String] $newPortGroupName) {
        Get-View -ViewType HostSystem -PipelineVariable esx |              # Loop through all ESXi nodes
        ForEach-Object -Process {
                $netSys = Get-View -Id $esx.ConfigManager.NetworkSystem
                $esx.Config.Network.Portgroup | where { $_.Spec.Name -eq $oldPortGroupName } |
                ForEach-Object -Process {
                        $spec = $_.Spec
                        $spec.Name = $newPortGroupName
                        $netSys.UpdatePortGroup($oldPortGroupName, $spec)
                
                        Get-VMHost -Name $esx.Name | Get-VM | Get-NetworkAdapter |
                        where{$_.NetworkName -eq $oldPortGroupName} | 
                        Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
                }
        }
}

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LHBL2003
Contributor
Contributor
Jump to solution

Hi @LucD

Unfortunately, this does not work with two Connect.

"$netSys" then contains two entries and that fails with "UpdatePortGroup"

Error: A specified parameter was not correct: Vim.Host.PortGroup::Specification::vswitchId

Your current example only works with one connection.

 

# Subfunction
function RenamePortGroup ([String] $oldPortGroupName, [String] $newPortGroupName) {
        Get-View -ViewType HostSystem -PipelineVariable esx |              # Loop through all ESXi nodes
        ForEach-Object -Process {
                $netSys = Get-View -Id $esx.ConfigManager.NetworkSystem
                $esx.Config.Network.Portgroup | where { $_.Spec.Name -eq $oldPortGroupName } |
                ForEach-Object -Process {
                        $spec = $_.Spec
                        $spec.Name = $newPortGroupName
                        $netSys.UpdatePortGroup($oldPortGroupName, $spec)
                
                        Get-VMHost -Name $esx.Name | Get-VM | Get-NetworkAdapter |
                        where{$_.NetworkName -eq $oldPortGroupName} | 
                        Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
                }
        }
}

# MAIN 

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.13" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.39" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.

$oldPortGroupName = Read-Host "Old Portgroup Name?"
$newPortGroupName = Read-Host "New Portgroup Name?"

RenamePortGroup  -oldPortGroupName $oldPortGroupName -newPortGroupName $newPortGroupName


Disconnect-VIServer -Server * -confirm:$false -Force # Belongs to Menu File.

 

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then try changing that line to

$netSys = Get-View -Id $esx.ConfigManager.NetworkSystem -Server $esx.Name


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LHBL2003
Contributor
Contributor
Jump to solution

Hi @LucD

It works now with your version.
But I still had to add Get-VMHost from my version.
Because Get-VMHost returns the name that was used for the connection. This is required for Get-View, Get-VMHost etc. Because with you the FQDN comes back. But the functions expect the name as indicated for the connection. So ServerName, FQDN or IP address.
So your example is similar to my example.

I made a mixed version of both. With the advantages of your version and the correction with Get-VMHost.

Thanks.

Finding:
The server names are still required for both.
The problem with the unsightly "For loop" has been fixed.
The constellation of you will be more resource-friendly.

 

 

# Subfunction
function RenamePortGroup ([String] $oldPortGroupName, [String] $newPortGroupName) 
{
 
    Get-VMHost -PipelineVariable ConViServer | # Hole die Liste der Verbundenen ESXi Server
    Foreach-Object -Process { # Gehe die Liste schleifenweise durch

        $esx =  Get-View -Server $ConViServer.Name -ViewType HostSystem # Hole die HostSystem Informationen zum ESXi
        $netSys = Get-View -Server $ConViServer.Name -ID $esx.ConfigManager.NetworkSystem # Hole die Network System Informationen zum ESXi

        $pg = $esx.Config.Network.Portgroup | where {$_.Spec.Name -eq $oldPortGroupName} # Suche nach der Gruppe mit dem alten Portgruppennamen
        ForEach-Object -Process { # Führe für die gefundene Gruppe folgendes aus

            $spec = $pg.Spec # Hole die Konfiguration zur Portgruppe
            $spec.Name = $newPortGroupName # Neuer name für die Portgruppe
            $netSys.UpdatePortGroup($oldPortGroupName, $spec) # Koniguration aktualisieren

            # Da die Portgruppe umbenannt wurde, werden nun die Netzwerkkarten geprüft und dort auch die Portgruppe umbenannt.
            Get-VM -Server $ConViServer.Name |Get-NetworkAdapter |
            where {$_.NetworkName -eq $oldPortGroupName } |
            Set-NetworkAdapter -NetworkName $newPortGroupName -Confirm:$false
        }
    }
}

# MAIN 

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.13" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.
Connect-VIServer -Server "10.10.10.39" -User "root" -Password "xxx" -SaveCredentials # Belongs to Menu File.

$oldPortGroupName = Read-Host "Old Portgroup Name?"
$newPortGroupName = Read-Host "New Portgroup Name?"

RenamePortGroup  -oldPortGroupName $oldPortGroupName -newPortGroupName $newPortGroupName


Disconnect-VIServer -Server * -confirm:$false -Force # Belongs to Menu File.

 

 

 

#########################

German:

Es geht jetzt mit deiner Version.
Ich musste aber noch Get-VMHost aus meiner Version hinzufügen.
Denn Get-VMHost gibt den Namen zurück der bei der Verbindung verwendet wurde. Dieser wird für Get-View, Get-VMHost usw. benötigt. Denn bei dir kommt der FQDN zurück. Aber die Funktionen erwarten den namen wie bei der Verbindung angegeben. Also ServerName, FQDN oder IP-Adresse.
Somit ist dein beispiel ähnlich wie mein beispiel.

Ich habe eine Mix version aus beiden erstellt. Mit den vorteilen deiner Version und der korrektur mit Get-VMHost.

Danke.

Feststellung:
Bei beiden sind die angaben der Servernamen weiterhin erforderlich.
Das Problem mit der For unschönen "For-Schleife" wurde behoben.
Die Konstellation von dir wird Recourcen schonender sein.

 

0 Kudos