0

如果我运行命令:

Resize-VHD -ComputerName $VMhost -Path "D:\VMs\$VMname\Virtual Hard Disks\$vmname.vhdx" -SizeBytes 70GB

Powershell 足够聪明,可以理解 70GB 是什么,接受争论并调整驱动器大小,

但是,如果我这样做:

$drivesize = "70GB"

Resize-VHD -ComputerName $VMhost -Path "D:\VMs\$VMname\Virtual Hard Disks\$vmname.vhdx" -SizeBytes $drivesize

我收到以下错误:

Resize-VHD : Cannot bind parameter 'SizeBytes'. Cannot convert value "70GB" to type "System.UInt64". Error: "Input string was 
not in a correct format."
At line:22 char:100
+ ... D:\VMs\$VMname\Virtual Hard Disks\$vmname.vhdx" -SizeBytes $drivesize
+                                                                ~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Resize-VHD], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Vhd.PowerShell.Cmdlets.ResizeVhd

我认为这是一个变量类型问题,错误说明了很多,我只是不知道如何解决它。

编辑:

如果我将值写入$drivesize控制台,我会得到:

PS C:\Windows\system32> $drivesize
70GB
4

1 回答 1

2

代替:

$drivesize = "70GB" # WRONG: Quoting creates a STRING, but you want a NUMBER

利用:

$drivesize = 70GB  # OK: 70GB is a NUMBER LITERAL, evaluating to 75161927680 

对于 PowerShell,带有二进制乘数后缀的不带引号的数字标记,例如GBare numbers
请注意,生成的数字的特定整数类型会有所不同:使用可以适合该数字的等于或大于[int]( ) 的最小有符号整数类型;System.Int32例如,1GB创建一个[int],而上面的示例70GB,创建一个[long]( System.Int64)。
不过,通常情况下,您不必担心 PowerShell 中的特定数字类型,因为它们会根据需要相互转换。

不要将此类标记存储在字符串中;虽然 PowerShell 在将看起来像数字的字符串转换为实际数字时通常非常灵活,但它通常不能识别诸如"70GB"数字之类的字符串 - 见下文。


可选阅读:字符串的数字转换,其中包含带有后缀的数字标记,例如GB

也许令人惊讶的是,PowerShell 的二进制乘法器后缀 - kb, mb, gb, tb, pb- 仅适用于数字文字,而不是(隐式)从字符串转换时。

PS> 1gb  # produces an [int] whose value is equivalent to 1 * [math]::Pow(2, 30)
1073741824

PS> [int] '1gb' # !! From-string conversion FAILS
Cannot convert value "1gb" to type "System.Int32". Error: "Input string was not in a correct format."

# Workaround: Simply divide by 1, because PowerShell does
#             recognize the suffix in the context of an *expression*.
PS> '1gb' / 1
1073741824

PetSerAl 致敬以提供解决方法。
[自从在 PowerShell (Core) 7+ 中修复] 在表达式中执行隐式数字转换时识别后缀与在此 GitHub 问题中讨论参数绑定时识别后缀之间的惊人差异。

从字符串转换不起作用的原因是后缀是特定于 PowerShell 的,而将字符串转换为数字类型 - 无论是在参数绑定期间隐式还是使用强制转换等显式[int]- 使用不知道的.NET 方法这些后缀。

因此,使用不带乘数后缀的表示相同值的字符串会起作用,例如:

PS> $driveSize = '1073741824'; [UInt64] $driveSize
1073741824

虽然如果你事先知道值,没有理由使用字符串开头,使用数字文字可以避免这个问题:

$driveSize = 70GB # creates a [long] (System.Int64) with value 75161927680

请注意,PowerShell 通常会按需扩展数字类型(根据需要使用更大容量的类型)并自动执行有符号/无符号类型转换。

因此,即使$driveSizeis System.Int64-typed 基于上面的语句,PowerShell在绑定参数System.UInt64时也会自动将其转换为 (unsigned) 。SizeBytes

于 2018-09-05T15:09:04.013 回答