0

I am using .NET with powershell trying to retrieve result of Get-Acl command of specific AD object. Unfortunately when I run the code from C# code I get 0 result. Also the ThrowIfError is not throwing any error.

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;
    }
}

This code running on server in powershell is working correctly:

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

Question

How to get the same result like I get from Powershell? I should get atleast something not a zero result.

Little background:

I am trying to get Send-As rights not using Get-ADPermission cmdlet because its taking too long time when I need to search for rights within thousands of mailboxes. Using this article link I am trying another approach to get the rights. I have already the slower version working using C# code:

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();
1

1 Answer 1

2

The better way is to define a powershell-script instead of multiple commands to get the values you need. Example with your powershell-code:

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*/

        }
    }
}

This example works for me.

You have to set a reference to the Powershell-Assembly (Usually you can find it at "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll")

Benefit of this solution is, you could read a .ps1-File you got from someone, fill the parameters with the objects you have and the script runs like in a standard powershell-session. The only requirement to set parameters is the param-part in the Script.

More Infos about param: https://technet.microsoft.com/en-us/library/jj554301.aspx

Hope, this helps...

Greetings, Ronny

Update:

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')}";

And the loop at the end looks like this now:

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

                /**do something with the AccessRule here**/
            }
Sign up to request clarification or add additional context in comments.

5 Comments

I got a result using your solution but I am not familiar with Select-Object and Where-Object using pipelines. Since its a script I have modified your code like this: string Content = "param($object); Import-Module ActiveDirectory; Set-Location AD:; Get-ACL -Path $object | select access | ?{($_.ActiveDirectoryRights -eq 'ExtendedRight') -and ($_.objectType -eq 'ab721a54-1e2f-11d0-9819-00aa0040529b')}"; //Add Scrip but this is not working. The test object was given a send-as rights so I should get atleast one result.
Use this as Script: "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')}" But beware: The result can now be a set of accessrules (If more than one has a send-as-right for the questioned object), you have to set the results in a loop: foreach (PSObject o in PSIResults) { ActiveDirectoryAccessRule AccessRule = (ActiveDirectoryAccessRule)o.BaseObject; /**do something here**/}
uh oh, unreadable, give me a moment, i put the changes in my answer
Select-Object can be used here, but is easier to pipe the Access-Collection to the Where-Object-Cmdlet (? is just an alias, i don't like aliases ;))
you deserve a medal! I was struggling with getting a name of user when you came with your additional comment! saved me a tons of time :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.