C# 在.NET返回null的情况下使用powershell

C# 在.NET返回null的情况下使用powershell,c#,powershell,active-directory,C#,Powershell,Active Directory,我正在使用.NET和powershell,试图检索特定AD对象的Get Acl命令的结果。不幸的是,当我从C代码运行代码时,得到的结果是0。另外,throwiferor也没有抛出任何错误 Command test01 = new Command("import-module"); test01.Parameters.Add("name", "activedirectory"); session.Commands.AddCommand(test01); Command test0 = new C

我正在使用.NET和powershell,试图检索特定AD对象的
Get Acl
命令的结果。不幸的是,当我从C代码运行代码时,得到的结果是0。另外,
throwiferor
也没有抛出任何错误

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脚本,而不是多个命令来获取所需的值。您的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*/

        }
    }
}
末端的循环现在看起来是这样的:

foreach (PSObject o in PSIResults)
            {
                ActiveDirectoryAccessRule AccessRule = (ActiveDirectoryAccessRule)o.BaseObject;

                /**do something with the AccessRule here**/
            }

更好的方法是定义一个powershell脚本,而不是多个命令来获取所需的值。您的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*/

        }
    }
}
末端的循环现在看起来是这样的:

foreach (PSObject o in PSIResults)
            {
                ActiveDirectoryAccessRule AccessRule = (ActiveDirectoryAccessRule)o.BaseObject;

                /**do something with the AccessRule here**/
            }

为什么不直接使用Directory.GetAccessControl?为什么不直接使用Directory.GetAccessControl?我使用您的解决方案得到了一个结果,但我不熟悉使用管道的
Select Object
Where Object
。由于它是一个脚本,所以我修改了您的代码如下:
string Content=“param($object);导入模块ActiveDirectory;设置位置AD:;获取ACL-Path$object |选择访问|?{($.ActiveDirectoryRights-eq'ExtendedRight')-和($.objectType-eq'ab721a54-1e2f-11d0-9819-00aa0040529b')//添加纸条
,但这不起作用。测试对象被授予了“发送为”权限,因此我应该至少获得一个结果。将此作为脚本使用:“param($object);导入模块ActiveDirectory;设置位置AD:;(get ACL-Path$object)。访问|其中对象{($\ ActiveDirectoryRights-eq'ExtendedRight')-和($\ objectType-eq'ab721a54-1e2f-11d0-9819-00aa0040529b')”但是要注意:结果现在可以是一组accessrules(如果有多个对象对被质疑的对象具有发送权限),则必须在循环中设置结果:foreach(PSIResults中的PSObject o){ActiveDirectoryAccessRule AccessRule=(ActiveDirectoryAccessRule)o.BaseObject;/**在这里做点什么**/}哦,不可读,给我一点时间,我将更改放在我的answerSelect对象中,该对象可以在此处使用,但更容易将Access集合传递到Where Object Cmdlet(?只是一个别名,我不喜欢别名;))你应该获得奖牌!当你带着你的附加评论来的时候,我正在努力获取一个用户名!为我节省了大量时间:)我使用您的解决方案得到了一个结果,但我不熟悉使用管道的
选择对象
Where Object
。由于它是一个脚本,所以我修改了您的代码如下:
string Content=“param($object);导入模块ActiveDirectory;设置位置AD:;获取ACL-Path$object |选择访问|?{($.ActiveDirectoryRights-eq'ExtendedRight')-和($.objectType-eq'ab721a54-1e2f-11d0-9819-00aa0040529b')//添加纸条
,但这不起作用。测试对象被授予了“发送为”权限,因此我应该至少获得一个结果。将此作为脚本使用:“param($object);导入模块ActiveDirectory;设置位置AD:;(get ACL-Path$object)。访问|其中对象{($\ ActiveDirectoryRights-eq'ExtendedRight')-和($\ objectType-eq'ab721a54-1e2f-11d0-9819-00aa0040529b')”但是要注意:结果现在可以是一组accessrules(如果有多个对象对被质疑的对象具有发送权限),则必须在循环中设置结果:foreach(PSIResults中的PSObject o){ActiveDirectoryAccessRule AccessRule=(ActiveDirectoryAccessRule)o.BaseObject;/**在这里做点什么**/}哦,不可读,给我一点时间,我将更改放在我的answerSelect对象中,该对象可以在此处使用,但更容易将Access集合传递到Where Object Cmdlet(?只是一个别名,我不喜欢别名;))你应该获得奖牌!当你带着你的附加评论来的时候,我正在努力获取一个用户名!节省了我很多时间:)