Afgelopen week zaten we behoorlijk in de stress. Door een fout tijdens een migratie waren alle Public folders gewist. De exacte oorzaak is nog steeds onduidelijk, maar er is iets bij de replicatie mis gegaan. Gelukkig konden we alle data terughalen doormiddel van een Microsoft tool voor Exhange 2003. Alleen kwam er iets anders naar voren. Bijna alle config instellingen met betrekking tot e-mail waren verdwenen.

Het meeste werk zat in het herstellen van deze informatie welke niet terug te vinden was. Vanuit dit perspectief heb ik het volgende script geschreven met de naam Dump-PublicFolders.ps1.....

Wat doet het script

Het script accepteert een aantal opties waarvan een aantal verplicht zijn:

-Server <servernaam>

Optioneel: Deze optie is optioneel, het is de naam van de server waartegen het script praat.

-TopPublicfolder <startpunt>

Verplicht: Dit is het startpunt in de foldertree, bijvoorbeeld “\”.

-DumpPath <pad van de dump>

Verplicht: Dit is het pad waar de configs gedumpt worden. Bijvoorbeeld “D:\Backup\PublicFolders”. Deze folder wordt aangemaakt wanneer deze niet bestaat, eventuele configs in deze folder worden overschreven.

-IncludeAdminPermissions <boolean>

Optioneel: Default waarde is $false. Wanneer deze optie wordt aangeroepen met –IncludeAdminPermissions:$true zullen de admin permissions worden gedumpt.

-IncludeClientPermissions <boolean>

Optioneel: Default waarde is $true. Hiermee worden de client permissies gedumpt. –IncludeClientPermissions:$false zet dit uit.

Wat wordt gegenereerd

Er wordt per public folder een bestand aangemaakt, alle bestanden zijn .csv met vaste kolom breedte.

AllPublicFolders.csv

Dit bestand is een overzicht van alle public folders. Velden: ParentPath, name, Identity, HiddenFromAddressListsEnabled, mailEnabled, Replicas

<Indentity>_(mail-info).csv

De postbus informatie. Let op, niet toegestane letters worden vervangen door een #. in de bestandsnaam. Velden: Name, Identity, Alias, DisplayName, SimpleDisplayName, EmailAddresses, GrantSendOnBehalfTo, HiddenFromAddressListsenabled, PrimarySMTPAddress, WindowsEmailAddress, ForwardingAddress, EmailAddressPolicyEnabled

<Indentity>_(client_permissions).csv

De client permissies van de mail enabled public folder. Let op, niet toegestane letters worden vervangen door een #. in de bestandsnaam. Velden: Identity, User, Accessrights

<identity>_(admin-permissions).csv

De admin permissies van de mail enabled public folder. Let op, niet toegestane letters worden vervangen door een #. in de bestandsnaam. Velden: Identity, User, Accessrights, IsInherited

Het script

#
# Created by Wim-Bart van der Waals
# Dumps Public folder information to files
#

Param(
    [string] $Server,
    [string] $TopPublicFolder = "",
    [string] $DumpPath = "",
    [bool]   $IncludeAdminPermissions = $false,
    [bool]   $IncludeClientPermissions = $true
)


# This function validates the scripts parameters
function ValidateParams
{
  $validInputs = $true
  $errorString =  ""

  if ($TopPublicFolder -eq "")
  {
    $validInputs = $false
    $errorString += "`nMissing parameter: The -TopPublicFolder parameter is required. Please pass in a valid Public Folder path, name, or entryID."
  }

  if ($DumpPath -eq "")
  {
    $validInputs = $false
    $errorString += "`nMissing parameter: The -DumpPath parameter is required. Please pass in a valid Filesystem Folder path."
  }

  if (!$validInputs)
  {
    Write-error "$errorString"
  }

  return $validInputs
}

# Function that returns true if the incoming argument is a help request
function IsHelpRequest
{
    param($argument)
    return ($argument -eq "-?" -or $argument -eq "-help");
}

