使用 PowerShell 将字符串解析为对象时遇到问题 [英] Trouble parsing string to object with PowerShell
问题描述
我有一个包含结构化数据的字符串(见下文).我需要把这个字符串转换成一个对象,这样我就可以将它导出到 .csv(或我要求的任何其他文件).我运行了以下代码:
I have a string with structured data (see below). I need to take this string and convert it to an object, so I can export it to .csv (or whatever else is requested of me). I ran the following code:
$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 参数一起使用,但还没有实现.
This is clearly not correct. What is a better way to make this conversion? I thought about using ConvertFrom-String with the TemplateContent parameter, but haven't been able to make that work yet.
这是字符串中的前两个条目(其中包含多个用户的数据):
Here are the first two entries in the string (which contains several users worth of data):
$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
"@
谢谢.
推荐答案
如果:
- 您可以依赖从不包含
:
自身的值 - 您不介意生成的自定义对象的属性不反映输入顺序(尽管您可以通过管道传递到
Select-Object
调用枚举轻松但效率低下)属性),
- you can rely on values never containing
:
themselves - you don't mind that the properties of the resulting custom objects don't reflect the input order (though you could easily, but inefficiently, correct that with piping to a
Select-Object
call enumerating the properties explicitly),
您可以使用 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 (...)
Note: Casting to [pscustomobject]
requires PSv3+; on PSv2, use New-Object PSCustomObject -Property (...)
$string.Trim() -split '(?m)(?=^City\b)' -ne ''
将输入行分割成行块每个代表一个对象;拆分由以City
开头的行执行;-ne ''
过滤掉解析输入开头的空块.
$string.Trim() -split '(?m)(?=^City\b)' -ne ''
splits the input lines into blocks of lines each representing one object; splitting is performed by lines that start withCity
;-ne ''
filters out the empty block that results from parsing the start of the input.
.Trim()
需要忽略字符串开头的空行.
.Trim()
is needed to ignore empty lines at the start of the string.
$_ -replace ':', '=' |ConvertFrom-StringData
将每个块转换为
行,ConvertFrom-StringData
作为一个组转换为一个 [hashtable]
实例;因为哈希表本质上以没有保证的顺序枚举它们的条目,这是属性的输入顺序丢失的地方.
$_ -replace ':', '=' | ConvertFrom-StringData
converts each block into
<key>=<value>
lines that ConvertFrom-StringData
converts as a group to a [hashtable]
instance; because hash tables inherently enumerate their entries in no guaranteed order, this is where the input ordering of properties is lost.
Cast [pscustomobject]
将每个hashtable转换成自定义对象,隐式输出;输出可以通过管道传输到 Export-Csv
.
Cast [pscustomobject]
converts each hashtable to a custom object, which is implicitly output; the output can be piped to Export-Csv
.
这篇关于使用 PowerShell 将字符串解析为对象时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!