【问题标题】:PoweShell: Casting the data type for properties in Select-ObjectPowerShell:为 Select-Object 中的属性转换数据类型
【发布时间】:2019-06-24 17:30:10
【问题描述】:

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

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

我这样做的原因是我将数据发送到 REST API,该 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}}

【问题讨论】:

  • $Data是什么类型的对象?
  • @MasonSchmidgall 这是一个 PSCustomObject
  • 您使用的是什么 API?可能与这个问题有关

标签: powershell casting select-object


【解决方案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 在线获取。

【讨论】:

  • 嗨 Moerwald,感谢您提供的信息。我将我的问题限制在整数上,看看是否有一些我遗漏的明显方法,不幸的是,我正在处理 30 多个对象和 400 多个属性,其中包括所有不同的数据类型。从它的外观来看,似乎选项要么使用表达式强制转换,要么循环遍历每个对象并使用上面的示例进行强制转换?
  • @Arbiter,请参阅我的答案更新。是的,我认为您必须遍历属性并找到要转换为的正确类型。
  • 这是一个很好的答案,让我有了一些思考。感谢您的帮助!
猜你喜欢
  • 2020-10-21
  • 2021-05-19
  • 2020-07-06
  • 2020-06-17
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
相关资源
最近更新 更多