Each object in Powershell has a default output defined for it, (even it is the one inherited from the Object class), and that is what the console uses to determine how to dump the object to the console host. This same default is used when passing the object down the pipeline to something that requires a string as input, including Out-String. Since you are pushing $member to Out-String, that cmdlet is taking the default output for that object and converting it all to a single string. In this case, the default output of the Deserialized.Microsoft.Exchange.Management.RecipientTasks.MailboxAcePresentationObject object created by the Get-MailboxPermission cmdlet is to dump all of the selected attributes to the console using a table format where the headers are the attribute names.
PS C:\> Get-MailboxPermission user1
Identity User AccessRights IsInherited Deny
-------- ---- ------------ ----------- ----
domain.com/People... NT AUTHORITY\SELF {FullAccess, ReadPermission} False False
...
...
In your code, each $member object in the foreach loop actually is an object with a User attribute, and when you dump it to the console, it includes the attribute header:
PS C:\> $membersOfExchange[0] | Get-Member
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
User NoteProperty string User=NT AUTHORITY\SELF
PS C:\> $membersOfExchange[0]
User
----
NT AUTHORITY\SELF
So, all of that to say that your “$helpvar = $member | Out-String” line is taking all of that text including the header and converting it to a single string of text and that is what messes up the rest of the script for you.
How do you fix it?
Don’t convert the object to a string, and then reference the User attribute of the object.
$membersOfExchange =@()
$membersOfExchange = Get-MailBoxPermission -Identity $var | Select-Object -Property User
foreach ($member in $membersOfExchange) {
$helpvar = $member
$helpvar.User.replace("\","-")
}
Also, you aren’t assigning the output of the Replace function to any variable, so when you reference $helpvar after executing the Replace, you are actually looking at the variable without the changes. You need to assign the output to a variable and then use the new variable in your Remove-MailboxPermission and Remove-ADPermission cmdlets.
$membersOfExchange =@()
$membersOfExchange = Get-MailBoxPermission -Identity $var | Where-Object { $_.User -match "COMPLUIS" }
foreach ($member in $membersOfExchange) {
$helpvar = $member.User.Replace("\","-")
Remove-MailboxPermission -Identity $var -User $helpvar -AccessRights FullAccess -InheritanceType All -Confirm:$false
Remove-ADPermission -Identity $var -User $helpvar -ExtendedRight Send-As -InheritanceType All -Confirm:$false
}
EDIT: More information on the default output view mechanism: Out-Default (Microsoft.PowerShell.Core) - PowerShell | Microsoft Docs. I was close, but not quite right on…