我正在寻找一种在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}}
答案 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下在线获取示例。