使用C#运行远程PowerShell代码通过序列化丢失信息?
由于各种原因,我需要使用C#代码中的远程PowerShell命令而不是使用EWS API来查询用户的邮箱自动回复配置。使用C#运行远程PowerShell代码通过序列化丢失信息?
我几乎使用this article作为模板如何做到这一点,我遇到了一个问题,我不能包裹我的头。具体来说,它看起来像是通过远程PowerShell命令的序列化/反序列化过程丢失了一些信息。所以我不能将它转换为另一种类型并将其用于C#代码中。有谁会有一个想法如何找到解决方法或避免这种情况?
向下可以看到运行PowerShell代码的代码,并返回对象并尝试使用它。问题是BaseObject
类型是PSCustomObject
,因此铸造/检查不起作用。我不知道如何访问自定义对象公开的属性。使用VS中的调试工具,我可以看到它实际上拥有所有数据。如果我直接在PowerShell中运行代码,则可以看到$configuration
的数据类型为Deserialized.Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration
。所以我猜它实际上在序列化过程中会丢失该对象的一些信息?
另一个问题我还没有检查(因为我真的想避免它)会是我运行此代码的系统没有安装Exchange程序集。这也是为什么我使用笨重的BaseObject.GetType().ToString()
方法来检查类型,因为我无法引用该类型并使用is
。但我实际上期待从PowerShell对象获得一个自给自足的数据结构。我错了,这将如何工作?
using (PowerShell PowerShellInstance = PowerShell.Create())
{
// add a script that creates a new instance of an object from the caller's namespace
PowerShellInstance.AddScript(@"
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI <URI>
Import-PSSession $session
$configuration = Get-MailboxAutoReplyConifguration -identity <E-Mail>
# Put it on the output stream
$configuration
");
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = PowerShellInstance.Invoke();
// loop through each output object item
foreach (PSObject outputItem in PSOutput)
{
if (outputItem != null)
{
if(outputItem.BaseObject.GetType().ToString() == "Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration"){
# We have a decrepancy here as the above is the Exchange API class and
# below would be the EWS API class. As they expose the same attributes I'd expect it to work.
OofSettings settings = outputItem.BaseObject as OofSettings
}
}
}
}
这正是问题:反序列化破坏了原有的PowerShell的对象生成脚本,并创建一个新的,与源对象的数据,而不是方法,据我所知(类型PSObject)。
解决方法是在PowerShell脚本中执行任务,或者直接在第一个脚本中完成任务(任何更适合您的需求)。
对于你的榜样,我的意思是这样的:
using (PowerShell PowerShellInstance = PowerShell.Create())
{
// add a script that creates a new instance of an object from the caller's namespace
PowerShellInstance.AddScript(@"
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI <URI>
Import-PSSession $session
$configuration = Get-MailboxAutoReplyConifguration -identity <E-Mail>
***INSERT HERE Powershell-Cmdlets to do the things you need***
# Put it on the output stream
$configuration
");
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = PowerShellInstance.Invoke();
// loop through each output object item
foreach (PSObject outputItem in PSOutput)
{
if (outputItem != null)
{
if(outputItem.BaseObject.GetType().ToString() == "Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration"){
# We have a decrepancy here as the above is the Exchange API class and
# below would be the EWS API class. As they expose the same attributes I'd expect it to work.
OofSettings settings = outputItem.BaseObject as OofSettings
}
}
}
}
我其实需要,因为它是一个ASP.NET MVC应用程序中的C#一部分的对象,我需要显示的信息。我的解决方案是检查类型(只使用'outputItem.ToString()',因为它具有原始类型)并使用'outputItem.Properties ['key'] .value'来访问属性。 – Seth