Powershell命令 - 让 ConvertTo-Json 具有以下限制 1)它将Enum值作为整数而不是文本返回 2)它不以可读格式返回日期
对于第1点,请参见下面的Status and VerificationMethod Properties
PS C:\Windows\system32> Get-Msoldomain | ConvertTo-Json
{
"ExtensionData": {
},
"Authentication": 0,
"Capabilities": 5,
"IsDefault": true,
"IsInitial": true,
"Name": "myemail.onmicrosoft.com",
"RootDomain": null,
"Status": 1,
"VerificationMethod": 1
}
为了解决这个问题,我改变了我的命令,如下所示
PS C:\Windows\system32> Get-Msoldomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json
{
"ExtensionData": "System.Runtime.Serialization.ExtensionDataObject",
"Authentication": "Managed",
"Capabilities": "Email, OfficeCommunicationsOnline",
"IsDefault": "True",
"IsInitial": "True",
"Name": "curtisjmspartnerhotmail.onmicrosoft.com",
"RootDomain": "",
"Status": "Verified",
"VerificationMethod": "DnsRecord"
}
现在您看到,返回的枚举的文本值高于(Status和VerificationMethod)而不是整数值。
但是,这种方法有一些限制:
1)ConvertTo-Csv不保留数组或复杂对象,和 将它们作为类名输出(观察ExtensionData属性 在两个输出中)。在第二个输出中,我们倾向于丢失数据, 并获取className System.Runtime.Serialization.ExtensionDataObject 作为字符串
2)ConvertTo-Csv和ConvertFrom-Csv都不是脚本级别 命令行,但它们是命令级的命令行开关,这意味着 我们不能在脚本的末尾使用它们,但它们必须是 与我上面所做的各个命令一起使用。鉴于, ConvertTo-Json不需要在commmandLevel中应用,只是 为脚本输出应用一次。
我的问题是:
1)我如何仍然使用convertTo-Json,以便我的所有枚举属性都返回其文本而不是整数,并且复杂对象或数组也不会丢失?在我使用的方法中,复杂的对象迷失了
2)此外,它应该是通用的,以便它可以应用于脚本的末尾,而不是在命令级别
答案 0 :(得分:2)
ConvertTo-Json
和ConvertTo-Csv
都是在某种文本表示中序列化对象的形式,并且在不同的用例中都很有用。
ConvertTo-Csv
可能最适合用于表格(如电子表格)中表达的二维数据。因此,尝试将“复杂”对象(即具有包含其他结构化数据的属性的对象)转换为简单表格是很尴尬的。在这种情况下,PowerShell将此类数据表示为数据类型的全名。
ConvertTo-Json
能够序列化更复杂的对象,因为格式允许嵌套的数组/数据结构,例如,示例中的 ExtensionData 属性。请注意,您可能需要使用-Depth
参数来确保正确序列化深层嵌套数据。
所以问题实际上归结为ConvertTo-Json
cmdlet序列化枚举的方式,可以通过以下方式演示:
[PS]> (Get-Date).DayOfWeek
Tuesday
[PS]> (Get-Date).DayOfWeek.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True DayOfWeek System.Enum
[PS]> Get-Date | Select DayOfWeek | ConvertTo-Json
{
"DayOfWeek": 2
}
因此,在转换为JSON之前,您需要确保 DayOfWeek 属性(在此示例中)或状态和 VerificationMethod 属性(来自你的例子)首先转换为它们的字符串等价物。
您可以使用带有Select-Object
的表达式来执行此操作,以便在数据传递到管道时进行转换。请注意,您执行需要包含所有要包含在最终JSON中的属性:
[PS]> Get-Date |
Select DateTime,@{Label="DayOfWeek";Expression={$_.DayOfWeek.ToString()}} |
ConvertTo-Json
{
"DateTime": "13 June 2017 10:33:51",
"DayOfWeek": "Tuesday"
}
所以在你的情况下,你需要这样的东西:
[PS]> Get-Msoldomain |
Select-Object ExtensionData,IsDefault,IsInitial,Name,RootDomain `
,{Label="Authentication";Expression={$_.Authentication.ToString()}} `
,{Label="Capabilities";Expression={$_.Capabilities.ToString()}} `
,{Label="Status";Expression={$_.Status.ToString()}} `
,{Label="VerificationMethod";Expression={$_.VerificationMethod.ToString()}} |
ConvertTo-Json
答案 1 :(得分:2)
@puneet,在您对我的其他答案发表评论之后,以下是一个示例,说明如何基于现有对象构建新对象,并将枚举类型转换为字符串。< / p>
我们的想法是创建一个新的“空”对象,然后循环遍历原始对象的所有属性并将它们添加到新对象中,但如果任何原始属性是Enums,那么这些属性将转换为字符串。
$data = [PSCustomObject]@{}
(Get-Date).PSObject.Properties | Select Name,Value | Foreach-Object {
if($_.Value.GetType().BaseType.FullName -eq "System.Enum"){
$data | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value.ToString()
}
else {
$data | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value
}
}
$data | ConvertTo-Json
您可能希望对自己的应用程序稍微有点精确,但希望它背后的想法很清楚。绝对检查JSON输出中是否正确处理了所有属性。
答案 2 :(得分:0)
在将psObject转换为json时保留枚举,数组和日期,可以使用newtonsoft。这里使用Nerdy Mishka powershell模块https://github.com/chavers/powershell-newtonsoft进行示例。
$obj = New-Object pscustomobject -Property @{Enum = (Get-DAte).DayOfWeek; int = 2; string = "du text"; array = @("un", "deux", "trois"); obj= @{enum = (Get-DAte).DayOfWeek; int = 2; string = "du text"; array = @("un", "deux", "trois")}}
Import-Module Fmg-PrettyJson
$settings = Get-NewtonsoftJsonSettings
$enumconv = "Newtonsoft.Json.Converters.StringEnumConverter"
$e = New-Object $enumconv
$settings.Converters.Add($e)
Set-NewtonsoftJsonSettings $settings
$obj | ConvertTo-NewtonsoftJson
返回:
{
"array": [
"un",
"deux",
"trois"
],
"enum": "Thursday",
"int": 2,
"obj": {
"enum": "Thursday",
"array": [
"un",
"deux",
"trois"
],
"int": 2,
"string": "du text"
},
"string": "du text"
}