PoweShell:为选择对象中的属性强制转换数据类型

时间:2019-06-24 17:30:10

标签: powershell casting select-object

我正在寻找一种在PowerShell Select-Object期间投射数据类型的更有效的方法(用于键入时间和性能)。

当前,我将每个单独的属性包装在一个表达式中以强制转换数据类型。我相信这不是正确的方法,只是感觉很脏...

之所以这样做,是因为我正在将数据发送到REST API,后者使用JSON模式进行严格的验证。 $Data中的数据不可靠。例如,属性有时是JSON字符串"12345",有时是意外的JSON整数12345

然后REST API返回403错误,因为它不希望该密钥使用整数。

$Results = $Data | select ` 
    @{Name = 'Name'; expression = {[string]$_.DisplayName}}, 
    @{Name = 'Version'; expression = {[string]$_.DisplayVersion}},  
    @{Name = 'HelpLink'; expression = {[string]$_.HelpLink}}, 
    @{Name = 'InstallLocation'; expression = {[string]$_.InstallLocation}}, 
    @{Name = 'InstallSource'; expression = {[string]$_.InstallSource}}, 
    @{Name = 'Language'; expression = {[int]$_.Language}},  
    @{Name = 'DisplayIcon'; expression = {[string]$_.DisplayIcon}}, 
    @{Name = 'UninstallString'; expression = {[string]$_.UninstallString}}, 
    @{Name = 'WindowsInstaller'; expression = {[int]$_.WindowsInstaller}},
    @{Name = 'AppGUID'; expression = {[string]$_.APP_GUID}},  
    @{Name = 'URLInfoAbout'; expression = {[string]$_.URLInfoAbout}}, 
    @{Name = 'Vendor'; expression = {[string]$_.Publisher}}, 
    @{Name = 'InstallDate'; expression = {[int]$_.InstallDate}},
    @{Name = 'EstimatedSize'; expression = {[int]$_.EstimatedSize}},
    @{Name = 'VersionMajor'; expression = {[string]$_.VersionMajor}},
    @{Name = 'VersionMinor'; expression = {[string]$_.VersionMinor}},
    @{Name = 'SystemComponent'; expression = {[int]$_.SystemComponent}},
    @{Name = 'NoModify'; expression = {[string]$_.NoModify}},
    @{Name = 'NoRepair'; expression = {[string]$_.NoRepair}},
    @{Name = 'ModifyPath'; expression = {[string]$_.ModifyPath}},
    @{Name = 'BundleVersion'; expression = {[string]$_.BundleVersion}},
    @{Name = 'EngineVersion'; expression = {[string]$_.EngineVersion}}

1 个答案:

答案 0 :(得分:1)

我只会转换需要类型为int的属性。由于PowerShell是基于动态类型的语言,因此您可以执行以下操作:

$obj = [PSCustomObject] @{ Number = "123" }
$obj.Number.GetType() # Type is string
$obj.Number = [int] $obj.Number
$obj.Number.GetType() # Type is int

Output:
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
True     True     Int32                                    System.ValueType

您可以找到此示例online。因此,您应该可以使用这种方法:

$Data.Language =  [int] $Data.Language

简而言之,您已经转换了必须为int类型的属性。

更新1

如果您的对象具有“扁平”层次结构,则可以尝试以下操作:

$obj = [PSCustomObject]@{
    IntNr = "123"
    DecNr = "4,56"
    Str   = "abc"
}

$result = $obj.PSObject.Properties | ForEach-Object {
    [int] $parsedInt = 0
    [decimal] $parsedDec = 0.0
    if ([int]::TryParse($_.Value, [ref]$parsedInt)) {
        $_.Value = $parsedInt
    }
    elseif ([decimal]::TryParse($_.Value, [ref]$parsedDec)) {
        $_.Value = $parsedDec
    }
    $_
}

$result

转储$result时的输出:

 Value           : 123
 MemberType      : NoteProperty
 IsSettable      : True
 IsGettable      : True
 TypeNameOfValue : System.Int32
 Name            : IntNr
 IsInstance      : True

 Value           : 456
 MemberType      : NoteProperty
 IsSettable      : True
 IsGettable      : True
 TypeNameOfValue : System.Decimal
 Name            : DecNr
 IsInstance      : True

 Value           : abc
 MemberType      : NoteProperty
 IsSettable      : True
 IsGettable      : True
 TypeNameOfValue : System.String
 Name            : Str
 IsInstance      : True

可以在此link下在线获取示例。