首页 > 解决方案 > 使用 PowerShell 将字符串解析为对象时遇到问题

问题描述

我有一个带有结构化数据的字符串(见下文)。我需要获取这个字符串并将其转换为一个对象,这样我就可以将它导出为 .csv(或我要求的任何其他内容)。我运行了以下代码:

$data = $string -replace "\s*:\s*","="

但我的输出如下所示:

City=Country=Department=DisplayName=John Doe
DistinguishedName=CN=John Doe, CN=Users, DC=domain, DC=com
EmailAddress=jdoe@domain.com
Enabled=False
Fax=GivenName=John
MobilePhone=Name=John Doe
ObjectClass=user
ObjectGUID=cdb9a45c-80f4-4919-bf43-5db8d9ca83da
Office=OfficePhone=PostalCode=SamAccountName=jdoe
SID=S-1-5-21-2025429266-2000478354-1606980848-16934
State=StreetAddress=Surname=Doe
Title=UserPrincipalName=jdoe@domain.com

这显然是不正确的。进行这种转换的更好方法是什么?我考虑过将 ConvertFrom-String 与 TemplateContent 参数一起使用,但还不能实现。

以下是字符串中的前两个条目(其中包含多个用户数据):

$string = @"
City              :
Country           :
Department        :
DisplayName       : John Doe
DistinguishedName : CN=John Doe,CN=Users,DC=domain,DC=com
EmailAddress      : jdoe@domain.com
Enabled           : False
Fax               :
GivenName         : John
MobilePhone       :
Name              : John Doe
ObjectClass       : user
ObjectGUID        : cdb9a45c-80f4-4919-bf43-5db8d9ca83da
Office            :
OfficePhone       :
PostalCode        :
SamAccountName    : jdoe
SID               : S-1-5-21-2025429266-2000478354-1606980848-16934
State             :
StreetAddress     :
Surname           : Doe
Title             :
UserPrincipalName : jdoe@domain.com

City              :
Country           :
Department        :
DisplayName       : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}
DistinguishedName : CN=DiscoverySearchMailbox {D919BA15-46A6-415f-80AD-7E09334BB852},CN=Users,DC=domain,DC=com
EmailAddress      : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}@domain.com
Enabled           : False
Fax               :
GivenName         :
MobilePhone       :
Name              : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}
ObjectClass       : user
ObjectGUID        : 0f35137a-de93-472f-9114-5488a462d178
Office            :
OfficePhone       :
PostalCode        :
SamAccountName    : SM_2187102a90634829b
SID               : S-1-5-21-2438891277-1009865731-3229889747-3109
State             :
StreetAddress     :
Surname           : MsExchDiscoveryMailbox D919BA15-46A6-415f-80AD-7E09334BB852
Title             :
UserPrincipalName : DiscoverySearchMailbox{D919BA15-46A6-415f-80AD-7E09334BB852}@domain.com
"@

谢谢。

标签: stringpowershellparsing

解决方案


如果:

  • 你可以依赖从不包含:自己的价值观
  • 您不介意生成的自定义对象的属性不反映输入顺序(尽管您可以轻松但效率低下地通过管道传递到Select-Object显式枚举属性的调用来纠正),

你可以使用ConvertFrom-StringData(我建议避免挑剔和记录不充分ConvertFrom-String):

$string.Trim() -split '(?m)(?=^City\b)' -ne '' | ForEach-Object { 
  [pscustomobject] ($_ -replace ':', '=' | ConvertFrom-StringData)
}  # | Export-Csv ....

注意:投射到[pscustomobject]需要 PSv3+;在 PSv2 上,使用New-Object PSCustomObject -Property (...)

  • $string.Trim() -split '(?m)(?=^City\b)' -ne ''将输入行分割成每行代表一个对象的行块;拆分由以City;开头的行执行 -ne ''过滤掉解析输入开始产生的空块。

    • .Trim()需要忽略字符串开头的空行。
  • $_ -replace ':', '=' | ConvertFrom-StringData将每个块转换为作为组转换为实例的
    <key>=<value>行;因为哈希表固有地以没有保证的顺序枚举它们的条目,这就是属性的输入顺序丢失的地方。ConvertFrom-StringData[hashtable]

  • Cast[pscustomobject]将每个哈希表转换为自定义对象,隐式输出;输出可以通过管道传输到Export-Csv.


推荐阅读