0

And this is my output EmailBody variable:

TEST GROUP --- @{InputObject=User01; SideIndicator==>}TEST GROUP --- @{InputObject=User02; SideIndicator==>}

Here is the kind of output I am looking for EmailBody variable as top and bottom :

TEST GROUP --- User01 added to mail group.
TEST GROUP --- User02 added to mail group.

Is it possible for me to format my output? I only want to display custom keyword instead of @{InputObject=User01; SideIndicator==>}

Any help would be greatly appreciated!

Here is the script that I wrote:

$EmailBody = ""

$Groups = Get-Content -Path "C:\temp\MyGroups.txt"

$Groups | ForEach-Object {
    $Group = $_
    $infoMember = Get-AdgroupMember "$Group" -Recursive
    $Members = foreach ($member in $infoMember) { get-aduser $member.samaccountname -properties displayname | select -ExpandProperty displayname  }

    if (!(Test-Path "C:\temp\$Group.txt"))
    {
     New-Item -path "C:\temp\$Group.txt" -type "file"
     Write-Host "Created new file"
     $Members | Out-File -FilePath "c:\temp\$Group.txt" -Force
    }
    else{
    $OldMembers = Get-Content -Path "C:\temp\$Group.txt"        
    $Change = Compare-Object -ReferenceObject $OldMembers -DifferenceObject $Members
     ForEach($Changes in $Change) {
          if ($Changes.sideindicator -eq "=>") {              
            if ($Changes){
            $EmailBody += "$Group`n---`n$Changes"
            }
          write-host "user added to mail group"  -ForegroundColor Cyan
          $Members | Out-File -FilePath "c:\temp\$Group.txt" -Force
          }
          else{
          write-host "nothing"  -ForegroundColor Yellow
        }
      }
    }
}
Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29
Arbelac
  • 1,698
  • 6
  • 37
  • 90
  • $changes will be an object with properties. You need to access a specific property of that object. You will need to use $($changes.InputObject) within your email body. – AdminOfThings Aug 29 '19 at 14:18

1 Answers1

0

There are a few ways to address your issue. The solution without modifying the rest of your code is to access the InputObject property of your Compare-Object output. Since you will be accessing a custom object property while inside of a string, you will need to use the subexpression operator ($()).

$EmailBody += "$Group`n---`n$($Changes.InputObject)"

If you do not use the subexpression operator, $Changes.InputObject expansion will stop at the . character resulting in only $Changes still being interpolated. The output would then be a hash table with the string .InputObject appended to the end.


An alternative that reduces complexity is to just use a Where-Object comparison. You won't need to do the SideIndicator comparison now. If $change contains any data, then you know there were differences.

$change = $members | Where-Object {$_ -notin $oldmembers}
if ($change) {
    $EmailBody = $change | Foreach-Object { 
                     "$Group`n---`n$_"
                 }
}

The issue with your attempt is the default Compare-Object output returns a custom object with properties InputObject and SideIndicator. If you attempt to output a custom object with properties as a string, it will return a hash table of your properties. See below for an example.

$change = Compare-Object  -ReferenceObject $members -DifferenceObject $oldmembers
$change

InputObject SideIndicator
----------- -------------
user1       <=
user3       <=

foreach ($changes in $change) {
    "the output is $changes"
}
the output is @{InputObject=user1; SideIndicator=<=}
the output is @{InputObject=user3; SideIndicator=<=}
AdminOfThings
  • 23,946
  • 4
  • 17
  • 27