Powershell Compare-Object

I have 2 lists - List1 contains names from a query; List2 contains names from file directory. Trying to cleanup the directories that students are no longer with the college. So, I need names on List2 that are not on List1.

I’m using Compare-Object with PassThru parameter; but, I’m getting mixture of differences and some with similar names.

  1. Does the lists have to be sorted?

  2. Is there a different way to achieve that?

Thank you

Since you do not share any code and no sample data for us to recreate and understand your issue and to play around with the answers will be short:

  1. No.
  2. Probably.

What’s the issue with that?

How do I share data?
List1 is a sql-cmd query

$Inactive = Invoke-Sqlcmd -Query "select upper(substring(Firstname,1,1) + LastName) from xyz.[dbo].[Students] where active=1;`"

List2 is

$Pdir = $Dir1, $Dir2 | Get-ChildItem -Directory | ForEach-Object {$_.Name.ToUpper()} 

Edit: The PS command to compare:

$Diff = Compare-Object $Pdir $Inactive -PassThru | Sort-Object Name 
Write-Output 'Diff:' $Diff

The subdirectories are created using first letter of firstname and lastname. So, for example, Joe Smith on List1 will be JSmith, with upper, JSMITH and List2 will have JSMITH (with ToUpper)

So, a student, for example Katie Holmes, that’s no longer in the college will not be on List1 but, will be on List2 as KHOLMES.

I just want KHOLMES. Problem in this case is Compare-Object doesn’t completely filters out. It’ll filter out some of the names but, still shows active ones, in this case, JSMITH.

Edit: I apologize if I’m still missing something. Please let me know where and how I can create sample data.

Sample data … as plain text CSV for example … formatted as code!!!

Speaking of … please when you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org 1 <---- Click :point_up_2:t4: :wink:

( !! Sometimes the preformatted text button hides behind the settings gear symbol. :wink: )

You might …

You may (re-)read the help for

With the parameters -ExcludeDifferent or -IncludeEqual you can adjust what you want to see. And you can use the property SideIndicator to filter whatever you need from the output.

And BTW: PowerShell is by default case insensitive. You don’t need to make the input strings all upper or lower case.

$DirectoryList = 

$UserList =

$Result = 
    Compare-Object -ReferenceObject  $UserList -DifferenceObject $DirectoryList -IncludeEqual 


The output looks like this:

InputObject SideIndicator
----------- -------------
JSmith      ==
PMcCartney  ==
rstar       ==
kholmes     =>
JLennon     =>
GHarrison   =>

Now … if you like to filter …

$Result |
    Where-Object -Property SideIndicator -NE -Value '=='

and the output looks like this:

InputObject SideIndicator
----------- -------------
kholmes     =>
JLennon     =>
GHarrison   =>

The only thing I noticed is different is my List1 and List2 results do not have the single quotes. I know I can add the quotes to the Invoke-Sqlcmd List1.

But, how do I include the single quotes on the PS Get-ChildItem for List2?

$Pdir = $Dir1, $Dir2 | Get-ChildItem -Directory | ForEach-Object {$_.Name.ToUpper()}


The quotes indicate strings. If you have objects with properties you don’t need quotes.

$Pdir = 
    $Dir1, $Dir2 | 
        Get-ChildItem -Directory | 
            Select-Object -ExpandProperty Name

BTW: Do you notice the difference between the format of the code I posted and yours? :smirk:

Yes, I tried to change the code posts.
I think there’s something wrong with the strings that I’ll need to look into. PsPad can’t even differentiate some of the outputs from Write-Host.
Enjoy your summer, Olaf.

It looks good now. Thanks. :+1:t3:

I don’t know what that means. If you need further assistance you would need to elaborate more detailed.

BTW: Compare-Object is actually made to compare objects with properties - not strings. So you actually make your task harder than necessary when you convert powerful dot Net objects with properties to boring plain text strings. :wink:

I don’t have any experience with PsPad but the most used IDE for PowerShell code development is probably VSCode. You may give it a shot - it is free and well maintained and supported.

… whatfor do you use Write-Host? You may read the following blog post to set your expectations about Write-Host

Here is a quote from the article you linked

The advice in this post is no longer current.

I personally have no problem with using write-host… when it’s appropriate. Unless it’s a controller script, that is almost never.

Using write-host with Windows Powershell ISE to sort of view the results at each stage of the script. I’m new to PS1, is there a better way / tool to use during development?

Ok. I think I got it to where I can show the issue / results. Can’t seem to get the correct results.
If I run the following

$DirectoryList = 
'jsmith', #userlist
'PMcCartney', #userlist
'RStar', #userlist
'KNutra' #userlist

$UserList =

$Result = 
    Compare-Object -ReferenceObject  $UserList -DifferenceObject $DirectoryList #| Where-Object -Property SideIndicator -NE -Value '=='


I get the following results


InputObject SideIndicator
----------- -------------
kholmes     =>           
JLennon     =>           
Knguyen     =>           
PMcCartney  <=           
rstar       <=           
knutra      <=           

I was expecting


Is that not what Compare-Object should return?

It’s perfectly fine to use it during development. More professional would be to use Write-Debug or Write-Verbose though. With increasing exeprience you will know when it is ok to use. :wink: … don’t worry too much.

You’ve got a missing comma after the Vietnamese guy in your $DirectoryList!!! :point_up:t3: :smirk: :smirk:


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.