xofox
Contributor
Contributor

Export used Portgroup/VMs/User, reimport Portgroup/VMs/User, after update/create new PG/User

Following this thread Create vLans in personal folders with specific permission/role .

I need to export current network configuration of each VMs of each user, in a group. Disconnect VMs of their networks, to be able to reproduce existing or create new PGs. Then run an import .csv (or else ?) to reconfigure VMs with their own networks. These are not production VMs and they can lose a few minutes their network connection.

"Reproduced existing" PGs will have the same name/VLanID.

Thanks.(Had a look around this topic in communities.vmware.com but didn't find with the same needs)

0 Kudos
9 Replies
LucD
Leadership
Leadership

I moved this thread to the VMware PowerCLI community.

Let's start with defining what your input is.

Is that the same as the layout in the other thread?

User
SIO/UFA213

Next, how can we find the associated VMs?

Are the Display names of the VMs reflecting the username?

Or are the VMs in a VM folder reflecting the name of the user?

If yes, what is the full path (DC\folder1\folder2...)?

Finally, how and where shall the new PGs be created?
Does each current connected G require a new PG?


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

0 Kudos
xofox
Contributor
Contributor

Hi again Luc !

I modified your previous script (line 177) :

        $pgName = "GRETA-LAN-"+([int]("$userId$_"))

After a test, I saw it was looking OK. Do you agree my syntax ?

Yes, it's in relation with our last thread.

Display name, for my test user UFA213, for his VLan 7 is : GRETA-LAN-2137.

Display name of users VMs are beginning with their username, example : UFA213-TEST-1

Yes , each user has an individual folder for all his VMs, in VMs & Templates. (I think that was written in getfolderpath.txt (attached)).

Each current connected VMs doesn't require a new PG, but I'm managing with the previous script which recreate them.

Finally, I "just" need to be able to create more PGs that the delivered cluster allows us to do.

0 Kudos
LucD
Leadership
Leadership

I'm not a fan of adding strings together.
I would do (but that is personal)

$pgName = "GRETA-LAN-$([int]("$userId$_"))"


How do you decide which VM needs to be connected to a new PG?
Is there a rule? Some logic behind?

What do you mean by

Finally, I "just" need to be able to create more PGs that the delivered cluster allows us to do.


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

0 Kudos
xofox
Contributor
Contributor

Because I'm a real newbie with script, I corrected what I did by what you would do. Thanks for the tip Smiley Wink

I work in a high school, students in digital (system&network) use the cluster for their exam. They have to make their own environment, so if they need 7 VLans, we have to provide them for them.

At the delivery of the cluster, we only got 3 VLans/user (($([int]("$userId$_"))0, 1 & 9). So the need is to add 2 to 8 or to (re)create from 0 to 9. Then users can decide themselves which VLans (only in their user network/folder) the ones they need.

For example, UFA213 needs 1 VLan for his vdesktops and another one for his servers, with a router between, he might be able to use PG GRETA-LAN-2135 & GRETA-LAN-2138 (any number between 2130 and 2139).

0 Kudos
LucD
Leadership
Leadership

Ok, as far as I could understand the actions you want to perform, I have the following flow

read user from CSV

     get all VMs in folder "DATACENTER - SIO\PEDAGO\GRETA\ETUDIANTS\<username>"

     foreach VM

          get all vNICs

          disconnect vNIC from current PG

          find new PG with same VLANId -> newPG

          if not found create new PG -> newPG

          connect vNIC to newPG

     continue VM loop

continue user loop

I'm not sure if this represents what you want to do

Also, I'm not sure how that new PG shall be created when there is no existing PG with the same VLANId

An abstract description of the actions (like I did above) would be useful


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

0 Kudos
xofox
Contributor
Contributor

I don't feel able to give you the abstract description you ask, really sorry. I propose you this way.

pastedImage_0.jpg

These 2 users have "genuine" PG (GRETA-DMZ-XXX9, GRETA-LAN-XXX0, GRETA-LAN-XXX1). XXX for the integer part of the userid. DMZ is not a necessary point, any VLan can used for DMZLan. Here, UFA211 has only 3 VLan. UFA212 has been lucky, we created (by clicking with the mouse/GUI) 2 more VLan for him (GRETA-LAN-2122 & GRETA-LAN-2128). But that's not a nice way to manage a cluster I think...

So, I imagine 2 solutions :

  1. Disconnecting VMs from their vNics and create Vlan from 0 to 9 (and erase/reproduce existing ones)
  2. Test if VLan between 0 and 9 already exist, if not : create them.

Because of my maternel language and my level in vmWare, it's not so easy to be clearly understood. Thanks again for your effort to try to understand my needs.

0 Kudos
LucD
Leadership
Leadership

Ok, I think I understand what you are trying to do.

I'll try to come up with something.


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

0 Kudos
xofox
Contributor
Contributor

Just to try to be more precise,

About the 2 solutions I wrote I imagined, the first one is already done by your previous script, without disconnecting VMs from already existing PG. (More heavy way ?)

Maybe the 2nd way to do the job is cleaner ? Creating a PG only if not already existing for the considered/regarded user.

I let you think about all this. Thanks.

0 Kudos
LucD
Leadership
Leadership

Let us start with this 1st version.

It assumes that all new PGs are already created (see other thread).

When any of the vNICs on any of the user's VMs are not connected to one these new PGs, the current PG is disconnected and the vNIC is connected to a new PG with the same VlanId.

# Values to be defined

$csvPath = '.\users.csv'

$vmFolderBase = 'PEDAGO\GRETA\ETUDIANTS'


# Helper functions

function Get-FolderByPath {

    <#

.SYNOPSIS Retrieve folders by giving a path

.DESCRIPTION The function will retrieve a folder by it's path.

The path can contain any type of leave (folder or datacenter).

.NOTES

Author: Luc Dekens .PARAMETER Path The path to the folder. This is a required parameter.

.PARAMETER

Path The path to the folder. This is a required parameter.

.PARAMETER

Separator The character that is used to separate the leaves in the path. The default is '/'

.EXAMPLE

PS> Get-FolderByPath -Path "Folder1/Datacenter/Folder2"

.EXAMPLE

PS> Get-FolderByPath -Path "Folder1>Folder2" -Separator '>'

#>

    param(

        [CmdletBinding()]

        [parameter(Mandatory = $true)]

        [System.String[]]${Path},

        [char]${Separator} = '/'

    )

    process {

        if ((Get-PowerCLIConfiguration).DefaultVIServerMode -eq "Multiple") {

            $vcs = $global:defaultVIServers

        }

        else {

            $vcs = $global:defaultVIServers[0]

        }

        foreach ($vc in $vcs) {

            $si = Get-View ServiceInstance -Server $vc

            $rootName = (Get-View -Id $si.Content.RootFolder -Property Name).Name

            foreach ($strPath in $Path) {

                $root = Get-Folder -Name $rootName -Server $vc -ErrorAction SilentlyContinue

                $strPath.Split($Separator) | ForEach-Object {

                    $root = Get-Inventory -Name $_ -Location $root -Server $vc -ErrorAction SilentlyContinue

                    if ((Get-Inventory -Location $root -NoRecursion | Select-Object -ExpandProperty Name) -contains "vm") {

                        $root = Get-Inventory -Name "vm" -Location $root -Server $vc -NoRecursion

                    }

                }

                $root | Where-Object { $_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl] } | ForEach-Object {

                    Get-Folder -Name $_.Name -Location $root.Parent -NoRecursion -Server $vc

                }

            }

        }

    }

}


# Loop over all users

Import-Csv -Path $csvPath -UseCulture -PipelineVariable row |

ForEach-Object -Process {

    # Extract required values

    $domain, $userName = $row.User.Split('/')

    $principal = "$domain\$userName"

    $userId = $userName -replace "^\D+"

    $dcName = "DATACENTER - $($domain)"

    $userFolderName = "$dcName\$($vmFolderBase)\$userName"


    # Get user folder

    $userFolder = Get-FolderByPath -Path $userFolderName


    # Loop over all the user's VMs

    Get-VM -Location $userFolder -PipelineVariable vm | ForEach-Object -Process {

        Get-NetworkAdapter -VM $vm -PipelineVariable vnic | ForEach-Object -Process {

            if ($vnic.NetworkName -notmatch "^$($userName)") {

                $newPg = "$($userName)$((Get-VirtualPortGroup -Name $vnic.NetworkName).VlanId)"               

                Set-NetworkAdapter -NetworkAdapter $vnic -NetworkName $newPG -Confirm:$false

            }

        }

    }

}


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

0 Kudos