MichaelGrafnetter / DSInternals

Directory Services Internals (DSInternals) PowerShell Module and Framework
https://www.dsinternals.com
MIT License
1.62k stars 250 forks source link

Modified Get-ADDBAccount to include more attributes : Object reference not set to an instance of an object. #168

Closed yghrt closed 9 months ago

yghrt commented 10 months ago

Hi, I've tried to modify the code to include more attributes when calling 'Get-ADDBAccount', so this way I don't have to use LDAP or get-aduser to get the remaining attributes for the users I can get with it, this is necessary for the whole password audit process I'm trying to set up, but at 80k+ users it takes 11-12 hours to get all the necessary/remaining attributes for every user.

I managed to set up the 'mail' and some other attributes already, and they show up fine, and I've found the corresponding column IDs for them, but it seems like I'm having problems with the 'Manager' attribute, as now I'm getting Get-ADDBAccount : Object reference not set to an instance of an object.

I am very much likely missing something, as I'm not that good with C# codes. Can you help me identify what I'm doing wrong?

I modified the code in the following way:

DSAccount.cs

       ...
        public string Manager
        {
            get;
            private set;
        }

       ...

        protected void LoadAccountInfo(DirectoryObject dsObject, string netBIOSDomainName)
        {
        ...
            dsObject.ReadAttribute(CommonDirectoryAttributes.Manager, out string Manager);
            this.Manager = Manager;
        ...

CommonDirectoryAttributes.cs:

        ...
        public const string Manager = "manager";
        public const int ManagerId = 1376266;
        ....

BasicSchemaFactory.cs:

...
(ISchemaAttribute)new BasicSchemaAttribute(CommonDirectoryAttributes.ManagerId, CommonDirectoryAttributes.Manager, AttributeSyntax.UnicodeString),
...

Here's the stacktrace:

   at Microsoft.Database.Isam.ColumnAccessor.get_Item(Columnid columnid)
   at DSInternals.DataStore.CursorExtensions.RetrieveColumnAsString(Cursor cursor, Columnid columnId) in D:\Projects\DSinternals\Src\DSInte
rnals.DataStore\Extensions\CursorExtensions.cs:line 44
   at DSInternals.DataStore.DatastoreObject.ReadAttribute(String name, String& value) in D:\Projects\DSinternals\Src\DSInternals.DataStore\
DatastoreObject.cs:line 144
   at DSInternals.Common.Data.DSAccount.LoadAccountInfo(DirectoryObject dsObject, String netBIOSDomainName)
   at DSInternals.Common.Data.DSAccount..ctor(DirectoryObject dsObject, String netBIOSDomainName, DirectorySecretDecryptor pek)
   at DSInternals.DataStore.DirectoryAgent.<GetAccounts>d__9.MoveNext() in D:\Projects\DSinternals\Src\DSInternals.DataStore\DirectoryAgent
.cs:line 75
   at DSInternals.PowerShell.Commands.GetADDBAccountCommand.ReturnAllAccounts(Byte[] bootKey)
   at System.Management.Automation.CommandProcessor.ProcessRecord()

############# Update while writing this, I've also tried the following, but same error message different stack trace

DSAccount.cs

       ...
        public DistinguishedName Manager
        {
            get;
            private set;
        }

       ...

        protected void LoadAccountInfo(DirectoryObject dsObject, string netBIOSDomainName)
        {
        ...
            dsObject.ReadAttribute(CommonDirectoryAttributes.Manager, out DistinguishedName Manager);
            this.Manager = Manager;
        ...

BasicSchemaFactory.cs:

...
(ISchemaAttribute)new BasicSchemaAttribute(CommonDirectoryAttributes.ManagerId, CommonDirectoryAttributes.Manager, AttributeSyntax.DN),
...
   at Microsoft.Database.Isam.ColumnAccessor.get_Item(Columnid columnid)
   at DSInternals.DataStore.CursorExtensions.RetrieveColumnAsInt(Cursor cursor, Columnid columnId) in D:\Projects\DSinternals\Src\DSInterna
ls.DataStore\Extensions\CursorExtensions.cs:line 125
   at DSInternals.DataStore.DatastoreObject.ReadAttribute(String name, DistinguishedName& value) in D:\Projects\DSinternals\Src\DSInternals
.DataStore\DatastoreObject.cs:line 184
   at DSInternals.Common.Data.DSAccount.LoadAccountInfo(DirectoryObject dsObject, String netBIOSDomainName)
   at DSInternals.Common.Data.DSAccount..ctor(DirectoryObject dsObject, String netBIOSDomainName, DirectorySecretDecryptor pek)
   at DSInternals.DataStore.DirectoryAgent.<GetAccounts>d__9.MoveNext() in D:\Projects\DSinternals\Src\DSInternals.DataStore\DirectoryAgent
.cs:line 75
   at DSInternals.PowerShell.Commands.GetADDBAccountCommand.ReturnAllAccounts(Byte[] bootKey)
   at System.Management.Automation.CommandProcessor.ProcessRecord()
MichaelGrafnetter commented 10 months ago

Hi @yghrt , the Manager attribute is a linked value, so the LinkResolver class must be used to get its value, similarly to the way how NGC and DPAPI keys are handled.

yghrt commented 9 months ago

Thank you very much for this informatiom, however since I'm not that profound or good in C# coding, I could not make it work yet, but I will close this issue now as this will be a long ongoing project for me.