I have been working on a report that captures VM information utilizing "Get-WmiObject" which requires that I provide login credentials for different domains. This causes errors and other issues that takes a lot of manual input and very time cosuming which takes away from the automation we are trying to implement.
I'm working with PowerCLI and trying to find ways to get my current report utilizing scripting connecting to vsphere.
I've done a lot of googling and have not come across any scripts or ideas on how to get my needed data utilizing powerCLI without having to use some of the powershell objects like WMI.
any help/advice would be greatly appreciated.
Thanks,
I have come across a script that will work, just need to add the WWN (PortWorldWideName) and could use some help:
Get-VM | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}} | export-csv C:\vmhostInfoByVM.csv
What I need to do is add one more column for WWN, using the same configuration in the "@" portion:
@{N=”WWPN”;E={Get-VMHostHba -VM $_}}
I have a current script that gets the WWN utilizing the information below but i'm not able to figure out what parts are needed and how to implement them in the portion above to get the WWN's for each VM:
$vm = Get-VM $computer
$ESX = Get-VMHost -name $vm.VMhost.name
$Hbas = Get-VMhostHba -vmhost $ESX -Type FibreChannel
$Hbas |
ForEach-object {
$Hba=$_
$wwns += "{0:x}" -f $Hba.PortWorldWideName
}
$Wwpn = $wwns -join ' '
Any help on understanding components of this added part and how to think it through to get the WWN's in a separate column would be greatly appreciated.
Try like this
@{N="WWN";E={
[string]::Join(',',(Get-VMHost VM $_ | Get-VMHostHba -Type Fibrechannel | %{
"{0:X}" -f $_.PortWorldWideName}))}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hey LucD,
thank you again for your assistance.
I tried to figure out my error but still not sure of the "in method call"
Missing ')' in method call.
At line:1 char:250
+ Get-VM $vm | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @
{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}},@{N="WWN";E={[string]::Join(',',(Get-V
MHost VM $_ ) <<<< | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName})}} | export-csv c:\scripts\s
chTasks\Disk_allocation_report\vmGuestInfo.csv
+ CategoryInfo : ParserError: (CloseParenToken:TokenId) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
It appears that a couple of closing Parenthesis were missing. I added but looks like i'm still missing something.
btw - my hope is to move the results to a database, have you moved a powercli result to a database before? I was at PDXVMUG yesterday and I saw a great presentation on something similar and thought it would be awesome to move this information to a DB to then allow others to view over an internal site. Just curious, once i begin that process I can start a new thread.
Thanks,
My mistake, some parenthesis were dropped during my copy/paste.
I corrected the code above, please try again.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Well with a LOT of help from the community, especially LucD, I have a working copy of a script to help us keep track of VM's. We use this to help track SAN space as well as VM monitoring in the environment.
param (
[parameter(Mandatory = $true, ValueFromPipeline = $true )]
[alias("InputObject", "VirtualMachine")]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VM
)
process {
$VM | ForEach-Object {
$vmPV = $_ | Get-Member
$vmview = $_ | Get-View
$vmDisks = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum)).ToString("N2")
$totalSpace = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum).ToString("N2")
$freeSpace = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString("N2")
$OSsize = $_.guest.OSFullName
$subtractedAmt = if ($OSsize -like '*2003*' -or $OSsize -like '*2000*') { 60 } else {80}
$wwn = (Get-VMHost -VM $_ | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName})
$VMProp = @{
Name = $_.Name
VirtualPhysical = if ($vmPV) {'V'} else {'P'}
MemoryMB = $_.MemoryMB
TotalSpace = $totalSpace
FreeSpace = $freeSpace
PerentageUsed = (($vmDisks / $totalSpace) * 100).ToString("N2")
DiskSpaceUsed = $vmDisks
NumCPU = $_.NumCpu
SubtractedAmt = $subtractedAmt
BillableAmt = $totalSpace - $subtractedAmt
OSName = $vmview.config.GuestFullName
WWN = $wwn
}
New-Object PSObject -Property $VMProp
}
}
The only drawback to using the hash table as I found out, that you can't keep the order as I have it listed.
So when I run this script: get-vmhost vmhostName | get-vm | .\scriptName.ps1 | export-csv vmexport.csv
I am still a newbie and will continue to look towards this community and the web to keep developing my skill set.
A quick solution is to use a Select-Object before the Export-Csv cmdlet.
That allows you to specify the order of the properties.
get-vmhost vmhostName | get-vm | .\scriptName.ps1 |
Select Name,VirtualPhysical,MemoryMB,TotalSpace,FreeSpace,PercentageUsed,DiskSpaceUsed,NumCPU,SubtractedAmt,BillableAmt,OSName,WWN |
export-csv vmexport.csv
Since PowerShell v3 there is now the [ordered] option, that maintains the order of the properties of the object.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I got an error
Bad numeric constant: 1,164.00.
At C:\xxx\vm-disk-free.ps1:43 char:44
+ PerentageUsed = (($vmDisks / <<<< $totalSpace) * 100).ToString("N2")
+ CategoryInfo : InvalidOperation: (1,164.00:String) [], RuntimeException
+ FullyQualifiedErrorId : BadNumericConstant
Got 1 more diff
You cannot call a method on a null-valued expression.
At C:\xxxt\vm-disk-free.ps1:23 char:95
+ $freeSpace = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString <<<< ("N2")
+ CategoryInfo : InvalidOperation: (ToString:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I copied the script to above ps1 file & ran as
get-vmhost -location xxx | get-vm | .\vm-disk-free.ps1 |
Select Name,VirtualPhysical,MemoryMB,TotalSpace,FreeSpace,PercentageUsed,DiskSpaceUsed,NumCPU,SubtractedAmt,BillableAmt,OSName,WWN |export-csv vmexport.csv
also its taking huge time for cluster with 30 odd vms last 12 min & couting
Yes, the script does take a long time to run with the added WWN component. If you remove that aspect, it should run a bit faster.
One thing i just noticed, when I run the script without exporting, I get the WWN numbers. However when I export-csv , it returns a Cell with:
going to do some additional testing.
As for the other error, i believe that might have to do with a template or blank vmdk file. I need to update the script to include for powered on VM's and no templates. Again, just a guess, still in the process of learning.
The square brackets on there indicate that you are trying to export an array into the CSV.
And the Export-Csv cmdlet doesn't know how to translate an array to a single column value, it will tell you by displaying this System.Object[] entry in the cell.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
i did ctrl+z & it moved head ..
PercentageUsed |
was empty
I did not understand the logic for
SubtractedAmt | BillableAmt |
Please guide
thank you for the explanation LucD, I have updated and testing now:
$wwn | = ((Get-VMHost -VM $_ | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName}) -join ',') |
As far as the logic, this script is to show how to gather some information from vcenter. Logic is an internal necessity.
I would not need WWN as well if i am using it for juts seeing space left for corrective action .
Ya got it for :-
SubtractedAmt | BillableAmt |
Just to confirm, that worked. Adding the -join did the trick.
I must credit my source - Avoiding System.Object[] (or Similar Output) when using Export-Csv | Learn Powershell | Achieve More
The script does take sometime to run but this has been a great learning opportunity. Next step, setup a daily task to run powershell on a server and send specific information to a database.
I removed the ToString("N2") stuff & the errors stopped coming
#$vmDisks | = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum)).ToString("N2") | |
#$totalSpace | = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum).ToString("N2") | |
#$freeSpace | = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString("N2") | |
$vmDisks | = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum)) | |
$totalSpace | = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum) | |
$freeSpace | = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum) |
Hello LucD, I hope you don't mind a direct question about my ultimate goal. This report is just for an overview of our existing VM's, however we have several other servers that are not VM's and I was thinking I could write a local ps script to extract specific wmi information and then send to a central DB where I can later create a web page.
I came across your post and wanted to see if this is the correct path to get to my ultimate goal.
Thanks,
No problem.
So if I understand correctly, you want to retrieve information from all servers in your environment, be they virtual or physical.
That is perfectly possible if a couple of conditions are met:
With the WMI calls, you can retrieve information from the servers.
For example, teh following code will query AD to find all stations whose name starts with 'Srv', and then display the name of the station, and wether or not it is a physical or virtual (vSPhere based) box.
Get-ADComputer -LDAPFilter "(name=Srv*)" | %{
Get-WmiObject -Class Win32_ComputerSystem -ComputerName $_.Name |
Select Name,Domain,@{N='HW';E={
if($_.Model -match '^VMware'){'virtual'}else{'physical'}
}}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you for the information. We currently have a VB script that is installed on all servers and sends a lot of vital server information to a sql database. The information covers Server name, OS version to local user accts, installed apps and soon on. All our servers are Windows and I was thinking we might be able to transfer from the VB script to a powershell that would include a bit more information. We lack some patching information as well as some other requested data. I figured if I was going to pull information, I would try to create a new DB with all of the data so it could be pulled from one location. The person who created the VB script is long gone and no one knows where the original code is located. I saw a demonstration on something very similar and thought I check with you.
Thanks again for all your assistance