Hi,
I have some basic PowerCLI skill but want to improve them using more advance features like function, modules and so on.
I want to create PowerShell function which to accept as pipeline VMs object (output from Get-VM).
Very frequently I want to export info about VMs, so I want to simplify this using function.
I write this simple function for this, but there is something wrong with it. Only one VM is display as output. I expect to be many. Where is my mistake.
Example:
Get-Datastore XXX |Get-VM |Info-VM |ft
function Info-VM {
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl[]]$Entity
)
$Entity | Select @{N="VmName";E={$_.Name} },
PowerState,
@{N="GuestOsHostname";E={$_.Guest.HostName} },
@{N="GuestOsIpAddress"; E={ ( ($_.Guest.IPaddress | where {([IPAddress]$_).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork} ) ) -join ", " } },
@{N="EsxHost";E={$_.VMHost } },
@{N="vCPU";E={$_.NumCPU} },
MemoryGB,
@{N="ProvStorageGB"; E={[math]::round($_.ProvisionedSpaceGB,2)}},
@{N="UsedStorageGB"; E={[math]::round($_.UsedSpaceGB,2)}},
Notes,
@{N="OsVersion_ReportedByTools"; E={$_.Guest.OSFullName } },
@{N="OsVersion_Configure"; E={$_.ExtensionData.Config.GuestFullName} },
@{N="BiosUuid"; E={$_.ExtensionData.Config.UUID} },
@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsRunningStatus} }
$VMInfo
}
You have to use a Process block when handling pipeline input.
Also, I changed the type to a strong type, see PowerCLI Best Practice: Correct Use of Strong Typing
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$Entity
)
process {
$Entity | Select @{N="VmName";E={$_.Name} },
PowerState,
@{N="GuestOsHostname";E={$_.Guest.HostName} },
@{N="GuestOsIpAddress"; E={ ( ($_.Guest.IPaddress | where {([IPAddress]$_).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork} ) ) -join ", " } },
@{N="EsxHost";E={$_.VMHost } },
@{N="vCPU";E={$_.NumCPU} },
MemoryGB,
@{N="ProvStorageGB"; E={[math]::round($_.ProvisionedSpaceGB,2)}},
@{N="UsedStorageGB"; E={[math]::round($_.UsedSpaceGB,2)}},
Notes,
@{N="OsVersion_ReportedByTools"; E={$_.Guest.OSFullName } },
@{N="OsVersion_Configure"; E={$_.ExtensionData.Config.GuestFullName} },
@{N="BiosUuid"; E={$_.ExtensionData.Config.UUID} },
@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsRunningStatus} }
}
}
Get-VM | info-VM
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You have to use a Process block when handling pipeline input.
Also, I changed the type to a strong type, see PowerCLI Best Practice: Correct Use of Strong Typing
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$Entity
)
process {
$Entity | Select @{N="VmName";E={$_.Name} },
PowerState,
@{N="GuestOsHostname";E={$_.Guest.HostName} },
@{N="GuestOsIpAddress"; E={ ( ($_.Guest.IPaddress | where {([IPAddress]$_).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork} ) ) -join ", " } },
@{N="EsxHost";E={$_.VMHost } },
@{N="vCPU";E={$_.NumCPU} },
MemoryGB,
@{N="ProvStorageGB"; E={[math]::round($_.ProvisionedSpaceGB,2)}},
@{N="UsedStorageGB"; E={[math]::round($_.UsedSpaceGB,2)}},
Notes,
@{N="OsVersion_ReportedByTools"; E={$_.Guest.OSFullName } },
@{N="OsVersion_Configure"; E={$_.ExtensionData.Config.GuestFullName} },
@{N="BiosUuid"; E={$_.ExtensionData.Config.UUID} },
@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsRunningStatus} }
}
}
Get-VM | info-VM
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If you want to read up on functions and pipeline input, this is a good article
Down the Rabbit Hole- A Study in PowerShell Pipelines, Functions, and Parameters
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD thank you.
You are bulletproof PS Guru. Fast and professional answer. But most important give people and some guidelines for self-improvement.