Click here to Skip to main content
15,888,521 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have been really stuck on the trying to figure out what dereferencing is for the past week.

I have a method that calls a powershell command as below
C#
private Collection<PSObject> fillADUsers()
{
    AdUsers = new Collection<PSObject>();
    AdUsers = PSCommandToRun("Get-ADUser -filter * -properties LastLogon, whenCreated, Enabled, LockedOut");

    return AdUsers;
}

I then have another method which extracts the properties from AdUsers and adds it to a listview which works perfectly on the first run.

I then have a button to disable a user which then reruns the fillADUsers method again but it gives me a null reference exception.

I posted this question on stackoverflow and got pointed to the below question

https://stackoverflow.com/questions/75802744/null-reference-exception-on-second-run-with-c-sharp[^]

In the comments to my question I was told that it is because of dereferencing which has totally gone over my head. I have read the above link numerous times but still don't understand why I would get a null reference exception on the second run.

Can any one explain dereferencing to a thicko like me?

What I have tried:

I have read the link on stack overflow many times.
Searched on google about dereferencing.

I have also changed my code a little by creating a seperate method to fill a collection as in the method above rather than use the PSCommandToRun method directly in a foreach statement.
Posted
Updated 6-Apr-23 4:14am
v2
Comments
Richard Deeming 28-Mar-23 5:18am    
There's nothing obvious in that code which would cause a NullReferenceException.

The comments on your SO question are simply telling you that you are trying to access a property or call a method on a null reference. If you debug your code, Visual Studio (2017 or later) should tell you which object was null:
Debugging System.NullReferenceException[^]
Ga22at 28-Mar-23 5:36am    
Hi Richard,

This is my issue, I don`t understand why if I am creating a new collection each time I call this method that it is not pulling in the same information. I have added this code to another form with 2 listboxes and two buttons and run the code and it pulls in the same information in both listboxes. When I debug in visual studio i get the null reference error on the below line

if (item.Properties["LastLogon"].Value != null)

I also cannot see the LastLogon properties in the view when i look at the results view (which i think is why i am getting the problem).
Richard MacCutchan 28-Mar-23 5:39am    
If you wish to reply to a comment then please use the Reply button above the message. But your guess is correct. If the entry does not have a LastLogon property then your reference item.Properties["LastLogon"] will be null and hence cause the error.
Richard MacCutchan 28-Mar-23 5:36am    
Where is the code for the PSCommandToRun method? It may be that it does not find any users and so returns null in the AdUsers variable. That would cause NullReferenceException when you try to use it. As Richard Deeming suggests above, you need to use the debugger to confirm exactlr where the error occurs.
Ga22at 28-Mar-23 5:54am    
Hi Richard,

the PSCommandToRun code is below

private Collection<psobject> PSCommandToRun(string CmdToRun)
{
//results = new Collection<psobject>();

PowerShell ps = PowerShell.Create();
string script = CmdToRun;
ps.AddScript(script);
Collection<psobject> results = ps.Invoke<psobject>();

return results;
}

I have confirmed that i am getting the data i need by using another tab form with two buttons and two listboxes and running the code multiple times.

OK, Its even more stranger now, I have just run the code and then run it a second time with a breakpoint on the return AdUsers line and couldn't notice any differences, so let the code run and it ran fine, so it seems to be a timing issue, any ideas????

OK, look at the code:
C#
AdUsers = new Collection<PSObject>();
Creates a new Collection, and assigns it to an external variable - either class level public/private/... or static
C#
AdUsers = PSCommandToRun("Get-ADUser -filter * -properties LastLogon, whenCreated, Enabled, LockedOut");
Discards the newly created collection and overwrites the variable with the return value.

So the null that is causing the problem is returned by the PSCommandToRun method, and nothing to do with dereferencing (which doesn't change variables at all!).

So start by looking at the PSCommandToRun method - use the debugger to look at exactly what it is trying to return, and why. That should give you clues - but you might also want to think "why am I returning the value of what is effectively a global variable anyway?"
 
Share this answer
 
Comments
Ga22at 28-Mar-23 11:46am    
Hi OriginalGriff,

I have changed the code slightly as below

private Collection<psobject> PSCommandToRun(string CmdToRun)
{
PowerShell ps = PowerShell.Create();
string script = CmdToRun;
ps.AddScript(script);
Collection<psobject> results = ps.Invoke<psobject>();

return results;
}

private void GetADUserList()
{

Collection<psobject> AdUsers = PSCommandToRun("Get-ADUser -filter * -properties LastLogon, whenCreated, Enabled, LockedOut");


foreach (PSObject item in AdUsers)
{
Code to fill Listview
}

I have to move the data from the results collection into another collection (AdUsers) as the PSCommandToRun method is used elsewhere in the ForEach Loop to get other information.

When I add a watch to the results collection and view the properties I see the LastLogon property has either a zero or a larger number for the date (got bored after object 54 out of the full 100 so didnt check all objects).

If I step through the code slow enough (very tedious) it works fine and fills the listview correctly, but if I go through the code too quickly then the error I get and have verified by looking at the watch view is the LastLogon property is missing from the object.

If I run the code normally, this error is on about the 2nd-5th object but if i step through the code it happens on about the 30th-50th object depending on how fast i step through.
To help with the debugging, I think that you require strict exceptions. You can turn this on in Visual Studio by going to the main Menubar and selecting:
Debug > Windows > Exception Settings

then tick the option:
Common Language Runtime Exceptions

This will force the debugger to break on all exceptions. Now run the code in debug mode.

I suspect the issue is with one of these lines:
C#
ps.AddScript(script);
Collection<psobject> results = ps.Invoke<psobject>();
 
Share this answer
 
Comments
Ga22at 28-Mar-23 11:56am    
Hi Greame,

Did as you suggested and got all sorts of socket errors and other errors which happen before it gets to any of my code (as far as I can tell) I am looking into them but didn't get an error on the line you expected (which I was hoping for).

See the comment to OriginalGriff for what I have done recently regarding the results Collection.
I have finally figured out what the issue was with help from the below

`https://stackoverflow.com/questions/34875985/powershell-invoke-method-neither-throwing-exception-nor-returning-result`

Using a runspace to run the method is what fixed it (see below)

        private Collection<PSObject> PSCommandToRun(string CmdToRun)
        {
            using (PowerShellProcessInstance pspi = new PowerShellProcessInstance())
            {
                string psfn = pspi.Process.StartInfo.FileName;
                psfn = psfn.ToLowerInvariant().Replace("\\syswow64\\", "\\sysnative\\");
                pspi.Process.StartInfo.FileName = psfn;
                using (Runspace r = RunspaceFactory.CreateOutOfProcessRunspace(null, pspi))
                {
                    r.Open();
                    using (PowerShell ps = PowerShell.Create())
                    {
                        ps.Runspace = r;
                        ps.AddScript(CmdToRun);
                        Collection<PSObject> results = ps.Invoke();

                        return results;
                    }
                }
            }
        }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900