我有以下功能:
Function Get-MsiProperty
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
[ValidateScript({$_ | Test-Path -PathType Leaf})]
[string]$Path,
[Parameter(Mandatory=$true)]
[string]$Property
)
Begin
{
$GetProperty = {
Param
(
$Object,
$PropertyName,
[object[]]$ArgumentList
)
Return $Object.GetType().InvokeMember($PropertyName, 'Public, Instance, GetProperty', $null, $Object, $ArgumentList)
}
$InvokeMethod = {
Param
(
$Object,
$MethodName,
$ArgumentList
)
Return $Object.GetType().InvokeMember($MethodName, 'Public, Instance, InvokeMethod', $null, $Object, $ArgumentList)
}
${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
$PSParameters = $PSBoundParameters | Format-Table -Auto | Out-String
}
Process
{
Try
{
Set-StrictMode -Version Latest
# http://msdn.microsoft.com/en-us/library/aa369432(v=vs.85).aspx
$msiOpenDatabaseModeReadOnly = 0
$Installer = New-Object -ComObject WindowsInstaller.Installer -ErrorAction 'Stop'
$Database = &$InvokeMethod -Object $Installer -MethodName OpenDatabase -ArgumentList @($Path, $msiOpenDatabaseModeReadOnly)
$View = &$InvokeMethod -Object $Database -MethodName OpenView -ArgumentList @("SELECT Value FROM Property WHERE Property='$Property'")
&$InvokeMethod -Object $View -MethodName Execute | Out-Null
$MSIProperty = $null
$Record = &$InvokeMethod -Object $View -MethodName Fetch
If ($Record)
{
$MSIProperty = &$GetProperty -Object $Record -PropertyName StringData -ArgumentList 1
}
Write-Output $MSIProperty
}
Catch
{
Write-Host -Message "Failed to get the MSI property [$Property]"
}
Finally
{
&$InvokeMethod -Object $View -MethodName Close -ArgumentList @() | Out-Null
}
}
}
如果我按下面的方式调用该函数,我会得到正确的结果:
$ProductCode = Get-MsiProperty -Path "ConfigMgrTools.msi" -Property 'ProductCode'
如果我按下面的方式调用该函数,结果在结果之前和之后都有一个空格。为什么会这样?我已经使用Get-Member来分析它显示为'system.string'的变量。
[string]$ProductCode = Get-MsiProperty -Path "ConfigMgrTools.msi" -Property 'ProductCode'
答案 0 :(得分:1)
原始的未经编辑的代码无意中在两个地方写出了$ null。
当$ ProductCode是无类型时,结果是一个数组,格式化数组时,数组中的$ null值将被忽略。
当$ ProductCode作为字符串输入时,$ null值用空格格式化,例如
PS> "__{0}__" -f ([string]@($null, "abc", $null))
__ abc __
将其与无类型进行比较(使用Out-String -Stream将数组转换为字符串而不是类型转换):
PS> "_{0}_" -f (@($null, "abc", $null) | out-string -Stream)
_abc_
$ null值通常来自.Net方法调用,或者在这种情况下,来自COM方法调用。我通常将这样的方法调用的结果分配给$ null,因为它在所有版本的PowerShell中都具有最佳性能,但是Out-Null或者转换为[void]的管道都等效地工作,因此您可以选择您喜欢的任何一个。