在c#中将psoobjects(或PS Command)转换为JSON
本文关键字:Command 转换 JSON PS 中将 psoobjects | 更新日期: 2023-09-27 18:08:36
我正在尝试创建一个web API,将PowerShell命令的输出转换为JSON。是否有一个库可以做到这一点或将PSObject转换为JSON?
PSObject属性根据生成它的命令而改变。我尝试将PSObject传递给"ConvertTo-Json",但我得到了额外的对象信息。
PowerShell命令:Get-Process | Select -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_}"
PowerShell命令给BeginInvoke.
PowerShell命令:Get-Process | Select -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>'"}}]
如果您可以使用第三方库,那么使用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;
}
}
当然,您可以为属性设置任何您喜欢的条件
对于仍然在寻找解决方案的人来说,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);
}
}
}
这对我有用。试一试。
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)
{
}
}
return null;