Compare-Object directory path

This topic contains 7 replies, has 5 voices, and was last updated by  Flynn Bundy 2 years, 1 month ago.

  • Author
    Posts
  • #27175

    Matt Saunders
    Participant

    Hey guys

    I am trying to compare two folders which is working and I can see the differences between them but I would like to get the directory path included in the output

    I have created two variables and then I used compare-object

    `$Folder1 = Get-ChildItem -Recurse "C:\users\Localadmin\Desktop\Folder1" | ft Name, Directory`

    `$Folder2 = Get-ChildItem -Recurse "C:\users\Localadmin\Desktop\Folder2";

    `

    InputObject SideIndicator
    ———– ————-
    New Contacts DB.accdb =>
    Passwords List.xlsx =>
    Report.docx =>
    Stats.xlsx =>
    Users.docx =>
    Microsoft.PowerShell.Commands.Internal.Format.FormatStartData <= Microsoft.PowerShell.Commands.Internal.Format.GroupStartData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData <= Microsoft.PowerShell.Commands.Internal.Format.GroupEndData <= Microsoft.PowerShell.Commands.Internal.Format.FormatEndData <= Any help would be great `

  • #27177

    Flynn Bundy
    Participant

    Hey mate,

    In this case we could use something like this:

     $Folder1 = Get-ChildItem -Recurse "C:\users\localadmins\Desktop\*" | select -ExpandProperty Fullname 
    
    $Folder2 = Get-ChildItem -Recurse "C:\users\userFred\Desktop\*" | select -ExpandProperty Fullname 

    If we just used Select and picked out the Fullname property this would give us back a hashtable which wouldn't format as nicely as we would want. So we use -Expandproperty to turn it into a string so its easy to view.

    Take a look at the properties available to your in the cmdlet for Compare-Object. You will see what you can play with. Even something like the SideIndicator property can be added to something like a Where-Object. like:

    Compare-Object $Folder1 -DifferenceObject $Folder2 | ? {$_.Sideindicator -eq '=>'} 

    Let me know if you still have any issues.

  • #27211

    Nathan Hartley
    Participant

    If you are just trying to compare folders and files, you might find a tool like WinMerge to give a better experience.

  • #27214

    Tim Curwick
    Participant

    Matt,

    Each of the results of a Compare-Object has a property name InputObject, which contains all of the original properties for the item.

    Try something like this:

    $Folder1 = Get-ChildItem C:\Folder1
    $Folder2 = Get-ChildItem C:\Folder2
    $Compare = Compare-Object $Folder1 $Folder2
    $Compare.InputObject.FullName
    

    or in PowerShell 2.0

    $Folder1 = Get-ChildItem C:\Folder1
    $Folder2 = Get-ChildItem C:\Folder2
    $Compare = Compare-Object $Folder1 $Folder2
    $Compare | ForEach { $_.InputObject.FullName }
    
  • #27215

    Rob Simmers
    Participant

    Compare-Object has a -Property attribute that can be used to specify which value you want to compare, which I would typically use Name. Then you can use the -PassThru switch to pass the object to the pipeline and get the remaining properties from the files:

    $sourceFiles = Get-ChildItem C:\Temp\* -Include *.ini
    $destFiles = Get-ChildItem C:\Windows\* -Include *.ini
    
    Compare-Object -ReferenceObject $sourceFiles -DifferenceObject $destFiles -Property Name -PassThru |
    Where {$_.SideIndicator -eq "=>"} |
    foreach{
        "File {0} is in directory {1} and has a size of {2} bytes" -f $_.Name, $_.Directory, $_.Length
    }
    

    Output:

    File HPMProp.INI is in directory C:\Windows and has a size of 0 bytes
    File system.ini is in directory C:\Windows and has a size of 219 bytes
    File win.ini is in directory C:\Windows and has a size of 167 bytes
    

    Notice how we can reference the properties of the file. In this example you are passing all of the default properties of the files over the pipeline, so if you know you are only going to use Name, Directory and Length, then you would do that after your Get-ChildItem, like so:

    $sourceFiles = Get-ChildItem C:\Temp\* -Include *.ini | Select Name, Directory, Length
    

    Note that Name is what we are using for comparison in the Compare-Object, so if we don't Select it, it would be null and comparison would fail.

  • #27216

    Tim Curwick
    Participant

    Flynn and Rob,

    If you "compare" full names, you do not get comparison. You get a full listing of the contents of each folder, because none of them will ever match between the two sources.

  • #27217

    Rob Simmers
    Participant

    @Tim,

    Thanks, updated my post. It's been a long day and meetings only allowed one cup of coffee, so I'm firing on 2 cylinders (out of 2 and 1/4). 🙂

  • #27219

    Flynn Bundy
    Participant

    @Tim you're exactly right! I think I interpreted the question a bit differently.

You must be logged in to reply to this topic.