8
0
2024-01-24 16:42:38 +01:00

320 lines
10 KiB
PowerShell

#
# Create-Folders.ps1
#
# By David Barrett, Microsoft Ltd. 2013. Use at your own risk. No warranties are given.
#
# DISCLAIMER:
# THIS CODE IS SAMPLE CODE. THESE SAMPLES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
# MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR
# A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLES REMAINS WITH YOU. IN NO EVENT SHALL
# MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
# BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE
# SAMPLES, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION
# OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
param (
[Parameter(Position=0,Mandatory=$True,HelpMessage="Specifies the mailbox to be accessed")]
[ValidateNotNullOrEmpty()]
[string]$Mailbox,
[Parameter(Position=1,Mandatory=$True,HelpMessage="Specifies the folder(s) that should be checked/created. For multiple folders, separate using semicolon")]
[ValidateNotNullOrEmpty()]
[string]$RequiredFolders,
[Parameter(Mandatory=$False,HelpMessage="The folder that should contain the subfolders (default is Inbox)")]
[string]$ParentFolder,
[Parameter(Mandatory=$False,HelpMessage="Username used to authenticate with EWS")]
[string]$AuthUsername,
[Parameter(Mandatory=$False,HelpMessage="Password used to authenticate with EWS")]
[string]$AuthPassword,
[Parameter(Mandatory=$False,HelpMessage="Domain used to authenticate with EWS")]
[string]$AuthDomain,
[Parameter(Mandatory=$False,HelpMessage="Whether we are using impersonation to access the mailbox")]
[switch]$Impersonate,
[Parameter(Mandatory=$False,HelpMessage="EWS Url (if omitted, then autodiscover is used)")]
[string]$EwsUrl,
[Parameter(Mandatory=$False,HelpMessage="Path to managed API (if omitted, a search of standard paths is performed)")]
[string]$EWSManagedApiPath = $Env:ProgramFiles + "\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll",
[Parameter(Mandatory=$False,HelpMessage="Whether to ignore any SSL errors (e.g. invalid certificate)")]
[switch]$IgnoreSSLCertificate,
[Parameter(Mandatory=$False,HelpMessage="Whether to allow insecure redirects when performing autodiscover")]
[switch]$AllowInsecureRedirection,
[Parameter(Mandatory=$False,HelpMessage="If specified, no changes will be applied")]
[switch]$WhatIf
)
write-host "Function start..."
Function SearchDll()
{
# Search for a program/library within Program Files (x64 and x86)
$path = $args[0]
$programDir = $Env:ProgramFiles
if (Get-Item -Path ($programDir + $path) -ErrorAction SilentlyContinue)
{
return $programDir + $path
}
$programDir = [environment]::GetEnvironmentVariable("ProgramFiles(x86)")
if ( [string]::IsNullOrEmpty($programDir) ) { return "" }
if (Get-Item -Path ($programDir + $path) -ErrorAction SilentlyContinue)
{
return $programDir + $path
}
}
Function LoadEWSManagedAPI()
{
# Check EWS Managed API available
if ( !(Get-Item -Path $EWSManagedApiPath -ErrorAction SilentlyContinue) )
{
#$EWSManagedApiPath = SearchDll("\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll")
$EWSManagedApiPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"
Write-Host "EWSManagedApiPath: $EWSManagedApiPath"
if ( [string]::IsNullOrEmpty($EWSManagedApiPath) )
{
$EWSManagedApiPath = SearchDll("\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll")
if ( [string]::IsNullOrEmpty($EWSManagedApiPath) )
{
$EWSManagedApiPath = SearchDll("\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll")
}
}
}
If ( ![string]::IsNullOrEmpty($EWSManagedApiPath) )
{
# Load EWS Managed API
Write-Host ([string]::Format("Using managed API found at: {0}", $EWSManagedApiPath))
Add-Type -Path $EWSManagedApiPath
return $true
}
return $false
}
Function GetFolder()
{
# Return a reference to a folder specified by path
Write-Host "Starting GetFolder function"
$RootFolder, $FolderPath = $args[0]
$Folder = $RootFolder
if ($FolderPath -ne '\')
{
$PathElements = $FolderPath -split '\\'
For ($i=0; $i -lt $PathElements.Count; $i++)
{
if ($PathElements[$i])
{
$View = New-Object Microsoft.Exchange.WebServices.Data.FolderView(2,0)
$View.PropertySet = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly
$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $PathElements[$i])
$FolderResults = $Folder.FindFolders($SearchFilter, $View)
if ($FolderResults.TotalCount -ne 1)
{
# We have either none or more than one folder returned... Either way, we can't continue
$Folder = $null
Write-Host ([string]::Format("Failed to find {0}", $PathElements[$i]))
Write-Host ([string]::Format("Requested folder path: {0}", $FolderPath))
break
}
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, $FolderResults.Folders[0].Id)
}
}
}
return $Folder
}
Function CreateFolders()
{
$FolderId = $args[0]
Write-Host "Binding to folder with id $FolderId"
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderId)
if (!$folder) { return }
foreach ($requiredFolder in $FolderCheckList)
{
Write-Host "Checking for existence of $requiredFolder"
$rf = GetFolder( $folder, $requiredFolder )
if ( $rf )
{
Write-Host "$requiredFolder already exists" -ForegroundColor Green
}
Else
{
# Create the folder
if (!$WhatIf)
{
$rf = New-Object Microsoft.Exchange.WebServices.Data.Folder($service)
$rf.DisplayName = $requiredFolder
$rf.Save($FolderId)
if ($rf.Id.UniqueId)
{
Write-Host "$requiredFolder created successfully" -ForegroundColor Green
}
}
Else
{
Write-Host "$requiredFolder would be created" -ForegroundColor Yellow
}
}
}
}
Function ProcessMailbox()
{
# Process mailbox
Write-Host "Processing mailbox $Mailbox" -ForegroundColor White
if ( $WhatIf )
{
Write-Host "NO CHANGES WILL BE APPLIED" -ForegroundColor Red
}
# Set EWS URL if specified, or use autodiscover if no URL specified.
Write-Host "EWS: $EwsUrl"
if ($EwsUrl)
{
$service.URL = New-Object Uri($EwsUrl)
Write-Host "EWS: $($service.URL)"
}
else
{
Write-Host "Performing autodiscover for $Mailbox"
if ( $AllowInsecureRedirection )
{
$service.AutodiscoverUrl($Mailbox, {$True})
}
else
{
$service.AutodiscoverUrl($Mailbox)
}
if ([string]::IsNullOrEmpty($service.Url))
{
Write-Host "Autodiscover failed, cannot process mailbox" -ForegroundColor Red
return
}
Write-Host ([string]::Format("EWS Url found: {0}", $service.Url))
}
Write-Host "Impersonating ?"
# Set impersonation if specified
if ($Impersonate)
{
Write-Host "Impersonating $Mailbox"
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $Mailbox)
$FolderId = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox
Write-Host $FolderId
}
else
{
# If we're not impersonating, we will specify the mailbox in case we are accessing a mailbox that is not the authenticating account's
Write-Host "Mailbox: $Mailbox"
$mbx = New-Object Microsoft.Exchange.WebServices.Data.Mailbox( $Mailbox )
Write-Host "MBX Object created: $mbx"
$FolderId = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox, $mbx )
Write-Host $FolderId
}
Write-Host "ParentFolder: $ParentFolder"
if ($ParentFolder)
{
Write-Host $service, $FolderId, $ParentFolder
#GetFolder
$Folder = GetFolder([Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderId), $ParentFolder)
Write-Host $service, $FolderId, $ParentFolder
if (!$FolderId)
{
Write-Host "Failed to find folder $ParentFolder" -ForegroundColor Red
return
}
$FolderId = $Folder.Id
}
Write-Host "Calling CreateFolders function"
CreateFolders $FolderId
}
# The following is the main script
if (!(LoadEWSManagedAPI))
{
Write-Host "Failed to locate EWS Managed API, cannot continue" -ForegroundColor Red
Exit
}
Write-Host "Service binding.."
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
# If we are ignoring any SSL errors, set up a callback
if ($IgnoreSSLCertificate)
{
Write-Host "WARNING: Ignoring any SSL certificate errors" -ForegroundColor Yellow
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
}
# Set credentials if specified, or use logged on user.
if ($AuthUsername -and $AuthPassword)
{
Write-Host "Applying given credentials for", $AuthUsername
if ($AuthDomain)
{
$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($AuthUsername,$AuthPassword,$AuthDomain)
} else {
$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($AuthUsername,$AuthPassword)
}
} else {
Write-Host "Using default credentials"
$service.UseDefaultCredentials = $true
}
if ($RequiredFolders.Contains(";"))
{
# Have more than one folder to check, so convert to array
$FolderCheckList = $RequiredFolders -split ';'
}
else
{
$FolderCheckList = $RequiredFolders
}
# Check whether we have a CSV file as input...
$FileExists = Test-Path $Mailbox
If ( $FileExists )
{
# We have a CSV to process
$csv = Import-CSV $Mailbox
foreach ($entry in $csv)
{
$Mailbox = $entry.PrimarySmtpAddress
if ( [string]::IsNullOrEmpty($Mailbox) -eq $False )
{
ProcessMailbox
}
}
}
Else
{
# Process as single mailbox
ProcessMailbox
}