locked
Adding Mailbox with VB - upgrade to Exchange 2010 RRS feed

  • Question

  • Hello
    We are getting ready to convert to Exchange 2010. Currently we're using VB code to add new users to AD and create mailbox for them with specific settings. I've been trying to figure out - what do I need to change in my code in order for the code to work in Exchange 2010 environment. I've seen some references about using Powershell in a remote environment and guessing that AddPSSnapIn will no longer work. Not sure about hardcoding username and password for remote access. Is there any way to avoid it? Whose u/p should it be anyway? AD user who runs the code? Below I'm posting the code that we using in Exchange 2007. Please let me know what I need to change? I appreciate your help!
    Thanks, Alla

    Private Sub CreateMailboxNew(ByVal UserNm As String) 
    Dim temp As String 
    Dim identityfinal As String = UserNm 
    Dim rsConfig As RunspaceConfiguration 
    Dim snapInException As PSSnapInException
    Dim info As PSSnapInInfo 
    Dim myRunSpace As Runspace
     Dim pipeLine As Pipeline 
    Dim myCommand 
    Dim MailUserResults As Collection(Of PSObject)
     Dim sMailBoxPath As String D
    im addresses As New ArrayList 
    Dim CorrUsername As String
     
    temp = ""
     snapInException = Nothing
     myRunSpace = Nothing
     pipeLine = Nothing 
    
    Try rsConfig = RunspaceConfiguration.Create() 
    'for exch 2010 - use Microsoft.Exchange.Management.PowerShell.E2010?
     info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", snapInException)
     myRunSpace = RunspaceFactory.CreateRunspace(rsConfig) 
    myRunSpace.Open() 
    sMailBoxPath = System.Configuration.ConfigurationManager.AppSettings("MailBoxStorePath")
     myCommand = New Command("Enable-Mailbox")
     myCommand.Parameters.Add("Identity", "something.net\" & UserNm) 
    
    If ExternalEmailFlag = 1 Then 
    myCommand.Parameters.Add("Alias", ExternalAlias)
     CorrUsername = ExternalAlias 
    Else 
    myCommand.Parameters.Add("Alias", UserNm)
     CorrUsername = UserNm 
    End If
     
    addresses.Add("SMTP:" & CorrUsername & "@something.net") 
    
    DB_Main = "Mailbox\Some Folder\SomeMailBoxes" 
    myCommand.Parameters.Add("Database", DB_Main)
     pipeLine = myRunSpace.CreatePipeline()
     pipeLine.Commands.Add(myCommand) 
    MailUserResults = pipeLine.Invoke()
     If pipeLine.Error IsNot Nothing And pipeLine.Error.Count > 0 Then
     For Each item As Object In pipeLine.Error.ReadToEnd 
      temp = item.ToString & vbNewLine 
     Next 
     Throw New ArgumentException(temp)
     MsgBox("Error in pipeline - step1 (setup mailbox). Description as follows... " & temp & "!") 
    End If
     
    pipeLine = Nothing 
    myCommand = Nothing
     Sleep(35000)
     
    If ExternalEmailFlag = 0 Then 
    
    Try 
    myCommand = New Command("Set-Mailbox")
     myCommand.Parameters.Add("Identity", UserNm)
     myCommand.Parameters.Add("RequireSenderAuthenticationEnabled", True)
     pipeLine = myRunSpace.CreatePipeline()
     pipeLine.Commands.Add(myCommand)
     MailUserResults = pipeLine.Invoke()
     Catch ex As Exception
     If pipeLine.Error IsNot Nothing And pipeLine.Error.Count > 0 Then 
     For Each item As Object In pipeLine.Error.ReadToEnd 
      temp = item.ToString & vbNewLine 
    Next 
    Throw New ArgumentException(temp) 
    MsgBox("Error in pipeline - authentication checkmark. Description as follows... " & temp & "!")
     End If
     End Try
     pipeLine = Nothing
     Else Sleep(25000)
     End If
    
     'added another command - to disable sync
     Try 
    myCommand = New Command("Set-CASMailbox") 
    myCommand.Parameters.Add("Identity", UserNm)
     myCommand.Parameters.Add("ActiveSyncEnabled", False)
     pipeLine = myRunSpace.CreatePipeline() 
    pipeLine.Commands.Add(myCommand) 
    MailUserResults = pipeLine.Invoke()
     Catch ex As Exception
      If pipeLine.Error IsNot Nothing And pipeLine.Error.Count > 0 Then
     For Each item As Object In pipeLine.Error.ReadToEnd
     temp = item.ToString & vbNewLine
     Next
     Throw New ArgumentException(temp)
     MsgBox("Error in pipeline - step2 - disabling sync. Description as follows... " & temp & "!")
     End If
     End Try 
    
    pipeLine = Nothing 
    
    Catch ex As ExecutionEngineException 
    MsgBox("Error Creating Mailbox: " & Err.Description) 
    If pipeLine.Error IsNot Nothing And pipeLine.Error.Count > 0 Then 
    For Each item As Object In pipeLine.Error.ReadToEnd
     temp = item.ToString & vbNewLine 
    Next 
    Throw New ArgumentException(temp)
     MsgBox("Error in pipeline during mailbox creation. Description as follows... " & temp & "!")
     End If 
    Catch ex As Exception 
    MsgBox("Error Creating Mailbox: " & Err.Description) 
    Finally 
    MsgBox("Final Step - Mailbox was Created!") 
    myRunSpace.Close() 
    myRunSpace = Nothing 
    rsConfig = Nothing 
    info = Nothing 
    snapInException = Nothing
     myCommand = Nothing 
    MailUserResults = Nothing
     End Try 
    End Sub 
    
    
    Friday, January 21, 2011 4:28 PM

Answers

  • Hi,

    In Exchange 2010 you will need to use a remote runspace and not a local one (i.e. don't use a snap in).  To do that, replace the code you have here:

    rsConfig = RunspaceConfiguration.Create()
    'for exch 2010 - use Microsoft.Exchange.Management.PowerShell.E2010?
    info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", snapInException)
    myRunSpace = RunspaceFactory.CreateRunspace(rsConfig)

    with code smilar to this:

    <code>

    Private SHELL_URI As String = "http://schemas.microsoft.com/powershell/Microsoft.Exchange"
    ....

    Dim securePassword As System.Security.SecureString = New System.Security.SecureString()

    Dim c As Char

    Dim password As String = "MyPassword"
                
                For Each c In password.ToCharArray()
                    securePassword.AppendChar(c)
                Next

                Dim  creds As System.Management.Automation.PSCredential = New System.Management.Automation.PSCredential("MyUserName", securePassword);
    Dim serverUri As System.Uri = New Uri(String.Format("http://{0}/powershell?serializationLevel=Full", "MyServerName"));
    Dim wsManInfo As WSManConnectionInfo = New WSManConnectionInfo(serverUri, SHELL_URI, creds)

    myRunSpace = RunspaceFactory.CreateRunspace(wsManInfo))
    </code>

    If you don't want to hardcode a username and password but want to instead use the security context that is executing the code please see this blog post:

    http://blogs.msdn.com/b/dvespa/archive/2010/02/22/how-to-use-windows-authentication-with-the-pscredential-class.aspx

     

    Thursday, January 27, 2011 6:40 PM

All replies

  • Hello Alla2552,

    Thanks for your post.

    We are currently looking into this issue and it might take some time before we get back to you. Thanks for your understanding and support.

    Have a nice day.

    Best regards


    Liliane Teng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, January 24, 2011 3:50 AM
  • Hi,

    In Exchange 2010 you will need to use a remote runspace and not a local one (i.e. don't use a snap in).  To do that, replace the code you have here:

    rsConfig = RunspaceConfiguration.Create()
    'for exch 2010 - use Microsoft.Exchange.Management.PowerShell.E2010?
    info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", snapInException)
    myRunSpace = RunspaceFactory.CreateRunspace(rsConfig)

    with code smilar to this:

    <code>

    Private SHELL_URI As String = "http://schemas.microsoft.com/powershell/Microsoft.Exchange"
    ....

    Dim securePassword As System.Security.SecureString = New System.Security.SecureString()

    Dim c As Char

    Dim password As String = "MyPassword"
                
                For Each c In password.ToCharArray()
                    securePassword.AppendChar(c)
                Next

                Dim  creds As System.Management.Automation.PSCredential = New System.Management.Automation.PSCredential("MyUserName", securePassword);
    Dim serverUri As System.Uri = New Uri(String.Format("http://{0}/powershell?serializationLevel=Full", "MyServerName"));
    Dim wsManInfo As WSManConnectionInfo = New WSManConnectionInfo(serverUri, SHELL_URI, creds)

    myRunSpace = RunspaceFactory.CreateRunspace(wsManInfo))
    </code>

    If you don't want to hardcode a username and password but want to instead use the security context that is executing the code please see this blog post:

    http://blogs.msdn.com/b/dvespa/archive/2010/02/22/how-to-use-windows-authentication-with-the-pscredential-class.aspx

     

    Thursday, January 27, 2011 6:40 PM
  • Thank you, Dave. I'll give it a try and let you know... I appreciate your help!
    Alla Sanders
    Thursday, January 27, 2011 9:06 PM
  • Hello Alla2552,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions? If you have any concerns, please feel free to follow up.

    Have a nice day.

    Best regards


    Liliane Teng [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, February 9, 2011 2:41 AM
  • Sorry - I'm still waiting on our network team to setup a virtual environment for me to test it.. I'll let you know as soon as it's done.
    Alla Sanders
    Thursday, February 10, 2011 1:27 PM
  • Hi!

    Finally starting testing it. Got an error for WSManConnectionInfo - saying that this type is undefined. Please let me know which reference should I add to define it?

    I appreciate your help!


    Alla Sanders
    Thursday, March 10, 2011 3:21 PM
  • Found out the answer from another user/different thread. Thought I'll share it here - in case someone else experinces the same problem:

    Sounds to me you are using an older version of the "System.Management.Automation.dll" (should be included in PowerShell 2.0 installation).

    I had to reinstall my computer two weeks back and now have the same problem (I'm using windows 7 pro x64).

    Default VS uses the System.Management.Automation.dll in "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0", which is version 6.1.7600.16385 and misses a fiew of the needed classes like PSCommand and WSManConnectionInfo. 

    In my "C:\Windows\winsxs\msil_system.management.automation_31bf3856ad364e35_6.1.7601.17514_none_236c706c3e93d144" I have version 6.1.7601.17514, and when I change the reference to that one, everything works fine.

    I think I'm still missing some framework update which puts the latest version of the dll in "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0". When I find out which one it is, I'll let you know...


    Alla Sanders
    Friday, March 11, 2011 2:01 PM
  • Still no luck. It compiles fine, runs with no errors, but won't create mailbox. I have error check - nothing shows up. Not sure if I didn't specify uri correctly? I listed full domain name -

    http://ourservername.companyname.net/powershell?serializationLevel=Full

    For database listed folders like "ourservername\Databases\OurMailbox"

    Is it correct way or not? Any suggestions on error trapping? Thank you!


    Alla Sanders
    Friday, March 11, 2011 9:17 PM