Powershell 对象未通过管道传递给函数
Powershell Object not being piped through to Functions
我有两个函数,一个创建一个自定义对象,完成后通过管道传输到下一个函数。问题是第二个函数没有正确接收我的对象。我没有使用管道,而是尝试设置一个变量,然后将该变量通过管道传递给函数。下面是两个函数,在返回的对象上有 get member 的输出。所有字符串参数都被正确处理。但是这些对象根本不起作用。在 New-BaseGuest
的 begin
块中,我无法将结果分配给变量。
基本上我想结束:
Get-ServerFromXML -XMLFile File -GuestName Name | New-BaseGuest
New-BaseGuest
函数不完整,因为我无法使参数正常工作。
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CDROM_Connected NoteProperty object CDROM_Connected=null
CDROM_ISO NoteProperty object CDROM_ISO=null
Floppy_Connected NoteProperty object Floppy_Connected=null
Floppy_ISO NoteProperty object Floppy_ISO=null
GuestType NoteProperty string GuestType=vmkernel6Guest
IPAddress NoteProperty string IPAddress=192.168.199.40
ServerName NoteProperty string ServerName=ESX-VSAN3
vCPU NoteProperty string vCPU=2
vHDD NoteProperty Object[] vHDD=System.Object[]
vNIC NoteProperty Object[] vNIC=System.Object[]
vRAM NoteProperty string vRAM=5120
function Get-ServerFromXML
{
<##>
[CmdletBinding()]
param
(
[String]
$XMLFile,
[String]
$GuestName
)
$xml = New-Object -TypeName XML
$xml.Load($XMLFile)
$Server = Select-Xml -Xml $xml -XPath ('/Servers/Server[@Name = "' + $GuestName + '" ]')
$vNicObjs = @()
$vHddobjs = @()
If ($Server.Node.Hardware.vnic.Count -ne $null)
{
$Server.Node.Hardware.vnic | %{
$NicProps = @{
NIC_ID = $_.ID;
NIC_Type = $_.Type;
NIC_StartConnected = $_.StartConnected;
NIC_MACAddress = $_.MACAddress;
NIC_WakeOnLan = $_.WakeOnLan;
NIC_PortGroup = $_.PortGroup
}
$vNicObj = New-Object -TypeName System.Management.Automation.PSObject -Property $NicProps
$vNicObjs += $vNicObj
}
}
Else
{
$NicProps = @{
NIC_ID = $Server.Node.Hardware.vnic.ID;
NIC_Type = $Server.Node.Hardware.vnic.Type;
NIC_StartConnected = $Server.Node.Hardware.vnic.StartConnected;
NIC_MACAddress = $Server.Node.Hardware.vnic.MACAddress;
NIC_WakeOnLan = $Server.Node.Hardware.vnic.WakeOnLan;
NIC_PortGroup = $Server.Node.Hardware.vnic.PortGroup
}
$vNivObj = New-Object -TypeName System.Management.Automation.PSObject -Property $NicProps
$vNicObjs += $vNivObj
}
If ($Server.Node.Hardware.vHDD.Count -ne $null)
{
$Server.Node.Hardware.vHDD | %{
$HDDProps = @{
HDD_ID = $_.ID;
HDD_Type = $_.Type;
HDD_Size = $Server.Node.Hardware.vHDD.Size;
HDD_Datastore = $_.Datastore;
HDD_StorageFormate = $_.StorageFormat
}
$vHDDObj = New-Object -TypeName System.Management.Automation.PSObject -Property $HDDProps
$vHDDObjs += $vHDDObj
}
}
Else
{
$HDDProps = @{
HDD_ID = $Server.Node.Hardware.vHDD.ID;
HDD_Type = $Server.Node.Hardware.vHDD.Type;
HDD_Size = $Server.Node.Hardware.vHDD.Size;
HDD_DataStore = $Server.Node.Hardware.vHDD.Datastore;
HDD_StorageFormat = $Server.Node.Hardware.vHDD.StorageFormat
}
$vHDDObj = New-Object -TypeName System.Management.Automation.PSObject -Property $HDDProps
$vHDDObjs += $vHDDObj
}
$ServerProps =[Ordered]@{
ServerName = $Server.Node.Description.Name;
GuestType = $Server.Node.Description.GuestType;
IPAddress = $Server.Node.Description.PrimaryIP;
vCPU = $Server.Node.Hardware.vCPU;
vRAM = $Server.Node.Hardware.vRAM;
vHDD = $vHddobjs;
vNIC = $vNicObjs;
CDROM_ISO = $Server.Node.Hardware.CDROM.ISOPath
CDROM_Connected = $Server.Node.Hardware.CDROM.StartConnected
Floppy_ISO = $Server.Node.Hardware.Floppy.ISOPath
Floppy_Connected = $Server.Node.Hardware.Floppy.StartConnected
}
$ServerObj = New-Object -TypeName System.Management.Automation.PSObject -Property $ServerProps
$ServerObj
}
function New-BaseGuest
{
<##>
[CmdletBinding(PositionalBinding = $true,
SupportsShouldProcess = $true)]
param
(
[Parameter(Mandatory = $true,
ValueFromPipeline = $false,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[string]
$ServerName,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[string]
$GuestType,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 3)]
[string]
$vCPU,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 4)]
[string]
$vRAM,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 5)]
[system.object]
$vHDD,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 6)]
[system.object]
$vNIC,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 7)]
[string]
$CDROM_ISO = $Null,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 8)]
[string]
$FLOPPY_ISO = $Null,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 9)]
[string]
$CDROM_Connected = $Null,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 10)]
[string]
$Floppy_Connected = $Null
)
BEGIN
{
$Datastore = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_DataStore).HDD_DataStore
$PortGroup = ($vNIC | Where-Object { $_.NIC_ID -eq 1 } | Select-Object -Property NIC_PortGroup).NIC_PortGroup
$DiskSize = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_Size).HDD_Size
$DiskFormat = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_StorageFormat).HDD_StorageFormat
}
PROCESS
{
New-VM -Name $ServerName `
-Datastore $Datastore `
-NumCPU $vCPU `
-MemoryGB $vRAM`
-DiskGB $DiskSize `
-NetworkName $PortGroup `
-DiskStorageFormat $CDROM_ISO `
-GuestID $GuestType | Out-Null
}
END
{
}
}
这是预期的行为。在遇到任何管道对象之前的 begin {}
块 运行,因此您无法访问通过开始块中的管道传入的任何参数。
process {}
块 运行 每个项目一次,所以你在开始块中的代码确实需要放在那里(因为它特定于单个 VM)。
我有两个函数,一个创建一个自定义对象,完成后通过管道传输到下一个函数。问题是第二个函数没有正确接收我的对象。我没有使用管道,而是尝试设置一个变量,然后将该变量通过管道传递给函数。下面是两个函数,在返回的对象上有 get member 的输出。所有字符串参数都被正确处理。但是这些对象根本不起作用。在 New-BaseGuest
的 begin
块中,我无法将结果分配给变量。
基本上我想结束:
Get-ServerFromXML -XMLFile File -GuestName Name | New-BaseGuest
New-BaseGuest
函数不完整,因为我无法使参数正常工作。
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CDROM_Connected NoteProperty object CDROM_Connected=null
CDROM_ISO NoteProperty object CDROM_ISO=null
Floppy_Connected NoteProperty object Floppy_Connected=null
Floppy_ISO NoteProperty object Floppy_ISO=null
GuestType NoteProperty string GuestType=vmkernel6Guest
IPAddress NoteProperty string IPAddress=192.168.199.40
ServerName NoteProperty string ServerName=ESX-VSAN3
vCPU NoteProperty string vCPU=2
vHDD NoteProperty Object[] vHDD=System.Object[]
vNIC NoteProperty Object[] vNIC=System.Object[]
vRAM NoteProperty string vRAM=5120
function Get-ServerFromXML
{
<##>
[CmdletBinding()]
param
(
[String]
$XMLFile,
[String]
$GuestName
)
$xml = New-Object -TypeName XML
$xml.Load($XMLFile)
$Server = Select-Xml -Xml $xml -XPath ('/Servers/Server[@Name = "' + $GuestName + '" ]')
$vNicObjs = @()
$vHddobjs = @()
If ($Server.Node.Hardware.vnic.Count -ne $null)
{
$Server.Node.Hardware.vnic | %{
$NicProps = @{
NIC_ID = $_.ID;
NIC_Type = $_.Type;
NIC_StartConnected = $_.StartConnected;
NIC_MACAddress = $_.MACAddress;
NIC_WakeOnLan = $_.WakeOnLan;
NIC_PortGroup = $_.PortGroup
}
$vNicObj = New-Object -TypeName System.Management.Automation.PSObject -Property $NicProps
$vNicObjs += $vNicObj
}
}
Else
{
$NicProps = @{
NIC_ID = $Server.Node.Hardware.vnic.ID;
NIC_Type = $Server.Node.Hardware.vnic.Type;
NIC_StartConnected = $Server.Node.Hardware.vnic.StartConnected;
NIC_MACAddress = $Server.Node.Hardware.vnic.MACAddress;
NIC_WakeOnLan = $Server.Node.Hardware.vnic.WakeOnLan;
NIC_PortGroup = $Server.Node.Hardware.vnic.PortGroup
}
$vNivObj = New-Object -TypeName System.Management.Automation.PSObject -Property $NicProps
$vNicObjs += $vNivObj
}
If ($Server.Node.Hardware.vHDD.Count -ne $null)
{
$Server.Node.Hardware.vHDD | %{
$HDDProps = @{
HDD_ID = $_.ID;
HDD_Type = $_.Type;
HDD_Size = $Server.Node.Hardware.vHDD.Size;
HDD_Datastore = $_.Datastore;
HDD_StorageFormate = $_.StorageFormat
}
$vHDDObj = New-Object -TypeName System.Management.Automation.PSObject -Property $HDDProps
$vHDDObjs += $vHDDObj
}
}
Else
{
$HDDProps = @{
HDD_ID = $Server.Node.Hardware.vHDD.ID;
HDD_Type = $Server.Node.Hardware.vHDD.Type;
HDD_Size = $Server.Node.Hardware.vHDD.Size;
HDD_DataStore = $Server.Node.Hardware.vHDD.Datastore;
HDD_StorageFormat = $Server.Node.Hardware.vHDD.StorageFormat
}
$vHDDObj = New-Object -TypeName System.Management.Automation.PSObject -Property $HDDProps
$vHDDObjs += $vHDDObj
}
$ServerProps =[Ordered]@{
ServerName = $Server.Node.Description.Name;
GuestType = $Server.Node.Description.GuestType;
IPAddress = $Server.Node.Description.PrimaryIP;
vCPU = $Server.Node.Hardware.vCPU;
vRAM = $Server.Node.Hardware.vRAM;
vHDD = $vHddobjs;
vNIC = $vNicObjs;
CDROM_ISO = $Server.Node.Hardware.CDROM.ISOPath
CDROM_Connected = $Server.Node.Hardware.CDROM.StartConnected
Floppy_ISO = $Server.Node.Hardware.Floppy.ISOPath
Floppy_Connected = $Server.Node.Hardware.Floppy.StartConnected
}
$ServerObj = New-Object -TypeName System.Management.Automation.PSObject -Property $ServerProps
$ServerObj
}
function New-BaseGuest
{
<##>
[CmdletBinding(PositionalBinding = $true,
SupportsShouldProcess = $true)]
param
(
[Parameter(Mandatory = $true,
ValueFromPipeline = $false,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[string]
$ServerName,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 2)]
[string]
$GuestType,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 3)]
[string]
$vCPU,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 4)]
[string]
$vRAM,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 5)]
[system.object]
$vHDD,
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 6)]
[system.object]
$vNIC,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 7)]
[string]
$CDROM_ISO = $Null,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 8)]
[string]
$FLOPPY_ISO = $Null,
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 9)]
[string]
$CDROM_Connected = $Null,
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 10)]
[string]
$Floppy_Connected = $Null
)
BEGIN
{
$Datastore = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_DataStore).HDD_DataStore
$PortGroup = ($vNIC | Where-Object { $_.NIC_ID -eq 1 } | Select-Object -Property NIC_PortGroup).NIC_PortGroup
$DiskSize = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_Size).HDD_Size
$DiskFormat = ($vHDD | Where-Object { $_.HDD_ID -eq 1 } | Select-Object -Property HDD_StorageFormat).HDD_StorageFormat
}
PROCESS
{
New-VM -Name $ServerName `
-Datastore $Datastore `
-NumCPU $vCPU `
-MemoryGB $vRAM`
-DiskGB $DiskSize `
-NetworkName $PortGroup `
-DiskStorageFormat $CDROM_ISO `
-GuestID $GuestType | Out-Null
}
END
{
}
}
这是预期的行为。在遇到任何管道对象之前的 begin {}
块 运行,因此您无法访问通过开始块中的管道传入的任何参数。
process {}
块 运行 每个项目一次,所以你在开始块中的代码确实需要放在那里(因为它特定于单个 VM)。