PowerShell:为 Select-Object 中的属性转换数据类型
PoweShell: Casting the data type for properties in Select-Object
我正在寻找一种在 PowerShell Select-Object
.
期间转换数据类型的更有效方法(对于键入时间和性能)
目前,我将每个个体 属性 包装在一个表达式中以转换数据类型。我相信这不是正确的方法,只是感觉很脏...
我这样做的原因是我将数据发送到 REST API,它使用 JSON 模式应用严格验证。 $Data
中的数据不可靠。例如,属性 有时是 JSON 字符串 "12345"
,有时是意想不到的 JSON 整数 12345
。
REST API 然后 returns 出现 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}}
我只会转换需要类型为 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
如果您的对象具有 "flat" 层次结构,您可以尝试以下操作:
$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。
我正在寻找一种在 PowerShell Select-Object
.
目前,我将每个个体 属性 包装在一个表达式中以转换数据类型。我相信这不是正确的方法,只是感觉很脏...
我这样做的原因是我将数据发送到 REST API,它使用 JSON 模式应用严格验证。 $Data
中的数据不可靠。例如,属性 有时是 JSON 字符串 "12345"
,有时是意想不到的 JSON 整数 12345
。
REST API 然后 returns 出现 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}}
我只会转换需要类型为 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
如果您的对象具有 "flat" 层次结构,您可以尝试以下操作:
$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。