Hi All!
I've seen many blogs and discussions about this proposite so i put my hands on the problem and generate my own script.
The algortihm is easy to understand.. You get a list of the vPorts used by the Vms and another list from the vPorts of the Cluster. Then i do something just like a procv in Excel and compare both lists, keeping the difference in another list, the unused PortGroup List.
To use, you have to put the Vcenter which you want to connect, choose the Cluster and wait a few seconds, then you have a csv Document in your c:\temp directory. 😃
Any sugestions i'll be here to update the script. Thanks!
Thanks to LucD by inspiring me on it!
Now, the output is OK, with no duplicated items. 😃
Clear
Write-Output " "
$Vcenter = Read-Host "Which Vcenter do you want to connect?"
Write-Output " "
Connect-Viserver -server $VCenter -WarningAction SilentlyContinue
# Getting Cluster info
$Cluster = Get-Cluster
$countCL = 0
Clear
Write-Output " "
Write-Output "Connected to $VCenter successfully!"
Write-Output " "
Write-Output "Clusters: "
Write-Output " "
foreach($oC in $Cluster){
Write-Output "[$countCL] $oc"
$countCL = $countCL+1
}
$choice = Read-Host "Which Cluster do you want to verify?"
Write-Output " "
Write-Output "Wait a minute..."
$cluster = get-cluster $cluster[$choice]
$vms = $cluster| get-vm
$Data = @()
foreach ($VM in $VMs){
$NICs = $VM.NetworkAdapters | select networkName
foreach ($NIC in $NICs) {
$into = New-Object PSObject
Add-Member -InputObject $into -MemberType NoteProperty -Name VMname $VM.Name
foreach($n in $NIC){
Add-Member -InputObject $into -MemberType NoteProperty -Name NetworkName $n.NetworkName }
$Data += $into
}
}
##
##$Data contains the list of virtual machines/Networkadapters by cluster
##$ClustervPortsData contains a list of the vPorts by Cluster
##
$ClustervPortsData = $cluster |get-vmhost | Get-VirtualPortGroup | select @{n="Cluster";e={$cluster.name}},Name
##
##Comparing vPorts used by VMs in that Cluster and the CLuster vPorts, we'll have the vPorts Unused...
##$Data x $ClustervPortsData
$a = $data | select NetworkName
$b = $ClustervPortsData | select Name
$cont = 0
$finalData = @()foreach($b1 in $b){
$obj = New-Object PSObject
foreach($a1 in $a){
if($b1.Name -eq $a1.NetworkName){
$cont = $cont+1
}elseif($b1.Name -ne $a1.NetworkName){
}
}
if($cont -eq 0){
#Add-Member -InputObject $obj -MemberType NoteProperty -Name VPORT $b1.Name
$obj = $b1.Name
$finalData += $obj
}
$cont = 0
}
$rand = Get-Random
$cluname = $Cluster.name
$CL = "$cluname$rand"
$path = "c:\temp\vPortsNotUsed_$Vcenter$CL.csv"
############################
##function to remove duplicated items
Function Remove-DuplicatedItems{
param ($arraylist)
$RemoveDup =@()$arraylist|%{
$itemDup = $_
#compare if the $itemdup already exists in the list
if($removedup -contains $itemDup){
#do nothing
#Write-host "$itemdup already exists in the new array"
}else{
#add to the new array unduplicated
#Write-host "$itemdup do not exists in the new array, adding"
$RemoveDup += $itemdup
}
}
return $RemoveDup
}
############################Remove-DuplicatedItems $finaldata | export-csv $path -NoTypeInformation -UseCulture
clear
Write-Output " "
Write-Output "The File $path was created and it's path was copied to the clipoard. Press any button to exit..."
Read-Host " "
$path | clip
Write-Output " "
Write-Output "Disconnecting from Vcenter $Vcenter..."
Write-Output " "
Disconnect-viserver * -Confirm:$false
Nice script, thanks for sharing.
I'll check why the script in my blog post didn't return the same results.
Thanks Luc. I was trying to use the Export-Xls too for other script and it were changing the columns order... then i've used Export-Csv $path -NoTypeInformation -UseCulture.
I know this is a problem related to the powershell v3 like you mentioned in your blog, but i'm getting the problem with a powershel v1...:smileyconfused: weird..
--------------------------------------------------------
Refreshing:
LucD, both scripts i mentioned here are OK. I was having problem to run your Unused-PortGroups script because of my computer. I ran from another and took just fine!
The expor-xls now becomes Export-xlsx and everything is better than ever. Thank you for both!
By the way, i'll refresh this script as soon as possible 'cause the results are being returned in duplicity and showing "Vmkernel Vm" and "Management Network" as Portgroups.
Great work, a really helpful script
As for the duplicity, the output is a portgroup per host in the cluster, (ie: 2 hosts = 2 entries, 4 hosts = 4 entries)
I suppose because $ClustervPortsData = $cluster |get-vmhost | Get-VirtualPortGroup | select @{n="Cluster";e={$cluster.name}},Name returns an entry per host...
Even so it doesn't return entries if the pg is used by one vm on only one host in the cluster
Using the remove duplicates function in the data tab of excel it's easy to remove these
Here’s my contribution... for a mass delete of portgroups on virtual standard switch
first a script (heavily plagiarized from Guilherme) which double checks that no ports are in use
It feeds from a txt file, C:\vSpherePowerCLI\input\unusedportgroups.txt
Note: be careful there is no whitespace, additional lines at the end of the txt..
After that is the delete portgroups, a bit crude, and slow, but we have cleaned up 400+ port groups so far
Its taking around 120 seconds for a 7 node cluster, so several hours if you are removing 100s of unused portgroups
checkUnusedPortGroupsInCluster
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Double check the imput of C:\vSpherePowerCLI\input\unusedportgroups.txt before deleting mas |
# Enter location
Clear
# Getting Cluster info | |
$Cluster = Get-Cluster | |
$countCL = 0 | |
Clear | |
Write-Output " " | |
Write-Output "Clusters: " | |
Write-Output " " | |
foreach($oC in $Cluster) |
{
Write-Output "[$countCL] $oc" | ||
$countCL = $countCL+1 | ||
} | ||
$choice = Read-Host "Which Cluster do you want to verify?" | ||
Write-Output " " | ||
Write-Output "Wait a minute..." | ||
$cluster = get-cluster $cluster[$choice] |
# list the vms in the cluster, create the placeholder variable @Data
$vms = $cluster| get-vm | ||
$Data = @() | ||
foreach ($VM in $VMs){ | ||
$NICs = $VM.NetworkAdapters | select networkName | ||
foreach ($NIC in $NICs) { | ||
$into = New-Object PSObject | ||
Add-Member -InputObject $into -MemberType NoteProperty -Name VMname $VM.Name | ||
foreach($n in $NIC){ | ||
Add-Member -InputObject $into -MemberType NoteProperty -Name NetworkName $n.NetworkName } | ||
$Data += $into | ||
} | ||
} | ||
##$Data contains the list of virtual machines/Networkadapters by cluster | ||
##$ClustervPortsData contains a list of the vPorts input from txt | ||
$ClustervPortsData = Get-Content "C:\vSpherePowerCLI\input\unusedportgroups.txt" | ||
##Comparing vPorts used by VMs in that Cluster and the CLuster vPorts, we'll have the vPorts Unused... | ||
##$Data compared to $ClustervPortsData | ||
$vmpg = $data | select NetworkName | ||
$esxpg = $ClustervPortsData | ||
$cont = 0 | ||
$finalData = @() | ||
foreach($esxpg1 in $esxpg) |
{
$obj = New-Object PSObject
## here the vm portgroup is compared with the esx portgroup, if it is in use then $cont is incremented
foreach($vmpg1 in $vmpg)
{
if($esxpg1 -ne $vmpg1.NetworkName)
{
$cont = $cont+1
}
if($esxpg1 -eq $vmpg1.NetworkName)
{
Write-Host "ERROR: Virtual Machine:" "Adapter:" ""$esxpg1"" "connected" -foregroundcolor red
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
}
if($cont -eq 0)
{
Write-Host "ok ..."
}
$cont = 0
}
clear | |
Write-Output "Finished" | |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
deleteMultipleUnusedPortGroupsInCluster
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Delete multiple unused portgroups from cluster
## Only use after adding the portgroups from GetUnusedPortGroupsInCluster.ps1
## Double check with CheckUnusedPortGroupsInCluster.ps1
# set foreground color to yellow
[console]::ForegroundColor = "yellow"
Write-Output " "
Write-Output "This script will delete multiple portgroups "
Write-Output "add the portgroup names to C:\vSpherePowerCLI\input\unusedportgroups.txt "
Write-Output " "
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Clear
# Getting Cluster info
$Cluster = Get-Cluster
$countCL = 0
Clear
Write-Output " "
Write-Output "Clusters: "
Write-Output " "
foreach($oC in $Cluster){
Write-Output "[$countCL] $oc"
$countCL = $countCL+1
}
$choice = Read-Host "Which Cluster do you want to delete the portgroups on?"
Write-Output " "
Write-Output "This is going to take a while..."
$cluster = get-cluster $cluster[$choice]
# manually enter the location where you want to remove the portgroup
#$Location = Read-Host "Enter location; cluster or datacenter"
# reset the colors back to default
[console]::ResetColor()
# Set system variable to ignore error messages
$ErrorActionPreference= 'silentlycontinue'
### Input from txt the portgroup name you want to remove
$OldPortGroupNames = Get-Content "C:\vSpherePowerCLI\input\unusedportgroups.txt"
foreach ($OldPortGroupName In $OldPortGroupNames)
{
foreach ($esx in get-VMhost -Location $cluster | sort Name)
{
Get-VMhost $esx | Get-VirtualPortGroup -name "$OldPortGroupName" | Remove-VirtualPortGroup -Confirm:$false
}
}
Very Nice!
"One is glad to be of service"
Now you can join both scripts roconnor