PowerShell: Create folders in users’ mailboxes


Here is a PowerShell EWS script that will create folders (one or more) in users' mailboxes.  To run it against a single mailbox, syntax is:

.\Create-Folders.ps1 user1.ex2k7@hybrid.local "Folder 1;Folder 2"

By default, folders are created under the inbox.  For multiple folders (as above), separate the folder names with a semicolon.  You can specify the parent folder (in case this isn't the inbox) by using the -ParentFolder parameter.

The script also supports taking a text file with a list of mailboxes as the input (just replace the mailbox address with the path to the text file).  You can also use it with standard PowerShell scripting.  To process all mailboxes (for example), you could do the following (from an Exchange Management Shell session):

Get-Mailbox | foreach {
     try
     {
           .\Create-Folders.ps1 $_.PrimarySmtpAddress "Private;Archive" -Impersonate
     } catch { }
}

 

Note that the try...catch is important in the above, as without it the script would stop at any mailbox that generated an error.

Other than the above, the usual parameters (for most of my EWS scripts) apply to this one: -AuthUsername, -AuthPassword, -AuthDomain, -Impersonate, -EwsUrl, -EwsManagedApiPath, -IgnoreSSLCertificate, -AllowInsecuredRedirection, -WhatIf

Create-Folders.zip

Comments (42)

  1. Shane Pollard says:

    I get the following when I run this script:

    Missing closing ')' in expression.

    At C:ProcessExchangeCreate-Folders.ps1:320 char:2

    +      <<<< [ValidateNotNullOrEmpty()]

       + CategoryInfo          : ParserError: (CloseParenToken:TokenId) [], ParseException

       + FullyQualifiedErrorId : MissingEndParenthesisInExpression

    That line equates to you doing a "[ValidateNotNullOrEmpty()]" call.  It would appear as though you have a closing ) there.  Thoughts?

  2. This script doesn't have 320 lines, it has 304.  There is a missing ) in your script (which has presumably been modified?), and it will most likely be in the code before line 320.

  3. Serg says:

    Hello! I'll try to make folder for a group of mailboxes

    I've made txt file but it didn't work

    [PS] C:Windowssystem32>Create-Folders.ps1 ".3.txt" "folder"

    Не удалось выполнить проверку переменной, так как значение  является недопустимым для переменной Mailbox.

    C:Windowssystem32Create-Folders.ps1:293 знак:11

    +         $Mailbox <<<<  = $entry.PrimarySmtpAddress

       + CategoryInfo          : MetadataError: (:) [], ValidationMetadataException

       + FullyQualifiedErrorId : ValidateSetFailure

    Processing mailbox .3.txt

    Исключение при вызове "AutodiscoverUrl" с "1" аргументами: "The e-mail address is formed incorrectly."

    C:Windowssystem32Create-Folders.ps1:200 знак:28

    +             $service.AutodiscoverUrl <<<< ($Mailbox)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

    Autodiscover failed, cannot process mailbox

    in file txt I wrote popov@contoso.com

  4. Serg:

    PowerShell is not finding ".3.txt" as an input file (the script basically tries to open that parameter as a file, and if it fails it assumes it is a mailbox).  Try using full path/filename e.g.

    Create-Folders.ps1 "c:3.txt" "folder"

  5. Serg says:

    I wrote as yo said, but it didn't work, can you write the example of txt file

  6. Sankar Munirathinam says:

    Hi Dave,

    How to delete all the folders from the users mailbox?

  7. Harley1955 says:

    Can't get the -ParentFolder to work:

    [PS] C:scripts>.Create-Folders.ps1 user@domain.com "AAAA;BBBB" -parentfolder CC

    Processing mailbox user@domain.com

    Exception calling "Bind" with "2" argument(s): "Value cannot be null.

    Parameter name: folderId"

    At C:scriptsCreate-Folders.ps1:144 char:62

    +     $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($service,$FolderId)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

    any ideas? Thanks.

  8. Jacky says:

    Exception calling "Bind" with "2" argument(s): "The request failed. The underly

    ing connection was closed: An unexpected error occurred on a send."

    At C:scriptsCreate-Folders.ps1:144 char:62

    +     $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($servi

    ce,$FolderId)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

  9. The "Unexpected error occurred on a send" is due to an issue with PowerShell, the EWS Managed API and self-signed certificates, as far as I am aware.  Unfortunately, I do not know of a workaround at present (except to used fully trusted certificates, OR use the Managed API 1.1 which appears not to have this issue).  I have also encountered the issue sporadically in my lab environment.

    With regards to deleting all folders from a user's mailbox, I don't currently have a script for this.  Also, it may be easier to simply remove the mailbox and create a new one if your intention is to clear it.

  10. Parent folder needs to be a full path to the folder (e.g. "InboxSubfolder").  If just a name is used, it must be a top-level folder.

  11. Syed says:

    How do I use this script to create a folder in the ROOT of a mailbox?  Using -parentfolder "" creates it in the inbox.  Thank you!

    Syed.

  12. StephCarb says:

    How would you create the folder at the root (top) level (same level as Inbox, Deleted Items, etc)?  We don't want the new folder to be nested in the Inbox.

  13. Andrew B says:

    Hi David – great script!  Would it be possible to modify it to handle:

    1. Creating Calendars (nested) undernearth the standard "Calendar"?

    2. Deleting out or overwriting and Calendars with the same name?

  14. Michael says:

    How do you specify the root of the mailbox?  I don't want to create the folders under the inbox.

  15. David Bennett says:

    Using the parms  -AuthUsername, -AuthPassword, -AuthDomain got rid of the Exception calling "Bind" with "2" argument(s) error. I can create a folder now.

    However, the -ParentFolder doesn't work as others have noted as well. I want to create folders off the root

    I tried the parm -Parent Folder "" which throws and error and created the folder under INBOX. Error is

    Write-Verbose : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Message'. Specified

    method is not supported.

    At C:ExchMgmtScriptscreate-folders.ps1:261 char:15

    +     Write-Verbose <<<<  "Applying given credentials for", $AuthUsername

       + CategoryInfo          : InvalidArgument: (:) [Write-Verbose], ParameterBindingException

       + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.WriteVerboseCommand

  16. Erin Crouse says:

    Any time I try to run this with the -ParentFolder parameter I get this error.  Even if I use a well known folder I get the error but if I run it without the -ParentFolder parameter it creates the subfolder specified under the inbox with no problems.

    Exception calling "Bind" with "2" argument(s): "The request failed. The underlying connection was closed: An unexpected

    error occurred on a send."

    At C:exchangepsCreate-Folders.ps1:226 char:73

    +         $Folder = GetFolder([Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($service,$FolderId), $ParentFold

    er)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

    Exception calling "Bind" with "2" argument(s): "Value cannot be null.

    Parameter name: folderId"

    At C:exchangepsCreate-Folders.ps1:144 char:62

    +     $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($service,$FolderId)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

  17. Dean Colpitts says:

    To create the folder outside of the inbox, search and replace ::Inbox with ::MsgFolderRoot

    See here for the WellKnowFolderName enumeration:

    msdn.microsoft.com/…/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx

    dcc

  18. Replacing ::Inbox for ::MsgFolderRoot in the script... says:

    …worked like a charm. +1 to Dean Colpitts!!

    David Barrett, great script with this single modification.

    Based on these results, I'll be developing a script that pulls all Primary SMTP addresses in the organization, pops them into a one-column csv, is used as the input for the cmdlet, then tossed when done. This will allow me to standardize a set of folders that all users should have, by default.

    (Eat that, Exchange Enterprise License)

  19. Soren says:

    Isn't this exactly what Managed Custom Folders did in Exchange 2007?

  20. Soren says:

    Isn't this just a Managed Custom Folder as we know it from Exchange 2007?

  21. No, this script hasn't got anything to do with managed folders – the folders created by the script aren't managed.

  22. DarrenM says:

    I get an error that Create-Folders.ps1 is not digitally signed.

  23. Akr Ofly says:

    running your script I seem to keep getting "Failed to locate EWS Managed API, cannot continue". Any clues?

  24. Akr Ofly says:

    Hello once again, my previous issue was solved by using the EwsManagedApiPath switch and pointing to the DLL location which in my case was "c:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll"

  25. mhk says:

    is it possible to create a folder form type contact with this script?

  26. Nicholas says:

    Hello,  I have been trying to run this in an Office365-connected Powershell window. Do I have to load any special EWS modules? If I don't specify the -EwsManagedApiPath then I get "Failed to locate EWS Managed API" although the API is in the default path. If I specify the DLL path I get a bunch of different errors:

    Unable to load one or more of the requested types…

    Unable to find type [Microsoft.Exchange.WebServices.Data.ExchangeVersion]….

    Property 'UseDefaultCredentials' cannot be found on this object….

  27. Nicholas says:

    I got this working on Office 365 and I was able to create a subfolder in another user's mailbox! 🙂

    Here are some comments to help other people.

    Assumptions:

    1. You already have Office 365 powershell working on your computer

    2. You are going to launch the script with username ie "FolderCreator@domain.com"

    Prepare your workstation:

    3. If you don't have it, download & Install "EWS Managed API"

    4. Make a note of the path for Microsoft.Exchange.WebServices.dll (in my case C:Program FilesMicrosoftExchangeWeb Services2.0Microsoft.Exchange.WebServices.dll)

    Prepare Office 365:

    5. Configure ApplicationImpersonation for the desired user from step 2. To do so follow these instructions http://www.exactsoftware.com/…/DocView.aspx

    6. Find the Office 365 EWS url (probably "outlook.office365.com/…/Exchange.asmx")

    Call the script with all parameters:

    .Create-Folders.ps1 <primary-email-address-of-target-mbox> <foldername-to-create> -EWSManagedApiPath <dll-path-from-step-4> -EwsUrl <url-from-step-6> -AuthUsername <username-from-step-2> -AuthPassword <password> -Impersonate -verbose

    I did not try any other parameters (ParentFolder, mutliple folders, CSV file) so I can provide no feedback on those parts.

    Many thanks to David for creating this! 🙂

    1. Vic says:

      Got is running fine on Office 365.
      Here are test command lines:

      #Create a test_folder1 in shared mailbox “shared_mail_box1”
      .\Create-Folders.ps1 shared_mail_box1@contoso.com “test_folder1” -EwsUrl https://outlook.office365.com/EWS/Exchange.asmx -AuthUsername John@contoso.com -AuthPassword JonhPassword -Verbose

      #Create a test_folder2 under test_folder1 in shared mailbox “shared_mail_box1”
      .\Create-Folders.ps1 shared_mail_box1@contoso.com “test_folder2” -EwsUrl https://outlook.office365.com/EWS/Exchange.asmx -AuthUsername John@contoso.com -AuthPassword JonhPassword -Verbose -ParentFolder test_folder1

      #Create a test_folder3 under test_folder2 in shared mailbox “shared_mail_box1”
      .\Create-Folders.ps1 shared_mail_box1@contoso.com “test_folder3” -EwsUrl https://outlook.office365.com/EWS/Exchange.asmx -AuthUsername John@contoso.com -AuthPassword JonhPassword -Verbose -ParentFolder test_folder1\test_folder2

    2. Pete says:

      Hi Nicholas,

      I need to do the exact thing. But for 40 365 mailboxes and it’s their online archives that need 2 folders created. Not the primary.
      How would I go about it additionally to your steps?
      Cheers

  28. Curt Riley says:

    I get the following when I tried to run the script:

    Exception calling "Bind" with "2" argument(s): "The specified object was not found in the store."

    At C:Create-FoldersCreate-Folders.ps1:144 char:62

    +     $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($service,$FolderId)

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

  29. Paul says:

    Great script, and really useful. One question – could you suggest a modification to set the default view of the new folder to a URL?

  30. Vepuchiro says:

    Hai guys,

    could you help to guide me, how to use this script? thankyou 🙂

  31. Stan Wasserman says:

    Dave,
    Great work on this script, it is exactly what I have been looking for. But I am running into some trouble using it with a text file. No matter how I format the text file or csv file it error with the following: The variable cannot be validated because the value is not a valid value for the Mailbox variable.
    At C:\scripts\Create-Folders.ps1:293 char:11
    + $Mailbox <<<< = $entry.PrimarySmtpAddress
    + CategoryInfo : MetadataError: (:) [], ValidationMetadataException
    + FullyQualifiedErrorId : ValidateSetFailure

    Processing mailbox import.txt
    Exception calling "AutodiscoverUrl" with "1" argument(s): "The e-mail address is formed incorrectly."
    At C:\scripts\Create-Folders.ps1:200 char:28
    + $service.AutodiscoverUrl <<<< ($Mailbox)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Autodiscover failed, cannot process mailbox

    Any ideas why this may be happening?

    Again many thanks for the great script.

    1. Vic says:

      Here is example of test_file.CSV:

      PrimarySmtpAddress
      user1@contoso.com
      user2@contoso.com
      user3@contoso.com

      You can test it from Powershell command prompt:

      $csv = Import-CSV .\test_file.csv
      foreach ($entry in $csv)
      {
      $Mailbox = $entry.PrimarySmtpAddress
      if ( [string]::IsNullOrEmpty($Mailbox) -eq $False )
      {
      Write-host $Mailbox
      }
      }

  32. Tony says:

    Another method, is to simply use new-mailboximport command, create a PST with the folders you want (mail, contacts, calendar, notes, etc) and any additional content, then import the PST into each mailbox.

  33. san says:

    How Create folder in root folder, near Inbox. I very need.

  34. Vassil says:

    David,

    Nice script. Works as expected. I was able to create subfolders in Contacts.

    I need some help on what needs to be modified in order to be able to copy Contacts within the same mailbox but into another Contacts folder?

    Thank you .
    Vassil

  35. Marco Mangiante says:

    Hello,

    as someone created a calendar with this script? Could you help me? I tried with:

    .\Create-Folders.ps1 user1@mydomain.com “Test2” -EwsUrl https://outlook.office365.com/EWS/Exchange.asmx -AuthUsername admin_user@mydomain.com -AuthPassword mypwd -Verbose -ParentFolder “Calendario”

    but have the error:

    DETTAGLIATO: Failed to find ictservices@imncloud.onmicrosoft.com
    DETTAGLIATO: Requested folder path: ictservices@imncloud.onmicrosoft.com\Calendario
    DETTAGLIATO: Binding to folder with id
    Eccezione durante la chiamata di “Bind” con “2” argomento/i: “Il valore non può essere null.
    Nome parametro: folderId”
    In C:\Users\mmangiante\Downloads\Create-Folders.ps1:144 car:2
    + $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($ser …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

    Sorry for the english with italian 🙂

    1. Marco Mangiante says:

      Finally I found a solution: I have searched and replaced, as suggested by Dean Colpitts, ::Inbox with ::MsgFolderRoot; also added, in CreateFolders function, a line to specify that I’mm creating a folder of type calendar:

      $rf.FolderClass = “IPF.Appointment”

      I know that it is not elegant and also not general purpose as the script, but it works for Calendar and it is ok for me.

  36. Alex says:

    Exchange 2013. I also get an error when you run the script. Someone decided this issue?

    Exception calling “Bind” with “2” argument(s): “The specified object was not found in the store.”
    At C:\scripts\Create-Folders-in-Inbox.ps1:144 char:2
    + $folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderId …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServiceResponseException

    1. Alex says:

      Understood. I need to have full access rights.
      Add-MailboxPermission -Identity user -User admin -AccessRights FullAccess -InheritanceType All –AutoMapping $false

      Another question. Can this script somehow applies to the group, which includes user mailboxes?
      With this construction: Get-mailbox -RecipientTypeDetails UserMailbox -Filter {MemberofGroup -Eq ‘CN=group,OU=YourOU,dc=domain,dc=local’}

  37. Rodney Frank says:

    Could you use something like this at the start of the script to identify users in a particular group to “Create the folder” for?

    Get-ADGroupMember “groupName” | ForEach-Object {

Skip to main content