# Function that displays the help related to this script following
# the same format provided by get-help or <cmdletcall> -?
function Usage
{
@"

NAME:
`tDump-PublicFolder.ps1

SYNOPSIS:
`tDumps all information of Public Folders needed to recreate them

SYNTAX:
`tdump-PublicFolder.ps1
`t`t[-Server <ServerIdParameter>]
`t`t[-TopPublicFolder <PublicFolderIdParameter>]
`t`t[-DumpPath <Filesystempath>]
`t`t[-IncludeAdminPermissions <Boolean>]
`t`t[-IncludeClientPermissions <Boolean>]

PARAMETERS:
`t-Server (optional)
`t`tThe server to operate against. Must be an Exchange 2007 Mailbox server
`t`twith a public folder database. Defaults to a convenient server.

`t-TopPublicFolder (required)
`t`tThe folder identity of the top of the tree of folders to modify

`t-DumpPath (required)
`t`tThe folder where the dumps are written. Depending on number of mail
`t`tenabled folders this folder can fill up with lots of files.

`t-IncludeAdminPermissions (optional)
`tDumps Administrative Permissions per public folder, can generate
`tlots of files.
`tDefault value: False

`t-IncludeClientPermissions (optional)
`tDumps Client Permissions per public folder, can generate
`tlots of files.
`tDefault value: True


`t-------------------------- EXAMPLE 1 --------------------------

C:\PS> .Dump-PublicFolder.ps1 -TopPublicFolder "\Folder" -DumpPath "D:\MyFiles\DumpOfToday"

`t-------------------------- EXAMPLE 2 --------------------------

C:\PS> .\Dump-PublicFolder.ps1 -Server "MyEx2007Server" -TopPublicFolder "\Folder"  -DumpPath "D:\MyFiles\DumpOfTomorrow\"

REMARKS:
`tNone

RELATED LINKS:
`tNone

"@
}

####################################################################################################
# Script starts here
####################################################################################################

# Check for Usage Statement Request
$args | foreach { if (IsHelpRequest $_) { Usage; exit; } }

# Validate the parameters
$ifValidParams = ValidateParams;

if (!$ifValidParams) { exit; }

$Result = test-path -path $DumpPath
if (!$Result)
{
  New-Item -ItemType directory -Path $DumpPath -confirm:$false -WarningAction:Stop -ErrorAction:Stop
}


if (!$DumpPath.EndsWith("\")) {
  $DumpPath += "\"
}


if ($server)
{
    $getpfcmd = "get-publicfolder -server $Server -identity $TopPublicFolder -Recurse -resultsize unlimited"
}
else
{
    $getpfcmd = "get-publicfolder -identity $TopPublicFolder -Recurse -resultsize unlimited"
     $Server = "."
}

$ListAll = $DumpPath + "AllPublicFolders.csv"

#Do your thing
invoke-expression $getpfcmd | ft -property ParentPath,name,Identity,HiddenFromAddressListsEnabled,mailEnabled,Replicas | Out-File -width 1024 -filepath $ListAll

invoke-expression $getpfcmd | foreach {
  $FileName = $_.Identity
  $pattern = "[{0}]" -f ([Regex]::Escape([String][System.IO.Path]::GetInvalidFileNameChars()))
  $FileName = [Regex]::Replace($FileName, $pattern, '#')
  $FileName = $DumpPath + $FileName

  if ($_.mailEnabled -eq "true") {
    $OutFile  = $fileName + '_(mail-info).csv'
    $_ |  get-mailpublicfolder | ft -autosize -property Name,Identity,Alias,DisplayName,SimpleDisplayName,EmailAddresses,GrantSendOnBehalfTo,HiddenFromAddressListsenabled,PrimarySMTPAddress,WindowsEmailAddress,ForwardingAddress,EmailAddressPolicyEnabled | Out-File -width 2048 -filepath "$OutFile"
  }
  if ($IncludeClientPermissions) {
    $OutFile  = $fileName + '_(Client-Permissions).csv'
    $_ | Get-PublicFolderClientPermission  |  ft -autosize -property  Identity,User,Accessrights  | Out-File -width 1024 -filepath "$OutFile"
  }
  if ($IncludeAdminPermissions) {
    $OutFile  = $fileName + '_(Admin-Permissions).csv'
    $_ | Get-PublicFolderAdministrativePermission | ft  -autosize -property Identity,User,Accessrights,IsInherited   | Out-File -width 1024 -filepath "$OutFile"
  }
}