例如,我要使用此类 Microsoft.HyperV.PowerShell.HardDiskDrive
我试图通过这种方式初始化它:
$obbb = [Microsoft.HyperV.PowerShell.HardDiskDrive]@{
Path = 'D:\\TEST\\test\\Virtual Hard Disks\\test.vhdx'
DiskNumber = $null
MaximumIOPS = '1000'
MinimumIOPS = '0'
QoSPolicyID = '00000000-0000-0000-0000-000000000000'
SupportPersistentReservations = $false
WriteHardeningMethod = '0'
ControllerLocation = '0'
ControllerNumber = '0'
ControllerType = '0'
Name = 'Hard Drive on IDE controller number 0 at location 0'
PoolName = 'Primordial'
Id = 'Microsoft:480244F9-44D4-4BFC-B34B-EC3C425D52F7\\83F8638B-8DCA-4152-9EDA-2CA8B33039B4\\0\\0\\D'
VMId = '480244f9-44d4-4bfc-b34b-ec3c425d52f7'
VMName = 'test'
VMSnapshotId = '00000000-0000-0000-0000-000000000000'
VMSnapshotName = ''
CimSession = $null
ComputerName = 'NodeTest'
IsDeleted = $false
VMCheckpointId = '00000000-0000-0000-0000-000000000000'
VMCheckpointName = ''
}
但是出现此错误:
Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "Microsoft.HyperV.PowerShell.HardDiskDrive".
At line:1 char:1
+ $obbb = [Microsoft.HyperV.PowerShell.HardDiskDrive]@{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
我还尝试了不同的New-Object变体https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-object?view=powershell-6
但是出现错误。
是否有可能?
谢谢。
答案 0 :(得分:1)
TheIncorrigible1在对该问题的评论中提供了关键指针:
PowerShell的从哈希表构造广播技术仅在目标类型(也)具有构造函数的情况下有效:
您看到的错误消息暗示[Microsoft.HyperV.PowerShell.HardDiskDrive]
确实没有这样的构造函数(有关如何检查构造函数的信息,请参见底部)。
假设具有此类构造函数的类型具有 settable 的 public 个属性,则可以从其条目的哈希表中进行广播匹配这些属性的任何子集 ,其中每个条目的键都必须是此类属性的名称,并且其值必须是类型兼容的(与属性具有相同类型或可转换的) )。
PowerShell首先使用无参数构造函数实例化类型,然后设置哈希表中指定的公共属性。
这是一个(有些人为的)示例:
$obj = [System.Exception] @{ # just [Exception] works too, because 'System.' is implied
HResult = 0x8000400
Source = 'SomeModule'
}
以上等同于:
$obj = New-Object System.Exception; $obj.HResult = 0x8000400; $obj.Source = 'SomeModule'
由于需要无参数构造函数,因此哈希表技术目前主要用于类似DTO的“属性包” 。
如果给定类型的所有公共构造函数具有参数,则哈希表技术将不起作用,您必须 调用构造函数以实例化类型-通过静态::new
方法(PSv5 +)或New-Object
cmdlet ;例如,调用(int year, int month, int day)
构造函数的[System.DateTime]
重载:
New-Object DateTime -ArgumentList 2018, 12, 1 # '-ArgumentList' is optional
[DateTime]::new(2018, 12, 1) # PSv5+ equivalent
要调用单个参数构造函数,可以替代使用 cast -请参阅下一节。
不过,an enhancement is coming是PowerShell的 Core 帽子的尖端是TessellatingHeckler。 只要具有哈希表项的集合与给定的构造函数重载的参数匹配,就可以在具有参数的构造函数中使用哈希表技术。
通常,除了上面讨论的哈希表情况外, 广播([<target-type>] <operand>
)和隐式转换在以下情况下都有效 >,按考虑顺序:
此信息来自PowerShell Core的源代码here。
(a)如果目标类型用TypeConverterAttribute
属性修饰,该属性指定支持自操作数类型转换的自定义TypeConverter
或PSTypeConverter
类。
另外,这些自定义转换器类可以通过PowerShell的ETS(扩展类型系统),通过Update-TypeData -TypeConverter
)与类型关联。
(b)如果目标类型支持从{em> string 构造静态实例的静态::Parse()
方法:
[DateTime] '2018-12-01'
# The above matches `::Parse()` overload `static datetime Parse(string s)`
# However, given that there's also an overload that accepts a
# System.IFormatProvider argument, PowerShell uses that in order
# to use *culture-invariant* parsing.
# Thus, the above is the equivalent of:
[DateTime]::Parse('2018-12-01', [cultureinfo]::InvariantCulture)
有关PowerShell使用不变文化的更多信息,请参见this answer。
(c)如果目标类型具有带有单个参数的公共构造函数,则该操作数的类型相同或与-兼容:
[Exception] 'Something failed'
# The above matches constructor `Exception(string message)` and is the
# equivalent of:
New-Object Exception -ArgumentList 'Something failed'
[Exception]::new('Something failed')
(d)如果目标类型为操作数的类型定义了隐式或显式conversion operator。
(e)如果操作数类型实现了IConvertible
接口,用于构造目标类型的等效实例(限于CLR运行时类型(内置类型))。
在 PSv5 + 中,很容易检查给定(加载)类型的构造函数:调用不带括号的静态::new
方法,该方法列出所有公共可用构造函数的方法重载(签名);以类型[System.Random]
为例:
PS> [Random]::new
OverloadDefinitions
-------------------
System.Random new()
System.Random new(int Seed)
存在{strong> new()
重载-没有参数-证明了无参数的公共构造函数。
如果根本没有输出,则表示该类型没有任何公共构造函数。