PowerShell中如何将字符串转换为对象数组?
解决PowerShell中将多对象键值对字符串转换为对象数组的问题
你需要将包含多组键值对的字符串转换为对象数组,示例字符串如下:
PS C:\Windows\system32> $datasets[0] id : 11111 name : test1 addRowsAPIEnabled : False configuredBy : xxxx isRefreshable : True isEffectiveIdentityRequired : False isEffectiveIdentityRolesRequired : False targetStorageMode : Abf createdDate : 2019-02-12T16:43:01.047Z contentProviderType : PbixInImportMode upstreamDatasets : {} users : {} isInPlaceSharingEnabled : False id : 22222 name : test2 addRowsAPIEnabled : False configuredBy : xxxx isRefreshable : True isEffectiveIdentityRequired : False isEffectiveIdentityRolesRequired : False targetStorageMode : Abf createdDate : 2019-07-15T15:53:15.057Z contentProviderType : PbixInImportMode upstreamDatasets : {} users : {} isInPlaceSharingEnabled : False
该变量类型为String,直接使用ConvertFrom-StringData会因重复键报错,ConvertFrom-Json也不适用(因为不是JSON格式)。
核心思路
原字符串中每组对象用空行分隔,需要先按空行拆分出单个对象的键值对块,再将每个块转换为自定义对象,最后合并为数组。
具体实现代码
处理单个字符串元素
# 将单个字符串按空行拆分为独立的对象键值对块,过滤空行 $singleObjectBlocks = $datasets[0] -split '\r?\n\r?\n' | Where-Object { $_ -match '\S' } # 遍历每个块,转换为PSCustomObject $objectArray = $singleObjectBlocks | ForEach-Object { # 将行首的键名后冒号替换为等号(避免修改值中的冒号) $formattedStr = $_ -replace '^\s*(\w+)\s*:', '$1=' # 转换为哈希表后转成自定义对象 [PSCustomObject](ConvertFrom-StringData $formattedStr) } # 查看结果 $objectArray
处理整个字符串数组
如果$datasets是包含多个此类字符串的数组,可一次性处理所有元素并合并结果:
$allObjects = $datasets | ForEach-Object { # 拆分当前字符串为对象块 $_ -split '\r?\n\r?\n' | Where-Object { $_ -match '\S' } | ForEach-Object { $formattedStr = $_ -replace '^\s*(\w+)\s*:', '$1=' [PSCustomObject](ConvertFrom-StringData $formattedStr) } }
代码说明
- 拆分字符串:
-split '\r?\n\r?\n'匹配Windows或Unix风格的空行,将多组对象拆分为独立块;Where-Object { $_ -match '\S' }过滤拆分后可能出现的空块。 - 格式化键值对:正则
^\s*(\w+)\s*:仅匹配行首的键名(前后允许空格)后的冒号,替换为等号,确保值中的特殊字符(如时间戳里的冒号)不受影响。 - 转换为对象:
ConvertFrom-StringData将格式化后的字符串转为哈希表,再强制转换为PSCustomObject,得到标准的PowerShell对象。
内容的提问来源于stack exchange,提问作者Oleg Kazanskyi
相关产品推荐
相关产品推荐

