我正在使用带有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**/
}