将 powershell 与 .NET 一起返回 null



我正在使用带有Powershell的.NET试图检索特定AD对象的Get-Acl命令的结果。不幸的是,当我从 C# 代码运行代码时,我得到的结果为 0。此外,ThrowIfError不会引发任何错误。

Command test01 = new Command("import-module");
test01.Parameters.Add("name", "activedirectory");
session.Commands.AddCommand(test01);
Command test0 = new Command("Set-Location");
test0.Parameters.Add("Path", "AD:");
session.Commands.AddCommand(test0);
Command test1 = new Command("Get-Acl");
test1.Parameters.Add("Path", identity);
session.Commands.AddCommand(test1);
session.AddCommand("select-object");
session.AddParameter("Property", "Access");
var tempResults1 = session.Invoke();
ThrowIfError();
private void ThrowIfError()
{
var errors = session.Streams.Error;
if (errors.Count > 0)
{
var ex = errors[0].Exception;
session.Streams.ClearStreams();
// Never close session to dispose already running scripts.
throw ex;
}
}

在 powershell 中的服务器上运行的此代码工作正常:

PS AD:> Import-Module -Name activedirectory
PS AD:> set-location ad:
PS AD:> get-acl -path <distinguishedNameOfADObject>

问题

如何获得与Powershell相同的结果?我应该至少得到一些不是零结果的东西。

小背景:

我正在尝试在不使用 cmdlet 的情况下获取Send-As权限Get-ADPermission因为当我需要在数千个邮箱中搜索权限时,它花费的时间太长。使用此文章链接,我正在尝试另一种方法来获得权利。我已经有使用 C# 代码工作的较慢版本:

Command command = new Command("Get-ADPermission");
command.Parameters.Add("Identity", identity);
session.Commands.AddCommand(command);
session.AddCommand("where-object");
ScriptBlock filter = ScriptBlock.Create("$_.ExtendedRights -eq 'send-as'");
session.AddParameter("FilterScript", filter);
session.AddCommand("select-object");
session.AddParameter("Property", "User");
tempResults = session.Invoke();

更好的方法是定义一个 powershell 脚本而不是多个命令来获取所需的值。使用您的电源外壳代码的示例:

using System.Collections.ObjectModel;
using System.DirectoryServices;
using System.Management.Automation;
namespace GetAclPowershellTest
{
class Program
{
static void Main(string[] args)
{
/****Create Powershell-Environment****/
PowerShell PSI = PowerShell.Create(); 
/****Insert PowershellScript****/
string Content = "param($object); Import-Module ActiveDirectory; Set-Location AD:; Get-ACL -Path $object"; //Add Scrip
PSI.AddScript(Content);
PSI.AddParameter("object", "<distinguishedNameOfADObject>");
/****Run your Script with PSI.Invoke()***/
Collection<PSObject> PSIResults = PSI.Invoke();
/****All Errors****/
Collection<ErrorRecord> Errors = PSI.Streams.Error.ReadAll();
/****needed, because garbagecollector ignores PSI otherwise****/
PSI.Dispose(); 
/**** Your ACL-Object ****/
ActiveDirectorySecurity MyACL = (ActiveDirectorySecurity)PSIResults[0].BaseObject;
/*insert your code here*/
}
}
}

这个例子对我有用。

您必须设置对Powershell程序集的引用(通常您可以在"C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll"中找到它")

此解决方案的好处是,您可以读取从某人那里获得的 .ps1 文件,用您拥有的对象填充参数,脚本像在标准 powershell 会话中一样运行。设置参数的唯一要求是脚本中的参数部分。

有关参数的更多信息: https://technet.microsoft.com/en-us/library/jj554301.aspx

希望,这有帮助...

问候,罗尼

更新:

string Content = "param($object); Import-Module ActiveDirectory; Set-Location AD:; (Get-ACL -Path $object).Access | Where-Object{($_.ActiveDirectoryRights -eq 'ExtendedRight') -and ($_.objectType -eq 'ab721a54-1e2f-11d0-9819-00aa0040529b')}";

最后的循环现在看起来像这样:

foreach (PSObject o in PSIResults)
{
ActiveDirectoryAccessRule AccessRule = (ActiveDirectoryAccessRule)o.BaseObject;
/**do something with the AccessRule here**/
}

最新更新