在C#中将PSObjects(或PS命令)转换为JSON

时间:2015-08-17 22:20:00

标签: c# json powershell

我正在尝试创建一个web api,它将powershell命令的输出转换为JSON。 有谁知道可以执行此操作的库或将PSObject转换为JSON? PSObject属性会根据生成它的命令而更改。 我尝试将PSObject传递给" ConvertTo-Json"但是我得到了额外的对象信息。

PS命令​​:Get-Process |选择-Property Handles,ProcessName |的ConvertTo JSON的

JsonConvert.SerializeObject()之后的输出:

"{\"CliXml\":\"<Objs Version=\\\"1.1.0.1\\\" xmlns=\\\"http://schemas.microsoft.com/powershell/2004/04\\\">\\r\\n  <Obj RefId=\\\"0\\\">\\r\\n<TN RefId=\\\"0\\\">\\r\\n <T>System.String</T>\\r\\n      <T>System.Object</T>\\r\\n    </TN>\\r\\n    <ToString>[_x000D__x000A_    {_x000D__x000A_\\\"Handles\\\":163,_x000D__x000A_\\\"ProcessName\\\":\\\"AppleMobileDeviceService\\\"_x000D__x000A_},_x000D__x000A_    {_x000D__x000A_\\\"Handles\\\":  972,_x000D__x000A_\\\"ProcessName\\\":\\\"CcmExec\\\"_x000D__x000A_},_x000D__x000A_{_x000D__x000A_\\\"Handles\\\":  1838,_x000D__x000A_\\\"ProcessName\\\":\\\"ccSvcHst\\\"_x000D__x000A_}"

对BeginInvoke的PS命令。 PS命令:Get-Process |选择-Property Handles,ProcessName JsonConvert.SerializeObject(PSObj)之后的输出:

"[{\"CliXml\":\"<Objs Version=\\\"1.1.0.1\\\" xmlns=\\\"http://schemas.microsoft.com/powershell/2004/04\\\">\\r\\n  <Obj RefId=\\\"0\\\">\\r\\n    <TN RefId=\\\"0\\\">\\r\\n      <T>Selected.System.Diagnostics.Process</T>\\r\\n      <T>System.Management.Automation.PSCustomObject</T>\\r\\n      <T>System.Object</T>\\r\\n    </TN>\\r\\n    <ToString>@{Handles=163; ProcessName=AppleMobileDeviceService}</ToString>\\r\\n    <Obj RefId=\\\"1\\\">\\r\\n      <TNRef RefId=\\\"0\\\" />\\r\\n      <MS>\\r\\n        <I32 N=\\\"Handles\\\">163</I32>\\r\\n        <S N=\\\"ProcessName\\\">AppleMobileDeviceService</S></Objs>\"}}]

3 个答案:

答案 0 :(得分:1)

如果您可以使用第三方库,则JSON.NET具有JsonConvert类。它使用相当简单:JsonConvert.SerializeObject(myObj)将返回包含JSON的字符串。

我发现这比尝试以编程方式从C#代码调用Powershell要容易一些。

如果您想省略额外的属性,那么JsonConvert允许您实现IContractResolver来指定您想要的属性。

最终看起来像这样:

JsonConvert.SerializeObject(myObj, new JsonSerializerSettings { ContractResolver = new MyContractResolver() });

ContractResolver看起来像这样:

public class MyContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        properties = properties.Where(p => p.PropertyName != "OmittedProperty").ToList();
        return properties;
    }
}

当然,您可以根据自己的喜好制作属性条件。

答案 1 :(得分:0)

这对我有用。试试吧。

                    if (item.TypeNames.FirstOrDefault() == "System.String")
                    {
                        return item.BaseObject.ToString();
                    }
                    else
                    {
                        var settings = new Newtonsoft.Json.JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };

                        var dict = new Dictionary<string, object>();
                        var objMembers = typeof(object).GetMembers();
                        var ignoreMembers = new List<string>();

                        ignoreMembers.AddRange(item.Members.Where(i => i.TypeNameOfValue.StartsWith("Deserialized.")).Select(i => i.Name).ToList());
                        ignoreMembers.AddRange(objMembers.Select(i => i.Name));


                        var filteredMembers = item.Members.Where(i => ignoreMembers.All(ig => ig.ToLower() != i.Name.ToLower())).ToList();
                        foreach (var mem in filteredMembers)
                        {
                            if (!dict.ContainsKey(mem.Name))
                            {
                                dict.Add(mem.Name, "");
                            }
                            dict[mem.Name] = mem.Value;
                        }

                        try
                        {
                            return Newtonsoft.Json.JsonConvert.SerializeObject(dict, settings);
                        }
                        catch (Exception e)
                        {
                        }
                    }

返回null;

答案 2 :(得分:0)

对于仍在寻找解决方案的任何人,可以利用Powershell的内置JSON转换器(ConvertTo-Json):

using System;
using System.Management.Automation;
using Microsoft.PowerShell.Commands;
using System.Collections.ObjectModel;

namespace PowerJson
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create the Powershell instance, and adds command to be executed
            PowerShell ps = PowerShell.Create();
            ps.AddCommand("Get-Process");
            Collection<PSObject> _ps_results = ps.Invoke();

            // Create a JSON Context Object
            JsonObject.ConvertToJsonContext _json_context = new JsonObject.ConvertToJsonContext(maxDepth: 12, enumsAsStrings: false, compressOutput: false);

            // Converts the PSObject into JSON
            string json_result = JsonObject.ConvertToJson(_ps_results, _json_context);

            // Outputs the result to console
            Console.WriteLine(json_result);
        }
    }
}