Using below method will delete the intended folder as well as emails and any subfolder inside that folder
1. Connect PowerShell to Exchange Online:-
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -allowclobber -verbose
2. Give Impersonation role to the admin account you want to use in O365 to run this script:-
Enable-OrganizationCustomization
New-ManagementRoleAssignment -Role “ApplicationImpersonation” -User “user@domain.com”
3. Load the script, just copy and paste below text and hit enter. This will create a function to delete the folders but will not delete anything.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
function Create-SOAPMessage
{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$True, HelpMessage=”User whose email is searched.”)]
[String]$User,
[Parameter(Mandatory=$True, HelpMessage=”The message body”)]
[String]$Body
)
$Message=@”
<?xml version=”1.0″ encoding=”utf-8″?>
<soap:Envelope xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:m=”http://schemas.microsoft.com/exchange/services/2006/messages”
xmlns:t=”http://schemas.microsoft.com/exchange/services/2006/types”
xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”>
<soap:Header>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>$User</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
$Body
</soap:Body>
</soap:Envelope>
“@
return $Message
}
function Invoke-SOAPRequest
{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$True, HelpMessage=”Credentials used to connect to Exchange Online.”)]
[System.Management.Automation.PSCredential]$Credentials,
[Parameter(Mandatory=$True, HelpMessage=”The message “)]
[String]$Message,
[Parameter(Mandatory=$False, HelpMessage=”The http method”)]
[String]$Method=”Post”
)
# EWS service url for Exchange Online
$webServiceUrl=”https://outlook.office365.com/EWS/Exchange.asmx”
$Response=Invoke-WebRequest -Uri $webServiceUrl -Credential $Credentials -Body $Message -Method $Method
[xml]$xmlResponse=$Response.Content
return $xmlResponse
}
function Delete-Folder
{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$True, HelpMessage=”Credentials used to connect to Exchange Online.”)]
[System.Management.Automation.PSCredential]$Credentials,
[Parameter(ValueFromPipeline, Mandatory=$True, HelpMessage=”User whose email is searched.”)]
[String]$User,
[Parameter(Mandatory=$True, HelpMessage=”Folder to be deleted.”)]
[String]$FolderName,
[Parameter(Mandatory=$False, HelpMessage=”The maximum number of activities returned (default 200).”)]
[Int]$MaxResults=200,
[Parameter(Mandatory=$False, HelpMessage=”The number contacts to skip.”)]
[Int]$Skip=0
)
# SOAP message for getting the folder id
$body=@”
<FindFolder Traversal=”Deep” xmlns=”http://schemas.microsoft.com/exchange/services/2006/messages”>
<FolderShape>
<t:BaseShape>Default</t:BaseShape>
</FolderShape>
<ParentFolderIds>
<t:DistinguishedFolderId Id=”root”/>
</ParentFolderIds>
</FindFolder>
“@
$getFolderIdMsg=Create-SOAPMessage -User $User -Body $body
$response = Invoke-SOAPRequest -Credentials $Credentials -Message $getFolderIdMsg
# Get the folders from the response
$folders = $response.Envelope.Body.FindFolderResponse.ResponseMessages.FindFolderResponseMessage.RootFolder.Folders.Folder
$folderId=$null
$changeKey=$null
$totalCount=$null
# Loop through folders
foreach($folder in $folders)
{
if($folder.DisplayName -eq $FolderName)
{
$folderId = $folder.FolderId.Id
$changeKey = $folder.FolderId.Changekey
$totalCount = $folder.TotalCount
Write-Verbose “Folder Id and ChangeKey for “”$FolderName””: $folderId, $changeKey”
break
}
}
# Empty and delete the folder if found
if(![String]::IsNullOrEmpty($folderId) -and ![String]::IsNullOrEmpty($changeKey))
{
Write-Verbose “Emptying folder $FolderName ($totalCount items)”
# DeleteType = HardDelete, MoveToDeletedItems, or SoftDelete
$body=@”
<m:EmptyFolder DeleteType=”HardDelete” DeleteSubFolders=”true”>
<m:FolderIds>
<t:FolderId Id=”$folderId” ChangeKey=”$changeKey” />
</m:FolderIds>
</m:EmptyFolder>
“@
$emptyFolderMsg = Create-SOAPMessage -User $User -Body $body
$response = Invoke-SOAPRequest -Credentials $Credentials -Message $emptyFolderMsg
Write-Verbose “Deleting folder $FolderName”
# DeleteType = HardDelete, MoveToDeletedItems, or SoftDelete
$body=@”
<m:DeleteFolder DeleteType=”HardDelete” DeleteSubFolders=”true”>
<m:FolderIds>
<t:FolderId Id=”$folderId” ChangeKey=”$changeKey” />
</m:FolderIds>
</m:DeleteFolder>
“@
$deleteFolderMsg = Create-SOAPMessage -User $User -Body $body
$response = Invoke-SOAPRequest -Credentials $Credentials -Message $deleteFolderMsg
Write-Host “Deleted folder $FolderName ($totalCount items)”
}
else
{
Write-Host “The folder $FolderName not found for $User” -ForegroundColor Red
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4. Test it for a single user:-
Delete-Folder -Credentials $cred -User user@domain.com -Folder “Folder to be deleted”
5. Run for all the users:-
$cred = Get-Credential
Get-MsolUser | Select -ExpandProperty UserPrincipalName | %{Delete-Folder -Credentials $cred -Folder “All Mail” -user $_}
5a. For selective users in a csv. Make sure to make a csv with “Msol” heading as in the below script.
$proxy = Import-Csv “csv path”
Foreach ($user in $users)
{Delete-Folder -Credentials $cred -User $user.msol -Folder “Folder Name”}